Files
ApiCore/ApiCore-Backend/test/queens.e2e-spec.ts
T
Nick Szaunig b18d61640d feat(backend): Koeniginnen-Modul (Modul 4)
QueensModule: CRUD + assign-colony + history, entsprechend Lastenheft
§4.5 (Koeniginnenverwaltung). assign-colony schliesst die offene
QueenColonyHistory der bisherigen Koenigin am Zielvolk (falls vorhanden)
sowie eine evtl. noch offene History dieser Koenigin an einem anderen
Volk, bevor Colony.currentQueenId gesetzt und ein neuer History-Eintrag
angelegt wird - damit bleibt jeder Koeniginnenwechsel nachvollziehbar,
wie gefordert. Rollen wie bei Apiaries/Colonies: Lesen offen, Schreiben
auf ADMIN/BEEKEEPER beschraenkt.

5 Unit-Tests + 2 e2e-Tests, Lint, Typecheck und Build gruen.
2026-08-21 18:26:55 +02:00

106 lines
3.3 KiB
TypeScript

import { INestApplication } from '@nestjs/common';
import * as bcrypt from 'bcryptjs';
import request from 'supertest';
import { App } from 'supertest/types';
import { PrismaService } from '../src/prisma/prisma.service';
import { createTestApp } from './utils/create-test-app';
import { login } from './utils/api';
interface QueenBody {
id: string;
code: string;
}
describe('Queens (e2e)', () => {
let app: INestApplication<App>;
let prisma: PrismaService;
const beekeeperEmail = `queens-e2e-beekeeper-${Date.now()}@example.com`;
const password = 'SuperSecret123!';
let beekeeperId: string;
let beekeeperToken: string;
let apiaryId: string;
let colonyId: string;
let queenId: string;
beforeAll(async () => {
app = await createTestApp();
prisma = app.get(PrismaService);
const passwordHash = await bcrypt.hash(password, 12);
const beekeeper = await prisma.user.create({
data: {
email: beekeeperEmail,
passwordHash,
name: 'Beekeeper',
role: 'BEEKEEPER',
},
});
beekeeperId = beekeeper.id;
beekeeperToken = (await login(app, beekeeperEmail, password)).accessToken;
const apiary = await prisma.apiary.create({
data: { name: `Stand ${Date.now()}` },
});
apiaryId = apiary.id;
const colony = await prisma.colony.create({
data: {
code: `V-${Date.now()}`,
apiaryId,
colonyType: 'PRODUCTION_COLONY',
},
});
colonyId = colony.id;
});
afterAll(async () => {
await prisma.queenColonyHistory.deleteMany({ where: { colonyId } });
if (colonyId) {
await prisma.colony.update({
where: { id: colonyId },
data: { currentQueenId: null },
});
}
if (queenId) {
await prisma.queen.delete({ where: { id: queenId } });
}
await prisma.colony.deleteMany({ where: { id: colonyId } });
await prisma.apiary.deleteMany({ where: { id: apiaryId } });
await prisma.refreshToken.deleteMany({ where: { userId: beekeeperId } });
await prisma.auditLog.deleteMany({ where: { userId: beekeeperId } });
await prisma.user.deleteMany({ where: { id: beekeeperId } });
await app.close();
});
it('lets a BEEKEEPER create a queen', async () => {
const response = await request(app.getHttpServer())
.post('/api/v1/queens')
.set('Authorization', `Bearer ${beekeeperToken}`)
.send({ code: `Q-${Date.now()}`, breed: 'Carnica' })
.expect(201);
queenId = (response.body as QueenBody).id;
expect(queenId).toEqual(expect.any(String));
});
it('assigns the queen to a colony and records history', async () => {
await request(app.getHttpServer())
.post(`/api/v1/queens/${queenId}/assign-colony`)
.set('Authorization', `Bearer ${beekeeperToken}`)
.send({ colonyId })
.expect(201);
const colony = await request(app.getHttpServer())
.get(`/api/v1/colonies/${colonyId}`)
.set('Authorization', `Bearer ${beekeeperToken}`)
.expect(200);
expect((colony.body as { currentQueenId: string }).currentQueenId).toBe(
queenId,
);
const history = await request(app.getHttpServer())
.get(`/api/v1/queens/${queenId}/history`)
.set('Authorization', `Bearer ${beekeeperToken}`)
.expect(200);
expect(history.body).toHaveLength(1);
});
});