test(nuxt): Add unit tests for catch-all routes#16891
Conversation
| @@ -0,0 +1,272 @@ | |||
| import { describe, expect, it } from 'vitest'; | |||
There was a problem hiding this comment.
Sadly the diff for this file is not visible as I did not commit the naming change in the previous PR :/
The file was already renamed with .test.ts in the other PR and the tests already went through locally. I just now found out that it was still committed with the old name (without .test.ts) which means it did not run through CI :(
| /** Creates a mock NuxtPage object with all existing pages. Nuxt provides this during the build time in the "pages:extend" hook. | ||
| * The content is inspired by a real-world example. */ | ||
| const createMockPagesData = ( | ||
| overrides: NuxtPageSubset[] = [], | ||
| addDefaultPageData: boolean = true, | ||
| ): NuxtPageSubset[] => { | ||
| const defaultBase = [ | ||
| // Basic routes | ||
| { path: '/', file: '/private/folders/application/pages/index.vue' }, | ||
| { path: '/simple-page', file: '/private/folders/application/pages/simple-page.vue' }, | ||
| { path: '/a/nested/simple-page', file: '/private/folders/application/pages/a/nested/simple-page.vue' }, | ||
| // Dynamic routes (directory and file) | ||
| { path: '/user/:userId()', file: '/private/folders/application/pages/user/[userId].vue' }, | ||
| { path: '/group-:name()/:id()', file: '/private/folders/application/pages/group-[name]/[id].vue' }, | ||
| // Catch-all routes | ||
| { path: '/catch-all/:path(.*)*', file: '/private/folders/application/pages/catch-all/[...path].vue' }, | ||
| ]; | ||
|
|
||
| return [...(addDefaultPageData ? defaultBase : []), ...overrides]; | ||
| }; | ||
|
|
||
| // The base of modules when loading a specific page during runtime (inspired by real-world examples). | ||
| const defaultSSRContextModules = new Set([ | ||
| 'node_modules/nuxt/dist/app/components/nuxt-root.vue', | ||
| 'app.vue', | ||
| 'components/Button.vue', | ||
| // ...the specific requested page is added in the test (e.g. 'pages/user/[userId].vue') | ||
| ]); |
There was a problem hiding this comment.
I will highlight the new stuff for the tests in this PR to make it easier to look through.
Those are the new functions to create some default data.
| description: 'dynamic route with brackets in file name', | ||
| modules: new Set([...defaultSSRContextModules, 'pages/user/[userId].vue']), | ||
| requestedUrl: '/user/123', | ||
| buildTimePagesData: createMockPagesData(), | ||
| expected: { parametrizedRoute: '/user/:userId()' }, | ||
| }, | ||
| { | ||
| description: 'dynamic route with brackets in directory and file name', | ||
| modules: new Set([...defaultSSRContextModules, 'pages/group-[name]/[id].vue']), | ||
| requestedUrl: '/group-sentry/123', | ||
| buildTimePagesData: createMockPagesData(), | ||
| expected: { parametrizedRoute: '/group-:name()/:id()' }, | ||
| }, | ||
| { | ||
| description: 'catch all route (simple)', | ||
| modules: new Set([...defaultSSRContextModules, 'pages/catch-all/[...path].vue']), | ||
| requestedUrl: '/catch-all/whatever', | ||
| buildTimePagesData: createMockPagesData(), | ||
| expected: { parametrizedRoute: '/catch-all/:path(.*)*' }, | ||
| }, | ||
| { | ||
| description: 'catch all route (nested)', | ||
| modules: new Set([...defaultSSRContextModules, 'pages/catch-all/[...path].vue']), | ||
| requestedUrl: '/catch-all/whatever/you/want', | ||
| buildTimePagesData: createMockPagesData(), | ||
| expected: { parametrizedRoute: '/catch-all/:path(.*)*' }, | ||
| }, |
There was a problem hiding this comment.
Those are all the basic tests for dynamic and catch-all routes.
| it('should return correct route app has a dynamic route and a static route that share the same path', () => { | ||
| const modules = new Set([...defaultSSRContextModules, 'pages/user/settings.vue']); | ||
|
|
||
| const buildTimePagesData = createMockPagesData( | ||
| [ | ||
| { path: '/user/settings', file: '/private/folders/application/pages/user/settings.vue' }, | ||
| { path: '/user/:userId()', file: '/private/folders/application/pages/user/[userId].vue' }, | ||
| ], | ||
| false, | ||
| ); | ||
|
|
||
| const result = extractParametrizedRouteFromContext(modules, '/user/settings', buildTimePagesData); | ||
| expect(result).toEqual({ parametrizedRoute: '/user/settings' }); | ||
| }); | ||
|
|
||
| it('should return correct route app has a dynamic route and a static route that share the same path (reverse)', () => { | ||
| const modules = new Set([...defaultSSRContextModules, 'pages/user/settings.vue']); | ||
|
|
||
| const buildTimePagesData = createMockPagesData([ | ||
| { path: '/user/:userId()', file: '/private/folders/application/pages/user/[userId].vue' }, | ||
| { path: '/user/settings', file: '/private/folders/application/pages/user/settings.vue' }, | ||
| ]); | ||
|
|
||
| const result = extractParametrizedRouteFromContext(modules, '/user/settings', buildTimePagesData); | ||
| expect(result).toEqual({ parametrizedRoute: '/user/settings' }); | ||
| }); |
There was a problem hiding this comment.
Those are the tests for users/:id vs users/settings.
Lms24
left a comment
There was a problem hiding this comment.
Nice, thanks a lot for adding these tests!
Test follow-up for this PR: #16843
Re-organizes the unit tests a bit to be less repetitive with default data that is aligned to real-world examples.
Adds unit tests for cases mentioned here:
users/:idvsusers/settings)