Skip to content

Commit

Permalink
Refactor amplify methods to single file
Browse files Browse the repository at this point in the history
  • Loading branch information
bangbay-bluetiger committed Oct 21, 2024
1 parent 198ebca commit 4d24713
Show file tree
Hide file tree
Showing 16 changed files with 322 additions and 233 deletions.
13 changes: 6 additions & 7 deletions services/ui-src/src/components/logins/LoginCognito.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import { LoginCognito } from "components";
import { RouterWrappedComponent } from "utils/testing/setupJest";

const mockSignIn = jest.fn();
jest.mock("aws-amplify/auth", () => ({
signIn: (credentials: any) => mockSignIn(credentials),

jest.mock("utils", () => ({
loginUser: (username: string, password: string) =>
mockSignIn(username, password),
}));

const mockUseNavigate = jest.fn();
Expand All @@ -30,12 +32,9 @@ describe("Test LoginCognito", () => {
const passwordInput = screen.getByLabelText("Password");
const submitButton = screen.getByRole("button");
await userEvent.type(emailInput, "[email protected]");
await userEvent.type(passwordInput, "p@$$w0rd"); //pragma: allowlist secret
await userEvent.type(passwordInput, "test");
await userEvent.click(submitButton);
expect(mockSignIn).toHaveBeenCalledWith({
username: "[email protected]",
password: "p@$$w0rd", //pragma: allowlist secret
});
expect(mockSignIn).toHaveBeenCalledWith("[email protected]", "test");
expect(mockUseNavigate).toHaveBeenCalledWith("/");
});
});
Expand Down
6 changes: 3 additions & 3 deletions services/ui-src/src/components/logins/LoginCognito.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { signIn } from "aws-amplify/auth";
// components
import { Box, Button, Heading, Input, Stack, Text } from "@chakra-ui/react";
import { ErrorAlert } from "components";
import { ErrorVerbiage } from "types";
import { loginUser } from "utils";

const useFormFields = (initialState: any) => {
const [fields, setValues] = useState(initialState);
Expand Down Expand Up @@ -32,8 +32,8 @@ export const LoginCognito = () => {
const handleLogin = async (event: any) => {
event.preventDefault();
try {
await signIn({ username: fields.email, password: fields.password });
navigate(`/`);
await loginUser(fields.email, fields.password);
navigate("/");
} catch (error: any) {
setError(error.message);
}
Expand Down
108 changes: 108 additions & 0 deletions services/ui-src/src/utils/api/request/request.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import {
deleteApi,
getApi,
getRequestHeaders,
getTokens,
loginUser,
logoutUser,
postApi,
putApi,
refreshSession,
} from "utils";

const mockResponse = { response: { body: { json: () => jest.fn() } } };
const mockDelete = jest.fn().mockImplementation(() => mockResponse);
const mockGet = jest.fn().mockImplementation(() => mockResponse);
const mockPost = jest.fn().mockImplementation(() => mockResponse);
const mockPut = jest.fn().mockImplementation(() => mockResponse);
const mockSession = jest.fn();
const mockSignIn = jest.fn();
const mockSignOut = jest.fn();

jest.mock("aws-amplify/api", () => ({
del: () => mockDelete(),
get: () => mockGet(),
post: () => mockPost(),
put: () => mockPut(),
}));

jest.mock("aws-amplify/auth", () => ({
fetchAuthSession: () => mockSession(),
signIn: () => mockSignIn(),
signOut: () => mockSignOut(),
}));

describe("request", () => {
beforeEach(() => {
jest.clearAllMocks();
});

describe("getRequestHeaders()", () => {
test("Logs error to console if Auth throws error", async () => {
jest.spyOn(console, "log").mockImplementation(jest.fn());
const spy = jest.spyOn(console, "log");

mockSession.mockImplementation(() => {
throw new Error();
});

await getRequestHeaders();

expect(spy).toHaveBeenCalled();
});

test("Returns token if current idToken exists", async () => {
mockSession.mockResolvedValue({
tokens: {
idToken: {
toString: () => "stringToken",
},
},
});

const result = await getRequestHeaders();

expect(result).toStrictEqual({ "x-api-key": "stringToken" });
});
});

test("getTokens()", async () => {
await getTokens();
expect(mockSession).toHaveBeenCalledTimes(1);
});

test("loginUser()", async () => {
await loginUser("[email protected]", "test");
expect(mockSignIn).toHaveBeenCalledTimes(1);
});

test("logoutUser()", async () => {
await logoutUser();
expect(mockSignOut).toHaveBeenCalledTimes(1);
});

test("refreshSession()", async () => {
await refreshSession();
expect(mockSession).toHaveBeenCalledTimes(1);
});

test("deleteApi()", async () => {
await deleteApi("/");
expect(mockDelete).toHaveBeenCalledTimes(1);
});

test("getApi()", async () => {
await getApi<string>("/");
expect(mockGet).toHaveBeenCalledTimes(1);
});

test("postApi()", async () => {
await postApi<string>("/", { body: "" });
expect(mockPost).toHaveBeenCalledTimes(1);
});

test("putApi()", async () => {
await putApi<string>("/");
expect(mockPut).toHaveBeenCalledTimes(1);
});
});
106 changes: 106 additions & 0 deletions services/ui-src/src/utils/api/request/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { del, get, post, put } from "aws-amplify/api";
import {
AuthTokens,
fetchAuthSession,
signIn,
signOut,
} from "aws-amplify/auth";

const apiName = "mcr";

interface RequestHeaders {
"x-api-key": string | undefined;
}

export const getRequestHeaders = async (): Promise<
RequestHeaders | undefined
> => {
try {
const tokens = await getTokens();
const headers = {
"x-api-key": tokens?.idToken?.toString(),
};

return headers;
} catch (error) {
console.log(error); //eslint-disable-line no-console
return;
}
};

export const getTokens = async (): Promise<AuthTokens | undefined> => {
return (await fetchAuthSession()).tokens;
};

export const loginUser = async (
username: string,
password: string
): Promise<void> => {
await signIn({ username, password });
};

export const logoutUser = async (): Promise<void> => {
await signOut();
};

export const refreshSession = async (): Promise<void> => {
await fetchAuthSession({ forceRefresh: true });
};

export const deleteApi = async (path: string, opts?: any): Promise<void> => {
const requestHeaders = await getRequestHeaders();
const options = {
headers: { ...requestHeaders },
...opts,
};
await del({
apiName,
path,
options,
}).response;
};

export const getApi = async <T>(path: string, opts?: any): Promise<T> => {
const requestHeaders = await getRequestHeaders();
const options = {
headers: { ...requestHeaders },
...opts,
};
const { body } = await get({
apiName,
path,
options,
}).response;

return (await body.json()) as T;
};

export const postApi = async <T>(path: string, opts?: any): Promise<T> => {
const requestHeaders = await getRequestHeaders();
const options = {
headers: { ...requestHeaders },
...opts,
};
const { body } = await post({
apiName,
path,
options,
}).response;

return (await body.json()) as T;
};

export const putApi = async <T>(path: string, opts?: any): Promise<T> => {
const requestHeaders = await getRequestHeaders();
const options = {
headers: { ...requestHeaders },
...opts,
};
const { body } = await put({
apiName,
path,
options,
}).response;

return (await body.json()) as T;
};
37 changes: 21 additions & 16 deletions services/ui-src/src/utils/api/requestMethods/banner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,38 @@ import { getBanner, writeBanner, deleteBanner } from "./banner";
import { bannerId } from "../../../constants";
import { mockBannerData } from "utils/testing/setupJest";

const mockAmplifyApi = require("aws-amplify/api");
const mockDelete = jest.fn();
const mockGet = jest.fn();
const mockPost = jest.fn();
const mockTimeout = jest.fn();

jest.mock("utils/auth/authLifecycle", () => ({
updateTimeout: jest.fn(),
initAuthManager: jest.fn(),
refreshCredentials: jest.fn(),
jest.mock("utils", () => ({
deleteApi: () => mockDelete(),
getApi: () => mockGet(),
postApi: () => mockPost(),
updateTimeout: () => mockTimeout(),
}));

describe("Test banner methods", () => {
describe("banner", () => {
beforeEach(() => {
jest.clearAllMocks();
});
test("getBanner", async () => {
const apiSpy = jest.spyOn(mockAmplifyApi, "get");
expect(await getBanner(bannerId)).toBeTruthy();
expect(apiSpy).toHaveBeenCalledTimes(1);

test("getBanner()", async () => {
await getBanner(bannerId);
expect(mockGet).toHaveBeenCalledTimes(1);
expect(mockTimeout).toHaveBeenCalledTimes(1);
});

test("postBanner", async () => {
const apiSpy = jest.spyOn(mockAmplifyApi, "post");
test("postBanner()", async () => {
await writeBanner(mockBannerData);
expect(apiSpy).toHaveBeenCalledTimes(1);
expect(mockPost).toHaveBeenCalledTimes(1);
expect(mockTimeout).toHaveBeenCalledTimes(1);
});

test("delBanner", async () => {
const apiSpy = jest.spyOn(mockAmplifyApi, "del");
test("deleteBanner()", async () => {
await deleteBanner(bannerId);
expect(apiSpy).toHaveBeenCalledTimes(1);
expect(mockDelete).toHaveBeenCalledTimes(1);
expect(mockTimeout).toHaveBeenCalledTimes(1);
});
});
38 changes: 4 additions & 34 deletions services/ui-src/src/utils/api/requestMethods/banner.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,25 @@
import { get, post, del } from "aws-amplify/api";
import { getRequestHeaders } from "./getRequestHeaders";
import { AdminBannerData } from "types/banners";
import { updateTimeout } from "utils";

const apiName = "mcr";
import { deleteApi, getApi, postApi, updateTimeout } from "utils";

async function getBanner(bannerKey: string) {
const requestHeaders = await getRequestHeaders();
const options = {
headers: { ...requestHeaders },
};
const path = `/banners/${bannerKey}`;

updateTimeout();
const { body } = await get({
apiName,
path,
options,
}).response;
return (await body.json()) as unknown as { Item: AdminBannerData };
return getApi<AdminBannerData>(path);
}

async function writeBanner(bannerData: AdminBannerData) {
const requestHeaders = await getRequestHeaders();
const options = {
headers: { ...requestHeaders },
body: bannerData,
};
const path = `/banners/${bannerData.key}`;

updateTimeout();
await post({
apiName,
path,
options,
}).response;
return postApi<AdminBannerData>(path, options);
}

async function deleteBanner(bannerKey: string) {
const requestHeaders = await getRequestHeaders();
const options = {
headers: { ...requestHeaders },
};
const path = `/banners/${bannerKey}`;

updateTimeout();
await del({
apiName,
path,
options,
}).response;
return deleteApi(path);
}

export { getBanner, writeBanner, deleteBanner };
Loading

0 comments on commit 4d24713

Please sign in to comment.