@hyper-fetch/core
Version:
Cache, Queue and Persist your requests no matter if you are online or offline!
220 lines (189 loc) • 7.32 kB
text/typescript
import { sleep } from "@hyper-fetch/testing";
import type { CacheValueType } from "cache";
import { createCache } from "../../utils";
import { Client } from "client";
import { xhrExtra } from "http-adapter";
import { Plugin } from "plugin";
describe("Cache [ Events ]", () => {
const cacheKey = "test";
let client = new Client({ url: "shared-base-url" });
let request = client.createRequest<{ response: any }>()({ endpoint: "shared-endpoint", cacheKey, cache: true });
let cache = createCache(client);
const spy = vi.fn();
const cacheData: CacheValueType = {
data: null,
error: null,
status: 200,
success: true,
extra: xhrExtra,
retries: 0,
requestTimestamp: +new Date(),
responseTimestamp: +new Date(),
addedTimestamp: +new Date(),
triggerTimestamp: +new Date(),
cached: true,
isCanceled: false,
isOffline: false,
willRetry: false,
cacheKey: request.cacheKey,
scope: null,
staleTime: request.staleTime,
version: cache.version,
cacheTime: 300000,
};
beforeEach(() => {
client = new Client({ url: "shared-base-url" });
request = client.createRequest<{ response: any }>()({ endpoint: "shared-endpoint", cacheKey, cache: true });
cache = createCache(client);
vi.resetAllMocks();
});
describe("when options events are triggered", () => {
it("should trigger onChange event when data is set", async () => {
const plugin = new Plugin({ name: "change" }).onCacheItemChange(spy);
const newCache = createCache(client.addPlugin(plugin));
newCache.set(request, cacheData);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith({
cache: newCache,
cacheKey: request.cacheKey,
newData: cacheData,
prevData: null,
});
});
it("should trigger onDelete event when data is deleted", async () => {
const plugin = new Plugin({ name: "delete" }).onCacheItemDelete(spy);
const newCache = createCache(client.addPlugin(plugin));
newCache.delete(request.cacheKey);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith({ cache: newCache, cacheKey: request.cacheKey });
});
it("should trigger onData event when data is set", async () => {
const plugin = new Plugin({ name: "data" });
const newCache = createCache(client.addPlugin(plugin));
newCache.events.onData(spy);
newCache.set(request, cacheData);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith(
expect.objectContaining({
data: null,
cacheKey: request.cacheKey,
}),
);
});
it("should trigger onDelete event when data is deleted", async () => {
const plugin = new Plugin({ name: "delete" });
const newCache = createCache(client.addPlugin(plugin));
newCache.events.onDelete(spy);
newCache.delete(request.cacheKey);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith(request.cacheKey);
});
it("should trigger onDeleteByKey event when specific cache key is deleted", async () => {
const plugin = new Plugin({ name: "deleteByKey" });
const newCache = createCache(client.addPlugin(plugin));
newCache.events.onDeleteByKey(request.cacheKey, spy);
newCache.delete(request.cacheKey);
expect(spy).toHaveBeenCalledTimes(1);
});
it("should properly cleanup onData listener when unmount function is called", async () => {
const plugin = new Plugin({ name: "data" });
const newCache = createCache(client.addPlugin(plugin));
const unmount = newCache.events.onData(spy);
unmount();
newCache.set(request, cacheData);
expect(spy).not.toHaveBeenCalled();
});
it("should properly cleanup onDataByKey listener when unmount function is called", async () => {
const plugin = new Plugin({ name: "dataByKey" });
const newCache = createCache(client.addPlugin(plugin));
const unmount = newCache.events.onDataByKey(request.cacheKey, spy);
unmount();
newCache.set(request, cacheData);
expect(spy).not.toHaveBeenCalled();
});
it("should properly cleanup onDelete listener when unmount function is called", async () => {
const plugin = new Plugin({ name: "delete" });
const newCache = createCache(client.addPlugin(plugin));
const unmount = newCache.events.onDelete(spy);
unmount();
newCache.delete(request.cacheKey);
expect(spy).not.toHaveBeenCalled();
});
it("should properly cleanup onDeleteByKey listener when unmount function is called", async () => {
const plugin = new Plugin({ name: "deleteByKey" });
const newCache = createCache(client.addPlugin(plugin));
const unmount = newCache.events.onDeleteByKey(request.cacheKey, spy);
unmount();
newCache.delete(request.cacheKey);
expect(spy).not.toHaveBeenCalled();
});
});
describe("when invalidate event is triggered", () => {
it("should invalidate cache using cache key", async () => {
cache.set(request, {
data: {},
error: null,
status: 200,
success: true,
extra: xhrExtra,
retries: 0,
requestTimestamp: +new Date(),
responseTimestamp: +new Date(),
addedTimestamp: +new Date(),
triggerTimestamp: +new Date(),
isCanceled: false,
isOffline: false,
willRetry: false,
});
cache.events.onInvalidateByKey(cacheKey, spy);
await cache.invalidate(cacheKey);
await sleep(1);
expect(spy).toHaveBeenCalledTimes(1);
});
it("should invalidate cache using regex", async () => {
cache.set(request, {
data: null,
error: null,
status: 200,
success: true,
extra: xhrExtra,
retries: 0,
requestTimestamp: +new Date(),
responseTimestamp: +new Date(),
addedTimestamp: +new Date(),
triggerTimestamp: +new Date(),
isCanceled: false,
isOffline: false,
willRetry: false,
});
cache.events.onInvalidateByKey(cacheKey, spy);
await cache.invalidate(new RegExp(cacheKey));
await sleep(1);
expect(spy).toHaveBeenCalledTimes(1);
});
it("should trigger onInvalidate event when cache is invalidated", async () => {
cache.set(request, cacheData);
cache.events.onInvalidate(spy);
await cache.invalidate(cacheKey);
await sleep(1);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith(cacheKey);
});
it("should properly cleanup onInvalidate listener when unmount function is called", async () => {
cache.set(request, cacheData);
const unmount = cache.events.onInvalidate(spy);
unmount();
await cache.invalidate(cacheKey);
await sleep(1);
expect(spy).not.toHaveBeenCalled();
});
it("should properly cleanup onInvalidateByKey listener when unmount function is called", async () => {
cache.set(request, cacheData);
const unmount = cache.events.onInvalidateByKey(cacheKey, spy);
unmount();
await cache.invalidate(cacheKey);
await sleep(1);
expect(spy).not.toHaveBeenCalled();
});
});
});