Skip to content

Commit ed26f3a

Browse files
committed
fix unit tests (finally)
1 parent 8e0c787 commit ed26f3a

16 files changed

+83
-199
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"@eslint/js": "^9.25.1",
3535
"@playwright/test": "^1.52.0",
3636
"@tsconfig/node22": "^22.0.1",
37+
"@types/ioredis-mock": "^8.2.5",
3738
"@types/node": "^22.15.2",
3839
"@types/pluralize": "^0.0.33",
3940
"@types/react": "^19.1.2",
@@ -63,6 +64,7 @@
6364
"eslint-plugin-react-hooks": "^5.2.0",
6465
"husky": "^9.1.4",
6566
"identity-obj-proxy": "^3.0.0",
67+
"ioredis-mock": "^8.9.0",
6668
"jsdom": "^26.1.0",
6769
"node-ical": "^0.20.1",
6870
"postcss": "^8.5.3",
@@ -85,4 +87,4 @@
8587
"resolutions": {
8688
"pdfjs-dist": "^4.8.69"
8789
}
88-
}
90+
}

src/api/plugins/auth.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ const authPlugin: FastifyPluginAsync = async (fastify, _options) => {
264264
verifiedTokenData.sub;
265265
const expectedRoles = new Set(validRoles);
266266
const cachedRoles = await fastify.redisClient.get(
267-
`authCache:${verifiedTokenData.sub}:roles`,
267+
`authCache:${request.username}:roles`,
268268
);
269269
if (cachedRoles) {
270270
request.userRoles = new Set(JSON.parse(cachedRoles));
@@ -318,7 +318,7 @@ const authPlugin: FastifyPluginAsync = async (fastify, _options) => {
318318
}
319319
request.userRoles = userRoles;
320320
fastify.redisClient.set(
321-
`authCache:${verifiedTokenData.sub}:roles`,
321+
`authCache:${request.username}:roles`,
322322
JSON.stringify([...userRoles]),
323323
"EX",
324324
AUTH_DECISION_CACHE_SECONDS,

tests/unit/apiKey.test.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@ import { afterAll, expect, test, beforeEach, vi, describe } from "vitest";
22
import { mockClient } from "aws-sdk-client-mock";
33
import init from "../../src/api/index.js";
44
import { createJwt } from "./auth.test.js";
5-
import { secretJson, secretObject } from "./secret.testdata.js";
5+
import { secretObject } from "./secret.testdata.js";
66
import supertest from "supertest";
7-
import {
8-
GetSecretValueCommand,
9-
SecretsManagerClient,
10-
} from "@aws-sdk/client-secrets-manager";
117
import {
128
ConditionalCheckFailedException,
139
DynamoDBClient,
@@ -32,7 +28,6 @@ vi.mock("../../src/api/functions/apiKey.js", () => {
3228

3329
// Mock DynamoDB client
3430
const dynamoMock = mockClient(DynamoDBClient);
35-
const smMock = mockClient(SecretsManagerClient);
3631
const jwt_secret = secretObject["jwt_key"];
3732

3833
vi.stubEnv("JwtSigningKey", jwt_secret);
@@ -42,13 +37,8 @@ const app = await init();
4237
describe("API Key Route Tests", () => {
4338
beforeEach(() => {
4439
dynamoMock.reset();
45-
smMock.reset();
4640
vi.clearAllMocks();
4741

48-
smMock.on(GetSecretValueCommand).resolves({
49-
SecretString: secretJson,
50-
});
51-
5242
dynamoMock.on(TransactWriteItemsCommand).resolves({});
5343

5444
dynamoMock.on(ScanCommand).resolves({

tests/unit/auth.test.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
import { expect, test, vi } from "vitest";
2-
import {
3-
GetSecretValueCommand,
4-
SecretsManagerClient,
5-
} from "@aws-sdk/client-secrets-manager";
62
import { mockClient } from "aws-sdk-client-mock";
73
import init from "../../src/api/index.js";
84
import {
9-
secretJson,
105
secretObject,
116
jwtPayload,
127
jwtPayloadNoGroups,
@@ -15,8 +10,6 @@ import jwt from "jsonwebtoken";
1510
import { allAppRoles, AppRoles } from "../../src/common/roles.js";
1611
import { beforeEach, describe } from "node:test";
1712

18-
const ddbMock = mockClient(SecretsManagerClient);
19-
2013
const app = await init();
2114
const jwt_secret = secretObject["jwt_key"];
2215
export function createJwt(date?: Date, groups?: string[], email?: string) {
@@ -54,9 +47,6 @@ const testJwtNoGroups = createJwtNoGroups();
5447

5548
describe("Test authentication", () => {
5649
test("Test happy path", async () => {
57-
ddbMock.on(GetSecretValueCommand).resolves({
58-
SecretString: secretJson,
59-
});
6050
const response = await app.inject({
6151
method: "GET",
6252
url: "/api/v1/protected",
@@ -73,9 +63,6 @@ describe("Test authentication", () => {
7363
});
7464

7565
test("Test user-specific role grants", async () => {
76-
ddbMock.on(GetSecretValueCommand).resolves({
77-
SecretString: secretJson,
78-
});
7966
const response = await app.inject({
8067
method: "GET",
8168
url: "/api/v1/protected",
@@ -93,5 +80,6 @@ describe("Test authentication", () => {
9380

9481
beforeEach(() => {
9582
(app as any).nodeCache.flushAll();
83+
(app as any).redisClient.flushAll();
9684
});
9785
});

tests/unit/discordEvent.test.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,12 @@ import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";
33
import { mockClient } from "aws-sdk-client-mock";
44
import init from "../../src/api/index.js";
55
import { createJwt } from "./auth.test.js";
6-
import { secretJson, secretObject } from "./secret.testdata.js";
6+
import { secretObject } from "./secret.testdata.js";
77
import supertest from "supertest";
88
import { describe } from "node:test";
9-
import {
10-
GetSecretValueCommand,
11-
SecretsManagerClient,
12-
} from "@aws-sdk/client-secrets-manager";
139
import { updateDiscord } from "../../src/api/functions/discord.js";
1410

1511
const ddbMock = mockClient(DynamoDBClient);
16-
const smMock = mockClient(SecretsManagerClient);
1712

1813
const jwt_secret = secretObject["jwt_key"];
1914
vi.stubEnv("JwtSigningKey", jwt_secret);
@@ -33,9 +28,6 @@ const app = await init();
3328
describe("Test Events <-> Discord integration", () => {
3429
test("Happy path: valid publish submission.", async () => {
3530
ddbMock.on(PutItemCommand).resolves({});
36-
smMock.on(GetSecretValueCommand).resolves({
37-
SecretString: secretJson,
38-
});
3931
const testJwt = createJwt();
4032
await app.ready();
4133
const response = await supertest(app.server)
@@ -57,9 +49,6 @@ describe("Test Events <-> Discord integration", () => {
5749

5850
test("Happy path: do not publish repeating events.", async () => {
5951
ddbMock.on(PutItemCommand).resolves({});
60-
smMock.on(GetSecretValueCommand).resolves({
61-
SecretString: secretJson,
62-
});
6352
const testJwt = createJwt();
6453
await app.ready();
6554
const response = await supertest(app.server)
@@ -87,7 +76,6 @@ describe("Test Events <-> Discord integration", () => {
8776
beforeEach(() => {
8877
(app as any).nodeCache.flushAll();
8978
ddbMock.reset();
90-
smMock.reset();
9179
vi.clearAllMocks();
9280
vi.useFakeTimers();
9381
});

tests/unit/entraGroupManagement.test.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
import { afterAll, expect, test, beforeEach, vi } from "vitest";
2-
import { mockClient } from "aws-sdk-client-mock";
32
import init from "../../src/api/index.js";
43
import { createJwt } from "./auth.test.js";
54
import supertest from "supertest";
65
import { describe } from "node:test";
7-
import {
8-
GetSecretValueCommand,
9-
SecretsManagerClient,
10-
} from "@aws-sdk/client-secrets-manager";
116
import { EntraGroupError } from "../../src/common/errors/index.js";
127

138
// Mock required dependencies - their real impl's are defined in the beforeEach section.
@@ -36,17 +31,12 @@ import {
3631
resolveEmailToOid,
3732
} from "../../src/api/functions/entraId.js";
3833
import { EntraGroupActions } from "../../src/common/types/iam.js";
39-
40-
const smMock = mockClient(SecretsManagerClient);
4134
const app = await init();
4235

4336
describe("Test Modify Group and List Group Routes", () => {
4437
beforeEach(() => {
4538
(app as any).nodeCache.flushAll();
4639
vi.clearAllMocks();
47-
smMock.on(GetSecretValueCommand).resolves({
48-
SecretString: JSON.stringify({ jwt_key: "test_jwt_key" }),
49-
});
5040
});
5141

5242
test("Modify group: Add and remove members", async () => {

tests/unit/entraInviteUser.test.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
import { afterAll, expect, test, beforeEach, vi } from "vitest";
2-
import { mockClient } from "aws-sdk-client-mock";
32
import init from "../../src/api/index.js";
43
import { createJwt } from "./auth.test.js";
5-
import { secretJson, secretObject } from "./secret.testdata.js";
4+
import { secretObject } from "./secret.testdata.js";
65
import supertest from "supertest";
76
import { describe } from "node:test";
8-
import {
9-
GetSecretValueCommand,
10-
SecretsManagerClient,
11-
} from "@aws-sdk/client-secrets-manager";
127

138
vi.mock("../../src/api/functions/entraId.js", () => {
149
return {
@@ -28,7 +23,6 @@ import {
2823
} from "../../src/api/functions/entraId.js";
2924
import { EntraInvitationError } from "../../src/common/errors/index.js";
3025

31-
const smMock = mockClient(SecretsManagerClient);
3226
const jwt_secret = secretObject["jwt_key"];
3327

3428
vi.stubEnv("JwtSigningKey", jwt_secret);
@@ -37,9 +31,6 @@ const app = await init();
3731

3832
describe("Test Microsoft Entra ID user invitation", () => {
3933
test("Emails must end in @illinois.edu.", async () => {
40-
smMock.on(GetSecretValueCommand).resolves({
41-
SecretString: secretJson,
42-
});
4334
const testJwt = createJwt();
4435
await app.ready();
4536

@@ -56,9 +47,6 @@ describe("Test Microsoft Entra ID user invitation", () => {
5647
expect(addToTenant).toHaveBeenCalled();
5748
});
5849
test("Happy path", async () => {
59-
smMock.on(GetSecretValueCommand).resolves({
60-
SecretString: secretJson,
61-
});
6250
const testJwt = createJwt();
6351
await app.ready();
6452

@@ -73,9 +61,6 @@ describe("Test Microsoft Entra ID user invitation", () => {
7361
expect(addToTenant).toHaveBeenCalled();
7462
});
7563
test("Happy path", async () => {
76-
smMock.on(GetSecretValueCommand).resolves({
77-
SecretString: secretJson,
78-
});
7964
const testJwt = createJwt();
8065
await app.ready();
8166

tests/unit/eventPost.test.ts

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,11 @@ import {
88
import { mockClient } from "aws-sdk-client-mock";
99
import init from "../../src/api/index.js";
1010
import { createJwt } from "./auth.test.js";
11-
import {
12-
GetSecretValueCommand,
13-
SecretsManagerClient,
14-
} from "@aws-sdk/client-secrets-manager";
1511
import { secretJson, secretObject } from "./secret.testdata.js";
1612
import supertest from "supertest";
1713
import { marshall } from "@aws-sdk/util-dynamodb";
1814

1915
const ddbMock = mockClient(DynamoDBClient);
20-
const smMock = mockClient(SecretsManagerClient);
2116
const jwt_secret = secretObject["jwt_key"];
2217
vi.stubEnv("JwtSigningKey", jwt_secret);
2318

@@ -81,9 +76,6 @@ test("Sad path: Prevent empty body request", async () => {
8176
});
8277
test("Sad path: Prevent specifying repeatEnds on non-repeating events", async () => {
8378
ddbMock.on(PutItemCommand).resolves({});
84-
smMock.on(GetSecretValueCommand).resolves({
85-
SecretString: secretJson,
86-
});
8779
const testJwt = createJwt();
8880
await app.ready();
8981
const response = await supertest(app.server)
@@ -112,9 +104,6 @@ test("Sad path: Prevent specifying repeatEnds on non-repeating events", async ()
112104

113105
test("Sad path: Prevent specifying unknown repeat frequencies", async () => {
114106
ddbMock.on(PutItemCommand).resolves({});
115-
smMock.on(GetSecretValueCommand).resolves({
116-
SecretString: secretJson,
117-
});
118107
const testJwt = createJwt();
119108
await app.ready();
120109
const response = await supertest(app.server)
@@ -144,9 +133,6 @@ test("Sad path: Prevent specifying unknown repeat frequencies", async () => {
144133

145134
test("Happy path: Adding a non-repeating, featured, paid event", async () => {
146135
ddbMock.on(PutItemCommand).resolves({});
147-
smMock.on(GetSecretValueCommand).resolves({
148-
SecretString: secretJson,
149-
});
150136
const testJwt = createJwt();
151137
await app.ready();
152138
const response = await supertest(app.server)
@@ -176,9 +162,6 @@ test("Happy path: Adding a non-repeating, featured, paid event", async () => {
176162

177163
test("Happy path: Adding a weekly repeating, non-featured, paid event", async () => {
178164
ddbMock.on(PutItemCommand).resolves({});
179-
smMock.on(GetSecretValueCommand).resolves({
180-
SecretString: secretJson,
181-
});
182165
const testJwt = createJwt();
183166
await app.ready();
184167
const response = await supertest(app.server)
@@ -211,14 +194,8 @@ describe("ETag Lifecycle Tests", () => {
211194
// Setup
212195
(app as any).nodeCache.flushAll();
213196
ddbMock.reset();
214-
smMock.reset();
215197
vi.useFakeTimers();
216198

217-
// Mock secrets manager
218-
smMock.on(GetSecretValueCommand).resolves({
219-
SecretString: secretJson,
220-
});
221-
222199
// Mock successful DynamoDB operations
223200
ddbMock.on(PutItemCommand).resolves({});
224201

@@ -299,14 +276,8 @@ describe("ETag Lifecycle Tests", () => {
299276
// Setup
300277
(app as any).nodeCache.flushAll();
301278
ddbMock.reset();
302-
smMock.reset();
303279
vi.useFakeTimers();
304280

305-
// Mock secrets manager
306-
smMock.on(GetSecretValueCommand).resolves({
307-
SecretString: secretJson,
308-
});
309-
310281
// Mock successful DynamoDB operations
311282
ddbMock.on(PutItemCommand).resolves({});
312283
ddbMock.on(ScanCommand).resolves({
@@ -397,14 +368,8 @@ describe("ETag Lifecycle Tests", () => {
397368
// Setup
398369
(app as any).nodeCache.flushAll();
399370
ddbMock.reset();
400-
smMock.reset();
401371
vi.useFakeTimers();
402372

403-
// Mock secrets manager
404-
smMock.on(GetSecretValueCommand).resolves({
405-
SecretString: secretJson,
406-
});
407-
408373
// Mock successful DynamoDB operations
409374
ddbMock.on(PutItemCommand).resolves({});
410375

@@ -538,8 +503,8 @@ afterAll(async () => {
538503
});
539504
beforeEach(() => {
540505
(app as any).nodeCache.flushAll();
506+
(app as any).redisClient.flushdb();
541507
ddbMock.reset();
542-
smMock.reset();
543508
vi.clearAllMocks();
544509
vi.useFakeTimers();
545510
});

0 commit comments

Comments
 (0)