const GetAllUsersQueryHandler = require('../../../src/application/user/queries/GetAllUsersQueryHandler');
const GetAllUsersQuery = require('../../../src/application/user/queries/GetAllUsersQuery');

describe('GetAllUsersQueryHandler', () => {
  let handler;
  let mockPrisma;

  beforeEach(() => {
    // Mock Prisma
    mockPrisma = {
      user: {
        findMany: jest.fn()
      }
    };

    handler = new GetAllUsersQueryHandler(mockPrisma);

    // Reset all mocks
    jest.clearAllMocks();
  });

  describe('handle - success cases', () => {
    it('should return all users successfully', async () => {
      // Arrange
      const query = new GetAllUsersQuery();
      
      mockPrisma.user.findMany.mockResolvedValue([
        {
          id: 1,
          name: 'John Doe',
          email: 'john@example.com',
          password: 'hashed_password_1',
          createdAt: new Date(),
          updatedAt: new Date()
        },
        {
          id: 2,
          name: 'Jane Doe',
          email: 'jane@example.com',
          password: 'hashed_password_2',
          createdAt: new Date(),
          updatedAt: new Date()
        }
      ]);

      // Act
      const result = await handler.handle(query);

      // Assert
      expect(mockPrisma.user.findMany).toHaveBeenCalledWith({
        orderBy: { createdAt: 'desc' }
      });
      expect(result).toHaveLength(2);
      expect(result[0]).toEqual({
        id: 1,
        name: 'John Doe',
        email: 'john@example.com',
        createdAt: expect.any(Date),
        updatedAt: expect.any(Date)
      });
      expect(result[1]).toEqual({
        id: 2,
        name: 'Jane Doe',
        email: 'jane@example.com',
        createdAt: expect.any(Date),
        updatedAt: expect.any(Date)
      });
      // Passwords should not be returned
      expect(result[0].password).toBeUndefined();
      expect(result[1].password).toBeUndefined();
    });

    it('should return empty array if no users exist', async () => {
      // Arrange
      const query = new GetAllUsersQuery();
      
      mockPrisma.user.findMany.mockResolvedValue([]);

      // Act
      const result = await handler.handle(query);

      // Assert
      expect(result).toEqual([]);
    });
  });
});
