Skip to content

Commit 5801f38

Browse files
committed
Adds more happy path E2E tests, now covering most commands
1 parent 262dc11 commit 5801f38

27 files changed

+3750
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import {
2+
describe,
3+
it,
4+
beforeEach,
5+
afterEach,
6+
beforeAll,
7+
afterAll,
8+
expect,
9+
} from "vitest";
10+
import {
11+
E2E_ACCESS_TOKEN,
12+
SHOULD_SKIP_CONTROL_E2E,
13+
forceExit,
14+
cleanupTrackedResources,
15+
testOutputFiles,
16+
testCommands,
17+
setupTestFailureHandler,
18+
resetTestTracking,
19+
} from "../../helpers/e2e-test-helper.js";
20+
import { runCommand } from "../../helpers/command-helpers.js";
21+
22+
describe.skipIf(SHOULD_SKIP_CONTROL_E2E)("Accounts E2E Tests", () => {
23+
beforeAll(() => {
24+
process.on("SIGINT", forceExit);
25+
});
26+
27+
afterAll(() => {
28+
process.removeListener("SIGINT", forceExit);
29+
});
30+
31+
beforeEach(() => {
32+
resetTestTracking();
33+
testOutputFiles.clear();
34+
testCommands.length = 0;
35+
});
36+
37+
afterEach(async () => {
38+
await cleanupTrackedResources();
39+
});
40+
41+
it(
42+
"should list locally configured accounts",
43+
{ timeout: 15000 },
44+
async () => {
45+
setupTestFailureHandler("should list locally configured accounts");
46+
47+
// accounts list reads from local config, not the API directly.
48+
// In E2E environment, there may or may not be configured accounts.
49+
// We just verify the command runs without crashing.
50+
const listResult = await runCommand(["accounts", "list"], {
51+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
52+
});
53+
54+
// The command may exit 0 (accounts found) or non-zero (no accounts configured).
55+
// Either way, it should produce output and not crash.
56+
const combinedOutput = listResult.stdout + listResult.stderr;
57+
expect(combinedOutput.length).toBeGreaterThan(0);
58+
},
59+
);
60+
61+
it("should show help for accounts current", { timeout: 10000 }, async () => {
62+
setupTestFailureHandler("should show help for accounts current");
63+
64+
const helpResult = await runCommand(["accounts", "current", "--help"], {
65+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
66+
});
67+
68+
expect(helpResult.exitCode).toBe(0);
69+
const output = helpResult.stdout + helpResult.stderr;
70+
expect(output).toContain("USAGE");
71+
});
72+
});
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
import {
2+
describe,
3+
it,
4+
beforeEach,
5+
afterEach,
6+
beforeAll,
7+
afterAll,
8+
expect,
9+
} from "vitest";
10+
import {
11+
E2E_ACCESS_TOKEN,
12+
SHOULD_SKIP_CONTROL_E2E,
13+
forceExit,
14+
cleanupTrackedResources,
15+
testOutputFiles,
16+
testCommands,
17+
setupTestFailureHandler,
18+
resetTestTracking,
19+
} from "../../helpers/e2e-test-helper.js";
20+
import { runCommand } from "../../helpers/command-helpers.js";
21+
import { parseNdjsonLines } from "../../helpers/ndjson.js";
22+
23+
describe.skipIf(SHOULD_SKIP_CONTROL_E2E)("Auth Keys E2E Tests", () => {
24+
let testAppId: string;
25+
26+
beforeAll(async () => {
27+
process.on("SIGINT", forceExit);
28+
29+
// Create a test app for key operations
30+
const createResult = await runCommand(
31+
["apps", "create", "--name", `e2e-keys-test-${Date.now()}`, "--json"],
32+
{
33+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
34+
},
35+
);
36+
37+
if (createResult.exitCode !== 0) {
38+
throw new Error(`Failed to create test app: ${createResult.stderr}`);
39+
}
40+
const result = parseNdjsonLines(createResult.stdout).find(
41+
(r) => r.type === "result",
42+
) as Record<string, unknown>;
43+
if (!result) {
44+
throw new Error(
45+
`No result record in app create output: ${createResult.stdout}`,
46+
);
47+
}
48+
const app = result?.app as Record<string, unknown>;
49+
testAppId = (app?.id ?? app?.appId) as string;
50+
if (!testAppId) {
51+
throw new Error(`No app ID found in result: ${JSON.stringify(result)}`);
52+
}
53+
});
54+
55+
afterAll(async () => {
56+
if (testAppId) {
57+
try {
58+
await runCommand(["apps", "delete", testAppId, "--force"], {
59+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
60+
});
61+
} catch {
62+
// Ignore cleanup errors — the app may already be deleted
63+
}
64+
}
65+
process.removeListener("SIGINT", forceExit);
66+
});
67+
68+
beforeEach(() => {
69+
resetTestTracking();
70+
testOutputFiles.clear();
71+
testCommands.length = 0;
72+
});
73+
74+
afterEach(async () => {
75+
await cleanupTrackedResources();
76+
});
77+
78+
it("should list API keys for an app", { timeout: 15000 }, async () => {
79+
setupTestFailureHandler("should list API keys for an app");
80+
81+
const listResult = await runCommand(
82+
["auth", "keys", "list", "--app", testAppId, "--json"],
83+
{
84+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
85+
},
86+
);
87+
88+
expect(listResult.exitCode).toBe(0);
89+
const records = parseNdjsonLines(listResult.stdout);
90+
const result = records.find((r) => r.type === "result");
91+
expect(result).toBeDefined();
92+
expect(result).toHaveProperty("success", true);
93+
expect(Array.isArray(result!.keys)).toBe(true);
94+
// Every app has at least one default key
95+
expect((result!.keys as unknown[]).length).toBeGreaterThan(0);
96+
});
97+
98+
it("should create a new API key", { timeout: 15000 }, async () => {
99+
setupTestFailureHandler("should create a new API key");
100+
101+
const keyName = `e2e-test-key-${Date.now()}`;
102+
const createResult = await runCommand(
103+
[
104+
"auth",
105+
"keys",
106+
"create",
107+
"--app",
108+
testAppId,
109+
"--name",
110+
keyName,
111+
"--json",
112+
],
113+
{
114+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
115+
},
116+
);
117+
118+
expect(createResult.exitCode).toBe(0);
119+
const result = parseNdjsonLines(createResult.stdout).find(
120+
(r) => r.type === "result",
121+
) as Record<string, unknown>;
122+
expect(result).toBeDefined();
123+
expect(result).toHaveProperty("success", true);
124+
const key = result.key as Record<string, unknown>;
125+
expect(key).toHaveProperty("name", keyName);
126+
expect(key).toHaveProperty("key");
127+
expect(key).toHaveProperty("keyName");
128+
});
129+
130+
it("should get details for a specific key", { timeout: 20000 }, async () => {
131+
setupTestFailureHandler("should get details for a specific key");
132+
133+
// First create a key to get
134+
const keyName = `e2e-get-key-${Date.now()}`;
135+
const createResult = await runCommand(
136+
[
137+
"auth",
138+
"keys",
139+
"create",
140+
"--app",
141+
testAppId,
142+
"--name",
143+
keyName,
144+
"--json",
145+
],
146+
{
147+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
148+
},
149+
);
150+
151+
const createRecord = parseNdjsonLines(createResult.stdout).find(
152+
(r) => r.type === "result",
153+
) as Record<string, unknown>;
154+
const createdKey = createRecord.key as Record<string, unknown>;
155+
const keyFullName = createdKey.keyName as string;
156+
157+
// Now get that key by its name
158+
const getResult = await runCommand(
159+
["auth", "keys", "get", keyFullName, "--app", testAppId, "--json"],
160+
{
161+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
162+
},
163+
);
164+
165+
expect(getResult.exitCode).toBe(0);
166+
const getRecord = parseNdjsonLines(getResult.stdout).find(
167+
(r) => r.type === "result",
168+
) as Record<string, unknown>;
169+
expect(getRecord).toBeDefined();
170+
expect(getRecord).toHaveProperty("success", true);
171+
const fetchedKey = getRecord.key as Record<string, unknown>;
172+
expect(fetchedKey).toHaveProperty("name", keyName);
173+
expect(fetchedKey).toHaveProperty("keyName", keyFullName);
174+
});
175+
176+
it("should update a key name", { timeout: 20000 }, async () => {
177+
setupTestFailureHandler("should update a key name");
178+
179+
// First create a key to update
180+
const originalName = `e2e-update-key-${Date.now()}`;
181+
const createResult = await runCommand(
182+
[
183+
"auth",
184+
"keys",
185+
"create",
186+
"--app",
187+
testAppId,
188+
"--name",
189+
originalName,
190+
"--json",
191+
],
192+
{
193+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
194+
},
195+
);
196+
197+
const createRecord = parseNdjsonLines(createResult.stdout).find(
198+
(r) => r.type === "result",
199+
) as Record<string, unknown>;
200+
const createdKey = createRecord.key as Record<string, unknown>;
201+
const keyFullName = createdKey.keyName as string;
202+
203+
// Update the key name
204+
const updatedName = `updated-key-${Date.now()}`;
205+
const updateResult = await runCommand(
206+
[
207+
"auth",
208+
"keys",
209+
"update",
210+
keyFullName,
211+
"--app",
212+
testAppId,
213+
"--name",
214+
updatedName,
215+
"--json",
216+
],
217+
{
218+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
219+
},
220+
);
221+
222+
expect(updateResult.exitCode).toBe(0);
223+
const updateRecord = parseNdjsonLines(updateResult.stdout).find(
224+
(r) => r.type === "result",
225+
) as Record<string, unknown>;
226+
expect(updateRecord).toBeDefined();
227+
expect(updateRecord).toHaveProperty("success", true);
228+
const updatedKey = updateRecord.key as Record<string, unknown>;
229+
const nameChange = updatedKey.name as Record<string, unknown>;
230+
expect(nameChange).toHaveProperty("before", originalName);
231+
expect(nameChange).toHaveProperty("after", updatedName);
232+
});
233+
});

0 commit comments

Comments
 (0)