import { Request, Response, NextFunction } from 'express';
import { postCodeController } from "../../controllers/postCodeController";
import { checkPostCode } from '../../libs/httpServices';
import { AddressResponse } from '../../types/addressResponse';
import { Address, CustomError } from '../../types/custom';

jest.mock('../../libs/httpServices', () => ({
    checkPostCode: jest.fn()
  }));

describe('Postcode page controller tests', () => {
    let req: Partial<Request>;
    let res: Partial<Response>
    let next: jest.MockedFunction<NextFunction> 
    beforeEach(()=>{
        req = {
            body: {postcode : 'aa235aa'},
            session: { formErrors: [],
                error: {},
                addresses: [],
                postCodeNotCovered: false},
        } as unknown as Request
        res = {
            redirect: jest.fn(),
            status: jest.fn().mockReturnThis(),
            render: jest.fn().mockReturnThis()
        };
        next = jest.fn();

    })

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

    test('should move to select page when response is 200', async () => {
        const response = { addresses: [] as Address[] } as AddressResponse;
        response.addresses.push({ UPRN: '1' } as Address);
        (checkPostCode as jest.Mock).mockResolvedValueOnce(response)
        await postCodeController(req as Request, res as Response, next, [])
        expect(next).toHaveBeenCalledTimes(1);
    })

    test('should move to select page when response is 204 and set postCodeNotCovered to true', async () => {
        const response = { addresses: [] as Address[] } as AddressResponse;
        (checkPostCode as jest.Mock).mockResolvedValueOnce(response);
        res.statusCode = 204;
        await postCodeController(req as Request, res as Response, next, [])
        expect(res.redirect).toHaveBeenCalledWith('/address-not-covered');
    })

    test('should throw error and redirect when there is an error', async () => {
        const errorResponse = {} as AddressResponse;
        errorResponse.error = {} as CustomError;
        errorResponse.error.status = 500;
        (checkPostCode as jest.Mock).mockRejectedValueOnce(errorResponse);
        await postCodeController(req as Request, res as Response, next, [])
        expect(next).toHaveBeenCalledTimes(1)
    })
})


