diff --git a/packages/rudy/package.json b/packages/rudy/package.json index 02e02f252..22b496023 100644 --- a/packages/rudy/package.json +++ b/packages/rudy/package.json @@ -23,7 +23,8 @@ "prettier": "prettier", "is-pretty": "prettier --ignore-path=../../config/.prettierignore '**/*' --list-different", "prettify": "prettier --ignore-path=../../config/.prettierignore '**/*' --write", - "lint": "eslint . || true" + "lint": "eslint . || true", + "test": "jest --config ../../jest.config.js --rootDir ." }, "repository": { "type": "git", diff --git a/packages/rudy/src/utils/actionToUrl.test.js b/packages/rudy/src/utils/actionToUrl.test.js new file mode 100644 index 000000000..e050718ef --- /dev/null +++ b/packages/rudy/src/utils/actionToUrl.test.js @@ -0,0 +1,201 @@ +import actionToUrl from './actionToUrl' + +describe('Serializes params', () => { + const NOT_FOUND = 'NOT_FOUND' + const ROOT = 'ROOT' + const STATIC = 'STATIC' + const SINGLE_PARAM = 'SINGLE_PARAM' + const OPTIONAL_PARAM = 'OPTIONAL_PARAM' + const MULTIPLE_PARAMS = 'MULTIPLE_PARAMS' + const OPTIONAL_PATH_PARAM = 'OPTIONAL_PATH_PARAM' + const COMPULSORY_PATH_PARAM = 'COMPULSORY_PATH_PARAM' + const MULTI_MULTI_PARAM = 'MULTI_MULTI_PARAM' + const routes = { + [NOT_FOUND]: { + path: '/404', + }, + [ROOT]: { + path: '', + }, + [STATIC]: { + path: '/static', + }, + [SINGLE_PARAM]: { + path: '/compulsory/:param', + }, + [OPTIONAL_PARAM]: { + path: '/optional/:param?', + }, + [MULTIPLE_PARAMS]: { + path: '/multiple/:p1/:p2', + }, + [OPTIONAL_PATH_PARAM]: { + path: '/multistar/:p*', + }, + [COMPULSORY_PATH_PARAM]: { + path: '/multiplus/:p+', + }, + [MULTI_MULTI_PARAM]: { + path: '/multimulti/:p1*/separator/:p2+', + }, + } + const api = { + routes, + options: {}, + } + const assertUrlForAction = (action, url) => + expect(actionToUrl(action, api, {})).toEqual({ + url, + state: {}, + }) + + it('Static path', () => { + /** + * TODO the route regex doesn't have a trailing slash, so this + * generated URL also should not! + */ + assertUrlForAction({ type: ROOT }, '/') + assertUrlForAction({ type: STATIC }, '/static') + }) + + it('Single compulsory parameter', () => { + assertUrlForAction({ type: SINGLE_PARAM }, '/404') + + /** + * TODO null should be treated as missing, not serialised to "null" + */ + assertUrlForAction( + { type: SINGLE_PARAM, params: { param: null } }, + '/compulsory/null', + ) + + assertUrlForAction( + { type: SINGLE_PARAM, params: { param: undefined } }, + '/404', + ) + + assertUrlForAction( + { type: SINGLE_PARAM, params: { param: 'apple' } }, + '/compulsory/apple', + ) + }) + + it('Single optional parameter', () => { + assertUrlForAction({ type: OPTIONAL_PARAM }, '/optional') + + /** + * TODO null should be treated as missing, not serialised to "null" + */ + assertUrlForAction( + { type: OPTIONAL_PARAM, params: { param: null } }, + '/optional/null', + ) + + assertUrlForAction( + { type: OPTIONAL_PARAM, params: { param: undefined } }, + '/optional', + ) + + assertUrlForAction( + { type: OPTIONAL_PARAM, params: { param: 'test' } }, + '/optional/test', + ) + }) + + it('Multiple parameters', () => { + assertUrlForAction({ type: MULTIPLE_PARAMS, params: {} }, '/404') + + assertUrlForAction({ type: MULTIPLE_PARAMS, params: { p1: 1 } }, '/404') + + assertUrlForAction( + { type: MULTIPLE_PARAMS, params: { p1: 1, p2: 2 } }, + '/multiple/1/2', + ) + }) + + it('Multi segment optional parameter', () => { + assertUrlForAction({ type: OPTIONAL_PATH_PARAM }, '/multistar') + + assertUrlForAction( + { type: OPTIONAL_PATH_PARAM, params: { p: undefined } }, + '/multistar', + ) + + /** + * TODO null should be treated as missing, not serialised to "null" + */ + assertUrlForAction( + { type: OPTIONAL_PATH_PARAM, params: { p: null } }, + '/multistar/null', + ) + + assertUrlForAction({ type: OPTIONAL_PATH_PARAM, params: { p: '' } }, '/404') + + assertUrlForAction( + { type: OPTIONAL_PATH_PARAM, params: { p: 'single' } }, + '/multistar/single', + ) + + assertUrlForAction( + { type: OPTIONAL_PATH_PARAM, params: { p: 'one/two/three' } }, + '/multistar/one/two/three', + ) + }) + + it('Multi segment compulsory parameter', () => { + assertUrlForAction( + { type: COMPULSORY_PATH_PARAM, params: { p: undefined } }, + '/404', + ) + + /** + * TODO null should be treated as missing, not serialised to "null" + */ + assertUrlForAction( + { type: COMPULSORY_PATH_PARAM, params: { p: null } }, + '/multiplus/null', + ) + + assertUrlForAction( + { type: COMPULSORY_PATH_PARAM, params: { p: '' } }, + '/404', + ) + + assertUrlForAction( + { type: COMPULSORY_PATH_PARAM, params: { p: 'one' } }, + '/multiplus/one', + ) + + assertUrlForAction( + { type: COMPULSORY_PATH_PARAM, params: { p: 'one/two' } }, + '/multiplus/one/two', + ) + }) + + it('Multiple multi segment params', () => { + assertUrlForAction({ type: MULTI_MULTI_PARAM, params: {} }, '/404') + + assertUrlForAction( + { type: MULTI_MULTI_PARAM, params: { p1: 'one' } }, + '/404', + ) + + assertUrlForAction( + { type: MULTI_MULTI_PARAM, params: { p2: 'one' } }, + '/multimulti/separator/one', + ) + + assertUrlForAction( + { type: MULTI_MULTI_PARAM, params: { p2: 'one/two' } }, + '/multimulti/separator/one/two', + ) + + assertUrlForAction( + { + type: MULTI_MULTI_PARAM, + params: { p1: 'one/two', p2: 'three/four' }, + }, + '/multimulti/one/two/separator/three/four', + ) + }) +}) diff --git a/packages/rudy/src/utils/urlToAction.test.js b/packages/rudy/src/utils/urlToAction.test.js new file mode 100644 index 000000000..c382c7338 --- /dev/null +++ b/packages/rudy/src/utils/urlToAction.test.js @@ -0,0 +1,143 @@ +import urlToAction from './urlToAction' + +describe('Parses params', () => { + const NOT_FOUND = 'NOT_FOUND' + const ROOT = 'ROOT' + const STATIC = 'STATIC' + const SINGLE_PARAM = 'SINGLE_PARAM' + const OPTIONAL_PARAM = 'OPTIONAL_PARAM' + const MULTIPLE_PARAMS = 'MULTIPLE_PARAMS' + const OPTIONAL_PATH_PARAM = 'OPTIONAL_PATH_PARAM' + const COMPULSORY_PATH_PARAM = 'COMPULSORY_PATH_PARAM' + const MULTI_MULTI_PARAM = 'MULTI_MULTI_PARAM' + const routes = { + [NOT_FOUND]: { + path: '/404', + }, + [ROOT]: { + path: '', + }, + [STATIC]: { + path: '/static', + }, + [SINGLE_PARAM]: { + path: '/compulsory/:param', + }, + [OPTIONAL_PARAM]: { + path: '/optional/:param?', + }, + [MULTIPLE_PARAMS]: { + path: '/multiple/:p1/:p2', + }, + [OPTIONAL_PATH_PARAM]: { + path: '/multistar/:p*', + }, + [COMPULSORY_PATH_PARAM]: { + path: '/multiplus/:p+', + }, + [MULTI_MULTI_PARAM]: { + path: '/multimulti/:p1*/separator/:p2+', + }, + } + const api = { + routes, + options: {}, + } + + const assertActionForUrl = (url, action) => + expect(urlToAction(api, url, {})).toEqual({ + basename: '', + hash: '', + location: { + key: '345678', + pathname: url, + scene: '', + search: '', + url, + }, + query: {}, + state: {}, + params: {}, + ...action, + }) + + it('Static path', () => { + /** + * TODO the route regex doesn't have a trailing slash, so this + * URL should match! + */ + // assertActionForUrl('', { type: ROOT }) + + assertActionForUrl('/static', { type: STATIC }) + }) + + it('Single compulsory parameter', () => { + assertActionForUrl('/compulsory', { type: NOT_FOUND }) + + assertActionForUrl('/compulsory/apple', { + type: SINGLE_PARAM, + params: { param: 'apple' }, + }) + }) + + it('Single optional parameter', () => { + assertActionForUrl('/optional', { type: OPTIONAL_PARAM }) + + assertActionForUrl('/optional/test', { + type: OPTIONAL_PARAM, + params: { param: 'test' }, + }) + }) + + it('Multiple parameters', () => { + assertActionForUrl('/multiple/1/2', { + type: MULTIPLE_PARAMS, + params: { p1: '1', p2: '2' }, + }) + }) + + it('Multi segment optional parameter', () => { + assertActionForUrl('/multistar', { type: OPTIONAL_PATH_PARAM }) + + assertActionForUrl('/multistar/single', { + type: OPTIONAL_PATH_PARAM, + params: { p: 'single' }, + }) + + assertActionForUrl('/multistar/one/two/three', { + type: OPTIONAL_PATH_PARAM, + params: { p: 'one/two/three' }, + }) + }) + + it('Multi segment compulsory parameter', () => { + assertActionForUrl('/multiplus', { type: NOT_FOUND }) + + assertActionForUrl('/multiplus/one', { + type: COMPULSORY_PATH_PARAM, + params: { p: 'one' }, + }) + + assertActionForUrl('/multiplus/one/two', { + type: COMPULSORY_PATH_PARAM, + params: { p: 'one/two' }, + }) + }) + + it('Multiple multi segment params', () => { + assertActionForUrl('/multimulti/separator/one', { + type: MULTI_MULTI_PARAM, + params: { p2: 'one' }, + }) + + assertActionForUrl('/multimulti/separator/one/two', { + type: MULTI_MULTI_PARAM, + params: { p2: 'one/two' }, + }) + + assertActionForUrl('/multimulti/one/two/separator/three/four', { + type: MULTI_MULTI_PARAM, + params: { p1: 'one/two', p2: 'three/four' }, + }) + }) +})