|
| 1 | +import { beforeEach, describe, expect, it, vi } from 'vitest'; |
| 2 | + |
| 3 | +const mocks = vi.hoisted(() => ({ |
| 4 | + apiFetchJson: vi.fn(), |
| 5 | +})); |
| 6 | + |
| 7 | +vi.mock('@workbench/backend/http', () => ({ |
| 8 | + apiFetchJson: mocks.apiFetchJson, |
| 9 | +})); |
| 10 | + |
| 11 | +describe('intermediates API helpers', () => { |
| 12 | + beforeEach(() => { |
| 13 | + mocks.apiFetchJson.mockReset(); |
| 14 | + }); |
| 15 | + |
| 16 | + it('reads the intermediate image count from the images endpoint', async () => { |
| 17 | + mocks.apiFetchJson.mockResolvedValueOnce(7); |
| 18 | + const { getIntermediatesCount } = await import('./intermediates'); |
| 19 | + |
| 20 | + await expect(getIntermediatesCount()).resolves.toBe(7); |
| 21 | + |
| 22 | + expect(mocks.apiFetchJson).toHaveBeenCalledWith('/api/v1/images/intermediates'); |
| 23 | + }); |
| 24 | + |
| 25 | + it('clears intermediate images with DELETE and returns the cleared count', async () => { |
| 26 | + mocks.apiFetchJson.mockResolvedValueOnce(3); |
| 27 | + const { clearIntermediates } = await import('./intermediates'); |
| 28 | + |
| 29 | + await expect(clearIntermediates()).resolves.toBe(3); |
| 30 | + |
| 31 | + expect(mocks.apiFetchJson).toHaveBeenCalledWith('/api/v1/images/intermediates', { method: 'DELETE' }); |
| 32 | + }); |
| 33 | +}); |
| 34 | + |
| 35 | +describe('clear intermediates UI state', () => { |
| 36 | + it('requires permission, a loaded nonzero count, and no active queue work', async () => { |
| 37 | + const { getClearIntermediatesState } = await import('./intermediates'); |
| 38 | + |
| 39 | + expect( |
| 40 | + getClearIntermediatesState({ canClearIntermediates: false, hasActiveQueueWork: false, intermediatesCount: 4 }) |
| 41 | + ).toEqual({ disabled: true, reason: 'Only administrators can clear intermediates.' }); |
| 42 | + |
| 43 | + expect( |
| 44 | + getClearIntermediatesState({ canClearIntermediates: true, hasActiveQueueWork: true, intermediatesCount: 4 }) |
| 45 | + ).toEqual({ disabled: true, reason: 'Wait for pending or running queue work to finish.' }); |
| 46 | + |
| 47 | + expect( |
| 48 | + getClearIntermediatesState({ canClearIntermediates: true, hasActiveQueueWork: false, intermediatesCount: 0 }) |
| 49 | + ).toEqual({ disabled: true, reason: 'There are no intermediates to clear.' }); |
| 50 | + |
| 51 | + expect( |
| 52 | + getClearIntermediatesState({ canClearIntermediates: true, hasActiveQueueWork: false, intermediatesCount: null }) |
| 53 | + ).toEqual({ disabled: true, reason: 'Loading intermediate count.' }); |
| 54 | + |
| 55 | + expect( |
| 56 | + getClearIntermediatesState({ canClearIntermediates: true, hasActiveQueueWork: false, intermediatesCount: 4 }) |
| 57 | + ).toEqual({ disabled: false }); |
| 58 | + }); |
| 59 | + |
| 60 | + it('describes the destructive clear action before confirmation', async () => { |
| 61 | + const { getClearIntermediatesConfirmation } = await import('./intermediates'); |
| 62 | + |
| 63 | + expect(getClearIntermediatesConfirmation(5)).toEqual({ |
| 64 | + body: 'This permanently deletes 5 temporary intermediate images and clears canvas layers or staged images that may reference them. Final gallery images are not removed.', |
| 65 | + confirmLabel: 'Clear intermediates', |
| 66 | + title: 'Clear intermediate images?', |
| 67 | + }); |
| 68 | + }); |
| 69 | +}); |
0 commit comments