import globalMethods from "@/global-methods";
import axios from "axios";
import analyticsMixIn from "@/mixins/analytics-mixin";
import router from "@/router";

//Mock external dependencies
jest.mock("axios");
jest.mock("@/mixins/analytics-mixin");

global.$logger = {
    logInformation: jest.fn(),
    logWarning: jest.fn(),
    logError: jest.fn(),
    logCritical: jest.fn(),
};
global.crypto = { randomUUID: jest.fn() };

it("Global Methods - Call Http Client - Should Resolve Promise", () => {
    //Arrange
    const endpoint = "https://mock.safelite.com";
    const httpArgs = setupMocksForHttpClient({ endpoint: endpoint });
    analyticsMixIn.methods.pushEventToGA = jest.fn();

    //Act
    globalMethods.callHttpClient(httpArgs).then((response) => {
        //Assert
        expect(axios.mock.calls[0][0].url).toContain(endpoint);
        expect(response.data.message).toContain("Success");
        expect(response.status).toEqual(200);
    });
});

it("Global Methods - Call Http Client - Should Reject Promise", () => {
    //Arrange
    const endpoint = "https://mock.safelite.com";
    const httpArgs = setupMocksForHttpClient({
        endpoint: endpoint,
        isError: true,
    });
    analyticsMixIn.methods.pushEventToGA = jest.fn();
    router.navigateError = jest.fn();

    //Act
    globalMethods.callHttpClient(httpArgs).catch((err) => {
        //Assert
        expect(axios.mock.calls[0][0].url).toContain(endpoint);
        expect(err.data.message).toContain("Error");
        expect(err.status).toEqual(500);
    });
});

function setupMocksForHttpClient({ endpoint = null, isError = false, additionalData = null }) {
    //Clear node module
    axios.mockClear();

    // Success Response
    const response = {
        status: 200,
        data: {
            message: "Success",
            additionalData: additionalData,
        },
    };

    // Error Response
    const error = {
        response: {
            status: 500,
            data: {
                message: "Error",
                additionalData: additionalData,
            },
        },
    };

    // Error interceptor on Axios returns a different object, so we need to mimic that.
    if (isError) {
        axios.mockRejectedValue(error);
    } else {
        axios.mockResolvedValue(response);
    }

    return {
        endpoint: endpoint,
        logApiCall: true,
    };
}
