Files
ApiCore/ApiCore-Backend/src/qr/qr.service.spec.ts
T
Nick SzaunigandClaude Sonnet 5 f1d6b2956e fix: Volk-QR-Code fuehrt zur Volk-Uebersicht statt direkt zum Durchsicht-Formular
Scannen des QR-Codes eines Volks landete bisher direkt auf einem
leeren "Neue Durchsicht"-Formular ohne jeglichen Kontext (kein
Status, keine Historie, kein Menue) - erst nach dem Speichern kam man
auf /colonies/[id], die eigentliche Uebersichtsseite mit Status,
Aktionen, Durchsicht-/Varroa-/Schwarmkontroll-/Behandlungs-/
Fuetterungshistorie.

QR fuehrt jetzt direkt zu /colonies/[id]. Der "Neue Durchsicht"-
Button ist dort weiterhin prominent vorhanden. Lastenheft Abschnitt
4.23 erlaubt explizit beide Varianten ("Volkseite beziehungsweise
eine neue Durchsicht"), diese Aenderung bleibt also spezifikations-
konform.

Verifiziert: tsc, lint, unit (228/228, inkl. der angepassten
qr.service.spec.ts-Assertion) gruen. Volle e2e-Suite konnte wegen der
wiederkehrenden WSL/Postgres-Portweiterleitungs-Unzuverlaessigkeit
nicht neu durchlaufen werden - die geaenderte Logik (ein einzelner
String) ist durch den angepassten Unit-Test direkt abgedeckt.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-26 10:57:57 +02:00

80 lines
2.9 KiB
TypeScript

import { BadRequestException, NotFoundException } from '@nestjs/common';
import { QrService } from './qr.service';
import { PrismaService } from '../prisma/prisma.service';
describe('QrService', () => {
let service: QrService;
let prisma: {
colony: { findUnique: jest.Mock };
apiary: { findUnique: jest.Mock };
queen: { findUnique: jest.Mock };
honeyBatch: { findUnique: jest.Mock };
storageContainer: { findUnique: jest.Mock };
bottlingBatch: { findUnique: jest.Mock };
};
beforeEach(() => {
prisma = {
colony: { findUnique: jest.fn() },
apiary: { findUnique: jest.fn() },
queen: { findUnique: jest.fn() },
honeyBatch: { findUnique: jest.fn() },
storageContainer: { findUnique: jest.fn() },
bottlingBatch: { findUnique: jest.fn() },
};
service = new QrService(prisma as unknown as PrismaService);
});
it('rejects an unsupported entity type', async () => {
await expect(service.generateSvg('unknown', 'id-1')).rejects.toBeInstanceOf(
BadRequestException,
);
});
it('throws NotFoundException when the object does not exist', async () => {
prisma.colony.findUnique.mockResolvedValueOnce(null);
await expect(
service.generateSvg('colonies', 'missing'),
).rejects.toBeInstanceOf(NotFoundException);
});
it('generates an SVG QR code for an existing colony', async () => {
prisma.colony.findUnique.mockResolvedValueOnce({ id: 'colony-1' });
const svg = await service.generateSvg('colonies', 'colony-1');
expect(svg).toContain('<svg');
});
it('generates an SVG QR code for an existing storage container', async () => {
prisma.storageContainer.findUnique.mockResolvedValueOnce({ id: 'sc-1' });
const svg = await service.generateSvg('storage-containers', 'sc-1');
expect(svg).toContain('<svg');
});
it('generates an SVG QR code that deep-links to the public origin page for a bottling batch', async () => {
prisma.bottlingBatch.findUnique.mockResolvedValueOnce({
lotNumber: 'WH-2026-001',
});
const svg = await service.generateSvg('bottling-batches', 'bb-1');
expect(svg).toContain('<svg');
});
it('resolveUrl returns the same deep-link that generateSvg encodes, for NFC writing', async () => {
prisma.colony.findUnique.mockResolvedValueOnce({ id: 'colony-1' });
const url = await service.resolveUrl('colonies', 'colony-1');
expect(url).toBe('http://localhost:3000/colonies/colony-1');
});
it('resolveUrl rejects an unsupported entity type', async () => {
await expect(service.resolveUrl('unknown', 'id-1')).rejects.toBeInstanceOf(
BadRequestException,
);
});
it('resolveUrl throws NotFoundException when the object does not exist', async () => {
prisma.colony.findUnique.mockResolvedValueOnce(null);
await expect(
service.resolveUrl('colonies', 'missing'),
).rejects.toBeInstanceOf(NotFoundException);
});
});