// Copyright (c) 2023 Tudor Stanciu

import React from "react";
import { renderHook } from "@testing-library/react";
import { TuitioContext, TuitioDispatchContext } from "../../src/contexts";
import { useTuitioClient } from "../../src/hooks";
import axios from "axios";

jest.mock("axios");

describe("useTuitioClient: dispatchActions", () => {
  let spyOnLoginSuccess: (token: string, validUntil: Date, userName: string) => void;
  let spyOnLogoutSuccess: () => void;

  beforeEach(() => {
    spyOnLoginSuccess = jest.fn();
    spyOnLogoutSuccess = jest.fn();
  });

  afterEach(() => {
    (spyOnLoginSuccess as jest.Mock).mockReset();
    (spyOnLogoutSuccess as jest.Mock).mockReset();
  });

  const tuitioContextState = {
    auth: {
      userName: null,
      token: null,
      validUntil: null
    },
    configuration: { tuitioUrl: "http://localhost:5063/" }
  };

  const wrapper = ({ children }: { children: React.ReactNode }) => (
    <TuitioContext.Provider value={tuitioContextState}>
      <TuitioDispatchContext.Provider
        value={{
          onLoginSuccess: spyOnLoginSuccess,
          onLogoutSuccess: spyOnLogoutSuccess,
          onUserInfoLoaded: jest.fn()
        }}
      >
        {children}
      </TuitioDispatchContext.Provider>
    </TuitioContext.Provider>
  );

  const optionsMock = {
    onLogoutFailed: jest.fn()
  };

  it("onLogoutFailed should be called if logout is called before login", async () => {
    (axios as jest.MockedFunction<typeof axios>).mockResolvedValue({
      data: {
        result: { userId: 0, userName: "tuitio.user", logoutDate: new Date() },
        error: null
      }
    });

    const { result } = renderHook(() => useTuitioClient(optionsMock), { wrapper });
    const response = await result.current.logout();
    expect(response.result).toBeNull();
    expect(response.error).toBe("UNAUTHENTICATED");
    expect(optionsMock.onLogoutFailed).toHaveBeenCalledWith("UNAUTHENTICATED");
  });
});
