-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathanalysis-console.test.ts
More file actions
145 lines (118 loc) · 5.86 KB
/
Copy pathanalysis-console.test.ts
File metadata and controls
145 lines (118 loc) · 5.86 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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import prompts from "prompts";
import { beforeEach, describe, expect, test, vi } from "vitest";
import { makeEnvironmentConfig } from "../../test-utils/mock-config.js";
import { makeAccount } from "../../test-utils/mock-sdk.js";
import { resetInjectedPrompts } from "../../test-utils/reset-prompts.js";
const getEnvironmentConfigMock = vi.fn();
const errorHandlerMock = vi.fn((str: unknown): void => {
throw new Error(String(str));
});
type SSECallback = (event?: unknown) => void;
let accountInstance: ReturnType<typeof makeAccount>;
const eventSourceInstances: Array<{ url: string; onmessage?: SSECallback; onerror?: SSECallback; onopen?: SSECallback }> = [];
vi.mock("@tago-io/sdk", () => ({
Account: function Account() {
return accountInstance;
},
}));
vi.mock("eventsource", () => ({
EventSource: function EventSource(url: string) {
const inst = { url, onmessage: undefined, onerror: undefined, onopen: undefined };
eventSourceInstances.push(inst);
return inst;
},
}));
vi.mock("../../lib/config-file.js", () => ({
getEnvironmentConfig: getEnvironmentConfigMock,
}));
vi.mock("../../lib/messages.js", () => ({
errorHandler: errorHandlerMock,
infoMSG: vi.fn(),
successMSG: vi.fn(),
highlightMSG: (s: string) => s,
}));
vi.mock("../../lib/resolve-scope.js", () => ({
requireLocalScope: () => ({
scope: "local" as const,
root: "/repo",
configPath: "/repo/tagoconfig.json",
envFilePath: "/repo/.tagoio/personal.env",
configExists: true,
}),
}));
describe("connectAnalysisConsole", () => {
const analysisList = [{ name: "script", fileName: "script.ts", id: "an-1" }];
beforeEach(() => {
accountInstance = makeAccount();
getEnvironmentConfigMock.mockReset();
errorHandlerMock.mockClear();
eventSourceInstances.length = 0;
resetInjectedPrompts();
});
test("opens an SSE connection for the matched script", async () => {
getEnvironmentConfigMock.mockReturnValue(makeEnvironmentConfig({ analysisList }));
accountInstance.analysis.info.mockResolvedValue({ id: "an-1", name: "script" });
const { connectAnalysisConsole } = await import("./analysis-console.js");
await connectAnalysisConsole("script", { environment: "prod" });
expect(eventSourceInstances).toHaveLength(1);
expect(eventSourceInstances[0].url).toContain("channel=analysis_console.an-1");
expect(eventSourceInstances[0].url).toContain("token=fake-token");
});
test("calls errorHandler when the config is missing", async () => {
getEnvironmentConfigMock.mockReturnValue(makeEnvironmentConfig({ profileToken: "" }));
const { connectAnalysisConsole } = await import("./analysis-console.js");
await expect(connectAnalysisConsole("script", { environment: "prod" })).rejects.toThrow(/Environment not found/);
});
test("calls errorHandler when the analysis info lookup fails", async () => {
getEnvironmentConfigMock.mockReturnValue(makeEnvironmentConfig({ analysisList }));
accountInstance.analysis.info.mockRejectedValue(new Error("404"));
const { connectAnalysisConsole } = await import("./analysis-console.js");
await expect(connectAnalysisConsole("script", { environment: "prod" })).rejects.toThrow(/couldn't be found/);
});
test("prompts for a script when none is provided via CLI", async () => {
getEnvironmentConfigMock.mockReturnValue(makeEnvironmentConfig({ analysisList }));
accountInstance.analysis.info.mockResolvedValue({ id: "an-1", name: "script" });
prompts.inject([analysisList[0]]);
const { connectAnalysisConsole } = await import("./analysis-console.js");
await connectAnalysisConsole(undefined as never, { environment: "prod" });
expect(eventSourceInstances).toHaveLength(1);
});
test("errors when scriptObj cannot be resolved", async () => {
getEnvironmentConfigMock.mockReturnValue(makeEnvironmentConfig({ analysisList: [] }));
const { connectAnalysisConsole } = await import("./analysis-console.js");
await expect(connectAnalysisConsole("missing", { environment: "prod" })).rejects.toThrow(/Analysis not found/);
});
test("onmessage logs the formatted payload", async () => {
getEnvironmentConfigMock.mockReturnValue(makeEnvironmentConfig({ analysisList }));
accountInstance.analysis.info.mockResolvedValue({ id: "an-1", name: "script" });
const logSpy = vi.spyOn(console, "log").mockImplementation(() => undefined);
const { connectAnalysisConsole } = await import("./analysis-console.js");
await connectAnalysisConsole("script", { environment: "prod" });
const sse = eventSourceInstances[0];
sse.onmessage?.({
data: JSON.stringify({ payload: { timestamp: "2026-01-01T00:00:00Z", message: "hello" } }),
});
expect(logSpy).toHaveBeenCalled();
logSpy.mockRestore();
});
test("onopen emits the connected info messages", async () => {
getEnvironmentConfigMock.mockReturnValue(makeEnvironmentConfig({ analysisList }));
accountInstance.analysis.info.mockResolvedValue({ id: "an-1", name: "script" });
const { connectAnalysisConsole } = await import("./analysis-console.js");
await connectAnalysisConsole("script", { environment: "prod" });
const sse = eventSourceInstances[0];
expect(() => sse.onopen?.()).not.toThrow();
});
test("onerror routes through errorHandler and logs the raw event", async () => {
getEnvironmentConfigMock.mockReturnValue(makeEnvironmentConfig({ analysisList }));
accountInstance.analysis.info.mockResolvedValue({ id: "an-1", name: "script" });
const errSpy = vi.spyOn(console, "error").mockImplementation(() => undefined);
const { connectAnalysisConsole } = await import("./analysis-console.js");
await connectAnalysisConsole("script", { environment: "prod" });
const sse = eventSourceInstances[0];
errorHandlerMock.mockImplementationOnce(() => undefined);
sse.onerror?.({ type: "error" });
expect(errSpy).toHaveBeenCalled();
errSpy.mockRestore();
});
});