test(housekeeping): verify polls vertical
CI / runtime-diagnostics (pull_request) Skipped
CI / check (pull_request) Successful in 45s
CI / deploy (pull_request) Skipped
CI / release (pull_request) Skipped

This commit is contained in:
Simo committed 2026-09-02 20:48:35 +02:00
1 parent 766e7e20c8
commit 1f10e15c1c
28 files changed
+275 -51

No files matched your search

@@ -471,6 +471,164 @@ describe("Content query", () => {
expect(queryMocks.execute).toHaveBeenCalledTimes(5);
});
it("rejects a poll detail with 101 questions before loading results", async () => {
queryMocks.execute
.mockResolvedValueOnce([
[{ id: 7, title: "Oversized poll", status: "draft" }],
])
.mockResolvedValueOnce([
Array.from({ length: 101 }, (_, index) => ({
id: index + 1,
question: `Question ${index + 1}`,
type: "single",
sort_order: index,
options: "Yes\nNo",
})),
]);
await expect(
loadProductionContentQuery({
routeId: "content.engagement.poll-detail",
params: { id: "7" },
list: {
...normalizedResponsePage,
search: "",
pageSize: 25,
offset: 0,
},
}),
).rejects.toThrow("poll question limit");
expect(queryMocks.execute).toHaveBeenCalledTimes(2);
});
it("rejects 10001 grouped poll result rows before aggregating them", async () => {
queryMocks.execute
.mockResolvedValueOnce([
[{ id: 7, title: "Oversized results", status: "active" }],
])
.mockResolvedValueOnce([
[
{
id: 21,
question: "Favourite colour?",
type: "single",
sort_order: 0,
options: "Red\nBlue",
},
],
])
.mockResolvedValueOnce([
Array.from({ length: 10_001 }, (_, index) => ({
question_id: 21,
answer: `Choice ${index + 1}`,
answer_count: 1,
})),
]);
await expect(
loadProductionContentQuery({
routeId: "content.engagement.poll-detail",
params: { id: "7" },
list: {
...normalizedResponsePage,
search: "",
pageSize: 25,
offset: 0,
},
}),
).rejects.toThrow("poll aggregate limit");
expect(queryMocks.execute).toHaveBeenCalledTimes(3);
});
it("rejects a poll question with more than 100 parsed options", async () => {
queryMocks.execute
.mockResolvedValueOnce([
[{ id: 7, title: "Oversized options", status: "draft" }],
])
.mockResolvedValueOnce([
[
{
id: 21,
question: "Choose one",
type: "single",
sort_order: 0,
options: Array.from(
{ length: 101 },
(_, index) => `Option ${index + 1}`,
).join("\n"),
},
],
]);
await expect(
loadProductionContentQuery({
routeId: "content.engagement.poll-detail",
params: { id: "7" },
list: {
...normalizedResponsePage,
search: "",
pageSize: 25,
offset: 0,
},
}),
).rejects.toThrow("poll option limit");
expect(queryMocks.execute).toHaveBeenCalledTimes(2);
});
it.each([
["a foreign question", "999"],
["a non-text question", "21"],
])(
"falls back to the first text question for %s",
async (_label, requestedId) => {
queryMocks.execute
.mockResolvedValueOnce([
[{ id: 7, title: "Response fallback", status: "active" }],
])
.mockResolvedValueOnce([
[
{
id: 21,
question: "Favourite colour?",
type: "single",
sort_order: 0,
options: "Red\nBlue",
},
{
id: 22,
question: "What should improve?",
type: "text",
sort_order: 1,
options: "",
},
],
])
.mockResolvedValueOnce([[]])
.mockResolvedValueOnce([[{ total: 0 }]])
.mockResolvedValueOnce([[]]);
const result = await loadProductionContentQuery({
routeId: "content.engagement.poll-detail",
params: { id: "7" },
list: {
...normalizedResponsePage,
search: "",
pageSize: 25,
offset: 0,
responseQuestionId: requestedId,
},
});
expect(result.items[0]?.privatePayload).toMatchObject({
textResponses: { questionId: "22" },
});
expect(JSON.stringify(queryMocks.execute.mock.calls.slice(3))).toContain(
"22",
);
expect(queryMocks.execute).toHaveBeenCalledTimes(5);
},
);
it("returns a valid empty detail result when the selected poll is missing", async () => {
queryMocks.execute.mockResolvedValueOnce([[]]);