Skip to content

Commit 51b24a4

Browse files
committed
Adds more happy path E2E tests, now covering most commands
1 parent d61dc90 commit 51b24a4

26 files changed

Lines changed: 3721 additions & 0 deletions
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: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
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+
const app = result.app as Record<string, unknown>;
44+
testAppId = (app.id ?? app.appId) as string;
45+
if (!testAppId) {
46+
throw new Error(`No app ID found in result: ${JSON.stringify(result)}`);
47+
}
48+
});
49+
50+
afterAll(async () => {
51+
if (testAppId) {
52+
try {
53+
await runCommand(["apps", "delete", testAppId, "--force"], {
54+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
55+
});
56+
} catch {
57+
// Ignore cleanup errors — the app may already be deleted
58+
}
59+
}
60+
process.removeListener("SIGINT", forceExit);
61+
});
62+
63+
beforeEach(() => {
64+
resetTestTracking();
65+
testOutputFiles.clear();
66+
testCommands.length = 0;
67+
});
68+
69+
afterEach(async () => {
70+
await cleanupTrackedResources();
71+
});
72+
73+
it("should list API keys for an app", { timeout: 15000 }, async () => {
74+
setupTestFailureHandler("should list API keys for an app");
75+
76+
const listResult = await runCommand(
77+
["auth", "keys", "list", "--app", testAppId, "--json"],
78+
{
79+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
80+
},
81+
);
82+
83+
expect(listResult.exitCode).toBe(0);
84+
const records = parseNdjsonLines(listResult.stdout);
85+
const result = records.find((r) => r.type === "result");
86+
expect(result).toBeDefined();
87+
expect(result).toHaveProperty("success", true);
88+
expect(Array.isArray(result!.keys)).toBe(true);
89+
// Every app has at least one default key
90+
expect((result!.keys as unknown[]).length).toBeGreaterThan(0);
91+
});
92+
93+
it("should create a new API key", { timeout: 15000 }, async () => {
94+
setupTestFailureHandler("should create a new API key");
95+
96+
const keyName = `e2e-test-key-${Date.now()}`;
97+
const createResult = await runCommand(
98+
[
99+
"auth",
100+
"keys",
101+
"create",
102+
"--app",
103+
testAppId,
104+
"--name",
105+
keyName,
106+
"--json",
107+
],
108+
{
109+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
110+
},
111+
);
112+
113+
expect(createResult.exitCode).toBe(0);
114+
const result = parseNdjsonLines(createResult.stdout).find(
115+
(r) => r.type === "result",
116+
) as Record<string, unknown>;
117+
expect(result).toBeDefined();
118+
expect(result).toHaveProperty("success", true);
119+
const key = result.key as Record<string, unknown>;
120+
expect(key).toHaveProperty("name", keyName);
121+
expect(key).toHaveProperty("key");
122+
expect(key).toHaveProperty("keyName");
123+
});
124+
125+
it("should get details for a specific key", { timeout: 20000 }, async () => {
126+
setupTestFailureHandler("should get details for a specific key");
127+
128+
// First create a key to get
129+
const keyName = `e2e-get-key-${Date.now()}`;
130+
const createResult = await runCommand(
131+
[
132+
"auth",
133+
"keys",
134+
"create",
135+
"--app",
136+
testAppId,
137+
"--name",
138+
keyName,
139+
"--json",
140+
],
141+
{
142+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
143+
},
144+
);
145+
146+
const createRecord = parseNdjsonLines(createResult.stdout).find(
147+
(r) => r.type === "result",
148+
) as Record<string, unknown>;
149+
const createdKey = createRecord.key as Record<string, unknown>;
150+
const keyFullName = createdKey.keyName as string;
151+
152+
// Now get that key by its name
153+
const getResult = await runCommand(
154+
["auth", "keys", "get", keyFullName, "--app", testAppId, "--json"],
155+
{
156+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
157+
},
158+
);
159+
160+
expect(getResult.exitCode).toBe(0);
161+
const getRecord = parseNdjsonLines(getResult.stdout).find(
162+
(r) => r.type === "result",
163+
) as Record<string, unknown>;
164+
expect(getRecord).toBeDefined();
165+
expect(getRecord).toHaveProperty("success", true);
166+
const fetchedKey = getRecord.key as Record<string, unknown>;
167+
expect(fetchedKey).toHaveProperty("name", keyName);
168+
expect(fetchedKey).toHaveProperty("keyName", keyFullName);
169+
});
170+
171+
it("should update a key name", { timeout: 20000 }, async () => {
172+
setupTestFailureHandler("should update a key name");
173+
174+
// First create a key to update
175+
const originalName = `e2e-update-key-${Date.now()}`;
176+
const createResult = await runCommand(
177+
[
178+
"auth",
179+
"keys",
180+
"create",
181+
"--app",
182+
testAppId,
183+
"--name",
184+
originalName,
185+
"--json",
186+
],
187+
{
188+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
189+
},
190+
);
191+
192+
const createRecord = parseNdjsonLines(createResult.stdout).find(
193+
(r) => r.type === "result",
194+
) as Record<string, unknown>;
195+
const createdKey = createRecord.key as Record<string, unknown>;
196+
const keyFullName = createdKey.keyName as string;
197+
198+
// Update the key name
199+
const updatedName = `updated-key-${Date.now()}`;
200+
const updateResult = await runCommand(
201+
[
202+
"auth",
203+
"keys",
204+
"update",
205+
keyFullName,
206+
"--app",
207+
testAppId,
208+
"--name",
209+
updatedName,
210+
"--json",
211+
],
212+
{
213+
env: { ABLY_ACCESS_TOKEN: E2E_ACCESS_TOKEN || "" },
214+
},
215+
);
216+
217+
expect(updateResult.exitCode).toBe(0);
218+
const updateRecord = parseNdjsonLines(updateResult.stdout).find(
219+
(r) => r.type === "result",
220+
) as Record<string, unknown>;
221+
expect(updateRecord).toBeDefined();
222+
expect(updateRecord).toHaveProperty("success", true);
223+
const updatedKey = updateRecord.key as Record<string, unknown>;
224+
const nameChange = updatedKey.name as Record<string, unknown>;
225+
expect(nameChange).toHaveProperty("before", originalName);
226+
expect(nameChange).toHaveProperty("after", updatedName);
227+
});
228+
});

0 commit comments

Comments
 (0)