UNPKG

@fedify/fedify

Version:

An ActivityPub server framework

197 lines (196 loc) • 5.87 kB
import { Temporal } from "@js-temporal/polyfill"; import { URLPattern } from "urlpattern-polyfill"; globalThis.addEventListener = () => {}; import { n as kvCache, t as MockKvStore } from "../kv-cache-DYsF2MhP.mjs"; import { mockDocumentLoader, test } from "@fedify/fixture"; import { deepStrictEqual, throws } from "node:assert"; import { preloadedContexts } from "@fedify/vocab-runtime"; //#region src/utils/kv-cache.test.ts test("kvCache()", async (t) => { const kv = new MockKvStore(); await t.step("cached", async () => { const loader = kvCache({ kv, loader: mockDocumentLoader, rules: [ ["https://example.org/", Temporal.Duration.from({ days: 1 })], [new URL("https://example.net/"), Temporal.Duration.from({ days: 1 })], [new URLPattern("https://example.com/*"), Temporal.Duration.from({ days: 30 })] ], prefix: ["_test", "cached"] }); const result = await loader("https://example.com/object"); deepStrictEqual(result, { contextUrl: null, documentUrl: "https://example.com/object", document: { "@context": "https://www.w3.org/ns/activitystreams", id: "https://example.com/object", name: "Fetched object", type: "Object" } }); deepStrictEqual(await kv.get([ "_test", "cached", "https://example.com/object" ]), result); await kv.set([ "_test", "cached", "https://example.org/" ], { contextUrl: null, documentUrl: "https://example.org/", document: { "id": "https://example.org/" } }); deepStrictEqual(await loader("https://example.org/"), { contextUrl: null, documentUrl: "https://example.org/", document: { "id": "https://example.org/" } }); await kv.set([ "_test", "cached", "https://example.net/" ], { contextUrl: null, documentUrl: "https://example.net/", document: { "id": "https://example.net/" } }); deepStrictEqual(await loader("https://example.net/"), { contextUrl: null, documentUrl: "https://example.net/", document: { "id": "https://example.net/" } }); }); await t.step("not cached", async () => { deepStrictEqual(await kvCache({ kv, loader: mockDocumentLoader, rules: [], prefix: ["_test", "not cached"] })("https://example.com/object"), { contextUrl: null, documentUrl: "https://example.com/object", document: { "@context": "https://www.w3.org/ns/activitystreams", id: "https://example.com/object", name: "Fetched object", type: "Object" } }); deepStrictEqual(await kv.get([ "test2", "not cached", "https://example.com/object" ]), void 0); }); await t.step("maximum cache duration", () => { throws(() => kvCache({ kv, loader: mockDocumentLoader, rules: [["https://example.com/", Temporal.Duration.from({ days: 30, seconds: 1 })]] }), TypeError, "The maximum cache duration is 30 days"); throws(() => kvCache({ kv, loader: mockDocumentLoader, rules: [[new URLPattern("https://example.com/*"), Temporal.Duration.from({ days: 30, seconds: 1 })]] }), TypeError, "The maximum cache duration is 30 days"); }); await t.step("on kv store exception", async () => { class KvStoreThrowsException { get(_key) { throw new Error("Failed to get key"); } set(_key, _value, _options) { throw new Error("Failed to set key"); } delete(_key) { throw new Error("Failed to delete key"); } async *list(_prefix) { throw new Error("Failed to list keys"); } } deepStrictEqual(await kvCache({ kv: new KvStoreThrowsException(), loader: mockDocumentLoader, rules: [ ["https://example.org/", Temporal.Duration.from({ days: 1 })], [new URL("https://example.net/"), Temporal.Duration.from({ days: 1 })], [new URLPattern("https://example.com/*"), Temporal.Duration.from({ days: 30 })] ], prefix: ["_test", "not cached"] })("https://example.com/object"), { contextUrl: null, documentUrl: "https://example.com/object", document: { "@context": "https://www.w3.org/ns/activitystreams", id: "https://example.com/object", name: "Fetched object", type: "Object" } }); }); await t.step("preloaded contexts bypass cache", async () => { const kv = new MockKvStore(); let loaderCalled = false; const mockLoader = (url) => { loaderCalled = true; return Promise.resolve({ contextUrl: null, documentUrl: url, document: { "mock": "document" } }); }; const loader = kvCache({ kv, loader: mockLoader, prefix: ["_test", "preloaded"] }); const activityStreamsUrl = "https://www.w3.org/ns/activitystreams"; loaderCalled = false; deepStrictEqual(await loader(activityStreamsUrl), { contextUrl: null, documentUrl: activityStreamsUrl, document: preloadedContexts[activityStreamsUrl] }); deepStrictEqual(loaderCalled, false, "Loader should not be called for preloaded contexts"); deepStrictEqual(await kv.get([ "_test", "preloaded", activityStreamsUrl ]), void 0, "Preloaded contexts should not be cached in KV store"); const securityUrl = "https://w3id.org/security/v1"; loaderCalled = false; deepStrictEqual(await loader(securityUrl), { contextUrl: null, documentUrl: securityUrl, document: preloadedContexts[securityUrl] }); deepStrictEqual(loaderCalled, false, "Loader should not be called for preloaded contexts"); const nonPreloadedUrl = "https://example.com/not-preloaded"; loaderCalled = false; const result3 = await loader(nonPreloadedUrl); deepStrictEqual(result3, { contextUrl: null, documentUrl: nonPreloadedUrl, document: { "mock": "document" } }); deepStrictEqual(loaderCalled, true, "Loader should be called for non-preloaded URLs"); deepStrictEqual(await kv.get([ "_test", "preloaded", nonPreloadedUrl ]), result3, "Non-preloaded URLs should be cached"); }); }); //#endregion export {};