|
@@ -0,0 +1,40 @@
|
|
|
|
|
+import { readFileSync } from "fs";
|
|
|
|
|
+import path from "path";
|
|
|
|
|
+
|
|
|
|
|
+describe("Realtime movies cache update logic", () => {
|
|
|
|
|
+ const src = readFileSync(
|
|
|
|
|
+ path.resolve(__dirname, "../../hooks/use-realtime-movies.ts"),
|
|
|
|
|
+ "utf-8",
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ it("handles INSERT events with duplicate guard", () => {
|
|
|
|
|
+ expect(src).toContain("INSERT");
|
|
|
|
|
+ // Verify duplicate check exists to prevent optimistic update collisions
|
|
|
|
|
+ expect(src).toMatch(/old\.some\(.*\.id\s*===\s*newMovie\.id/);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ it("handles UPDATE events with map replacement", () => {
|
|
|
|
|
+ expect(src).toContain("UPDATE");
|
|
|
|
|
+ // Verify map-based replacement pattern
|
|
|
|
|
+ expect(src).toMatch(/old\.map\(/);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ it("handles DELETE events with filter removal", () => {
|
|
|
|
|
+ expect(src).toContain("DELETE");
|
|
|
|
|
+ // Verify filter-based removal pattern
|
|
|
|
|
+ expect(src).toMatch(/old\.filter\(/);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ it("guards against null old data in setQueryData callbacks", () => {
|
|
|
|
|
+ // Each callback should handle the case where old cache data is undefined/null
|
|
|
|
|
+ const setQueryDataBlocks = src.match(/setQueryData.*?\(.*?old.*?\)/gs);
|
|
|
|
|
+ expect(setQueryDataBlocks).not.toBeNull();
|
|
|
|
|
+ expect(src).toMatch(/if\s*\(\s*!old\s*\)/);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ it("uses moviesQueryKey helper for consistent key generation", () => {
|
|
|
|
|
+ expect(src).toMatch(/function\s+moviesQueryKey/);
|
|
|
|
|
+ // Verify the helper is used in the callback
|
|
|
|
|
+ expect(src).toMatch(/const\s+key\s*=\s*moviesQueryKey\(/);
|
|
|
|
|
+ });
|
|
|
|
|
+});
|