// src/middleware/fileUpload.middleware.test.ts
import { describe, it, expect, vi, beforeEach, type Mock } from 'vitest';
import { Request, Response, NextFunction } from 'express';
import { requireFileUpload } from './fileUpload.middleware';
import { ValidationError } from '../services/db/errors.db';

describe('requireFileUpload Middleware', () => {
  let mockRequest: Partial<Request>;
  let mockResponse: Partial<Response>;
  let mockNext: NextFunction;

  beforeEach(() => {
    // Reset mocks before each test
    mockRequest = {};
    mockResponse = {
      status: vi.fn().mockReturnThis(),
      json: vi.fn(),
    };
    mockNext = vi.fn();
  });

  it('should call next() without an error if the file exists and has the correct fieldname', () => {
    // Arrange
    const fieldName = 'flyerImage';
    mockRequest.file = {
      fieldname: fieldName,
      // other multer properties are not needed for this test
    } as Express.Multer.File;

    const middleware = requireFileUpload(fieldName);

    // Act
    middleware(mockRequest as Request, mockResponse as Response, mockNext);

    // Assert
    expect(mockNext).toHaveBeenCalledTimes(1);
    expect(mockNext).toHaveBeenCalledWith(); // Called with no arguments
  });

  it('should call next() with a ValidationError if req.file is missing', () => {
    // Arrange
    const fieldName = 'flyerImage';
    // req.file is not set on mockRequest

    const middleware = requireFileUpload(fieldName);

    // Act
    middleware(mockRequest as Request, mockResponse as Response, mockNext);

    // Assert
    expect(mockNext).toHaveBeenCalledTimes(1);
    const error = (mockNext as Mock).mock.calls[0][0];
    expect(error).toBeInstanceOf(ValidationError);
    expect(error.validationErrors[0].message).toBe(`A file for the '${fieldName}' field is required.`);
    expect(error.validationErrors[0].path).toEqual(['file', fieldName]);
  });

  it('should call next() with a ValidationError if req.file has the wrong fieldname', () => {
    // Arrange
    const expectedFieldName = 'correctField';
    mockRequest.file = { fieldname: 'wrongField' } as Express.Multer.File;
    const middleware = requireFileUpload(expectedFieldName);

    // Act
    middleware(mockRequest as Request, mockResponse as Response, mockNext);

    // Assert
    expect(mockNext).toHaveBeenCalledWith(expect.any(ValidationError));
  });
});