mirror of
https://github.com/home-assistant/frontend.git
synced 2026-08-29 09:36:48 +01:00
179 lines
4.3 KiB
TypeScript
179 lines
4.3 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
|
|
import { timeCachePromiseFunc } from "../../../src/common/util/time-cache-function-promise";
|
|
|
|
describe("timeCachePromiseFunc", () => {
|
|
it("reuses an in-flight request when the cache key is unchanged", async () => {
|
|
let resolveRequest!: (value: string) => void;
|
|
|
|
const request = new Promise<string>((resolve) => {
|
|
resolveRequest = resolve;
|
|
});
|
|
|
|
const fetchData = vi.fn(() => request);
|
|
const hass = { version: 1 };
|
|
|
|
const calls = Array.from({ length: 20 }, () =>
|
|
timeCachePromiseFunc(
|
|
"_testCache",
|
|
30_000,
|
|
fetchData,
|
|
(currentHass: typeof hass) => currentHass.version,
|
|
hass
|
|
)
|
|
);
|
|
|
|
expect(fetchData).toHaveBeenCalledTimes(1);
|
|
|
|
resolveRequest("result");
|
|
|
|
await expect(Promise.all(calls)).resolves.toEqual(Array(20).fill("result"));
|
|
|
|
expect(fetchData).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("reuses a resolved cached result while the cache key is unchanged", async () => {
|
|
const fetchData = vi.fn().mockResolvedValue("result");
|
|
const hass = { version: 1 };
|
|
|
|
const first = await timeCachePromiseFunc(
|
|
"_testCache",
|
|
30_000,
|
|
fetchData,
|
|
(currentHass: typeof hass) => currentHass.version,
|
|
hass
|
|
);
|
|
|
|
const second = await timeCachePromiseFunc(
|
|
"_testCache",
|
|
30_000,
|
|
fetchData,
|
|
(currentHass: typeof hass) => currentHass.version,
|
|
hass
|
|
);
|
|
|
|
expect(first).toBe("result");
|
|
expect(second).toBe("result");
|
|
expect(fetchData).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("refetches a resolved cached result when the cache key changes", async () => {
|
|
const fetchData = vi
|
|
.fn()
|
|
.mockResolvedValueOnce("first")
|
|
.mockResolvedValueOnce("second");
|
|
|
|
const hass = { version: 1 };
|
|
|
|
const first = await timeCachePromiseFunc(
|
|
"_testCache",
|
|
30_000,
|
|
fetchData,
|
|
(currentHass: typeof hass) => currentHass.version,
|
|
hass
|
|
);
|
|
|
|
hass.version = 2;
|
|
|
|
const second = await timeCachePromiseFunc(
|
|
"_testCache",
|
|
30_000,
|
|
fetchData,
|
|
(currentHass: typeof hass) => currentHass.version,
|
|
hass
|
|
);
|
|
|
|
expect(first).toBe("first");
|
|
expect(second).toBe("second");
|
|
expect(fetchData).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it("reuses an in-flight request without a cache key validator", async () => {
|
|
let resolveRequest!: (value: string) => void;
|
|
|
|
const request = new Promise<string>((resolve) => {
|
|
resolveRequest = resolve;
|
|
});
|
|
|
|
const fetchData = vi.fn(() => request);
|
|
const hass = {};
|
|
|
|
const first = timeCachePromiseFunc(
|
|
"_testCacheNoValidator",
|
|
30_000,
|
|
fetchData,
|
|
undefined,
|
|
hass
|
|
);
|
|
|
|
const second = timeCachePromiseFunc(
|
|
"_testCacheNoValidator",
|
|
30_000,
|
|
fetchData,
|
|
undefined,
|
|
hass
|
|
);
|
|
|
|
expect(fetchData).toHaveBeenCalledTimes(1);
|
|
|
|
resolveRequest("result");
|
|
|
|
await expect(first).resolves.toBe("result");
|
|
await expect(second).resolves.toBe("result");
|
|
expect(fetchData).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
|
|
describe("timeCachePromiseFunc cache ownership", () => {
|
|
it("does not let an older cache timer clear a newer cached result", async () => {
|
|
vi.useFakeTimers();
|
|
|
|
try {
|
|
const fetchData = vi
|
|
.fn()
|
|
.mockResolvedValueOnce("first")
|
|
.mockResolvedValueOnce("second")
|
|
.mockResolvedValueOnce("third");
|
|
|
|
const hass = { version: 1 };
|
|
|
|
await timeCachePromiseFunc(
|
|
"_testTimerOwnership",
|
|
1000,
|
|
fetchData,
|
|
(currentHass: typeof hass) => currentHass.version,
|
|
hass
|
|
);
|
|
|
|
await vi.advanceTimersByTimeAsync(500);
|
|
|
|
hass.version = 2;
|
|
|
|
await timeCachePromiseFunc(
|
|
"_testTimerOwnership",
|
|
1000,
|
|
fetchData,
|
|
(currentHass: typeof hass) => currentHass.version,
|
|
hass
|
|
);
|
|
|
|
expect(fetchData).toHaveBeenCalledTimes(2);
|
|
|
|
await vi.advanceTimersByTimeAsync(500);
|
|
|
|
const result = await timeCachePromiseFunc(
|
|
"_testTimerOwnership",
|
|
1000,
|
|
fetchData,
|
|
(currentHass: typeof hass) => currentHass.version,
|
|
hass
|
|
);
|
|
|
|
expect(result).toBe("second");
|
|
expect(fetchData).toHaveBeenCalledTimes(2);
|
|
} finally {
|
|
vi.useRealTimers();
|
|
}
|
|
});
|
|
});
|