Files
optima/api/tests/unit/signPermissions.test.ts
T

90 lines
2.8 KiB
TypeScript

import { describe, test, expect } from "bun:test";
import jwt from "jsonwebtoken";
import crypto from "crypto";
import { signPermissions } from "../../src/modules/permission-utils/signPermissions";
// The test setup mocks the constants module with a test RSA key pair.
// signPermissions imports permissionsPrivateKey from constants, which
// is the test private key generated in setup.ts. We can verify with the
// corresponding test public key.
// Re-generate the same key pair used in setup.ts from constants mock:
// The mock uses _testPrivateKey/_testPublicKey, but we can decode the JWT
// to verify its contents without needing the public key directly.
describe("signPermissions", () => {
test("returns a string (JWT)", () => {
const token = signPermissions({
issuer: "optima",
subject: "user-1",
permissions: ["company.fetch.many"],
});
expect(typeof token).toBe("string");
expect(token.split(".")).toHaveLength(3); // header.payload.signature
});
test("JWT payload contains permissions array", () => {
const permissions = ["company.fetch.many", "credential.read"];
const token = signPermissions({
issuer: "optima",
subject: "user-1",
permissions,
});
const decoded = jwt.decode(token) as any;
expect(decoded.permissions).toEqual(permissions);
});
test("JWT contains issuer claim", () => {
const token = signPermissions({
issuer: "optima",
subject: "user-1",
permissions: ["*"],
});
const decoded = jwt.decode(token, { complete: true }) as any;
expect(decoded.payload.iss).toBe("optima");
});
test("JWT contains subject claim", () => {
const token = signPermissions({
issuer: "optima",
subject: "role-abc",
permissions: ["*"],
});
const decoded = jwt.decode(token, { complete: true }) as any;
expect(decoded.payload.sub).toBe("role-abc");
});
test("JWT uses RS256 algorithm", () => {
const token = signPermissions({
issuer: "optima",
subject: "user-1",
permissions: [],
});
const decoded = jwt.decode(token, { complete: true }) as any;
expect(decoded.header.alg).toBe("RS256");
});
test("handles empty permissions array", () => {
const token = signPermissions({
issuer: "optima",
subject: "user-1",
permissions: [],
});
const decoded = jwt.decode(token) as any;
expect(decoded.permissions).toEqual([]);
});
test("handles large permissions arrays", () => {
const permsList = Array.from({ length: 100 }, (_, i) => `perm.${i}`);
const token = signPermissions({
issuer: "optima",
subject: "user-1",
permissions: permsList,
});
const decoded = jwt.decode(token) as any;
expect(decoded.permissions).toHaveLength(100);
expect(decoded.permissions[0]).toBe("perm.0");
expect(decoded.permissions[99]).toBe("perm.99");
});
});