Skip to content

Commit

Permalink
ES-1011: Verification Screen Unit Test Integration (#295)
Browse files Browse the repository at this point in the history
* fix: move from msw service to worker

Signed-off-by: bunsy-0900 <[email protected]>

* wip: testing mock stomp broker

Signed-off-by: bunsy-0900 <[email protected]>

* fix: add todos and jest-websocket-mock

Signed-off-by: bunsy-0900 <[email protected]>

* chore: add what to do

Signed-off-by: bunsy-0900 <[email protected]>

* fix: add unit test for web socket indicator

Signed-off-by: bunsy-0900 <[email protected]>

---------

Signed-off-by: bunsy-0900 <[email protected]>
Signed-off-by: Aravindhan Alagesan <[email protected]>
Co-authored-by: Aravindhan Alagesan <[email protected]>
  • Loading branch information
bunsy-0900 and aranaravi authored Aug 28, 2024
1 parent 1149ded commit 0f86a49
Show file tree
Hide file tree
Showing 14 changed files with 333 additions and 16 deletions.
5 changes: 5 additions & 0 deletions signup-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@
"react-webcam": "^7.2.0",
"rooks": "^7.14.1",
"socket.io-client": "^4.7.5",
"stomp-broker-js": "^1.3.0",
"tailwind-merge": "^2.0.0",
"tailwindcss-animate": "^1.0.7",
"typescript": "^4.9.5",
"uuid": "^10.0.0",
"web-vitals": "^2.1.4",
"yup": "^1.3.2",
"zustand": "^4.4.6"
Expand Down Expand Up @@ -107,6 +109,8 @@
"@types/platform": "^1.3.6",
"@types/react-detect-offline": "^2.4.5",
"@types/react-google-recaptcha": "^2.1.7",
"@types/text-encoding": "^0.0.39",
"@types/uuid": "^10.0.0",
"autoprefixer": "^10.4.16",
"craco-alias": "^3.0.1",
"eslint": "^8.52.0",
Expand All @@ -123,6 +127,7 @@
"storybook": "^7.6.0",
"tailwindcss": "^3.4.1",
"tailwindcss-dir": "^4.0.0",
"text-encoding": "^0.7.0",
"ts-jest": "^29.1.4",
"tsconfig-paths-webpack-plugin": "^4.1.0",
"type-fest": "^4.6.0",
Expand Down
36 changes: 36 additions & 0 deletions signup-ui/src/global.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,37 @@
/// <reference types="jest-extended" />

declare module "mock-stomp-broker" {
interface Config {
port?: number;
portRange?: [number, number];
endpoint?: string;
}

class MockStompBroker {
private static PORTS_IN_USE;
private static BASE_SESSION;
private static getRandomInt;
private static getPort;
private readonly port;
private readonly httpServer;
private readonly stompServer;
private readonly sentMessageIds;
private queriedSessionIds;
private sessions;
private thereAreNewSessions;
private setMiddleware;
private registerMiddlewares;

constructor({ port, portRange, endpoint }?: Config);

public newSessionsConnected(): Promise<string[]>;
public subscribed(sessionId: string): Promise<void>;
public scheduleMessage(topic: string, payload: any, headers?: {}): string;
public messageSent(messageId: string): Promise<void>;
public disconnected(sessionId: string): Promise<void>;
public kill(): void;
public getPort(): number;
}

export default MockStompBroker;
}
5 changes: 5 additions & 0 deletions signup-ui/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import App from "./App";
import "./services/i18n.service";
import "react-tooltip/dist/react-tooltip.css";

if (process.env.NODE_ENV === "development") {
import("./mocks/msw-browser").then(({ mswWorker }) => mswWorker.start());
}

const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);

