// Copyright (c) 2023 Tudor Stanciu import { renderHook, act } from "@testing-library/react-hooks"; import { TuitioClient } from "@flare/tuitio-client"; import { useTuitioClient } from "../../src/hooks"; const userName = "tuitio.user"; const password = "password"; const token = "mocked-token"; const expiresIn = 600000; const validUntil = new Date(); jest.mock("@flare/tuitio-client", () => ({ TuitioClient: jest.fn().mockImplementation(() => ({ login: jest.fn().mockResolvedValue({ result: { token, expiresIn, validUntil }, error: null }), logout: jest.fn().mockResolvedValue({ result: { userId: 0, userName, logoutDate: new Date() }, error: null }) })), fetch: jest.fn().mockResolvedValue({ token, validUntil, userName }) })); describe("useTuitioClient", () => { it("should call onLoginSuccess when login is successful and should call onLogoutSuccess when logout is called", async () => { const onLoginSuccess = jest.fn(); const onLogoutSuccess = jest.fn(); const { result } = renderHook(() => useTuitioClient({ onLoginSuccess, onLoginFailed: jest.fn(), onLoginError: jest.fn(), onLogoutSuccess }) ); await act(async () => { await result.current.login(userName, password); await result.current.logout(); }); expect(onLoginSuccess).toHaveBeenCalledWith(userName, token, expiresIn, validUntil); expect(onLogoutSuccess).toHaveBeenCalled(); }); it("should call onLoginFailed when login is unsuccessful", async () => { const error = "error"; const onLoginFailed = jest.fn(); (TuitioClient as jest.Mocked).mockImplementation(() => ({ login: jest.fn().mockResolvedValue({ result: null, error }) })); const { result } = renderHook(() => useTuitioClient({ onLoginSuccess: jest.fn(), onLoginFailed, onLoginError: jest.fn() }) ); await act(async () => { await result.current.login(userName, password); }); expect(onLoginFailed).toHaveBeenCalledWith(error); }); it("should call onLoginError with error if authentication fails", async () => { (TuitioClient as jest.Mocked).mockImplementation(() => ({ login: jest.fn().mockRejectedValue(new Error("Login failed")) })); const onLoginError = jest.fn(); const { result } = renderHook(() => useTuitioClient({ onLoginSuccess: jest.fn(), onLoginFailed: jest.fn(), onLoginError }) ); await act(async () => { try { await result.current.login(userName, password); } catch (error) { expect(onLoginError).toHaveBeenCalledWith(error); } }); }); it("should return error if logout returns error", async () => { (TuitioClient as jest.Mocked).mockImplementation(() => ({ logout: jest.fn().mockResolvedValue({ result: null, error: "error" }) })); const onLogoutFailed = jest.fn(); const { result } = renderHook(() => useTuitioClient({ onLogoutFailed }) ); const response = await result.current.logout(); expect(response.result).toBeNull(); expect(response.error).toBe("error"); expect(onLogoutFailed).toHaveBeenCalledWith(response.error); }); it("should call onLogoutError with error if logout fails", async () => { (TuitioClient as jest.Mocked).mockImplementation(() => ({ logout: jest.fn().mockRejectedValue(new Error("Login failed")) })); const onLogoutError = jest.fn(); const { result } = renderHook(() => useTuitioClient({ onLogoutError })); await act(async () => { try { await result.current.logout(); } catch (error) { expect(onLogoutError).toHaveBeenCalledWith(error); } }); }); it("should throw exception if both result and error are null", async () => { (TuitioClient as jest.Mocked).mockImplementation(() => ({ login: jest.fn().mockResolvedValue({ result: null, error: null }), logout: jest.fn().mockResolvedValue({ result: null, error: null }) })); const { result } = renderHook(() => useTuitioClient()); await act(async () => { try { await result.current.login(userName, password); } catch (error) { expect(error).toBeDefined(); } try { await result.current.logout(); } catch (error) { expect(error).toBeDefined(); } }); }); });