From c7c54fe0b12250b3739b131549587772fe689543 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 18 Mar 2026 18:21:01 +0000 Subject: [PATCH 1/6] tests: add tests for `parsePackageParams` --- .../server/utils/parse-package-params.spec.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 test/unit/server/utils/parse-package-params.spec.ts diff --git a/test/unit/server/utils/parse-package-params.spec.ts b/test/unit/server/utils/parse-package-params.spec.ts new file mode 100644 index 000000000..f020f7068 --- /dev/null +++ b/test/unit/server/utils/parse-package-params.spec.ts @@ -0,0 +1,53 @@ +import { describe, expect, it } from 'vitest' +import { parsePackageParams } from '#server/utils/parse-package-params' + +describe('parsePackageParams', () => { + describe('unscoped packages', () => { + it('parses package name without version', () => { + const segments = ['vue'] + const result = parsePackageParams(segments) + expect(result).toEqual({ + rawPackageName: 'vue', + rawVersion: undefined, + }) + }) + + it('parses package name with version', () => { + const segments = ['vue', 'v', '3.4.0'] + const result = parsePackageParams(segments) + expect(result).toEqual({ + rawPackageName: 'vue', + rawVersion: '3.4.0', + }) + }) + + it('parses package name with prerelease version', () => { + const segments = ['nuxt', 'v', '4.0.0-rc.1'] + const result = parsePackageParams(segments) + expect(result).toEqual({ + rawPackageName: 'nuxt', + rawVersion: '4.0.0-rc.1', + }) + }) + }) + + describe('scoped packages', () => { + it('parses scoped package name without version', () => { + const segments = ['@nuxt', 'kit'] + const result = parsePackageParams(segments) + expect(result).toEqual({ + rawPackageName: '@nuxt/kit', + rawVersion: undefined, + }) + }) + + it('parses scoped package name with version', () => { + const segments = ['@nuxt', 'kit', 'v', '1.0.0'] + const result = parsePackageParams(segments) + expect(result).toEqual({ + rawPackageName: '@nuxt/kit', + rawVersion: '1.0.0', + }) + }) + }) +}) From 2c0f0cb171355062351089af55caccd11f923cf7 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 18 Mar 2026 18:26:12 +0000 Subject: [PATCH 2/6] fix: correctly decode `rawPackageName` --- server/api/registry/analysis/[...pkg].get.ts | 2 +- server/api/registry/install-size/[...pkg].get.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/api/registry/analysis/[...pkg].get.ts b/server/api/registry/analysis/[...pkg].get.ts index e9a2e906a..940bc2592 100644 --- a/server/api/registry/analysis/[...pkg].get.ts +++ b/server/api/registry/analysis/[...pkg].get.ts @@ -41,7 +41,7 @@ export default defineCachedEventHandler( try { const { packageName, version } = v.parse(PackageRouteParamsSchema, { - packageName: rawPackageName, + packageName: decodeURIComponent(rawPackageName), version: rawVersion, }) diff --git a/server/api/registry/install-size/[...pkg].get.ts b/server/api/registry/install-size/[...pkg].get.ts index 007ae4d68..1035e4c66 100644 --- a/server/api/registry/install-size/[...pkg].get.ts +++ b/server/api/registry/install-size/[...pkg].get.ts @@ -18,7 +18,7 @@ export default defineCachedEventHandler( try { const { packageName, version: requestedVersion } = v.parse(PackageRouteParamsSchema, { - packageName: rawPackageName, + packageName: decodeURIComponent(rawPackageName), version: rawVersion, }) From e57d3ee28563dc82578ca16419132b69cf28142e Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 13:25:03 +0000 Subject: [PATCH 3/6] test: add suggested e2e test by rabbit --- test/e2e/interactions.spec.ts | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/test/e2e/interactions.spec.ts b/test/e2e/interactions.spec.ts index adcefba80..7170b210c 100644 --- a/test/e2e/interactions.spec.ts +++ b/test/e2e/interactions.spec.ts @@ -47,6 +47,62 @@ test.describe('Compare Page', () => { const noDepColumn = grid.locator('.comparison-cell-nodep') await expect(noDepColumn).toBeVisible() }) + + test('loads install-size data for a scoped package', async ({ page, goto }) => { + // Intercept the internal API call the browser makes for install-size. + // The browser will request /api/registry/install-size/@nuxt%2Fkit (encoded slash). + // Before the fix this would fail to parse and return an error; after it returns 200. + const installSizeResponse = page.waitForResponse( + res => + res.url().includes('/api/registry/install-size/') && + res.url().includes('nuxt') && + res.request().method() === 'GET', + { timeout: 20_000 }, + ) + + await goto('/compare?packages=@nuxt/kit,vue', { waitUntil: 'hydration' }) + + const response = await installSizeResponse + expect(response.status()).toBe(200) + + const body = await response.json() + // The API should return a valid install size object, not an error + expect(body).toHaveProperty('installSize') + }) + + test('loads analysis data for a scoped package', async ({ page, goto }) => { + const analysisResponse = page.waitForResponse( + res => + res.url().includes('/api/registry/analysis/') && + res.url().includes('nuxt') && + res.request().method() === 'GET', + { timeout: 20_000 }, + ) + + await goto('/compare?packages=@nuxt/kit,vue', { waitUntil: 'hydration' }) + + const response = await analysisResponse + expect(response.status()).toBe(200) + + const body = await response.json() + expect(body).toHaveProperty('package', '@nuxt/kit') + }) + + test('compare grid shows data (not all dashes) for a scoped package', async ({ + page, + goto, + }) => { + await goto('/compare?packages=@nuxt/kit,vue', { waitUntil: 'hydration' }) + + const grid = page.locator('.comparison-grid') + await expect(grid).toBeVisible({ timeout: 20_000 }) + + // Package size row should have a value for the scoped package column, + // not a dash, which would indicate the API call failed before the fix. + const packageSizeRow = grid.locator('[data-facet="packageSize"]') + await expect(packageSizeRow).toBeVisible({ timeout: 15_000 }) + await expect(packageSizeRow.locator('.comparison-cell').first()).not.toContainText('-') + }) }) test.describe('Search Pages', () => { From 35e613f2dec31379ee181f890bafdc86d3242cd3 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 13:26:07 +0000 Subject: [PATCH 4/6] [autofix.ci] apply automated fixes --- test/e2e/interactions.spec.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/e2e/interactions.spec.ts b/test/e2e/interactions.spec.ts index 7170b210c..d910f1769 100644 --- a/test/e2e/interactions.spec.ts +++ b/test/e2e/interactions.spec.ts @@ -88,10 +88,7 @@ test.describe('Compare Page', () => { expect(body).toHaveProperty('package', '@nuxt/kit') }) - test('compare grid shows data (not all dashes) for a scoped package', async ({ - page, - goto, - }) => { + test('compare grid shows data (not all dashes) for a scoped package', async ({ page, goto }) => { await goto('/compare?packages=@nuxt/kit,vue', { waitUntil: 'hydration' }) const grid = page.locator('.comparison-grid') From 86138995ed1de9c11ec5aa76c2cc4748d8badca3 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 13:34:44 +0000 Subject: [PATCH 5/6] fix test --- test/e2e/interactions.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/e2e/interactions.spec.ts b/test/e2e/interactions.spec.ts index d910f1769..87169fefb 100644 --- a/test/e2e/interactions.spec.ts +++ b/test/e2e/interactions.spec.ts @@ -67,7 +67,8 @@ test.describe('Compare Page', () => { const body = await response.json() // The API should return a valid install size object, not an error - expect(body).toHaveProperty('installSize') + expect(body).toHaveProperty('selfSize') + expect(body).toHaveProperty('totalSize') }) test('loads analysis data for a scoped package', async ({ page, goto }) => { @@ -86,6 +87,7 @@ test.describe('Compare Page', () => { const body = await response.json() expect(body).toHaveProperty('package', '@nuxt/kit') + expect(body).toHaveProperty('moduleFormat', 'esm') }) test('compare grid shows data (not all dashes) for a scoped package', async ({ page, goto }) => { From 7142d6db295e1c5f98926d6c2115549fbba3054d Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 19 Mar 2026 13:41:21 +0000 Subject: [PATCH 6/6] test: remove hallucinated thing --- test/e2e/interactions.spec.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/test/e2e/interactions.spec.ts b/test/e2e/interactions.spec.ts index 87169fefb..4a1a582fb 100644 --- a/test/e2e/interactions.spec.ts +++ b/test/e2e/interactions.spec.ts @@ -89,19 +89,6 @@ test.describe('Compare Page', () => { expect(body).toHaveProperty('package', '@nuxt/kit') expect(body).toHaveProperty('moduleFormat', 'esm') }) - - test('compare grid shows data (not all dashes) for a scoped package', async ({ page, goto }) => { - await goto('/compare?packages=@nuxt/kit,vue', { waitUntil: 'hydration' }) - - const grid = page.locator('.comparison-grid') - await expect(grid).toBeVisible({ timeout: 20_000 }) - - // Package size row should have a value for the scoped package column, - // not a dash, which would indicate the API call failed before the fix. - const packageSizeRow = grid.locator('[data-facet="packageSize"]') - await expect(packageSizeRow).toBeVisible({ timeout: 15_000 }) - await expect(packageSizeRow.locator('.comparison-cell').first()).not.toContainText('-') - }) }) test.describe('Search Pages', () => {