Skip to content

Commit b9154e9

Browse files
committed
add tests for new apis
1 parent 2c4a2a8 commit b9154e9

File tree

7 files changed

+592
-0
lines changed

7 files changed

+592
-0
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ const project = await client.projects.create("workspace-slug", {
7272
- **Workspace**: Workspace-level operations
7373
- **Epics**: Epic management and organization
7474
- **Intake**: Intake form and request management
75+
- **Stickies**: Stickies management
76+
- **Teamspaces**: Teamspace management
77+
- **Initiatives**: Initiative management
78+
- **Features**: Workspace and project features management
7579

7680
## Development
7781

@@ -129,6 +133,8 @@ pnpm test
129133

130134
# Run specific test files
131135
pnpx ts-node tests/page.test.ts
136+
# or
137+
pnpm test page.test.ts
132138
```
133139

134140
## License

env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Plane Node SDK Test Configuration
22
# Copy this file to .env.test and update with your test environment values
33

4+
# API configuration
5+
PLANE_API_KEY=your-plane-api-key
6+
PLANE_BASE_URL=your-plane-base-url
7+
48
# Workspace configuration
59
TEST_WORKSPACE_SLUG=your-workspace-slug
610

tests/unit/initiative.test.ts

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
import { PlaneClient } from "../../src/client/plane-client";
2+
import { Initiative, UpdateInitiative } from "../../src/models/Initiative";
3+
import { InitiativeLabel } from "../../src/models/InitiativeLabel";
4+
import { Project } from "../../src/models/Project";
5+
import { Epic } from "../../src/models/Epic";
6+
import { config } from "./constants";
7+
import { createTestClient, randomizeName } from "../helpers/test-utils";
8+
import { describeIf } from "../helpers/conditional-tests";
9+
10+
describeIf(!!(config.workspaceSlug && config.projectId), "Initiative API Tests", () => {
11+
let client: PlaneClient;
12+
let workspaceSlug: string;
13+
let projectId: string;
14+
let initiative: Initiative;
15+
let initiativeLabel: InitiativeLabel;
16+
let testProject: Project;
17+
let testEpic: Epic;
18+
19+
beforeAll(async () => {
20+
client = createTestClient();
21+
workspaceSlug = config.workspaceSlug;
22+
projectId = config.projectId;
23+
24+
// Create a test project for initiative operations
25+
testProject = await client.projects.create(workspaceSlug, {
26+
name: randomizeName("Test Project for Initiative"),
27+
identifier: randomizeName("TPI").slice(0, 5).toUpperCase(),
28+
});
29+
30+
// Create an initiative label
31+
initiativeLabel = await client.initiatives.labels.create(workspaceSlug, {
32+
name: randomizeName("Test Initiative Label"),
33+
color: "#FF5733",
34+
sort_order: 100,
35+
});
36+
37+
// Create a test epic if epics are available
38+
try {
39+
const epics = await client.epics.list(workspaceSlug, projectId);
40+
if (epics.results.length > 0) {
41+
testEpic = epics.results[0];
42+
}
43+
} catch (error) {
44+
console.warn("Epics not available for testing:", error);
45+
}
46+
});
47+
48+
afterAll(async () => {
49+
// Clean up created resources
50+
if (initiative?.id) {
51+
try {
52+
await client.initiatives.delete(workspaceSlug, initiative.id);
53+
} catch (error) {
54+
console.warn("Failed to delete initiative:", error);
55+
}
56+
}
57+
if (initiativeLabel?.id) {
58+
try {
59+
await client.initiatives.labels.delete(workspaceSlug, initiativeLabel.id);
60+
} catch (error) {
61+
console.warn("Failed to delete initiative label:", error);
62+
}
63+
}
64+
if (testProject?.id) {
65+
try {
66+
await client.projects.delete(workspaceSlug, testProject.id);
67+
} catch (error) {
68+
console.warn("Failed to delete test project:", error);
69+
}
70+
}
71+
});
72+
73+
it("should create an initiative", async () => {
74+
initiative = await client.initiatives.create(workspaceSlug, {
75+
name: randomizeName("Test Initiative"),
76+
description: "Test Initiative Description",
77+
state: "DRAFT",
78+
});
79+
80+
expect(initiative).toBeDefined();
81+
expect(initiative.id).toBeDefined();
82+
expect(initiative.name).toContain("Test Initiative");
83+
expect(initiative.description).toBe("Test Initiative Description");
84+
expect(initiative.state).toBe("DRAFT");
85+
});
86+
87+
it("should retrieve an initiative", async () => {
88+
const retrievedInitiative = await client.initiatives.retrieve(workspaceSlug, initiative.id);
89+
90+
expect(retrievedInitiative).toBeDefined();
91+
expect(retrievedInitiative.id).toBe(initiative.id);
92+
expect(retrievedInitiative.name).toBe(initiative.name);
93+
});
94+
95+
it("should update an initiative", async () => {
96+
const updateData: UpdateInitiative = {
97+
name: randomizeName("Updated Test Initiative"),
98+
description: "Updated Test Initiative Description",
99+
};
100+
101+
const updatedInitiative = await client.initiatives.update(workspaceSlug, initiative.id, updateData);
102+
103+
expect(updatedInitiative).toBeDefined();
104+
expect(updatedInitiative.id).toBe(initiative.id);
105+
expect(updatedInitiative.name).toContain("Updated Test Initiative");
106+
});
107+
108+
it("should list initiatives", async () => {
109+
const initiatives = await client.initiatives.list(workspaceSlug);
110+
111+
expect(initiatives).toBeDefined();
112+
expect(Array.isArray(initiatives.results)).toBe(true);
113+
expect(initiatives.results.length).toBeGreaterThan(0);
114+
115+
const foundInitiative = initiatives.results.find((i) => i.id === initiative.id);
116+
expect(foundInitiative).toBeDefined();
117+
});
118+
119+
describe("Initiative Labels", () => {
120+
it("should create an initiative label", async () => {
121+
expect(initiativeLabel).toBeDefined();
122+
expect(initiativeLabel.id).toBeDefined();
123+
expect(initiativeLabel.name).toContain("Test Initiative Label");
124+
});
125+
126+
it("should retrieve an initiative label", async () => {
127+
const retrievedLabel = await client.initiatives.labels.retrieve(workspaceSlug, initiativeLabel.id);
128+
129+
expect(retrievedLabel).toBeDefined();
130+
expect(retrievedLabel.id).toBe(initiativeLabel.id);
131+
expect(retrievedLabel.name).toBe(initiativeLabel.name);
132+
});
133+
134+
it("should update an initiative label", async () => {
135+
const updatedLabel = await client.initiatives.labels.update(workspaceSlug, initiativeLabel.id, {
136+
name: randomizeName("Updated Test Initiative Label"),
137+
color: "#33FF57",
138+
});
139+
140+
expect(updatedLabel).toBeDefined();
141+
expect(updatedLabel.id).toBe(initiativeLabel.id);
142+
expect(updatedLabel.name).toContain("Updated Test Initiative Label");
143+
expect(updatedLabel.color).toBe("#33FF57");
144+
});
145+
146+
it("should list initiative labels", async () => {
147+
const labels = await client.initiatives.labels.list(workspaceSlug);
148+
149+
expect(labels).toBeDefined();
150+
expect(Array.isArray(labels.results)).toBe(true);
151+
expect(labels.results.length).toBeGreaterThan(0);
152+
153+
const foundLabel = labels.results.find((l) => l.id === initiativeLabel.id);
154+
expect(foundLabel).toBeDefined();
155+
});
156+
157+
it("should add labels to initiative", async () => {
158+
const labels = await client.initiatives.labels.addLabels(workspaceSlug, initiative.id, {
159+
label_ids: [initiativeLabel.id],
160+
});
161+
162+
expect(labels).toBeDefined();
163+
expect(Array.isArray(labels)).toBe(true);
164+
expect(labels.length).toBeGreaterThan(0);
165+
});
166+
167+
it("should list labels in initiative", async () => {
168+
const labels = await client.initiatives.labels.listLabels(workspaceSlug, initiative.id);
169+
170+
expect(labels).toBeDefined();
171+
expect(Array.isArray(labels.results)).toBe(true);
172+
expect(labels.results.length).toBeGreaterThan(0);
173+
174+
const foundLabel = labels.results.find((l) => l.id === initiativeLabel.id);
175+
expect(foundLabel).toBeDefined();
176+
});
177+
178+
it("should remove labels from initiative", async () => {
179+
await client.initiatives.labels.removeLabels(workspaceSlug, initiative.id, {
180+
label_ids: [initiativeLabel.id],
181+
});
182+
183+
const labels = await client.initiatives.labels.listLabels(workspaceSlug, initiative.id);
184+
const foundLabel = labels.results.find((l) => l.id === initiativeLabel.id);
185+
expect(foundLabel).toBeUndefined();
186+
});
187+
});
188+
189+
describe("Initiative Projects", () => {
190+
it("should add projects to initiative", async () => {
191+
const projects = await client.initiatives.projects.add(workspaceSlug, initiative.id, {
192+
project_ids: [testProject.id],
193+
});
194+
195+
expect(projects).toBeDefined();
196+
expect(Array.isArray(projects)).toBe(true);
197+
expect(projects.length).toBeGreaterThan(0);
198+
});
199+
200+
it("should list projects in initiative", async () => {
201+
const projects = await client.initiatives.projects.list(workspaceSlug, initiative.id);
202+
203+
expect(projects).toBeDefined();
204+
expect(Array.isArray(projects.results)).toBe(true);
205+
expect(projects.results.length).toBeGreaterThan(0);
206+
207+
const foundProject = projects.results.find((p) => p.id === testProject.id);
208+
expect(foundProject).toBeDefined();
209+
});
210+
211+
it("should remove projects from initiative", async () => {
212+
await client.initiatives.projects.remove(workspaceSlug, initiative.id, {
213+
project_ids: [testProject.id],
214+
});
215+
216+
const projects = await client.initiatives.projects.list(workspaceSlug, initiative.id);
217+
const foundProject = projects.results.find((p) => p.id === testProject.id);
218+
expect(foundProject).toBeUndefined();
219+
});
220+
});
221+
222+
describe("Initiative Epics", () => {
223+
it("should add epics to initiative", async () => {
224+
if (!testEpic?.id) {
225+
return;
226+
}
227+
228+
const epics = await client.initiatives.epics.add(workspaceSlug, initiative.id, {
229+
epic_ids: [testEpic.id],
230+
});
231+
232+
expect(epics).toBeDefined();
233+
expect(Array.isArray(epics)).toBe(true);
234+
});
235+
236+
it("should list epics in initiative", async () => {
237+
if (!testEpic?.id) {
238+
return;
239+
}
240+
241+
const epics = await client.initiatives.epics.list(workspaceSlug, initiative.id);
242+
243+
expect(epics).toBeDefined();
244+
expect(Array.isArray(epics.results)).toBe(true);
245+
});
246+
247+
it("should remove epics from initiative", async () => {
248+
if (!testEpic?.id) {
249+
return;
250+
}
251+
252+
await client.initiatives.epics.remove(workspaceSlug, initiative.id, {
253+
epic_ids: [testEpic.id],
254+
});
255+
256+
const epics = await client.initiatives.epics.list(workspaceSlug, initiative.id);
257+
const foundEpic = epics.results.find((e) => e.id === testEpic.id);
258+
expect(foundEpic).toBeUndefined();
259+
});
260+
});
261+
});
262+

tests/unit/project.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,38 @@ describe(!!config.workspaceSlug, "Project API Tests", () => {
8080
expect(members).toBeDefined();
8181
expect(Array.isArray(members)).toBe(true);
8282
});
83+
84+
describe(!!config.workspaceSlug, "Project Features", () => {
85+
it("should retrieve project features", async () => {
86+
const features = await client.projects.retrieveFeatures(workspaceSlug, project.id);
87+
88+
expect(features).toBeDefined();
89+
expect(typeof features.epics).toBe("boolean");
90+
expect(typeof features.modules).toBe("boolean");
91+
expect(typeof features.cycles).toBe("boolean");
92+
expect(typeof features.views).toBe("boolean");
93+
expect(typeof features.pages).toBe("boolean");
94+
expect(typeof features.intakes).toBe("boolean");
95+
expect(typeof features.work_item_types).toBe("boolean");
96+
});
97+
98+
it("should update project features", async () => {
99+
const originalFeatures = await client.projects.retrieveFeatures(workspaceSlug, project.id);
100+
101+
const updatedFeatures = await client.projects.updateFeatures(workspaceSlug, project.id, {
102+
epics: !originalFeatures.epics,
103+
modules: !originalFeatures.modules,
104+
});
105+
106+
expect(updatedFeatures).toBeDefined();
107+
expect(updatedFeatures.epics).toBe(!originalFeatures.epics);
108+
expect(updatedFeatures.modules).toBe(!originalFeatures.modules);
109+
110+
// Restore original values
111+
await client.projects.updateFeatures(workspaceSlug, project.id, {
112+
epics: originalFeatures.epics,
113+
modules: originalFeatures.modules,
114+
});
115+
});
116+
});
83117
});

0 commit comments

Comments
 (0)