Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tnorling committed Nov 1, 2020
1 parent 3228adf commit dfa33dc
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 20 deletions.
2 changes: 2 additions & 0 deletions lib/msal-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
"build": "tsdx build --tsconfig ./tsconfig.build.json",
"build:modules:watch": "tsdx watch --verbose",
"test": "tsdx test .*.spec.*",
"test:watch": "tsdx test .*.spec.* --watch",
"test:coverage": "tsdx test .*.spec.* --coverage",
"lint": "cd ../../ && npm run lint:react",
"lint:fix": "npm run lint -- -- --fix",
"build:all": "npm run build:common && npm run build:browser && npm run build",
Expand Down
17 changes: 15 additions & 2 deletions lib/msal-react/test/TestConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
* Licensed under the MIT License.
*/

import { AccountInfo } from "@azure/msal-browser";
import { AccountInfo, AuthenticationResult } from "@azure/msal-browser";

export const TEST_CONFIG = {
MSAL_CLIENT_ID: "0813e1d1-ad72-46a9-8665-399bba48c201"
MSAL_CLIENT_ID: "0813e1d1-ad72-46a9-8665-399bba48c201",
};

export const TEST_DATA_CLIENT_INFO = {
Expand All @@ -29,3 +29,16 @@ export const testAccount: AccountInfo = {
username: "[email protected]",
name: "Abe Lincoln"
};

export const testResult: AuthenticationResult = {
uniqueId: "unique-id",
tenantId: "tenant-id",
scopes: ["openid", "profile"],
idToken: "test-id-token",
idTokenClaims: {},
accessToken: "test-access-token",
fromCache: false,
expiresOn: new Date(Date.now() + (3600000)),
account: testAccount,
tokenType: "Bearer"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ import React from "react";
import { render, screen, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";
import { testAccount, TEST_CONFIG } from "../TestConstants";
import { MsalProvider } from "../../src/MsalProvider";
import { AuthenticatedTemplate } from "../../src/components/AuthenticatedTemplate";
import { MsalProvider, AuthenticatedTemplate } from "../../src/index";
import { PublicClientApplication, IPublicClientApplication, Configuration } from "@azure/msal-browser";

describe("MsalProvider tests", () => {
describe("AuthenticatedTemplate tests", () => {
let pca: IPublicClientApplication;
const msalConfig: Configuration = {
auth: {
Expand All @@ -28,7 +27,7 @@ describe("MsalProvider tests", () => {
jest.clearAllMocks();
});

test("AuthenticatedComponent does not show child component if no account is signed in", async () => {
test("Does not show child component if no account is signed in", async () => {
const handleRedirectSpy = jest.spyOn(pca, "handleRedirectPromise");
render(
<MsalProvider instance={pca}>
Expand All @@ -44,7 +43,7 @@ describe("MsalProvider tests", () => {
expect(screen.queryByText("A user is authenticated!")).not.toBeInTheDocument();
});

test("AuthenticatedComponent shows child component if any account is signed in", async () => {
test("Shows child component if any account is signed in", async () => {
const handleRedirectSpy = jest.spyOn(pca, "handleRedirectPromise");
const getAllAccountsSpy = jest.spyOn(pca, "getAllAccounts");
getAllAccountsSpy.mockImplementation(() => [testAccount]);
Expand All @@ -62,7 +61,7 @@ describe("MsalProvider tests", () => {
expect(screen.queryByText("A user is authenticated!")).toBeInTheDocument();
});

test("AuthenticatedComponent shows child component if specific username is signed in", async () => {
test("Shows child component if specific username is signed in", async () => {
const handleRedirectSpy = jest.spyOn(pca, "handleRedirectPromise");
const getAllAccountsSpy = jest.spyOn(pca, "getAllAccounts");
getAllAccountsSpy.mockImplementation(() => [testAccount]);
Expand All @@ -80,7 +79,7 @@ describe("MsalProvider tests", () => {
expect(screen.queryByText("A user is authenticated!")).toBeInTheDocument();
});

test("AuthenticatedComponent shows child component if specific homeAccountId is signed in", async () => {
test("Shows child component if specific homeAccountId is signed in", async () => {
const handleRedirectSpy = jest.spyOn(pca, "handleRedirectPromise");
const getAllAccountsSpy = jest.spyOn(pca, "getAllAccounts");
getAllAccountsSpy.mockImplementation(() => [testAccount]);
Expand All @@ -98,7 +97,7 @@ describe("MsalProvider tests", () => {
expect(screen.queryByText("A user is authenticated!")).toBeInTheDocument();
});

test("AuthenticatedComponent shows child component if specific username is not signed in", async () => {
test("Shows child component if specific username is not signed in", async () => {
const handleRedirectSpy = jest.spyOn(pca, "handleRedirectPromise");
const getAllAccountsSpy = jest.spyOn(pca, "getAllAccounts");
getAllAccountsSpy.mockImplementation(() => [testAccount]);
Expand All @@ -116,7 +115,7 @@ describe("MsalProvider tests", () => {
expect(screen.queryByText("A user is authenticated!")).not.toBeInTheDocument();
});

test("AuthenticatedComponent shows child component if specific homeAccountId is not signed in", async () => {
test("Shows child component if specific homeAccountId is not signed in", async () => {
const handleRedirectSpy = jest.spyOn(pca, "handleRedirectPromise");
const getAllAccountsSpy = jest.spyOn(pca, "getAllAccounts");
getAllAccountsSpy.mockImplementation(() => [testAccount]);
Expand Down
244 changes: 244 additions & 0 deletions lib/msal-react/test/components/MsalAuthenticationTemplate.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import React from "react";
import { render, screen, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";
import { testAccount, testResult, TEST_CONFIG } from "../TestConstants";
import { MsalProvider, MsalAuthenticationTemplate } from "../../src/index";
import { PublicClientApplication, Configuration, InteractionType, EventType, AccountInfo, EventCallbackFunction, EventMessage, PopupRequest } from "@azure/msal-browser";

describe("MsalAuthenticationTemplate tests", () => {
let pca: PublicClientApplication;
const msalConfig: Configuration = {
auth: {
clientId: TEST_CONFIG.MSAL_CLIENT_ID
}
};

let eventCallback: EventCallbackFunction;
let handleRedirectSpy: jest.SpyInstance;
let accounts: AccountInfo[] = [];

beforeEach(() => {
pca = new PublicClientApplication(msalConfig);
jest.spyOn(pca, "addEventCallback").mockImplementation((callbackFn) => {
eventCallback = callbackFn;
return "callbackId";
});
handleRedirectSpy = jest.spyOn(pca, "handleRedirectPromise").mockImplementation(() => {
const eventMessage: EventMessage = {
eventType: EventType.HANDLE_REDIRECT_END,
interactionType: InteractionType.Redirect,
payload: null,
error: null,
timestamp: 10000
}
eventCallback(eventMessage);
return Promise.resolve(null);
});

jest.spyOn(pca, "getAllAccounts").mockImplementation(() => accounts);
});

afterEach(() => {
// cleanup on exiting
jest.clearAllMocks();
accounts = [];
});

test("Calls loginPopup if no account is signed in", async () => {
const loginPopupSpy = jest.spyOn(pca, "loginPopup").mockImplementation((request) => {
expect(request).toBe(undefined);
accounts = [testAccount];
const eventMessage: EventMessage = {
eventType: EventType.LOGIN_SUCCESS,
interactionType: InteractionType.Popup,
payload: null,
error: null,
timestamp: 10000
}
eventCallback(eventMessage);

return Promise.resolve(testResult);
});

render(
<MsalProvider instance={pca}>
<p>This text will always display.</p>
<MsalAuthenticationTemplate interactionType={InteractionType.Popup}>
<span> A user is authenticated!</span>
</MsalAuthenticationTemplate>
</MsalProvider>
);

await waitFor(() => expect(handleRedirectSpy).toHaveBeenCalledTimes(1));
await waitFor(() => expect(loginPopupSpy).toHaveBeenCalledTimes(1));
expect(screen.queryByText("This text will always display.")).toBeInTheDocument();
expect(screen.queryByText("A user is authenticated!")).toBeInTheDocument();
});

test("Calls loginRedirect if no account is signed in", async () => {
const loginRedirectSpy = jest.spyOn(pca, "loginRedirect").mockImplementation((request) => {
expect(request).toBe(undefined);
accounts = [testAccount];
const eventMessage: EventMessage = {
eventType: EventType.LOGIN_SUCCESS,
interactionType: InteractionType.Redirect,
payload: null,
error: null,
timestamp: 10000
}
eventCallback(eventMessage);
return Promise.resolve();
});

render(
<MsalProvider instance={pca}>
<p>This text will always display.</p>
<MsalAuthenticationTemplate interactionType={InteractionType.Redirect}>
<span> A user is authenticated!</span>
</MsalAuthenticationTemplate>
</MsalProvider>
);

await waitFor(() => expect(handleRedirectSpy).toHaveBeenCalledTimes(1));
await waitFor(() => expect(loginRedirectSpy).toHaveBeenCalledTimes(1));
expect(screen.queryByText("This text will always display.")).toBeInTheDocument();
expect(screen.queryByText("A user is authenticated!")).toBeInTheDocument();
});

test("Calls ssoSilent if no account is signed in", async () => {
const ssoSilentSpy = jest.spyOn(pca, "ssoSilent").mockImplementation((request) => {
expect(request).toBe(undefined);
accounts = [testAccount];
const eventMessage: EventMessage = {
eventType: EventType.LOGIN_SUCCESS,
interactionType: InteractionType.Silent,
payload: null,
error: null,
timestamp: 10000
}
eventCallback(eventMessage);
return Promise.resolve(testResult);
});

render(
<MsalProvider instance={pca}>
<p>This text will always display.</p>
<MsalAuthenticationTemplate interactionType={InteractionType.Silent}>
<span> A user is authenticated!</span>
</MsalAuthenticationTemplate>
</MsalProvider>
);

await waitFor(() => expect(handleRedirectSpy).toHaveBeenCalledTimes(1));
await waitFor(() => expect(ssoSilentSpy).toHaveBeenCalledTimes(1));
expect(screen.queryByText("This text will always display.")).toBeInTheDocument();
expect(screen.queryByText("A user is authenticated!")).toBeInTheDocument();
});

test("Calls loginPopup with provided request if no account is signed in", async () => {
const loginRequest: PopupRequest = {
scopes: ["openid"],
redirectUri: "http://localhost"
};
const loginPopupSpy = jest.spyOn(pca, "loginPopup").mockImplementation((request) => {
expect(request).toBe(loginRequest);
accounts = [testAccount];
const eventMessage: EventMessage = {
eventType: EventType.LOGIN_SUCCESS,
interactionType: InteractionType.Popup,
payload: null,
error: null,
timestamp: 10000
}
eventCallback(eventMessage);

return Promise.resolve(testResult);
});

render(
<MsalProvider instance={pca}>
<p>This text will always display.</p>
<MsalAuthenticationTemplate interactionType={InteractionType.Popup} authenticationRequest={loginRequest}>
<span> A user is authenticated!</span>
</MsalAuthenticationTemplate>
</MsalProvider>
);

await waitFor(() => expect(handleRedirectSpy).toHaveBeenCalledTimes(1));
await waitFor(() => expect(loginPopupSpy).toHaveBeenCalledTimes(1));
expect(screen.queryByText("This text will always display.")).toBeInTheDocument();
expect(screen.queryByText("A user is authenticated!")).toBeInTheDocument();
});

test("Calls loginRedirect with provided request if no account is signed in", async () => {
const loginRequest: PopupRequest = {
scopes: ["openid"],
redirectUri: "http://localhost"
};
const loginRedirectSpy = jest.spyOn(pca, "loginRedirect").mockImplementation((request) => {
expect(request).toBe(loginRequest);
accounts = [testAccount];
const eventMessage: EventMessage = {
eventType: EventType.LOGIN_SUCCESS,
interactionType: InteractionType.Redirect,
payload: null,
error: null,
timestamp: 10000
}
eventCallback(eventMessage);
return Promise.resolve();
});

render(
<MsalProvider instance={pca}>
<p>This text will always display.</p>
<MsalAuthenticationTemplate interactionType={InteractionType.Redirect} authenticationRequest={loginRequest}>
<span> A user is authenticated!</span>
</MsalAuthenticationTemplate>
</MsalProvider>
);

await waitFor(() => expect(handleRedirectSpy).toHaveBeenCalledTimes(1));
await waitFor(() => expect(loginRedirectSpy).toHaveBeenCalledTimes(1));
expect(screen.queryByText("This text will always display.")).toBeInTheDocument();
expect(screen.queryByText("A user is authenticated!")).toBeInTheDocument();
});

test("Calls ssoSilent with provided request if no account is signed in", async () => {
const loginRequest: PopupRequest = {
scopes: ["openid"]
};
const ssoSilentSpy = jest.spyOn(pca, "ssoSilent").mockImplementation((request) => {
expect(request).toBe(loginRequest);
accounts = [testAccount];
const eventMessage: EventMessage = {
eventType: EventType.LOGIN_SUCCESS,
interactionType: InteractionType.Silent,
payload: null,
error: null,
timestamp: 10000
}
eventCallback(eventMessage);
return Promise.resolve(testResult);
});

render(
<MsalProvider instance={pca}>
<p>This text will always display.</p>
<MsalAuthenticationTemplate interactionType={InteractionType.Silent} authenticationRequest={loginRequest}>
<span> A user is authenticated!</span>
</MsalAuthenticationTemplate>
</MsalProvider>
);

await waitFor(() => expect(handleRedirectSpy).toHaveBeenCalledTimes(1));
await waitFor(() => expect(ssoSilentSpy).toHaveBeenCalledTimes(1));
expect(screen.queryByText("This text will always display.")).toBeInTheDocument();
expect(screen.queryByText("A user is authenticated!")).toBeInTheDocument();
});
});
Loading

0 comments on commit dfa33dc

Please sign in to comment.