Merge branch 'worktree-agent-a5f48334696288159'
# Conflicts: # gerbil-manager-web/e2e/mock-data.ts
This commit is contained in:
45
gerbil-manager-web/e2e/erwerb.spec.ts
Normal file
45
gerbil-manager-web/e2e/erwerb.spec.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
/** ERWERB: Erwerb/Kauf je Tier — Sektion in der Rennmausakte (anlegen / bearbeiten / löschen). */
|
||||
import { de, expect, skipUnlessMock, test } from './fixtures'
|
||||
|
||||
const t = de.pages.tierTabs.acquisition
|
||||
|
||||
test('Tierakte: Erwerb erfassen, bearbeiten und löschen', async ({ page, mockDb }) => {
|
||||
skipUnlessMock()
|
||||
await page.goto('/rennmaeuse/kruemel')
|
||||
|
||||
const section = page.locator('section.ak-card', { hasText: t.sectionTitle })
|
||||
await expect(section).toBeVisible()
|
||||
await expect(section).toContainText(t.empty)
|
||||
|
||||
// Anlegen: Formular öffnen, Felder füllen, speichern.
|
||||
await section.getByRole('button', { name: t.addButton }).click()
|
||||
await section.getByLabel(t.fields.date).fill('2025-03-14')
|
||||
await section.getByLabel(t.fields.price).fill('25.50')
|
||||
await section.getByLabel(t.fields.note).fill('Auf der Börse gekauft.')
|
||||
await section.getByRole('button', { name: t.addButton }).click()
|
||||
|
||||
// Eintrag erscheint in der Liste, im Mock gespeichert.
|
||||
await expect(section).toContainText('25,50')
|
||||
await expect(section).toContainText('Auf der Börse gekauft.')
|
||||
expect(mockDb).not.toBeNull()
|
||||
expect(mockDb!.acquisitions.length).toBe(1)
|
||||
expect(mockDb!.acquisitions[0]).toMatchObject({
|
||||
gerbilId: 'kruemel',
|
||||
date: '2025-03-14',
|
||||
price: 25.5,
|
||||
note: 'Auf der Börse gekauft.',
|
||||
})
|
||||
|
||||
// Bearbeiten: Preis ändern.
|
||||
await section.getByRole('button', { name: t.edit }).click()
|
||||
await section.getByLabel(t.fields.price).fill('30')
|
||||
await section.getByRole('button', { name: t.saveButton }).click()
|
||||
await expect(section).toContainText('30,00')
|
||||
expect(mockDb!.acquisitions[0]).toMatchObject({ price: 30 })
|
||||
|
||||
// Löschen (window.confirm bestätigen).
|
||||
page.once('dialog', (d) => d.accept())
|
||||
await section.getByRole('button', { name: t.delete }).click()
|
||||
await expect(section).toContainText(t.empty)
|
||||
expect(mockDb!.acquisitions.length).toBe(0)
|
||||
})
|
||||
@@ -533,6 +533,50 @@ export async function installMockApi(page: Page): Promise<MockDb> {
|
||||
return json(route, 200, db.rpro3.execute)
|
||||
}
|
||||
|
||||
// ERWERB: Erwerb/Kauf je Tier — GET ?gerbilId= (Array, kein Gridify-Paging),
|
||||
// POST/PUT/DELETE. Vor den generischen Kollektionen, weil GET kein {items}-Objekt
|
||||
// liefert und nach gerbilId statt Gridify-filter selektiert.
|
||||
const acqMatch = path.match(/^\/acquisitions(?:\/([^/]+))?$/)
|
||||
if (acqMatch) {
|
||||
const acqId = acqMatch[1] ? decodeURIComponent(acqMatch[1]) : null
|
||||
if (!acqId) {
|
||||
if (method === 'GET') {
|
||||
const gid = url.searchParams.get('gerbilId')
|
||||
const rows = db.acquisitions.filter((a) => !gid || a.gerbilId === gid)
|
||||
return json(route, 200, [...rows].reverse())
|
||||
}
|
||||
if (method === 'POST') {
|
||||
const created = {
|
||||
id: newId('acq'),
|
||||
sourceContactId: null,
|
||||
date: null,
|
||||
price: null,
|
||||
note: null,
|
||||
...(request.postDataJSON() as Row),
|
||||
createdAt: new Date().toISOString(),
|
||||
}
|
||||
db.acquisitions.push(created)
|
||||
return json(route, 201, created)
|
||||
}
|
||||
return json(route, 405)
|
||||
}
|
||||
const ai = db.acquisitions.findIndex((a) => a.id === acqId)
|
||||
if (method === 'GET') {
|
||||
return ai >= 0 ? json(route, 200, db.acquisitions[ai]) : json(route, 404, { title: 'Not Found' })
|
||||
}
|
||||
if (method === 'PUT') {
|
||||
if (ai < 0) return json(route, 404, { title: 'Not Found' })
|
||||
Object.assign(db.acquisitions[ai], request.postDataJSON() as Row)
|
||||
return json(route, 204)
|
||||
}
|
||||
if (method === 'DELETE') {
|
||||
if (ai < 0) return json(route, 404, { title: 'Not Found' })
|
||||
db.acquisitions.splice(ai, 1)
|
||||
return json(route, 204)
|
||||
}
|
||||
return json(route, 405)
|
||||
}
|
||||
|
||||
// Generische Kollektionen: /<resource> und /<resource>/<id>
|
||||
m = path.match(/^\/([a-z-]+)(?:\/([^/]+))?$/)
|
||||
const col = m ? collections[m[1]] : undefined
|
||||
|
||||
@@ -85,6 +85,8 @@ export interface MockDb {
|
||||
analyze: Record<string, unknown>
|
||||
execute: Record<string, unknown>
|
||||
}
|
||||
// ERWERB: Erwerb/Kauf je Tier (Kaufdatum, Preis, Notiz) — /acquisitions
|
||||
acquisitions: Record<string, unknown>[]
|
||||
}
|
||||
|
||||
function gerbil(
|
||||
@@ -541,5 +543,6 @@ export function seedDb(): MockDb {
|
||||
message: 'Import erfolgreich: 3694 Tiere, 1678 Würfe, 508 Kontakte.',
|
||||
},
|
||||
},
|
||||
acquisitions: [],
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user