root.render(
<React.StrictMode>
<App />
Expand Down
8 changes: 7 additions & 1 deletion signup-ui/src/mocks/handlers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { checkSlotHandlers } from "./slot-checking";
import { testConnectionHandlers } from "./test-connection";

export const handlers = [...checkSlotHandlers];
export const handlers = [
// intercept the "test connection" endpoint
...testConnectionHandlers,
// intercept the "check slot" endpoint
...checkSlotHandlers,
];
16 changes: 16 additions & 0 deletions signup-ui/src/mocks/handlers/test-connection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { http, HttpResponse } from "msw";

// endpoint to be intercepted
const testConnectionEP = "http://localhost:8088/v1/signup/test";

const testConnectionSuccess = http.get(testConnectionEP, async () => {
return HttpResponse.json({
responseTime: "2024-03-25T18:10:18.520Z",
response: {
connection: true,
},
errors: [],
});
});

export const testConnectionHandlers = [testConnectionSuccess];
5 changes: 5 additions & 0 deletions signup-ui/src/mocks/msw-browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { setupWorker } from "msw/browser";

import { handlers } from "./handlers";

export const mswWorker = setupWorker(...handlers);
5 changes: 0 additions & 5 deletions signup-ui/src/mocks/msw-server.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -469,4 +469,4 @@ export const VerificationScreen = ({
</button>
</div>
);
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
import { QueryCache, QueryClient } from "@tanstack/react-query";
import { screen } from "@testing-library/react";

import { renderWithClient } from "~utils/test";
import * as useStompClient from "~pages/shared/stompWs";
import { SettingsDto } from "~typings/types";

import { VerificationScreen } from "../VerificationScreen";

describe("VerificationScreen (vs)", () => {
const queryCache = new QueryCache();
const queryClient = new QueryClient({ queryCache });

const settings = {
response: {
configs: {
"signin.redirect-url":
"https://esignet.camdgc-dev1.mosip.net/authorize",
},
},
} as SettingsDto;
const cancelPopup = jest.fn();

it("should have a connected indicator when web socket is connected", async () => {
// Arrange
jest.spyOn(useStompClient, "default").mockReturnValue({
client: null,
connected: true,
subscribe: jest.fn(),
publish: jest.fn(),
unsubscribe: jest.fn(),
});

renderWithClient(
queryClient,
<VerificationScreen
settings={settings.response}
cancelPopup={cancelPopup}
/>
);

// Act

// Assert
const statusConnected = await screen.findByTestId("websocket-connected");
expect(statusConnected).toBeInTheDocument();
});

it("should have a disconnected indicator when web socket is disconnected", async () => {
// Arrange
jest.spyOn(useStompClient, "default").mockReturnValue({
client: null,
connected: false,
subscribe: jest.fn(),
publish: jest.fn(),
unsubscribe: jest.fn(),
});

renderWithClient(
queryClient,
<VerificationScreen
settings={settings.response}
cancelPopup={cancelPopup}
/>
);

// Act

// Assert
const statusDisconnected = await screen.findByTestId(
"websocket-disconnected"
);
expect(statusDisconnected).toBeInTheDocument();
});

it("should show onscreen instructions above the video frame", async () => {
// Arrange
jest.spyOn(useStompClient, "default").mockReturnValue({
client: null,
connected: true,
subscribe: jest.fn(),
publish: jest.fn(),
unsubscribe: jest.fn(),
});

renderWithClient(
queryClient,
<VerificationScreen
settings={settings.response}
cancelPopup={cancelPopup}
/>
);

// Act

// Assert
// 1. `vs-onscreen-instruction` is in the document
// 2. `vs-onscreen-instruction` should say "Welcome! Initiating Identity verification process in..."
const vsOnScreenInstruction = await screen.findByTestId(
"vs-onscreen-instruction"
);
expect(vsOnScreenInstruction).toBeInTheDocument();
});

// Currently not sure since liveness depends on the web socket's response
it("should show liveliness verification screen", () => {
// Arrange
renderWithClient(
queryClient,
<VerificationScreen
settings={settings.response}
cancelPopup={cancelPopup}
/>
);

// Act

// Assert
const vsLiveliness = screen.getByTestId("vs-liveliness");
expect(vsLiveliness).toBeInTheDocument();
});

// Currently not sure since liveness depends on the web socket's response
it("should show solid colors across the full screen for color based frame verification", async () => {
// Arrange
renderWithClient(
queryClient,
<VerificationScreen
settings={settings.response}
cancelPopup={cancelPopup}
/>
);

// Act
// TODO: add wait for x seconds

// Assert
const vsSolidColorScreen = screen.getByTestId("vs-solid-color-screen");
expect(vsSolidColorScreen).toBeInTheDocument();
});

// Currently not sure since liveness depends on the web socket's response
it("should show NID verification screen", () => {
// Arrange
renderWithClient(
queryClient,
<VerificationScreen
settings={settings.response}
cancelPopup={cancelPopup}
/>
);

// Act

// Assert
const vsNID = screen.getByTestId("vs-nid");
expect(vsNID).toBeInTheDocument();
});

// This one should be moved to IdentityVerificationScreen instead
// https://xd.adobe.com/view/d1ca3fd3-a54c-4055-b7a2-ee5ad0389788-8499/screen/ba9b246e-7658-4c2b-adb5-b908ecdc3825/specs/
// https://xd.adobe.com/view/d1ca3fd3-a54c-4055-b7a2-ee5ad0389788-8499/screen/8f43b20a-1a6a-4a49-b751-e1e2ccb2346b/specs/
it("should show feedback message when verification fails", () => {
// Arrange
// TODO: mock failed verification
renderWithClient(
queryClient,
<VerificationScreen
settings={settings.response}
cancelPopup={cancelPopup}
/>
);

// Act

// Assert
const vsFailedVerification = screen.getByTestId("vs-failed-verification");
expect(vsFailedVerification).toBeInTheDocument();
});

// This one should be moved to IdentityVerificationScreen instead
// https://xd.adobe.com/view/d1ca3fd3-a54c-4055-b7a2-ee5ad0389788-8499/screen/ba9b246e-7658-4c2b-adb5-b908ecdc3825/specs/
// https://xd.adobe.com/view/d1ca3fd3-a54c-4055-b7a2-ee5ad0389788-8499/screen/8f43b20a-1a6a-4a49-b751-e1e2ccb2346b/specs/
it("should show warning message if there is any technical issue", () => {
// Arrange
// TODO: mock technical issue: internet connection lost, ...
renderWithClient(
queryClient,
<VerificationScreen
settings={settings.response}
cancelPopup={cancelPopup}
/>
);

// Act

// Assert
const vsTechnicalIssueWarningMsg = screen.getByTestId(
"vs-technical-issue-warning-msg"
);
expect(vsTechnicalIssueWarningMsg).toBeInTheDocument();
});

// This one should be moved to IdentityVerificationScreen instead
// https://xd.adobe.com/view/d1ca3fd3-a54c-4055-b7a2-ee5ad0389788-8499/screen/8ee5c56c-1cd5-4b52-adc4-4350f88e8973/specs/
it("should be redirected to the leading screen when the verification is successful", () => {
// Arrange
// TODO: mock successful verification
renderWithClient(
queryClient,
<VerificationScreen
settings={settings.response}
cancelPopup={cancelPopup}
/>
);

// Act

// Assert
// to be redirected to and land on the leading screen
});
});
6 changes: 3 additions & 3 deletions signup-ui/src/services/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ const API_BASE_URL =
: window.origin + "/v1/signup";

export const WS_BASE_URL =
process.env.NODE_ENV === "development"
? `ws://${process.env.REACT_APP_API_BASE_URL?.split("://")[1]}`
: `wss://${window.location.host}/v1/signup`;
process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test"
? `ws://${process.env.REACT_APP_API_BASE_URL?.split("://")[1]}`
: `wss://${window.location.host}/v1/signup`;

export class HttpError extends Error {
code: number;
Expand Down
6 changes: 1 addition & 5 deletions signup-ui/src/setupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// learn more: https://github.com/testing-library/jest-dom
import "@testing-library/jest-dom";

import { mswServer } from "./mocks/msw-server";
import { mswWorker } from "./mocks/msw-browser";

require("whatwg-fetch");

Expand All @@ -26,7 +26,3 @@ jest.mock("react-i18next", () => ({
};
},
}));

beforeAll(() => mswServer.listen());
afterEach(() => mswServer.resetHandlers());
afterAll(() => mswServer.close());
1 change: 1 addition & 0 deletions signup-ui/src/typings/stompBroker.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module 'stomp-broker-js';
Loading

0 comments on commit 0f86a49

Please sign in to comment.