import { ForbiddenException } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { InventoryService } from './inventory.service';

describe('InventoryService security', () => {
  const prismaMock = {
    inventoryItem: {
      findUnique: jest.fn(),
      findMany: jest.fn(),
      create: jest.fn(),
      update: jest.fn(),
      delete: jest.fn(),
    },
    inventoryConsumption: {
      findMany: jest.fn(),
      create: jest.fn(),
    },
    product: {
      findFirst: jest.fn(),
    },
    $transaction: jest.fn(),
  };

  const service = new InventoryService(prismaMock as any);

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('scopar findAll till userId', async () => {
    prismaMock.inventoryItem.findMany.mockResolvedValue([]);

    await service.findAll(42, { location: 'fridge', sort: 'bestBeforeAsc' });

    expect(prismaMock.inventoryItem.findMany).toHaveBeenCalledWith(
      expect.objectContaining({
        where: expect.objectContaining({ userId: 42, location: 'fridge' }),
      }),
    );
  });

  it('sätter userId vid create', async () => {
    prismaMock.product.findFirst.mockResolvedValue({ id: 99, ownerId: 42 });
    prismaMock.inventoryItem.create.mockResolvedValue({ id: 1 });

    await service.create(42, {
      productId: 99,
      quantity: 2,
      unit: 'st',
    } as any);

    expect(prismaMock.inventoryItem.create).toHaveBeenCalledWith(
      expect.objectContaining({
        data: expect.objectContaining({ userId: 42, productId: 99 }),
      }),
    );
  });

  it('nekar update om inventoryItem tillhör annan användare', async () => {
    prismaMock.inventoryItem.findUnique.mockResolvedValue({
      id: 10,
      userId: 7,
      quantity: new Prisma.Decimal(1),
    });

    await expect(service.update(10, 42, {} as any)).rejects.toThrow(ForbiddenException);
  });

  it('nekar remove om inventoryItem tillhör annan användare', async () => {
    prismaMock.inventoryItem.findUnique.mockResolvedValue({
      id: 11,
      userId: 7,
      quantity: new Prisma.Decimal(1),
    });

    await expect(service.remove(11, 42)).rejects.toThrow(ForbiddenException);
  });

  it('nekar consumption-history om inventoryItem tillhör annan användare', async () => {
    prismaMock.inventoryItem.findUnique.mockResolvedValue({
      id: 12,
      userId: 7,
      quantity: new Prisma.Decimal(1),
    });

    await expect(service.findConsumptionHistory(12, 42)).rejects.toThrow(ForbiddenException);
  });
});
