Skip to content

Commit

Permalink
chore: adding tests + coverage for common (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
aversini authored Jul 7, 2024
1 parent 4a4defa commit 486d73e
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 5 deletions.
7 changes: 3 additions & 4 deletions packages/auth-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"files": ["dist"],
"scripts": {
"build:check": "tsc",
"build:js": "vite build",
Expand All @@ -29,7 +27,8 @@
"lint": "biome lint src",
"start": "static-server dist --port 5173",
"test:watch": "vitest",
"test": "vitest run"
"test": "vitest run",
"test:coverage": "vitest run --coverage"
},
"dependencies": {
"jose": "5.6.3",
Expand Down
50 changes: 50 additions & 0 deletions packages/auth-common/src/components/__tests__/getToken.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { type HeadersLike, getToken } from "..";

describe("getToken", () => {
const clientId = "testClient";

it("should return empty string if no token is found", () => {
const headers: HeadersLike = {};
expect(getToken(headers, clientId)).toBe("");
});

it("should extract token from authorization header", () => {
const token = "someToken";
const headers: HeadersLike = {
authorization: `Bearer ${token}`,
};
expect(getToken(headers, clientId)).toBe(token);
});

it("should extract token from cookie", () => {
const token = "anotherToken";
const headers: HeadersLike = {
cookie: `auth.${clientId}=${token};`,
};
expect(getToken(headers, clientId)).toBe(token);
});

it("should prioritize token from cookie over authorization header", () => {
const headerToken = "headerToken";
const cookieToken = "cookieToken";
const headers: HeadersLike = {
authorization: `Bearer ${headerToken}`,
cookie: `auth.${clientId}=${cookieToken};`,
};
expect(getToken(headers, clientId)).toBe(cookieToken);
});

it("should return empty string if authorization header is not in correct format", () => {
const headers: HeadersLike = {
authorization: "InvalidHeader",
};
expect(getToken(headers, clientId)).toBe("");
});

it("should return empty string if cookie does not contain the token", () => {
const headers: HeadersLike = {
cookie: "someOtherCookie=value;",
};
expect(getToken(headers, clientId)).toBe("");
});
});
63 changes: 63 additions & 0 deletions packages/auth-common/src/components/__tests__/verifyToken.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { decodeJwt, importSPKI, jwtVerify } from "jose";
import { decodeToken, verifyAndExtractToken } from "..";
import { JWT, JWT_PUBLIC_KEY } from "../constants";
vi.mock("jose");

describe("verifyAndExtractToken", () => {
const token = "testToken";

it("should verify and extract token successfully", async () => {
const mockPublicKey = {};
const mockJwtVerifyResult = {
payload: "testPayload",
protectedHeader: "testHeader",
};
// @ts-expect-error
(importSPKI as vi.Mock).mockResolvedValue(mockPublicKey);
// @ts-expect-error
(jwtVerify as vi.Mock).mockResolvedValue(mockJwtVerifyResult);

const result = await verifyAndExtractToken(token);

expect(importSPKI).toHaveBeenCalledWith(JWT_PUBLIC_KEY, JWT.ALG);
expect(jwtVerify).toHaveBeenCalledWith(token, mockPublicKey, {
issuer: JWT.ISSUER,
});
expect(result).toEqual(mockJwtVerifyResult);
});

it("should return undefined on error", async () => {
// @ts-expect-error
(importSPKI as vi.Mock).mockRejectedValue(new Error("test error"));

const result = await verifyAndExtractToken(token);

expect(result).toBeUndefined();
});
});

describe("decodeToken", () => {
const token = "testToken";

it("should decode token successfully", () => {
const mockDecodeResult = { payload: "testPayload" };
// @ts-expect-error
(decodeJwt as vi.Mock).mockReturnValue(mockDecodeResult);

const result = decodeToken(token);

expect(decodeJwt).toHaveBeenCalledWith(token);
expect(result).toEqual(mockDecodeResult);
});

it("should return undefined on error", () => {
// @ts-expect-error
(decodeJwt as vi.Mock).mockImplementation(() => {
throw new Error("test error");
});

const result = decodeToken(token);

expect(result).toBeUndefined();
});
});
2 changes: 1 addition & 1 deletion packages/auth-common/src/components/getToken.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type HeadersLike = Record<string, unknown> & {
export type HeadersLike = Record<string, unknown> & {
authorization?: string;
"content-type"?: string;
cookie?: string;
Expand Down
2 changes: 2 additions & 0 deletions packages/auth-common/src/components/pkce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ const toBase64 = (val: ArrayBuffer): string =>
* @returns The base64 url encoded code challenge.
*/
export async function generateCodeChallenge(code_verifier: string) {
/* c8 ignore start */
if (!crypto.subtle) {
throw new Error(
"crypto.subtle is available only in secure contexts (HTTPS).",
);
}
/* c8 ignore end */
const data = new TextEncoder().encode(code_verifier);
const hashed = await crypto.subtle.digest("SHA-256", data);
return toBase64(hashed)
Expand Down

0 comments on commit 486d73e

Please sign in to comment.