Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/apps/web/app/shared-store.server.test.ts
T

101 lines
2.9 KiB
TypeScript

import { afterEach, describe, expect, test, vi } from "vitest";
import {
__resetSharedStoreForTests,
__setSharedStoreFactoryForTests,
closeSharedStores,
getCrossAppCacheStore,
getSharedStore,
} from "./shared-store.server";
afterEach(() => {
__resetSharedStoreForTests();
});
describe("web shared-store singleton", () => {
test("memoizes the factory result", () => {
const factory = vi.fn(() => ({
namespace: "web",
ttlDefault: undefined,
adapter: {} as never,
key: (s: string) => s,
get: async () => null,
set: async () => true,
del: async () => 0,
incr: async () => 0,
expire: async () => true,
mget: async () => [],
scan: async function* () {},
publish: async () => 0,
subscribe: async () => async () => undefined,
zAdd: async () => 0,
zRemRangeByScore: async () => 0,
zCard: async () => 0,
eval: async () => null,
close: async () => undefined,
}));
__setSharedStoreFactoryForTests(factory);
const first = getSharedStore();
const second = getSharedStore();
expect(first).toBe(second);
expect(factory).toHaveBeenCalledTimes(1);
});
test("returns a memory-backed store when REDIS_URL is unset", async () => {
const originalRedisUrl = process.env.REDIS_URL;
delete process.env.REDIS_URL;
__resetSharedStoreForTests();
try {
const store = getSharedStore();
expect(store.namespace).toBe("web");
await store.set("ping", "pong");
expect(await store.get("ping")).toBe("pong");
} finally {
if (originalRedisUrl !== undefined) process.env.REDIS_URL = originalRedisUrl;
}
});
test("binds cross-app cache traffic to the shared namespace and adapter", () => {
const local = getSharedStore();
const crossApp = getCrossAppCacheStore();
expect(crossApp.namespace).toBe("cross-app-cache");
expect(crossApp.adapter).toBe(local.adapter);
expect(getCrossAppCacheStore()).toBe(crossApp);
});
test("closes a shared adapter once and clears both singleton stores", async () => {
const close = vi.fn(async () => undefined);
const adapter = { close } as never;
const factory = vi.fn(() => ({
namespace: "web",
ttlDefault: undefined,
adapter,
key: (suffix: string) => suffix,
get: async () => null,
set: async () => true,
del: async () => 0,
incr: async () => 0,
expire: async () => true,
mget: async () => [],
scan: async function* () {},
publish: async () => 0,
subscribe: async () => async () => undefined,
zAdd: async () => 0,
zRemRangeByScore: async () => 0,
zCard: async () => 0,
eval: async () => null,
close,
}));
__setSharedStoreFactoryForTests(factory);
getSharedStore();
getCrossAppCacheStore();
await closeSharedStores();
expect(close).toHaveBeenCalledTimes(1);
getSharedStore();
expect(factory).toHaveBeenCalledTimes(2);
});
});