Skip to content

Commit 0658b43

Browse files
committed
Add caching behavior tests for RetrieveLatestApp and RetrieveLatestSystemRecovery handlers, ensuring cached redirects and SKU-specific cache keys are correctly implemented
1 parent 39ea9e2 commit 0658b43

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

test/releases.test.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,72 @@ describe("RetrieveLatestApp handler", () => {
10381038
await expect(RetrieveLatestApp(req, res)).rejects.toThrow("is not available for version");
10391039
});
10401040
});
1041+
1042+
describe("cache behavior", () => {
1043+
it("should return cached redirect on second call with same parameters", async () => {
1044+
const req1 = createMockRequest({});
1045+
const res1 = createMockResponse();
1046+
1047+
s3Mock.on(ListObjectsV2Command, { Prefix: "app/" }).resolves({
1048+
CommonPrefixes: [{ Prefix: "app/1.0.0/" }],
1049+
});
1050+
1051+
const content = "cached-app-content";
1052+
const crypto = await import("crypto");
1053+
const hash = crypto.createHash("sha256").update(content).digest("hex");
1054+
1055+
mockS3LegacyVersionWithContent("app", "1.0.0", "jetkvm_app", content, hash);
1056+
1057+
await RetrieveLatestApp(req1, res1);
1058+
expect(res1._redirectUrl).toBe("https://cdn.test.com/app/1.0.0/jetkvm_app");
1059+
1060+
// Reset S3 mock to return different data
1061+
s3Mock.reset();
1062+
s3Mock.on(ListObjectsV2Command, { Prefix: "app/" }).resolves({
1063+
CommonPrefixes: [{ Prefix: "app/2.0.0/" }],
1064+
});
1065+
mockS3LegacyVersionWithContent("app", "2.0.0", "jetkvm_app", "new-content", "new-hash");
1066+
1067+
// Second call should return cached result (1.0.0), not new S3 data (2.0.0)
1068+
const req2 = createMockRequest({});
1069+
const res2 = createMockResponse();
1070+
1071+
await RetrieveLatestApp(req2, res2);
1072+
expect(res2._redirectUrl).toBe("https://cdn.test.com/app/1.0.0/jetkvm_app");
1073+
});
1074+
1075+
it("should use different cache keys for different SKUs", async () => {
1076+
// First call with default SKU
1077+
const req1 = createMockRequest({});
1078+
const res1 = createMockResponse();
1079+
1080+
s3Mock.on(ListObjectsV2Command, { Prefix: "app/" }).resolves({
1081+
CommonPrefixes: [{ Prefix: "app/1.0.0/" }],
1082+
});
1083+
1084+
const content = "sku-cache-test";
1085+
const crypto = await import("crypto");
1086+
const hash = crypto.createHash("sha256").update(content).digest("hex");
1087+
1088+
mockS3LegacyVersionWithContent("app", "1.0.0", "jetkvm_app", content, hash);
1089+
1090+
await RetrieveLatestApp(req1, res1);
1091+
expect(res1._redirectUrl).toBe("https://cdn.test.com/app/1.0.0/jetkvm_app");
1092+
1093+
// Second call with different SKU should NOT use cached result
1094+
s3Mock.reset();
1095+
s3Mock.on(ListObjectsV2Command, { Prefix: "app/" }).resolves({
1096+
CommonPrefixes: [{ Prefix: "app/2.0.0/" }],
1097+
});
1098+
mockS3SkuVersionWithContent("app", "2.0.0", "jetkvm-2", "jetkvm_app", content, hash);
1099+
1100+
const req2 = createMockRequest({ sku: "jetkvm-2" });
1101+
const res2 = createMockResponse();
1102+
1103+
await RetrieveLatestApp(req2, res2);
1104+
expect(res2._redirectUrl).toBe("https://cdn.test.com/app/2.0.0/skus/jetkvm-2/jetkvm_app");
1105+
});
1106+
});
10411107
});
10421108

10431109
describe("RetrieveLatestSystemRecovery handler", () => {
@@ -1276,4 +1342,70 @@ describe("RetrieveLatestSystemRecovery handler", () => {
12761342
await expect(RetrieveLatestSystemRecovery(req, res)).rejects.toThrow("is not available for version");
12771343
});
12781344
});
1345+
1346+
describe("cache behavior", () => {
1347+
it("should return cached redirect on second call with same parameters", async () => {
1348+
const req1 = createMockRequest({});
1349+
const res1 = createMockResponse();
1350+
1351+
s3Mock.on(ListObjectsV2Command, { Prefix: "system/" }).resolves({
1352+
CommonPrefixes: [{ Prefix: "system/1.0.0/" }],
1353+
});
1354+
1355+
const content = "cached-system-recovery-content";
1356+
const crypto = await import("crypto");
1357+
const hash = crypto.createHash("sha256").update(content).digest("hex");
1358+
1359+
mockS3LegacyVersionWithContent("system", "1.0.0", "update.img", content, hash);
1360+
1361+
await RetrieveLatestSystemRecovery(req1, res1);
1362+
expect(res1._redirectUrl).toBe("https://cdn.test.com/system/1.0.0/update.img");
1363+
1364+
// Reset S3 mock to return different data
1365+
s3Mock.reset();
1366+
s3Mock.on(ListObjectsV2Command, { Prefix: "system/" }).resolves({
1367+
CommonPrefixes: [{ Prefix: "system/2.0.0/" }],
1368+
});
1369+
mockS3LegacyVersionWithContent("system", "2.0.0", "update.img", "new-content", "new-hash");
1370+
1371+
// Second call should return cached result (1.0.0), not new S3 data (2.0.0)
1372+
const req2 = createMockRequest({});
1373+
const res2 = createMockResponse();
1374+
1375+
await RetrieveLatestSystemRecovery(req2, res2);
1376+
expect(res2._redirectUrl).toBe("https://cdn.test.com/system/1.0.0/update.img");
1377+
});
1378+
1379+
it("should use different cache keys for different SKUs", async () => {
1380+
// First call with default SKU
1381+
const req1 = createMockRequest({});
1382+
const res1 = createMockResponse();
1383+
1384+
s3Mock.on(ListObjectsV2Command, { Prefix: "system/" }).resolves({
1385+
CommonPrefixes: [{ Prefix: "system/1.0.0/" }],
1386+
});
1387+
1388+
const content = "sku-cache-test-recovery";
1389+
const crypto = await import("crypto");
1390+
const hash = crypto.createHash("sha256").update(content).digest("hex");
1391+
1392+
mockS3LegacyVersionWithContent("system", "1.0.0", "update.img", content, hash);
1393+
1394+
await RetrieveLatestSystemRecovery(req1, res1);
1395+
expect(res1._redirectUrl).toBe("https://cdn.test.com/system/1.0.0/update.img");
1396+
1397+
// Second call with different SKU should NOT use cached result
1398+
s3Mock.reset();
1399+
s3Mock.on(ListObjectsV2Command, { Prefix: "system/" }).resolves({
1400+
CommonPrefixes: [{ Prefix: "system/2.0.0/" }],
1401+
});
1402+
mockS3SkuVersionWithContent("system", "2.0.0", "jetkvm-2", "update.img", content, hash);
1403+
1404+
const req2 = createMockRequest({ sku: "jetkvm-2" });
1405+
const res2 = createMockResponse();
1406+
1407+
await RetrieveLatestSystemRecovery(req2, res2);
1408+
expect(res2._redirectUrl).toBe("https://cdn.test.com/system/2.0.0/skus/jetkvm-2/update.img");
1409+
});
1410+
});
12791411
});

0 commit comments

Comments
 (0)