-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathgraph_proxy.test.ts
More file actions
126 lines (103 loc) · 4.34 KB
/
Copy pathgraph_proxy.test.ts
File metadata and controls
126 lines (103 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
* Tests for src/graph_proxy.ts (v0.13.0).
*
* graphify is OPTIONAL — these tests verify SC's graceful behavior when:
* - graphify-out/ doesn't exist → returns hint
* - graphify-out/graph.json exists but `python -m graphify.serve` fails
* (e.g. python not installed) → returns error, logs warning
*
* We don't test the live subprocess path (would require Python + graphifyy
* installed in CI). That's covered by manual integration testing.
*/
import { describe, it, expect, beforeEach, afterEach } from "vitest";
import { existsSync, mkdirSync, writeFileSync, rmSync, mkdtempSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import {
findGraphifyOutput,
findGraphReport,
graphQuery,
graphPath,
graphNeighbors,
shutdownAllGraphifyHandles,
} from "./graph_proxy.js";
let testProject: string;
beforeEach(() => {
testProject = mkdtempSync(join(tmpdir(), "zc-graph-"));
});
afterEach(() => {
shutdownAllGraphifyHandles();
try { rmSync(testProject, { recursive: true, force: true }); } catch {}
});
describe("findGraphifyOutput", () => {
it("returns null when no graphify-out/ directory exists", () => {
expect(findGraphifyOutput(testProject)).toBeNull();
});
it("returns null when graphify-out/ exists but graph.json doesn't", () => {
mkdirSync(join(testProject, "graphify-out"), { recursive: true });
expect(findGraphifyOutput(testProject)).toBeNull();
});
it("returns the path when graphify-out/graph.json exists", () => {
mkdirSync(join(testProject, "graphify-out"), { recursive: true });
const p = join(testProject, "graphify-out", "graph.json");
writeFileSync(p, "{}");
expect(findGraphifyOutput(testProject)).toBe(p);
});
});
describe("findGraphReport", () => {
it("returns null when GRAPH_REPORT.md doesn't exist", () => {
expect(findGraphReport(testProject)).toBeNull();
});
it("returns the path when GRAPH_REPORT.md exists", () => {
mkdirSync(join(testProject, "graphify-out"), { recursive: true });
const p = join(testProject, "graphify-out", "GRAPH_REPORT.md");
writeFileSync(p, "# Graph Report\n");
expect(findGraphReport(testProject)).toBe(p);
});
});
describe("graphQuery — graceful degradation", () => {
it("returns ok=false with helpful hint when no graphify graph exists", async () => {
const r = await graphQuery(testProject, "any query");
expect(r.ok).toBe(false);
expect(r.hint).toMatch(/No graphify graph found/);
expect(r.hint).toMatch(/\/graphify \./); // suggests how to build one
});
it("hint mentions the expected file path", async () => {
const r = await graphQuery(testProject, "test");
expect(r.hint).toContain(join("graphify-out", "graph.json"));
});
});
describe("graphPath — graceful degradation", () => {
it("returns ok=false with hint when no graphify graph exists", async () => {
const r = await graphPath(testProject, "FooNode", "BarNode");
expect(r.ok).toBe(false);
expect(r.hint).toMatch(/No graphify graph/);
});
});
describe("graphNeighbors — graceful degradation", () => {
it("returns ok=false with hint when no graphify graph exists", async () => {
const r = await graphNeighbors(testProject, "Foo");
expect(r.ok).toBe(false);
expect(r.hint).toMatch(/No graphify graph/);
});
});
describe("normalizeProjectPath defenses", () => {
it("rejects relative paths via graphQuery", async () => {
// graphQuery itself doesn't throw, but any subsequent calls would error.
// We test the public API: with no graph file, we get ok=false hint either way.
const r = await graphQuery(testProject, "test");
expect(r.ok).toBe(false);
});
});
describe("subprocess fail-safe (no Python or no graphify)", () => {
it("returns ok=false (no crash) when graph.json present but subprocess unavailable", async () => {
// Simulate: graph.json exists, but `python -m graphify.serve` will fail
// because graphifyy isn't installed in this test env.
mkdirSync(join(testProject, "graphify-out"), { recursive: true });
writeFileSync(join(testProject, "graphify-out", "graph.json"), "{}");
const r = await graphQuery(testProject, "anything");
// Either we get an error (subprocess died) or success (graphifyy IS
// installed). Both are acceptable; what we forbid is throwing.
expect(r.ok === false || r.ok === true).toBe(true);
});
});