135 lines
3.6 KiB
TypeScript
135 lines
3.6 KiB
TypeScript
import { NotFoundException } from '@nestjs/common';
|
|
import { MealPlanService } from './meal-plan.service';
|
|
|
|
describe('MealPlanService IDOR security', () => {
|
|
const fromDate = '2026-05-01';
|
|
const toDate = '2026-05-07';
|
|
|
|
const prismaMock = {
|
|
mealPlanEntry: {
|
|
findMany: jest.fn(),
|
|
findUnique: jest.fn(),
|
|
upsert: jest.fn(),
|
|
delete: jest.fn(),
|
|
},
|
|
inventoryItem: {
|
|
findMany: jest.fn(),
|
|
},
|
|
pantryItem: {
|
|
findMany: jest.fn(),
|
|
},
|
|
recipe: {
|
|
findUnique: jest.fn(),
|
|
},
|
|
$transaction: jest.fn(),
|
|
};
|
|
|
|
const service = new MealPlanService(prismaMock as any);
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
const mockEmptyRangeData = () => {
|
|
prismaMock.mealPlanEntry.findMany.mockResolvedValue([]);
|
|
prismaMock.inventoryItem.findMany.mockResolvedValue([]);
|
|
prismaMock.pantryItem.findMany.mockResolvedValue([]);
|
|
};
|
|
|
|
it('scopar findByRange till userId', async () => {
|
|
mockEmptyRangeData();
|
|
|
|
await service.findByRange(42, fromDate, toDate);
|
|
|
|
expect(prismaMock.mealPlanEntry.findMany).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
where: expect.objectContaining({
|
|
userId: 42,
|
|
date: expect.any(Object),
|
|
}),
|
|
}),
|
|
);
|
|
});
|
|
|
|
it('scopar shoppingList till userId', async () => {
|
|
mockEmptyRangeData();
|
|
|
|
await service.shoppingList(42, fromDate, toDate);
|
|
|
|
expect(prismaMock.mealPlanEntry.findMany).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
where: expect.objectContaining({
|
|
userId: 42,
|
|
}),
|
|
}),
|
|
);
|
|
});
|
|
|
|
it('scopar inventoryCompare till userId', async () => {
|
|
mockEmptyRangeData();
|
|
|
|
await service.inventoryCompare(42, fromDate, toDate);
|
|
|
|
expect(prismaMock.mealPlanEntry.findMany).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
where: expect.objectContaining({
|
|
userId: 42,
|
|
}),
|
|
}),
|
|
);
|
|
});
|
|
|
|
it('upsert sätter userId på nya matplansintrag', async () => {
|
|
prismaMock.mealPlanEntry.upsert.mockResolvedValue({
|
|
id: 1,
|
|
userId: 42,
|
|
date: new Date(),
|
|
});
|
|
|
|
await service.upsert(42, { date: '2026-05-11', recipeId: 1 } as any);
|
|
|
|
expect(prismaMock.mealPlanEntry.upsert).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
where: expect.objectContaining({
|
|
userId_date: expect.objectContaining({
|
|
userId: 42,
|
|
}),
|
|
}),
|
|
create: expect.objectContaining({
|
|
userId: 42,
|
|
}),
|
|
}),
|
|
);
|
|
});
|
|
|
|
it('removeByDate nekar access för annan user', async () => {
|
|
prismaMock.mealPlanEntry.findUnique.mockResolvedValue(null);
|
|
|
|
await expect(service.removeByDate(42, '2026-05-11')).rejects.toThrow(NotFoundException);
|
|
|
|
expect(prismaMock.mealPlanEntry.findUnique).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
where: expect.objectContaining({
|
|
userId_date: expect.objectContaining({
|
|
userId: 42,
|
|
}),
|
|
}),
|
|
}),
|
|
);
|
|
});
|
|
|
|
it('removeByDate verifierar userId innan radering', async () => {
|
|
const entry = { id: 1, userId: 42, date: new Date() };
|
|
prismaMock.mealPlanEntry.findUnique.mockResolvedValue(entry);
|
|
prismaMock.mealPlanEntry.delete.mockResolvedValue(entry);
|
|
|
|
await service.removeByDate(42, '2026-05-11');
|
|
|
|
expect(prismaMock.mealPlanEntry.delete).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
where: expect.objectContaining({ id: 1 }),
|
|
}),
|
|
);
|
|
});
|
|
});
|