Skip to content

Commit

Permalink
chore: add with authorization dashboard middleware tests
Browse files Browse the repository at this point in the history
  • Loading branch information
marcellmueller committed Jun 27, 2024
1 parent 286a813 commit 075e862
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 2 deletions.
149 changes: 149 additions & 0 deletions bciers/apps/dashboard/middlewares/withAuthorizationDashboard.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { NextURL } from "next/dist/server/web/next-url";
import { NextRequest, NextResponse } from "next/server";
import { instance, mock, reset, when } from "ts-mockito";
import middleware from "../middleware";
import { getToken } from "@bciers/testConfig/mocks";

const mockBaseToken = {
name: "Test User",
email: "[email protected]",
sub: "uuid",
given_name: "Test",
family_name: "User",
bceid_business_name: "Cas, Bcgov",
bceid_business_guid: "guid",
user_guid: "guid",
full_name: "Test User",
iat: 1719517475,
exp: 1719519275,
jti: "uuid",
};

const mockIndustryUserToken = {
...mockBaseToken,
app_role: "industry_user",
identity_provider: "bceidbusiness",
};

const mockCasPendingToken = {
...mockBaseToken,
app_role: "cas_pending",
identity_provider: "idir",
};

const mockCasUserToken = {
...mockBaseToken,
app_role: "cas_user",
identity_provider: "idir",
};

const domain = "https://localhost:3000";
const mockedRequest: NextRequest = mock(NextRequest);
const dashboardUrl = new URL("/dashboard", domain);

vi.spyOn(NextResponse, "redirect");
vi.spyOn(NextResponse, "rewrite");

describe("withAuthorizationDashboard middleware", () => {
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(() => {
reset(mockedRequest);
});

test("redirects to the registration profile page if the user has no app role", async () => {
getToken.mockResolvedValue(mockBaseToken);
const nextUrl = new NextURL(`${domain}/dashboard`);

when(mockedRequest.nextUrl).thenReturn(nextUrl);
when(mockedRequest.url).thenReturn(domain);

const result = await middleware(instance(mockedRequest));

expect(NextResponse.redirect).toHaveBeenCalledOnce();
expect(NextResponse.redirect).toHaveBeenCalledWith(
new URL("/registration/profile", domain),
);
expect(result).toBeInstanceOf(NextResponse);

// 307 is the status code for a temporary redirect
expect(result?.status).toBe(307);
});

it("calls NextMiddleware if the user has no app role and the route ends in /profile", async () => {
getToken.mockResolvedValue(mockBaseToken);
const nextUrl = new NextURL(`${domain}/profile`);

when(mockedRequest.nextUrl).thenReturn(nextUrl);

const result = await middleware(instance(mockedRequest));
expect(result?.status).toBe(200);
});

it("redirects to the registration page if the user has cas_pending app role", async () => {
getToken.mockResolvedValue(mockCasPendingToken);
const nextUrl = new NextURL(`${domain}/dashboard`);

when(mockedRequest.nextUrl).thenReturn(nextUrl);

const result = await middleware(instance(mockedRequest));
nextUrl.pathname = "/registration";
expect(NextResponse.rewrite).toHaveBeenCalledOnce();
expect(NextResponse.rewrite).toHaveBeenCalledWith(nextUrl);

expect(result?.status).toBe(200);
});

it("redirects authenticated industry_user to the common dashboard if the route is /onboarding", async () => {
getToken.mockResolvedValue(mockIndustryUserToken);
const nextUrl = new NextURL("/onboarding", domain);

when(mockedRequest.nextUrl).thenReturn(nextUrl);
when(mockedRequest.url).thenReturn(domain);

const result = await middleware(instance(mockedRequest));
expect(NextResponse.redirect).toHaveBeenCalledOnce();
expect(NextResponse.redirect).toHaveBeenCalledWith(dashboardUrl);
expect(result?.status).toBe(307);
});

it("redirects authenticated industry_user to the common dashboard if the route is /", async () => {
getToken.mockResolvedValue(mockIndustryUserToken);
const nextUrl = new NextURL(domain);

when(mockedRequest.nextUrl).thenReturn(nextUrl);
when(mockedRequest.url).thenReturn(domain);

const result = await middleware(instance(mockedRequest));
expect(NextResponse.redirect).toHaveBeenCalledOnce();
expect(NextResponse.redirect).toHaveBeenCalledWith(dashboardUrl);
expect(result?.status).toBe(307);
});

it("Redirects authenticated cas_user to the common dashboard if the route is /onboarding", async () => {
getToken.mockResolvedValue(mockCasUserToken);
const nextUrl = new NextURL("/onboarding", domain);

when(mockedRequest.nextUrl).thenReturn(nextUrl);
when(mockedRequest.url).thenReturn(domain);

const result = await middleware(instance(mockedRequest));
expect(NextResponse.redirect).toHaveBeenCalledOnce();
expect(NextResponse.redirect).toHaveBeenCalledWith(dashboardUrl);
expect(result?.status).toBe(307);
});

it("Redirects authenticated cas_user to the common dashboard if the route is /", async () => {
getToken.mockResolvedValue(mockCasUserToken);
const nextUrl = new NextURL(domain);

when(mockedRequest.nextUrl).thenReturn(nextUrl);
when(mockedRequest.url).thenReturn(domain);

const result = await middleware(instance(mockedRequest));
expect(NextResponse.redirect).toHaveBeenCalledOnce();
expect(NextResponse.redirect).toHaveBeenCalledWith(dashboardUrl);
expect(result?.status).toBe(307);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ export const withAuthorizationDashboard: MiddlewareFactory = (

// Should the user be redirected to the onboarding page?
if (token.app_role.includes("pending")) {
request.nextUrl.pathname = "/registration/";
const url = request.nextUrl.clone();
url.pathname = "/registration";

return NextResponse.rewrite(request.nextUrl);
return NextResponse.rewrite(url);
}

if (pathname === "/" || pathname === `/${onboarding}`) {
Expand Down
2 changes: 2 additions & 0 deletions bciers/libs/shared/testConfig/src/global.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { expect, vi } from "vitest";
import {
actionHandler,
auth,
getToken,
useParams,
usePathname,
useRouter,
Expand Down Expand Up @@ -45,6 +46,7 @@ vi.mock("@/dashboard/auth", () => ({

vi.mock("@bciers/actions", () => ({
actionHandler,
getToken,
}));

// mock fetch
Expand Down
2 changes: 2 additions & 0 deletions bciers/libs/shared/testConfig/src/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { fetchMocker } from "./global";
// https://github.com/IanVS/vitest-fetch-mock

const actionHandler = vi.fn();
const getToken = vi.fn();
const useRouter = vi.fn();
const useParams = vi.fn();
const usePathname = vi.fn();
Expand All @@ -34,6 +35,7 @@ const fetchOperationsPageData = vi.fn();
export {
actionHandler,
fetchMocker as fetch,
getToken,
auth,
useRouter,
useParams,
Expand Down

0 comments on commit 075e862

Please sign in to comment.