Files
hanko/frontend/frontend-sdk/tests/lib/client/PasswordClient.spec.ts
2022-11-10 10:58:31 +01:00

128 lines
4.3 KiB
TypeScript

import {
PasswordClient,
InvalidPasswordError,
TooManyRequestsError,
TechnicalError,
} from "../../../src";
import { Response } from "../../../src/lib/client/HttpClient";
const userID = "test-user-1";
const password = "test-password-1";
const passwordRetryAfter = 180;
let passwordClient: PasswordClient;
beforeEach(() => {
passwordClient = new PasswordClient("http://test.api");
});
describe("PasswordClient.login()", () => {
it("should do a password login", async () => {
const response = new Response(new XMLHttpRequest());
response.ok = true;
jest.spyOn(passwordClient.client, "post").mockResolvedValue(response);
const loginResponse = passwordClient.login(userID, password);
await expect(loginResponse).resolves.toBeUndefined();
expect(passwordClient.client.post).toHaveBeenCalledWith("/password/login", {
user_id: userID,
password,
});
});
it("should throw error when using an invalid password", async () => {
const response = new Response(new XMLHttpRequest());
response.status = 401;
jest.spyOn(passwordClient.client, "post").mockResolvedValue(response);
const loginResponse = passwordClient.login(userID, password);
await expect(loginResponse).rejects.toThrow(InvalidPasswordError);
});
it("should throw error and set retry after in state on too many request response from API", async () => {
const xhr = new XMLHttpRequest();
const response = new Response(xhr);
response.status = 429;
jest.spyOn(passwordClient.client, "post").mockResolvedValue(response);
jest
.spyOn(response.headers, "get")
.mockReturnValue(`${passwordRetryAfter}`);
jest.spyOn(passwordClient.state, "read");
jest.spyOn(passwordClient.state, "setRetryAfter");
jest.spyOn(passwordClient.state, "write");
await expect(passwordClient.login(userID, password)).rejects.toThrowError(
TooManyRequestsError
);
expect(passwordClient.state.read).toHaveBeenCalledTimes(1);
expect(passwordClient.state.setRetryAfter).toHaveBeenCalledWith(
userID,
passwordRetryAfter
);
expect(passwordClient.state.write).toHaveBeenCalledTimes(1);
expect(response.headers.get).toHaveBeenCalledWith("X-Retry-After");
});
it("should throw error when API response is not ok", async () => {
const response = new Response(new XMLHttpRequest());
passwordClient.client.post = jest.fn().mockResolvedValue(response);
const loginResponse = passwordClient.login(userID, password);
await expect(loginResponse).rejects.toThrowError(TechnicalError);
});
it("should throw error on API communication failure", async () => {
passwordClient.client.post = jest
.fn()
.mockRejectedValue(new Error("Test error"));
const loginResponse = passwordClient.login(userID, password);
await expect(loginResponse).rejects.toThrowError("Test error");
});
});
describe("PasswordClient.update()", () => {
it("should update a password", async () => {
const response = new Response(new XMLHttpRequest());
response.ok = true;
jest.spyOn(passwordClient.client, "put").mockResolvedValue(response);
const loginResponse = passwordClient.update(userID, password);
await expect(loginResponse).resolves.toBeUndefined();
expect(passwordClient.client.put).toHaveBeenCalledWith("/password", {
user_id: userID,
password,
});
});
it("should throw error when API response is not ok", async () => {
const response = new Response(new XMLHttpRequest());
passwordClient.client.put = jest.fn().mockResolvedValue(response);
const config = passwordClient.update(userID, password);
await expect(config).rejects.toThrowError(TechnicalError);
});
it("should throw error on API communication failure", async () => {
passwordClient.client.put = jest
.fn()
.mockRejectedValue(new Error("Test error"));
const config = passwordClient.update(userID, password);
await expect(config).rejects.toThrowError("Test error");
});
describe("PasswordClient.getRetryAfter()", () => {
it("should return password resend after seconds", async () => {
jest
.spyOn(passwordClient.state, "getRetryAfter")
.mockReturnValue(passwordRetryAfter);
expect(passwordClient.getRetryAfter(userID)).toEqual(passwordRetryAfter);
});
});
});