refactor(client): docs, ts and test challenges (#42978)

* refactor(client): relocate to learn path tests file

* refactor(client): add docs for to learn path

Co-authored-by: Huyen Nguyen <25715018+huyenltnguyen@users.noreply.github.com>

* fix: order imports

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Victor Duarte
2021-08-10 08:22:39 -05:00
committed by GitHub
parent 0de2cc97db
commit 7c6524186e
5 changed files with 125 additions and 66 deletions

View File

@ -1,38 +0,0 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
/**
* TODO:
* Passing incomplete objects here is causing TS to be angry.
* We should either make the expected properties optional, or reevaluate
* these tests.
*/
import { withPrefix } from 'gatsby';
import toLearnPath from '../utils/to-learn-path';
describe('toLearnPath', () => {
it('should return a string', () => {
expect(typeof toLearnPath({})).toBe('string');
});
it('should include /learn', () => {
expect(toLearnPath({})).toMatch(withPrefix('/learn'));
});
it('should include superBlock after learn', () => {
expect(toLearnPath({ superBlock: 'testSuper' })).toBe(
withPrefix('/learn/testSuper')
);
});
it('should include superBlock, then block after learn', () => {
expect(toLearnPath({ superBlock: 'testSuper', block: 'testBlock' })).toBe(
withPrefix('/learn/testSuper/testBlock')
);
});
it('should include superBlock, block, then challenge after learn', () => {
expect(
toLearnPath({
superBlock: 'testSuper',
block: 'testBlock',
challenge: 'testChallenge'
})
).toBe(withPrefix('/learn/testSuper/testBlock/testChallenge'));
});
});

View File

@ -0,0 +1,61 @@
import {
createHistory,
createMemorySource,
LocationProvider
} from '@reach/router';
import { render } from '@testing-library/react';
import { navigate, withPrefix } from 'gatsby';
import React from 'react';
import Challenges from './challenges';
describe('Challenges', () => {
// Source: https://testing-library.com/docs/example-reach-router/
function renderWithRouterWrapper({
route = '/',
history = createHistory(createMemorySource(route))
} = {}) {
return {
...render(
<LocationProvider history={history}>
<Challenges />
</LocationProvider>
),
// adding `history` to the returned utilities to allow us
// to reference it in our tests (just try to avoid using
// this to test implementation details).
history
};
}
const challenges = withPrefix('/challenges');
const learn = withPrefix('/learn');
it('should handle redirect to /learn', () => {
renderWithRouterWrapper({ route: challenges });
expect(navigate).toHaveBeenLastCalledWith(learn);
});
it('should handle redirect to /learn/:super-block', () => {
renderWithRouterWrapper({ route: `${challenges}/super-block` });
expect(navigate).toHaveBeenLastCalledWith(`${learn}/super-block`);
});
it('should handle redirect to /learn/:super-block/:block', () => {
renderWithRouterWrapper({ route: `${challenges}/super-block/block` });
expect(navigate).toHaveBeenLastCalledWith(`${learn}/super-block/block`);
});
it('should handle redirect to /learn/:super-block/:block/:challenge', () => {
renderWithRouterWrapper({
route: `${challenges}/super-block/block/challenge`
});
expect(navigate).toHaveBeenLastCalledWith(
`${learn}/super-block/block/challenge`
);
});
});

View File

@ -1,32 +1,25 @@
// this exists purely to redirect legacy challenge paths to /learn
import { Router } from '@reach/router';
// This exists purely to redirect legacy challenge paths to /learn that could
// exist in the web (posts, url shares, etc).
import { Router, RouteComponentProps } from '@reach/router';
import { navigate, withPrefix } from 'gatsby';
import React from 'react';
import toLearnPath from '../utils/to-learn-path';
// interface RedirectProps1 {
// superBlock: string;
// block: string;
// challenge: string;
// }
type RouteComponentPropsExtended = RouteComponentProps & {
block?: string;
challenge?: string;
superBlock?: string;
};
// interface RedirectProps2 {
// path?: string;
// default?: boolean;
// }
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
function Redirect(props) {
function Redirect(props: RouteComponentPropsExtended): null {
if (typeof window !== 'undefined') {
void navigate(toLearnPath(props));
}
return null;
}
// Unsure about Redirect props shape:
// toLearnPath() takes required superBlock, block, and challenge props
// but usage below has optional path and default props
function Challenges(): JSX.Element {
return (

View File

@ -0,0 +1,31 @@
import { withPrefix } from 'gatsby';
import toLearnPath from './to-learn-path';
describe('To learn path utility (toLearnPath)', () => {
const learn = withPrefix('/learn');
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({ block: 'testBlock', superBlock: 'testSuper' })).toBe(
`${learn}/testSuper/testBlock`
);
});
it('should include superBlock, block, then challenge after learn', () => {
expect(
toLearnPath({
block: 'testBlock',
challenge: 'testChallenge',
superBlock: 'testSuper'
})
).toBe(`${learn}/testSuper/testBlock/testChallenge`);
});
});

View File

@ -1,18 +1,30 @@
import { withPrefix } from 'gatsby';
interface ToLearnPathKwargs {
superBlock: string;
block: string;
challenge: string;
block?: string;
challenge?: string;
superBlock?: string;
}
/**
* Builds a learning url path from folders.
* - /learn/:superBlock/:block/:challenge
* @params {Object} Path kwargs.
* @returns {string} A learning url path.
*/
export default function toLearnPath({
superBlock,
block,
challenge
challenge,
superBlock
}: ToLearnPathKwargs): string {
let path = withPrefix('/learn');
if (superBlock) path += `/${superBlock}`;
if (block) path += `/${block}`;
if (challenge) path += `/${challenge}`;
return path;
// Match path order /:super-block/:block/:challenge
const folders = [superBlock, block, challenge];
return folders.reduce((path: string, folder) => {
if (folder) {
return `${path}/${folder}`;
}
return path;
}, withPrefix('/learn'));
}