feat(v2.4): 切换根数据领域主写
This commit is contained in:
83
apps/server/src/modules/project/project.service.spec.ts
Normal file
83
apps/server/src/modules/project/project.service.spec.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { NotFoundException } from '@nestjs/common';
|
||||
import { ProjectService } from './project.service';
|
||||
|
||||
describe('ProjectService domain writes', () => {
|
||||
const makeService = () => {
|
||||
const prisma = {
|
||||
product: {
|
||||
findUnique: jest.fn(),
|
||||
},
|
||||
project: {
|
||||
create: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
findFirst: jest.fn(),
|
||||
findMany: jest.fn(),
|
||||
update: jest.fn(),
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
prisma,
|
||||
service: new ProjectService(prisma as any),
|
||||
};
|
||||
};
|
||||
|
||||
it('creates projects directly under a product relation row', async () => {
|
||||
const { prisma, service } = makeService();
|
||||
prisma.product.findUnique.mockResolvedValue({ id: 'product-1' });
|
||||
prisma.project.create.mockResolvedValue({ id: 'project-1', productId: 'product-1' });
|
||||
|
||||
await service.create('product-1', { name: 'CRM', description: 'Customer system' });
|
||||
|
||||
expect(prisma.project.create).toHaveBeenCalledWith({
|
||||
data: {
|
||||
productId: 'product-1',
|
||||
name: 'CRM',
|
||||
description: 'Customer system',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('lists projects by product id', async () => {
|
||||
const { prisma, service } = makeService();
|
||||
prisma.project.findMany.mockResolvedValue([]);
|
||||
|
||||
await service.findAll('product-1');
|
||||
|
||||
expect(prisma.project.findMany).toHaveBeenCalledWith({
|
||||
where: { productId: 'product-1' },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
});
|
||||
|
||||
it('updates projects only inside their product scope', async () => {
|
||||
const { prisma, service } = makeService();
|
||||
prisma.project.findFirst.mockResolvedValue({ id: 'project-1', productId: 'product-1' });
|
||||
prisma.project.update.mockResolvedValue({ id: 'project-1', name: 'CRM v2' });
|
||||
|
||||
await service.update('product-1', 'project-1', { name: 'CRM v2' });
|
||||
|
||||
expect(prisma.project.update).toHaveBeenCalledWith({
|
||||
where: { id: 'project-1' },
|
||||
data: { name: 'CRM v2' },
|
||||
});
|
||||
});
|
||||
|
||||
it('throws when updating a project outside the product scope', async () => {
|
||||
const { prisma, service } = makeService();
|
||||
prisma.project.findFirst.mockResolvedValue(null);
|
||||
|
||||
await expect(service.update('product-1', 'project-404', { name: 'Ghost' })).rejects.toBeInstanceOf(NotFoundException);
|
||||
expect(prisma.project.update).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('deletes projects only inside their product scope', async () => {
|
||||
const { prisma, service } = makeService();
|
||||
prisma.project.findFirst.mockResolvedValue({ id: 'project-1', productId: 'product-1' });
|
||||
prisma.project.delete.mockResolvedValue({ id: 'project-1' });
|
||||
|
||||
await service.remove('product-1', 'project-1');
|
||||
|
||||
expect(prisma.project.delete).toHaveBeenCalledWith({ where: { id: 'project-1' } });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user