import { Test } from '@nestjs/testing'; import { BadRequestException, ConflictException, NotFoundException, } from '@nestjs/common'; import { CountriesService } from './countries.service'; import { PrismaService } from '../prisma/prisma.service'; describe('CountriesService', () => { let service: CountriesService; let prisma: PrismaService; const created: string[] = []; beforeAll(async () => { const moduleRef = await Test.createTestingModule({ providers: [CountriesService, PrismaService], }).compile(); service = moduleRef.get(CountriesService); prisma = moduleRef.get(PrismaService); await prisma.onModuleInit(); }); afterAll(async () => { if (created.length) { // Delete goods/origin_goods first so we can remove the countries. await prisma.good.deleteMany({ where: { country: { countryName: { in: created } } }, }); await prisma.position.deleteMany({ where: { country: { countryName: { in: created } } }, }); await prisma.country.deleteMany({ where: { countryName: { in: created } }, }); } await prisma.onModuleDestroy(); }); it('should be defined', () => { expect(service).toBeDefined(); }); it('creates and reads back a country', async () => { const name = `Test Country ${Date.now()}`; created.push(name); const createdRow = await service.create({ countryName: name }); expect(createdRow.countryName).toBe(name); const fetched = await service.findOne(createdRow.id); expect(fetched.countryName).toBe(name); }); it('rejects duplicate names with ConflictException', async () => { const name = `Dup Country ${Date.now()}`; created.push(name); await service.create({ countryName: name }); await expect(service.create({ countryName: name })).rejects.toBeInstanceOf( ConflictException, ); }); it('throws NotFoundException for unknown id', async () => { await expect(service.findOne(BigInt(99999999))).rejects.toBeInstanceOf( NotFoundException, ); }); it('throws BadRequestException when deleting a country referenced by goods', async () => { const name = `Ref Country ${Date.now()}`; created.push(name); const country = await service.create({ countryName: name }); // Need a category + origin good to satisfy the foreign keys before // we can attach a good that references the country. const category = await prisma.category.create({ data: { categoryName: `Cat ${Date.now()}` }, }); const originGood = await prisma.originGood.create({ data: { sdsGoodId: `sds-${Date.now()}-${Math.random()}` }, }); await prisma.good.create({ data: { originGoodId: originGood.id, countryId: country.id, categoryId: category.id, goodName: 'sample', }, }); await expect(service.remove(country.id)).rejects.toBeInstanceOf( BadRequestException, ); // cleanup await prisma.good.deleteMany({ where: { countryId: country.id } }); await prisma.originGood.delete({ where: { id: originGood.id } }); await prisma.category.delete({ where: { id: category.id } }); }); it('updates fields and deletes when unreferenced', async () => { const name = `Upd Country ${Date.now()}`; created.push(name); const c = await service.create({ countryName: name }); const updated = await service.update(c.id, { countryName: `${name}-v2` }); expect(updated.countryName).toBe(`${name}-v2`); created[created.indexOf(name)] = `${name}-v2`; await service.remove(c.id); const idx = created.indexOf(`${name}-v2`); if (idx !== -1) created.splice(idx, 1); }); it('reorder persists sortOrder and findAll honors it', async () => { const stamp = Date.now(); const a = await service.create({ countryName: `Sort A ${stamp}` }); const b = await service.create({ countryName: `Sort B ${stamp}` }); const c = await service.create({ countryName: `Sort C ${stamp}` }); created.push(a.countryName, b.countryName, c.countryName); // 新顺序 C, A, B(id 序与 sortOrder 无关时也能稳定验证) const reordered = await service.reorder({ items: [ { id: Number(c.id), sortOrder: 0 }, { id: Number(a.id), sortOrder: 1 }, { id: Number(b.id), sortOrder: 2 }, ], }); const ours = reordered.filter((r) => [a.id, b.id, c.id].some((id) => id.toString() === r.id.toString()), ); expect(ours.map((r) => r.id.toString())).toEqual([c.id.toString(), a.id.toString(), b.id.toString()]); const list = await service.findAll(); const pos = (id: bigint) => list.findIndex((r) => r.id.toString() === id.toString()); expect(pos(c.id)).toBeLessThan(pos(a.id)); expect(pos(a.id)).toBeLessThan(pos(b.id)); }); });