Skip to content

Commit cb828db

Browse files
committed
Fix version dropdown group expansion behavior
- cover version page links for scoped and unscoped packages - add regression tests for collapsing groups, prop resets, and loading guards
1 parent 27f331a commit cb828db

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

test/nuxt/components/Package/Versions.spec.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { describe, expect, it, vi, beforeEach } from 'vitest'
22
import { mountSuspended } from '@nuxt/test-utils/runtime'
33
import type { DOMWrapper } from '@vue/test-utils'
4+
import type { Router } from 'vue-router'
45
import PackageVersions from '~/components/Package/Versions.vue'
6+
import { packageVersionsRoute } from '~/utils/router'
57

68
// Mock the fetchAllPackageVersions function
79
const mockFetchAllPackageVersions = vi.fn()
@@ -109,6 +111,42 @@ describe('PackageVersions', () => {
109111
expect(versionLinks[0]?.text()).toBe('1.0.0')
110112
})
111113

114+
it('view-all-versions link uses packageVersionsRoute for unscoped packages', async () => {
115+
const component = await mountSuspended(PackageVersions, {
116+
props: {
117+
packageName: 'test-package',
118+
versions: {
119+
'1.0.0': createVersion('1.0.0'),
120+
},
121+
distTags: { latest: '1.0.0' },
122+
time: { '1.0.0': '2024-01-15T12:00:00.000Z' },
123+
},
124+
})
125+
126+
const router = component.vm.$router as Router
127+
const expectedHref = router.resolve(packageVersionsRoute('test-package')).href
128+
const viewAll = component.find('[data-testid="view-all-versions-link"]')
129+
expect(viewAll.attributes('href')).toBe(expectedHref)
130+
})
131+
132+
it('view-all-versions link uses packageVersionsRoute for scoped packages', async () => {
133+
const component = await mountSuspended(PackageVersions, {
134+
props: {
135+
packageName: '@scope/test-package',
136+
versions: {
137+
'1.0.0': createVersion('1.0.0'),
138+
},
139+
distTags: { latest: '1.0.0' },
140+
time: { '1.0.0': '2024-01-15T12:00:00.000Z' },
141+
},
142+
})
143+
144+
const router = component.vm.$router as Router
145+
const expectedHref = router.resolve(packageVersionsRoute('@scope/test-package')).href
146+
const viewAll = component.find('[data-testid="view-all-versions-link"]')
147+
expect(viewAll.attributes('href')).toBe(expectedHref)
148+
})
149+
112150
it('highlights the current version row when selectedVersion prop matches', async () => {
113151
const component = await mountSuspended(PackageVersions, {
114152
props: {

test/nuxt/components/VersionSelector.spec.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { describe, expect, it, vi, beforeEach } from 'vitest'
22
import { mountSuspended } from '@nuxt/test-utils/runtime'
3+
import type { PackageVersionInfo } from '#shared/types/npm-registry'
34
import VersionSelector from '~/components/VersionSelector.vue'
45

56
// Mock the fetchAllPackageVersions function
@@ -466,6 +467,99 @@ describe('VersionSelector', () => {
466467
expect(collapsedButton.exists()).toBe(true)
467468
})
468469
})
470+
471+
it('collapses additional version groups with ArrowLeft when showAllGroups is open', async () => {
472+
mockFetchAllPackageVersions.mockResolvedValue([
473+
{ version: '1.0.0', time: '2024-01-15T12:00:00.000Z', hasProvenance: false },
474+
{ version: '0.9.0', time: '2024-01-10T12:00:00.000Z', hasProvenance: false },
475+
])
476+
477+
const component = await mountSuspended(VersionSelector, {
478+
props: {
479+
packageName: 'test-package',
480+
currentVersion: '1.0.0',
481+
versions: { '1.0.0': {}, '0.9.0': {} },
482+
distTags: { latest: '1.0.0' },
483+
urlPattern: '/package-docs/test-package/v/{version}',
484+
},
485+
})
486+
487+
const trigger = component.find('button[aria-haspopup="listbox"]')
488+
await trigger.trigger('click')
489+
490+
await component.find('[role="listbox"] button[aria-expanded="false"]').trigger('click')
491+
492+
await vi.waitFor(() => {
493+
expect(component.find('[role="listbox"]').text()).toContain('0.9')
494+
})
495+
496+
const listbox = component.find('[role="listbox"]')
497+
await listbox.trigger('keydown', { key: 'ArrowLeft' })
498+
499+
await vi.waitFor(() => {
500+
expect(listbox.text()).not.toContain('0.9')
501+
})
502+
})
503+
504+
it('resets showAllGroups when dist-tags props change after loading', async () => {
505+
mockFetchAllPackageVersions.mockResolvedValue([
506+
{ version: '1.0.0', time: '2024-01-15T12:00:00.000Z', hasProvenance: false },
507+
{ version: '0.9.0', time: '2024-01-10T12:00:00.000Z', hasProvenance: false },
508+
])
509+
510+
const component = await mountSuspended(VersionSelector, {
511+
props: {
512+
packageName: 'test-package',
513+
currentVersion: '1.0.0',
514+
versions: { '1.0.0': {}, '0.9.0': {} },
515+
distTags: { latest: '1.0.0' },
516+
urlPattern: '/package-docs/test-package/v/{version}',
517+
},
518+
})
519+
520+
const trigger = component.find('button[aria-haspopup="listbox"]')
521+
await trigger.trigger('click')
522+
await component.find('[role="listbox"] button[aria-expanded="false"]').trigger('click')
523+
524+
await vi.waitFor(() => {
525+
expect(component.find('[role="listbox"]').text()).toContain('0.9')
526+
})
527+
528+
await component.setProps({ distTags: { latest: '1.0.0' } })
529+
530+
await vi.waitFor(() => {
531+
expect(component.find('[role="listbox"]').text()).not.toContain('0.9')
532+
})
533+
})
534+
535+
it('ignores expand clicks while a group is already loading', async () => {
536+
let finishLoad: (value: PackageVersionInfo[]) => void
537+
const loadPromise = new Promise<PackageVersionInfo[]>(resolve => {
538+
finishLoad = resolve
539+
})
540+
mockFetchAllPackageVersions.mockReturnValue(loadPromise)
541+
542+
const component = await mountSuspended(VersionSelector, {
543+
props: {
544+
packageName: 'test-package',
545+
currentVersion: '1.0.0',
546+
versions: { '1.0.0': {} },
547+
distTags: { latest: '1.0.0' },
548+
urlPattern: '/package-docs/test-package/v/{version}',
549+
},
550+
})
551+
552+
const trigger = component.find('button[aria-haspopup="listbox"]')
553+
await trigger.trigger('click')
554+
555+
const expandButton = component.find('[role="listbox"] button[aria-expanded]')
556+
await expandButton.trigger('click')
557+
await expandButton.trigger('click')
558+
559+
expect(mockFetchAllPackageVersions).toHaveBeenCalledTimes(1)
560+
561+
finishLoad!([{ version: '1.0.0', time: '2024-01-15T12:00:00.000Z', hasProvenance: false }])
562+
})
469563
})
470564

471565
describe('0.x version grouping', () => {

0 commit comments

Comments
 (0)