test(security): add and refactor api security/idor coverage
Test Suite / test (24.15.0) (push) Has been cancelled
Test Suite / test (24.15.0) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
import { NotFoundException } from '@nestjs/common';
|
||||
import { PantryService } from './pantry.service';
|
||||
|
||||
describe('PantryService IDOR security', () => {
|
||||
const makeCreatePantryDto = (overrides: Partial<{ productId: number; userId: number }> = {}) => ({
|
||||
productId: 1,
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const prismaMock = {
|
||||
pantryItem: {
|
||||
findMany: jest.fn(),
|
||||
findUnique: jest.fn(),
|
||||
findFirst: jest.fn(),
|
||||
create: jest.fn(),
|
||||
update: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
},
|
||||
product: {
|
||||
findUnique: jest.fn(),
|
||||
},
|
||||
user: {
|
||||
findUnique: jest.fn(),
|
||||
},
|
||||
inventoryItem: {
|
||||
create: jest.fn(),
|
||||
},
|
||||
$transaction: jest.fn(),
|
||||
};
|
||||
|
||||
const service = new PantryService(prismaMock as any);
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
const mockPantryFindManyEmpty = () => {
|
||||
prismaMock.pantryItem.findMany.mockResolvedValue([]);
|
||||
};
|
||||
|
||||
it('scopar findAll till userId', async () => {
|
||||
mockPantryFindManyEmpty();
|
||||
|
||||
await service.findAll(42);
|
||||
|
||||
expect(prismaMock.pantryItem.findMany).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
where: expect.objectContaining({ userId: 42 }),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('findAllAdmin kan filtrera per userId', async () => {
|
||||
mockPantryFindManyEmpty();
|
||||
|
||||
await service.findAllAdmin({ userId: 99 });
|
||||
|
||||
expect(prismaMock.pantryItem.findMany).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
where: expect.objectContaining({ userId: 99 }),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('findAllAdmin returnerar alla items om userId inte specificeras', async () => {
|
||||
mockPantryFindManyEmpty();
|
||||
|
||||
await service.findAllAdmin({});
|
||||
|
||||
expect(prismaMock.pantryItem.findMany).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
where: {},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('create sätter userId på nya pantry-items', async () => {
|
||||
prismaMock.product.findUnique.mockResolvedValue({ id: 1 });
|
||||
prismaMock.pantryItem.create.mockResolvedValue({ id: 1, userId: 42 });
|
||||
|
||||
await service.create(42, makeCreatePantryDto() as any);
|
||||
|
||||
expect(prismaMock.pantryItem.create).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
data: expect.objectContaining({ userId: 42, productId: 1 }),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('createAdmin kan skapa pantry-item för explicit userId', async () => {
|
||||
prismaMock.user.findUnique.mockResolvedValue({ id: 99 });
|
||||
prismaMock.product.findUnique.mockResolvedValue({ id: 1 });
|
||||
prismaMock.pantryItem.create.mockResolvedValue({ id: 1, userId: 99 });
|
||||
|
||||
await service.createAdmin(1, makeCreatePantryDto({ userId: 99 }) as any, 99);
|
||||
|
||||
expect(prismaMock.pantryItem.create).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
data: expect.objectContaining({ userId: 99, productId: 1 }),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('createAdmin throws NotFoundException om target user saknas', async () => {
|
||||
prismaMock.user.findUnique.mockResolvedValue(null);
|
||||
|
||||
await expect(service.createAdmin(1, makeCreatePantryDto({ userId: 999 }) as any, 999)).rejects.toThrow(
|
||||
NotFoundException,
|
||||
);
|
||||
});
|
||||
|
||||
it('remove nekar icke-owner', async () => {
|
||||
// Simulera att item inte hittas (userId matchar inte)
|
||||
prismaMock.pantryItem.findFirst.mockResolvedValue(null);
|
||||
|
||||
await expect(service.remove(42, 1)).rejects.toThrow(NotFoundException);
|
||||
});
|
||||
|
||||
it('moveToInventory nekar icke-owner', async () => {
|
||||
// Simulera att item inte hittas (userId matchar inte)
|
||||
prismaMock.pantryItem.findFirst.mockResolvedValue(null);
|
||||
|
||||
await expect(service.moveToInventory(42, 1, {} as any)).rejects.toThrow(NotFoundException);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user