-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtestCacheAndRedisExtended.js
More file actions
172 lines (143 loc) · 5.97 KB
/
testCacheAndRedisExtended.js
File metadata and controls
172 lines (143 loc) · 5.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import BosBase from "bosbase";
function createStubClient() {
const pb = new BosBase("https://cache.test");
const calls = [];
pb.send = async (path, options = {}) => {
calls.push({ path, options });
// Cache endpoints
if (path === "/api/cache") {
if (options.method === "GET") {
return { items: [{ name: "demo", sizeBytes: 1024, defaultTTLSeconds: 60, readTimeoutMs: 50 }] };
}
if (options.method === "POST") {
return {
name: options.body?.name,
sizeBytes: options.body?.sizeBytes ?? 0,
defaultTTLSeconds: options.body?.defaultTTLSeconds ?? 0,
readTimeoutMs: options.body?.readTimeoutMs ?? 0,
};
}
}
if (path.startsWith("/api/cache/") && options.method === "PATCH") {
const name = decodeURIComponent(path.split("/").pop() || "");
return { name, ...options.body };
}
if (path.startsWith("/api/cache/") && options.method === "DELETE") {
return {};
}
if (path.includes("/entries/")) {
const key = decodeURIComponent(path.split("/").pop() || "");
return {
cache: "demo",
key,
value: options.body?.value ?? "unset",
ttlSeconds: options.body?.ttlSeconds,
source: "cache",
};
}
// Redis endpoints
if (path === "/api/redis/keys") {
if (options.method === "GET") {
return { cursor: "0", items: [{ key: "demo" }] };
}
if (options.method === "POST") {
return {
key: options.body?.key,
value: options.body?.value,
ttlSeconds: options.body?.ttlSeconds,
};
}
}
if (path.startsWith("/api/redis/keys/")) {
const key = decodeURIComponent(path.split("/").pop() || "");
if (options.method === "GET" || !options.method) {
return { key, value: "existing", ttlSeconds: 30 };
}
if (options.method === "PUT") {
return { key, value: options.body?.value, ttlSeconds: options.body?.ttlSeconds };
}
if (options.method === "DELETE") {
return {};
}
}
throw new Error(`Unexpected request: ${path} ${options.method || ""}`);
};
return { pb, calls };
}
async function main() {
const { pb, calls } = createStubClient();
try {
console.log("[INFO] Testing CacheService full entry lifecycle...");
const cacheList = await pb.caches.list();
if (!Array.isArray(cacheList) || cacheList.length !== 1 || cacheList[0].name !== "demo") {
throw new Error("caches.list did not return stubbed cache list");
}
const created = await pb.caches.create({ name: "demo", sizeBytes: 2048, defaultTTLSeconds: 10 });
if (created.name !== "demo" || created.sizeBytes !== 2048) {
throw new Error("caches.create did not echo configuration");
}
const updated = await pb.caches.update("demo", { defaultTTLSeconds: 120 });
if (updated.defaultTTLSeconds !== 120) {
throw new Error("caches.update did not persist TTL change");
}
const entry = await pb.caches.setEntry("demo", "greeting", { text: "hello" }, 90);
if (entry.key !== "greeting" || entry.value?.text !== "hello" || entry.ttlSeconds !== 90) {
throw new Error("caches.setEntry did not preserve key/value/ttl");
}
const fetched = await pb.caches.getEntry("demo", "greeting");
if (fetched.key !== "greeting") {
throw new Error("caches.getEntry did not fetch expected key");
}
const renewed = await pb.caches.renewEntry("demo", "greeting", 180);
if (renewed.ttlSeconds !== 180) {
throw new Error("caches.renewEntry did not update ttlSeconds");
}
const deleteEntryResult = await pb.caches.deleteEntry("demo", "greeting");
if (deleteEntryResult !== true) {
throw new Error("caches.deleteEntry did not resolve to true");
}
const deleteCacheResult = await pb.caches.delete("demo");
if (deleteCacheResult !== true) {
throw new Error("caches.delete did not resolve to true");
}
const cachePaths = calls.filter((c) => c.path.startsWith("/api/cache"));
const entryPath = cachePaths.find((c) => c.path.includes("/entries/greeting"));
if (!entryPath || !entryPath.path.endsWith("greeting")) {
throw new Error("Cache entry paths were not encoded correctly");
}
console.log("[SUCCESS] CacheService CRUD + entry helpers verified");
console.log("[INFO] Testing RedisService key CRUD helpers...");
const redisList = await pb.redis.listKeys({ count: 1 });
if (!redisList?.items?.length) {
throw new Error("redis.listKeys did not return stubbed list");
}
const createdKey = await pb.redis.createKey({ key: "session:1", value: { user: "u1" }, ttlSeconds: 45 });
if (createdKey.key !== "session:1" || createdKey.ttlSeconds !== 45) {
throw new Error("redis.createKey did not return key with ttlSeconds");
}
const fetchedKey = await pb.redis.getKey("session:1");
if (fetchedKey.key !== "session:1") {
throw new Error("redis.getKey did not fetch expected key");
}
const updatedKey = await pb.redis.updateKey("session:1", { value: { user: "u2" }, ttlSeconds: 99 });
if (updatedKey.value?.user !== "u2" || updatedKey.ttlSeconds !== 99) {
throw new Error("redis.updateKey did not apply updates");
}
const deleteKeyResult = await pb.redis.deleteKey("session:1");
if (deleteKeyResult !== true) {
throw new Error("redis.deleteKey did not resolve to true");
}
const redisCalls = calls.filter((c) => c.path.startsWith("/api/redis/keys"));
const updateCall = redisCalls.find((c) => c.options.method === "PUT");
if (!updateCall || !updateCall.path.endsWith("session%3A1")) {
throw new Error("Redis key paths were not URL encoded");
}
console.log("[SUCCESS] RedisService key CRUD helpers verified");
console.log("\n========== Cache and Redis helper coverage completed ==========");
} catch (error) {
console.error("[ERROR] Cache/Redis helper coverage failed:");
console.error(error?.stack || error);
process.exit(1);
}
}
main();