79 lines
2.8 KiB
TypeScript
79 lines
2.8 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { buildTestApp, setupAdmin, auth } from './helpers.js'
|
|
import { discogsReleaseFixture } from './fixtures.js'
|
|
|
|
const discogsStub = (async (input: any) =>
|
|
String(input).includes('/releases/1001')
|
|
? new Response(JSON.stringify(discogsReleaseFixture), {
|
|
status: 200,
|
|
headers: { 'content-type': 'application/json' },
|
|
})
|
|
: new Response('nope', { status: 404 })) as typeof fetch
|
|
|
|
async function appWithItem() {
|
|
const app = await buildTestApp(discogsStub)
|
|
const cookie = await setupAdmin(app)
|
|
await app.inject({ method: 'PUT', url: '/api/settings', ...auth(cookie), payload: { discogsToken: 't' } })
|
|
const added = await app.inject({ method: 'POST', url: '/api/collection', ...auth(cookie), payload: { releaseId: 1001 } })
|
|
return { app, cookie, itemId: added.json().id as number }
|
|
}
|
|
|
|
describe('loans', () => {
|
|
it('lend, list active, return', async () => {
|
|
const { app, cookie, itemId } = await appWithItem()
|
|
|
|
const lend = await app.inject({
|
|
method: 'POST',
|
|
url: `/api/collection/${itemId}/loan`,
|
|
...auth(cookie),
|
|
payload: { borrower: 'Bob' },
|
|
})
|
|
expect(lend.statusCode).toBe(200)
|
|
const loan = lend.json()
|
|
expect(loan).toMatchObject({ itemId, borrower: 'Bob', returnedAt: null })
|
|
|
|
const dup = await app.inject({
|
|
method: 'POST',
|
|
url: `/api/collection/${itemId}/loan`,
|
|
...auth(cookie),
|
|
payload: { borrower: 'Eve' },
|
|
})
|
|
expect(dup.statusCode).toBe(409)
|
|
expect(dup.json()).toEqual({ error: 'already_on_loan' })
|
|
|
|
const list = await app.inject({ method: 'GET', url: '/api/loans', ...auth(cookie) })
|
|
expect(list.json().active).toHaveLength(1)
|
|
expect(list.json().history).toHaveLength(0)
|
|
|
|
const ret = await app.inject({ method: 'POST', url: `/api/loans/${loan.id}/return`, ...auth(cookie) })
|
|
expect(ret.statusCode).toBe(200)
|
|
const after = await app.inject({ method: 'GET', url: '/api/loans', ...auth(cookie) })
|
|
expect(after.json().active).toHaveLength(0)
|
|
expect(after.json().history).toHaveLength(1)
|
|
|
|
const again = await app.inject({ method: 'POST', url: `/api/loans/${loan.id}/return`, ...auth(cookie) })
|
|
expect(again.statusCode).toBe(404)
|
|
await app.close()
|
|
})
|
|
|
|
it('validates borrower and ownership', async () => {
|
|
const { app, cookie, itemId } = await appWithItem()
|
|
const empty = await app.inject({
|
|
method: 'POST',
|
|
url: `/api/collection/${itemId}/loan`,
|
|
...auth(cookie),
|
|
payload: { borrower: ' ' },
|
|
})
|
|
expect(empty.statusCode).toBe(400)
|
|
|
|
const missing = await app.inject({
|
|
method: 'POST',
|
|
url: `/api/collection/9999/loan`,
|
|
...auth(cookie),
|
|
payload: { borrower: 'Bob' },
|
|
})
|
|
expect(missing.statusCode).toBe(404)
|
|
await app.close()
|
|
})
|
|
})
|