diff --git a/client/src/features/book-requests/__tests__/RequestSearchPanel.spec.ts b/client/src/features/book-requests/__tests__/RequestSearchPanel.spec.ts index 453f8a9e0..86f7f0b4e 100644 --- a/client/src/features/book-requests/__tests__/RequestSearchPanel.spec.ts +++ b/client/src/features/book-requests/__tests__/RequestSearchPanel.spec.ts @@ -347,6 +347,24 @@ describe('RequestSearchPanel provider sources', () => { expect(document.body.textContent).toContain('Recommended') }) + it('makes the selected media kind visually distinct', async () => { + const wrapper = await render() + const ebook = wrapper.findAll('button').find((button) => button.text() === 'E-book')! + const audiobook = wrapper.findAll('button').find((button) => button.text() === 'Audiobook')! + + expect(ebook.attributes('aria-pressed')).toBe('true') + expect(ebook.classes()).toEqual(expect.arrayContaining(['bg-primary', 'text-primary-foreground'])) + expect(audiobook.attributes('aria-pressed')).toBe('false') + expect(audiobook.classes()).toEqual(expect.arrayContaining(['text-foreground', 'hover:bg-accent'])) + + await audiobook.trigger('click') + + expect(ebook.attributes('aria-pressed')).toBe('false') + expect(ebook.classes()).toEqual(expect.arrayContaining(['text-foreground', 'hover:bg-accent'])) + expect(audiobook.attributes('aria-pressed')).toBe('true') + expect(audiobook.classes()).toEqual(expect.arrayContaining(['bg-primary', 'text-primary-foreground'])) + }) + it('defaults a user with both fulfillment permissions to automation', async () => { state.hasPermission.mockImplementation( (permission: string) => permission === Permission.BookRequestAutoApprove || permission === Permission.BookRequestSelfFulfill, @@ -358,7 +376,9 @@ describe('RequestSearchPanel provider sources', () => { const automatic = wrapper.findAll('button').find((button) => button.text() === 'Automatic')! const choose = wrapper.findAll('button').find((button) => button.text() === 'Choose a release')! expect(automatic.attributes('aria-pressed')).toBe('true') + expect(automatic.classes()).toEqual(expect.arrayContaining(['bg-primary', 'text-primary-foreground'])) expect(choose.attributes('aria-pressed')).toBe('false') + expect(choose.classes()).toEqual(expect.arrayContaining(['text-foreground', 'hover:bg-accent'])) expect(wrapper.find('button[aria-label="How BookOrbit chooses the recommended ISBN"]').exists()).toBe(false) await wrapper @@ -385,12 +405,12 @@ describe('RequestSearchPanel provider sources', () => { .find((button) => button.text() === 'Choose a release')! .trigger('click') - expect( - wrapper - .findAll('button') - .find((button) => button.text() === 'Choose a release')! - .attributes('aria-pressed'), - ).toBe('true') + const automatic = wrapper.findAll('button').find((button) => button.text() === 'Automatic')! + const choose = wrapper.findAll('button').find((button) => button.text() === 'Choose a release')! + expect(automatic.attributes('aria-pressed')).toBe('false') + expect(automatic.classes()).toEqual(expect.arrayContaining(['text-foreground', 'hover:bg-accent'])) + expect(choose.attributes('aria-pressed')).toBe('true') + expect(choose.classes()).toEqual(expect.arrayContaining(['bg-primary', 'text-primary-foreground'])) expect(wrapper.find('button[aria-label="How BookOrbit chooses the recommended ISBN"]').exists()).toBe(true) await wrapper diff --git a/client/src/features/book-requests/__tests__/RequestSeedPanel.spec.ts b/client/src/features/book-requests/__tests__/RequestSeedPanel.spec.ts index 10097f3d8..c493bde25 100644 --- a/client/src/features/book-requests/__tests__/RequestSeedPanel.spec.ts +++ b/client/src/features/book-requests/__tests__/RequestSeedPanel.spec.ts @@ -80,6 +80,33 @@ describe('RequestSeedPanel', () => { expect(wrapper.text()).toContain('1.25 of 2') }) + it('shows an active transfer as downloading rather than stopped', async () => { + apiMock.mockResolvedValue(response(JSON.stringify(seed({ seeding: false, ratio: 0, seedingTimeSeconds: 0, uploadedBytes: 0 })))) + + const wrapper = await mountPanel({ + request: request({ download: { ...request().download!, status: 'downloading' } }), + }) + + expect(wrapper.text()).toContain('Downloading') + expect(wrapper.text()).not.toContain('Stopped') + }) + + it('re-reads the seed state when the download advances', async () => { + apiMock + .mockResolvedValueOnce(response(JSON.stringify(seed({ seeding: false, ratio: 0, seedingTimeSeconds: 0, uploadedBytes: 0 })))) + .mockResolvedValueOnce(response(JSON.stringify(seed()))) + const wrapper = await mountPanel({ + request: request({ download: { ...request().download!, status: 'downloading' } }), + }) + + await wrapper.setProps({ request: request() }) + await flushPromises() + + expect(apiMock).toHaveBeenCalledTimes(2) + expect(wrapper.text()).toContain('Seeding') + expect(wrapper.text()).not.toContain('Stopped') + }) + it('shows the ratio and the time against the goals the client was given', async () => { const wrapper = await mountPanel() diff --git a/client/src/features/book-requests/components/RequestSearchPanel.vue b/client/src/features/book-requests/components/RequestSearchPanel.vue index fc89c3b44..ec912de78 100644 --- a/client/src/features/book-requests/components/RequestSearchPanel.vue +++ b/client/src/features/book-requests/components/RequestSearchPanel.vue @@ -601,7 +601,7 @@ function mediaIconFor(kind: BookRequestMediaKind) { :key="kind" type="button" class="inline-flex h-full items-center gap-1.5 rounded-md px-2.5 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none motion-reduce:transition-none" - :class="mediaKind === kind ? 'bg-background text-foreground shadow-xs' : 'text-muted-foreground hover:text-foreground'" + :class="mediaKind === kind ? 'bg-primary text-primary-foreground shadow-sm' : 'text-foreground hover:bg-accent'" :aria-pressed="mediaKind === kind" @click="selectMediaKind(kind)" > @@ -618,7 +618,7 @@ function mediaIconFor(kind: BookRequestMediaKind) {