feat: settings data section with export and backups
This commit is contained in:
@@ -20,6 +20,8 @@ vi.mock('../src/api.js', async (importOriginal) => {
|
||||
createUser: vi.fn(),
|
||||
deleteUser: vi.fn(),
|
||||
logout: vi.fn(),
|
||||
triggerBackup: vi.fn(),
|
||||
getBackups: vi.fn(),
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -56,12 +58,13 @@ function stubAuthFetch(user: User) {
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
for (const fn of [api.getSettings, api.putSettings, api.syncStatus, api.startSync, api.listUsers, api.createUser, api.deleteUser, api.logout] as const) {
|
||||
for (const fn of [api.getSettings, api.putSettings, api.syncStatus, api.startSync, api.listUsers, api.createUser, api.deleteUser, api.logout, api.triggerBackup, api.getBackups] as const) {
|
||||
vi.mocked(fn).mockReset()
|
||||
}
|
||||
vi.mocked(api.getSettings).mockResolvedValue(emptyView as never)
|
||||
vi.mocked(api.syncStatus).mockResolvedValue(idleSync as never)
|
||||
vi.mocked(api.listUsers).mockResolvedValue({ users: [admin] } as never)
|
||||
vi.mocked(api.getBackups).mockResolvedValue({ backups: [] } as never)
|
||||
stubAuthFetch(admin)
|
||||
})
|
||||
|
||||
@@ -179,4 +182,23 @@ describe('SettingsPage', () => {
|
||||
await waitFor(() => expect(screen.getByText(/42 albums synced/i)).toBeTruthy(), { timeout: 3000 })
|
||||
expect(vi.mocked(api.syncStatus).mock.calls.length).toBeGreaterThanOrEqual(3)
|
||||
})
|
||||
|
||||
it('data section: export link, backup now, backups list', async () => {
|
||||
vi.mocked(api.triggerBackup).mockResolvedValue({ file: 'record-shop-2026-09-03-120000.db' } as never)
|
||||
vi.mocked(api.getBackups).mockResolvedValue({
|
||||
backups: [{ file: 'record-shop-2026-09-03-120000.db', sizeBytes: 12345, createdAt: '2026-09-03T12:00:00Z' }],
|
||||
} as never)
|
||||
renderSettings()
|
||||
expect(await screen.findByRole('link', { name: /export json/i })).toHaveProperty('href')
|
||||
await userEvent.click(screen.getByRole('button', { name: /back up now/i }))
|
||||
await waitFor(() => expect(api.triggerBackup).toHaveBeenCalled())
|
||||
await waitFor(() => expect(screen.getByText(/record-shop-2026-09-03-120000\.db/)).toBeTruthy())
|
||||
})
|
||||
|
||||
it('backup failure surfaces in the flash banner', async () => {
|
||||
vi.mocked(api.triggerBackup).mockRejectedValue(new TypeError('fetch failed'))
|
||||
renderSettings()
|
||||
await userEvent.click(await screen.findByRole('button', { name: /back up now/i }))
|
||||
await waitFor(() => expect(screen.getByText(/backup failed/i)).toBeTruthy())
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user