Skip to content

Commit 752cda0

Browse files
committed
Switch to console post API for drafts/publish
Replace usage of the UC Post API with the Console post API for draft, update and publish operations. syncPostPublishState now accepts the console post API and calls publishPost/unpublishPost. import/create/update flows use clients.console.content.post (draftPost, updateDraftPost, fetchPostHeadContent) and clients.core.content.post.getPost to read canonical post state; serialized content-annotation helpers and loadEditablePostState were removed. CLI handlers were updated to use the new client shape and to sync publish state via the console API. Corresponding tests were adjusted to mock the console/core client methods and to remove the old @halo-dev/api-client UC mocks.
1 parent bf33649 commit 752cda0

File tree

7 files changed

+296
-460
lines changed

7 files changed

+296
-460
lines changed

src/commands/post/__test__/post-create-prompt-order.spec.ts

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,11 @@
11
import { afterEach, expect, test, vi } from "vitest";
22

3-
const ucPostApiState = vi.hoisted(() => ({
4-
implementation: {} as Record<string, unknown>,
5-
}));
6-
73
const promptState = vi.hoisted(() => ({
84
input: vi.fn(),
95
confirm: vi.fn(),
106
checkbox: vi.fn(),
117
}));
128

13-
vi.mock("@halo-dev/api-client", async () => {
14-
const actual =
15-
await vi.importActual<typeof import("@halo-dev/api-client")>("@halo-dev/api-client");
16-
17-
return {
18-
...actual,
19-
PostV1alpha1UcApi: vi.fn(function MockPostV1alpha1UcApi() {
20-
return ucPostApiState.implementation;
21-
}),
22-
};
23-
});
24-
259
vi.mock("@inquirer/prompts", () => ({
2610
input: promptState.input,
2711
confirm: promptState.confirm,
@@ -34,7 +18,6 @@ const originalStdinTty = process.stdin.isTTY;
3418
const originalStdoutTty = process.stdout.isTTY;
3519

3620
afterEach(() => {
37-
ucPostApiState.implementation = {};
3821
promptState.input.mockReset();
3922
promptState.confirm.mockReset();
4023
promptState.checkbox.mockReset();
@@ -78,20 +61,13 @@ test("tryRunPostCommand prompts title and slug before categories and tags on cre
7861
return [];
7962
});
8063

81-
const createMyPost = vi.fn().mockResolvedValue({
64+
const draftPost = vi.fn().mockResolvedValue({
8265
data: { metadata: { name: "post-1" } },
8366
});
84-
const getMyPost = vi.fn().mockResolvedValue({
67+
const getPost = vi.fn().mockResolvedValue({
8568
data: { metadata: { name: "post-1" } },
8669
});
8770

88-
ucPostApiState.implementation = {
89-
createMyPost,
90-
getMyPost,
91-
publishMyPost: vi.fn().mockResolvedValue(undefined),
92-
unpublishMyPost: vi.fn().mockResolvedValue(undefined),
93-
};
94-
9571
const runtimeMock = {
9672
getClientsForOptions: vi.fn().mockResolvedValue({
9773
profile: { baseUrl: "https://example.com" },
@@ -110,6 +86,22 @@ test("tryRunPostCommand prompts title and slug before categories and tags on cre
11086
}),
11187
post: vi.fn(),
11288
},
89+
console: {
90+
content: {
91+
post: {
92+
draftPost,
93+
publishPost: vi.fn().mockResolvedValue(undefined),
94+
unpublishPost: vi.fn().mockResolvedValue(undefined),
95+
},
96+
},
97+
},
98+
core: {
99+
content: {
100+
post: {
101+
getPost,
102+
},
103+
},
104+
},
113105
},
114106
}),
115107
};

src/commands/post/__test__/post-json-entry.spec.ts

Lines changed: 67 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,9 @@
11
import { afterEach, expect, test, vi } from "vitest";
22

33
import { renderContentByRawType } from "../../../utils/content.js";
4-
5-
const ucPostApiState = vi.hoisted(() => ({
6-
implementation: {} as Record<string, unknown>,
7-
}));
8-
9-
vi.mock("@halo-dev/api-client", async () => {
10-
const actual =
11-
await vi.importActual<typeof import("@halo-dev/api-client")>("@halo-dev/api-client");
12-
13-
return {
14-
...actual,
15-
PostV1alpha1UcApi: vi.fn(function MockPostV1alpha1UcApi() {
16-
return ucPostApiState.implementation;
17-
}),
18-
};
19-
});
20-
214
import { tryRunPostCommand } from "../index.js";
225

236
afterEach(() => {
24-
ucPostApiState.implementation = {};
257
vi.restoreAllMocks();
268
});
279

@@ -32,27 +14,20 @@ function silenceStdout() {
3214
test("tryRunPostCommand imports json as a new post when it does not exist", async () => {
3315
silenceStdout();
3416

35-
const getMyPost = vi.fn().mockRejectedValue({
36-
isAxiosError: true,
37-
response: { status: 404 },
38-
});
39-
const createMyPost = vi.fn().mockResolvedValue({
17+
const draftPost = vi.fn().mockResolvedValue({
4018
data: { metadata: { name: "post-1" } },
4119
});
42-
const publishMyPost = vi.fn().mockResolvedValue(undefined);
43-
ucPostApiState.implementation = {
44-
getMyPost,
45-
getMyPostDraft: vi.fn(),
46-
updateMyPost: vi.fn(),
47-
updateMyPostDraft: vi.fn(),
48-
createMyPost,
49-
publishMyPost,
50-
unpublishMyPost: vi.fn(),
51-
};
20+
const publishPost = vi.fn().mockResolvedValue(undefined);
5221

53-
const getPost = vi.fn().mockResolvedValue({
54-
data: { metadata: { name: "post-1" } },
55-
});
22+
const getPost = vi
23+
.fn()
24+
.mockRejectedValueOnce({
25+
isAxiosError: true,
26+
response: { status: 404 },
27+
})
28+
.mockResolvedValueOnce({
29+
data: { metadata: { name: "post-1" } },
30+
});
5631
const fetchPostHeadContent = vi.fn().mockResolvedValue({
5732
data: { raw: "# Halo", content: "<h1>Halo</h1>", rawType: "markdown" },
5833
});
@@ -71,6 +46,8 @@ test("tryRunPostCommand imports json as a new post when it does not exist", asyn
7146
console: {
7247
content: {
7348
post: {
49+
draftPost,
50+
publishPost,
7451
fetchPostHeadContent,
7552
},
7653
},
@@ -92,69 +69,42 @@ test("tryRunPostCommand imports json as a new post when it does not exist", asyn
9269
),
9370
).resolves.toBe(true);
9471

95-
expect(createMyPost).toHaveBeenCalledOnce();
96-
expect(createMyPost).toHaveBeenCalledWith({
97-
post: expect.objectContaining({
98-
metadata: expect.objectContaining({
99-
name: "post-1",
100-
annotations: expect.objectContaining({
101-
"content.halo.run/content-json": JSON.stringify({
102-
raw: "# Halo",
103-
content: renderContentByRawType("# Halo", "markdown"),
104-
rawType: "markdown",
105-
}),
72+
expect(draftPost).toHaveBeenCalledOnce();
73+
expect(draftPost).toHaveBeenCalledWith({
74+
postRequest: expect.objectContaining({
75+
post: expect.objectContaining({
76+
metadata: expect.objectContaining({
77+
name: "post-1",
10678
}),
79+
spec: { publish: false },
80+
}),
81+
content: expect.objectContaining({
82+
raw: "# Halo",
83+
content: renderContentByRawType("# Halo", "markdown"),
84+
rawType: "markdown",
10785
}),
108-
spec: { publish: false },
10986
}),
11087
});
111-
expect(publishMyPost).toHaveBeenCalledWith({ name: "post-1" });
88+
expect(publishPost).toHaveBeenCalledWith({ name: "post-1" });
11289
});
11390

11491
test("tryRunPostCommand imports json by updating an existing post", async () => {
11592
silenceStdout();
11693

117-
const getMyPost = vi
118-
.fn()
119-
.mockResolvedValueOnce({
120-
data: {
121-
metadata: { name: "post-1" },
122-
spec: { publish: false },
123-
},
124-
})
125-
.mockResolvedValueOnce({
126-
data: {
127-
metadata: { name: "post-1" },
128-
},
129-
});
130-
const getMyPostDraft = vi.fn().mockResolvedValue({
94+
const getPost = vi.fn().mockResolvedValue({
13195
data: {
132-
metadata: { name: "post-1", annotations: {} },
133-
spec: { rawType: "markdown" },
96+
metadata: { name: "post-1" },
97+
spec: { publish: false },
13498
},
13599
});
136-
const updateMyPost = vi.fn().mockResolvedValue({
137-
data: { metadata: { name: "post-1" } },
138-
});
139-
const updateMyPostDraft = vi.fn().mockResolvedValue(undefined);
140-
const publishMyPost = vi.fn().mockResolvedValue(undefined);
141-
142-
ucPostApiState.implementation = {
143-
getMyPost,
144-
getMyPostDraft,
145-
updateMyPost,
146-
updateMyPostDraft,
147-
createMyPost: vi.fn(),
148-
publishMyPost,
149-
unpublishMyPost: vi.fn(),
150-
};
151-
152-
const getPost = vi.fn().mockResolvedValue({
153-
data: { metadata: { name: "post-1" } },
154-
});
155100
const fetchPostHeadContent = vi.fn().mockResolvedValue({
156101
data: { raw: "# Halo", content: "<h1>Halo</h1>", rawType: "markdown" },
157102
});
103+
const updateDraftPost = vi.fn().mockResolvedValue({
104+
data: { metadata: { name: "post-1" } },
105+
});
106+
const publishPost = vi.fn().mockResolvedValue(undefined);
107+
158108
const runtimeMock = {
159109
getClientsForOptions: vi.fn().mockResolvedValue({
160110
profile: { baseUrl: "https://example.com" },
@@ -171,6 +121,9 @@ test("tryRunPostCommand imports json by updating an existing post", async () =>
171121
content: {
172122
post: {
173123
fetchPostHeadContent,
124+
updateDraftPost,
125+
publishPost,
126+
unpublishPost: vi.fn(),
174127
},
175128
},
176129
},
@@ -192,55 +145,49 @@ test("tryRunPostCommand imports json by updating an existing post", async () =>
192145
),
193146
).resolves.toBe(true);
194147

195-
expect(updateMyPost).toHaveBeenCalledOnce();
196-
expect(updateMyPostDraft).toHaveBeenCalledOnce();
197-
expect(updateMyPostDraft).toHaveBeenCalledWith({
148+
expect(updateDraftPost).toHaveBeenCalledOnce();
149+
expect(updateDraftPost).toHaveBeenCalledWith({
198150
name: "post-1",
199-
snapshot: expect.objectContaining({
200-
metadata: expect.objectContaining({
201-
annotations: expect.objectContaining({
202-
"content.halo.run/content-json": JSON.stringify({
203-
raw: "# Halo",
204-
content: renderContentByRawType("# Halo", "markdown"),
205-
rawType: "markdown",
206-
}),
151+
postRequest: expect.objectContaining({
152+
post: expect.objectContaining({
153+
metadata: expect.objectContaining({
154+
name: "post-1",
207155
}),
156+
spec: expect.objectContaining({ publish: false }),
157+
}),
158+
content: expect.objectContaining({
159+
raw: "# Halo",
160+
content: renderContentByRawType("# Halo", "markdown"),
161+
rawType: "markdown",
208162
}),
209163
}),
210164
});
211-
expect(publishMyPost).toHaveBeenCalledWith({ name: "post-1" });
165+
expect(publishPost).toHaveBeenCalledWith({ name: "post-1" });
212166
});
213167

214168
test("tryRunPostCommand prints import summary with permalink and inspect command", async () => {
215169
const stdoutSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
216170

217-
const getMyPost = vi.fn().mockRejectedValue({
218-
isAxiosError: true,
219-
response: { status: 404 },
220-
});
221-
const createMyPost = vi.fn().mockResolvedValue({
171+
const getPost = vi
172+
.fn()
173+
.mockRejectedValueOnce({
174+
isAxiosError: true,
175+
response: { status: 404 },
176+
})
177+
.mockResolvedValueOnce({
178+
data: {
179+
metadata: { name: "post-1" },
180+
status: { permalink: "/archives/post-1" },
181+
},
182+
});
183+
const draftPost = vi.fn().mockResolvedValue({
222184
data: { metadata: { name: "post-1" } },
223185
});
224-
const publishMyPost = vi.fn().mockResolvedValue(undefined);
225-
ucPostApiState.implementation = {
226-
getMyPost,
227-
getMyPostDraft: vi.fn(),
228-
updateMyPost: vi.fn(),
229-
updateMyPostDraft: vi.fn(),
230-
createMyPost,
231-
publishMyPost,
232-
unpublishMyPost: vi.fn(),
233-
};
234-
235-
const getPost = vi.fn().mockResolvedValue({
236-
data: {
237-
metadata: { name: "post-1" },
238-
status: { permalink: "/archives/post-1" },
239-
},
240-
});
186+
const publishPost = vi.fn().mockResolvedValue(undefined);
241187
const fetchPostHeadContent = vi.fn().mockResolvedValue({
242188
data: { raw: "# Halo", content: "<h1>Halo</h1>", rawType: "markdown" },
243189
});
190+
244191
const runtimeMock = {
245192
getClientsForOptions: vi.fn().mockResolvedValue({
246193
profile: { baseUrl: "https://example.com/console" },
@@ -256,6 +203,8 @@ test("tryRunPostCommand prints import summary with permalink and inspect command
256203
console: {
257204
content: {
258205
post: {
206+
draftPost,
207+
publishPost,
259208
fetchPostHeadContent,
260209
},
261210
},

0 commit comments

Comments
 (0)