import { UnauthorizedException } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { JwtAuthGuard } from '../auth/jwt-auth.guard'; import { RecipesController } from './recipes.controller'; describe('Recipes controller security', () => { const makeUser = (overrides: Partial<{ userId: number; role: string }> = {}) => ({ userId: 42, role: 'user', ...overrides, }); const recipesServiceMock = { findAll: jest.fn(), findOne: jest.fn(), create: jest.fn(), update: jest.fn(), remove: jest.fn(), shareWithUser: jest.fn(), unshareWithUser: jest.fn(), setVisibility: jest.fn(), }; const controller = new RecipesController(recipesServiceMock as any, {} as any); beforeEach(() => { jest.clearAllMocks(); }); it('JwtAuthGuard kräver autentisering på findAll', () => { const guard = new JwtAuthGuard(new Reflector()); expect(() => guard.handleRequest(null, null, null)).toThrow(UnauthorizedException); }); it('JwtAuthGuard tillåter autentiserad användare på findAll', () => { const guard = new JwtAuthGuard(new Reflector()); const user = makeUser({ userId: 1 }); expect(guard.handleRequest(null, user, null)).toBe(user); }); it('findOne vidarebefordrar @CurrentUser.userId till service', () => { recipesServiceMock.findOne.mockResolvedValue({ id: 1 }); controller.findOne(1, makeUser()); expect(recipesServiceMock.findOne).toHaveBeenCalledWith(1, 42); }); it('create vidarebefordrar @CurrentUser.userId till service', async () => { const dto = { name: 'test' }; recipesServiceMock.create.mockResolvedValue({ id: 1 }); await controller.create(dto as any, makeUser()); expect(recipesServiceMock.create).toHaveBeenCalledWith(dto, 42); }); it('update vidarebefordrar @CurrentUser.userId till service', async () => { const dto = { name: 'updated' }; recipesServiceMock.update.mockResolvedValue({ id: 1 }); await controller.update(1, dto as any, makeUser()); expect(recipesServiceMock.update).toHaveBeenCalledWith(1, dto, 42); }); it('remove vidarebefordrar @CurrentUser.userId till service', async () => { recipesServiceMock.remove.mockResolvedValue(undefined); await controller.remove(1, makeUser()); expect(recipesServiceMock.remove).toHaveBeenCalledWith(1, 42); }); it('shareRecipe vidarebefordrar userId och trimmar username', async () => { recipesServiceMock.shareWithUser.mockResolvedValue(undefined); await controller.shareRecipe(1, { username: ' alice ' } as any, makeUser()); expect(recipesServiceMock.shareWithUser).toHaveBeenCalledWith(1, 42, 'alice'); }); it('unshareRecipe vidarebefordrar userId och trimmar username', async () => { recipesServiceMock.unshareWithUser.mockResolvedValue(undefined); await controller.unshareRecipe(1, ' alice ', makeUser()); expect(recipesServiceMock.unshareWithUser).toHaveBeenCalledWith(1, 42, 'alice'); }); it('setVisibility vidarebefordrar userId till service', async () => { recipesServiceMock.setVisibility.mockResolvedValue(undefined); await controller.setVisibility(1, { isPublic: true } as any, makeUser()); expect(recipesServiceMock.setVisibility).toHaveBeenCalledWith(1, 42, true); }); });