fix: redirect /challenges/* to /learn/*
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
e0407bf020
commit
4a45b5ac1c
@ -208,6 +208,18 @@ exports.onCreateBabelConfig = ({ actions }) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.onCreatePage = async ({ page, actions }) => {
|
||||||
|
const { createPage } = actions;
|
||||||
|
// Only update the `/challenges` page.
|
||||||
|
if (page.path.match(/^\/challenges/)) {
|
||||||
|
// page.matchPath is a special key that's used for matching pages
|
||||||
|
// with corresponding routes only on the client.
|
||||||
|
page.matchPath = '/challenges/*';
|
||||||
|
// Update the page.
|
||||||
|
createPage(page);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: this broke the React challenges, not sure why, but I'll investigate
|
// TODO: this broke the React challenges, not sure why, but I'll investigate
|
||||||
// further and reimplement if it's possible and necessary (Oliver)
|
// further and reimplement if it's possible and necessary (Oliver)
|
||||||
// Typically the schema can be inferred, but not when some challenges are
|
// Typically the schema can be inferred, but not when some challenges are
|
||||||
|
36
client/src/pages/challenges.js
Normal file
36
client/src/pages/challenges.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// this exists purely to redirect legacy challenge paths to /learn
|
||||||
|
import React from 'react';
|
||||||
|
import { Router } from '@reach/router';
|
||||||
|
import { navigate } from 'gatsby';
|
||||||
|
|
||||||
|
import createRedirect from '../components/createRedirect';
|
||||||
|
|
||||||
|
const RedirectToLearn = createRedirect('/learn');
|
||||||
|
|
||||||
|
const Redirect = props => {
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
navigate(toLearnPath(props));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Challenges = () => (
|
||||||
|
<Router basepath='/challenges'>
|
||||||
|
<Redirect path='/:superBlock/' />
|
||||||
|
<Redirect path='/:superBlock/:block/' />
|
||||||
|
<Redirect path='/:superBlock/:block/:challenge' />
|
||||||
|
<RedirectToLearn default={true} />
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
|
||||||
|
Challenges.displayName = 'Challenges';
|
||||||
|
|
||||||
|
export function toLearnPath({ superBlock, block, challenge }) {
|
||||||
|
let path = '/learn';
|
||||||
|
if (superBlock) path += `/${superBlock}`;
|
||||||
|
if (block) path += `/${block}`;
|
||||||
|
if (challenge) path += `/${challenge}`;
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Challenges;
|
28
client/src/pages/challenges.test.js
Normal file
28
client/src/pages/challenges.test.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* global expect */
|
||||||
|
import { toLearnPath } from './challenges';
|
||||||
|
|
||||||
|
describe('toLearnPath', () => {
|
||||||
|
it('should return a string', () => {
|
||||||
|
expect(typeof toLearnPath({})).toBe('string');
|
||||||
|
});
|
||||||
|
it('should include /learn', () => {
|
||||||
|
expect(toLearnPath({})).toMatch(/\/learn/);
|
||||||
|
});
|
||||||
|
it('should include superBlock after learn', () => {
|
||||||
|
expect(toLearnPath({ superBlock: 'testSuper' })).toBe('/learn/testSuper');
|
||||||
|
});
|
||||||
|
it('should include superBlock, then block after learn', () => {
|
||||||
|
expect(toLearnPath({ superBlock: 'testSuper', block: 'testBlock' })).toBe(
|
||||||
|
'/learn/testSuper/testBlock'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should include superBlock, block, then challenge after learn', () => {
|
||||||
|
expect(
|
||||||
|
toLearnPath({
|
||||||
|
superBlock: 'testSuper',
|
||||||
|
block: 'testBlock',
|
||||||
|
challenge: 'testChallenge'
|
||||||
|
})
|
||||||
|
).toBe('/learn/testSuper/testBlock/testChallenge');
|
||||||
|
});
|
||||||
|
});
|
51
cypress/integration/learn/redirects/challenges.js
Normal file
51
cypress/integration/learn/redirects/challenges.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* global cy expect */
|
||||||
|
|
||||||
|
const locations = {
|
||||||
|
chalSuper: '/challenges/responsive-web-design/',
|
||||||
|
chalBlock: '/challenges/responsive-web-design/basic-html-and-html5',
|
||||||
|
chalChallenge:
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
'/challenges/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements',
|
||||||
|
learnSuper: '/learn/responsive-web-design',
|
||||||
|
learnBlock: '/learn/responsive-web-design/basic-html-and-html5',
|
||||||
|
learnChallenge:
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
'/learn/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements'
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('challenges/superblock redirect', function() {
|
||||||
|
it('redirects to learn/superblock', () => {
|
||||||
|
cy.visit(locations.chalSuper);
|
||||||
|
|
||||||
|
cy.title().should('eq', 'Responsive Web Design | freeCodeCamp.org');
|
||||||
|
cy.location().should(loc => {
|
||||||
|
expect(loc.pathname).to.eq(locations.learnSuper);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('challenges/superblock/block redirect', function() {
|
||||||
|
it('redirects to learn/superblock/block', () => {
|
||||||
|
cy.visit(locations.chalBlock);
|
||||||
|
|
||||||
|
cy.title().should('eq', 'Basic HTML and HTML5 | freeCodeCamp.org');
|
||||||
|
cy.location().should(loc => {
|
||||||
|
expect(loc.pathname).to.eq(locations.learnBlock);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('challenges/superblock/block/challenge redirect', function() {
|
||||||
|
it('redirects to learn/superblock/block/challenge', () => {
|
||||||
|
cy.visit(locations.chalChallenge);
|
||||||
|
|
||||||
|
cy.title().should(
|
||||||
|
'eq',
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
'Learn Basic HTML and HTML5: Say Hello to HTML Elements | freeCodeCamp.org'
|
||||||
|
);
|
||||||
|
cy.location().should(loc => {
|
||||||
|
expect(loc.pathname).to.eq(locations.learnChallenge);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Reference in New Issue
Block a user