101 lines
2.9 KiB
TypeScript
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);
|
|
});
|
|
});
|