Initial Commit
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import {
|
||||
CampaignIdParamSchema,
|
||||
CampaignListResponseSchema,
|
||||
CampaignQuerySchema,
|
||||
CampaignResponseSchema,
|
||||
CampaignStatusSchema,
|
||||
CampaignTypeSchema,
|
||||
CreateCampaignSchema,
|
||||
EMPTY_STATS,
|
||||
UpdateCampaignSchema,
|
||||
} from "./schemas.js";
|
||||
|
||||
describe("campaign route schemas", () => {
|
||||
it("CampaignStatusSchema accepts all 7 statuses", { timeout: 5000 }, () => {
|
||||
for (const s of [
|
||||
"draft",
|
||||
"scheduled",
|
||||
"sending",
|
||||
"paused",
|
||||
"completed",
|
||||
"cancelled",
|
||||
"failed",
|
||||
] as const) {
|
||||
expect(CampaignStatusSchema.parse(s)).toBe(s);
|
||||
}
|
||||
expect(() => CampaignStatusSchema.parse("bogus")).toThrow();
|
||||
});
|
||||
|
||||
it("CampaignTypeSchema accepts all 4 types", { timeout: 5000 }, () => {
|
||||
for (const t of [
|
||||
"broadcast",
|
||||
"triggered",
|
||||
"ab_test",
|
||||
"drip",
|
||||
] as const) {
|
||||
expect(CampaignTypeSchema.parse(t)).toBe(t);
|
||||
}
|
||||
expect(() => CampaignTypeSchema.parse("bogus")).toThrow();
|
||||
});
|
||||
|
||||
it("CampaignIdParamSchema rejects empty id", { timeout: 5000 }, () => {
|
||||
expect(() => CampaignIdParamSchema.parse({ id: "" })).toThrow();
|
||||
expect(CampaignIdParamSchema.parse({ id: "a" })).toEqual({ id: "a" });
|
||||
});
|
||||
|
||||
it("CreateCampaignSchema applies all documented defaults", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const parsed = CreateCampaignSchema.parse({ name: "x" });
|
||||
expect(parsed.type).toBe("broadcast");
|
||||
expect(parsed.channel).toBe("email");
|
||||
expect(parsed.audienceConfig).toEqual({ groupIds: [] });
|
||||
expect(parsed.templateData).toEqual({});
|
||||
expect(parsed.metadata).toEqual({});
|
||||
});
|
||||
|
||||
it("CreateCampaignSchema rejects empty name", { timeout: 5000 }, () => {
|
||||
expect(() => CreateCampaignSchema.parse({ name: "" })).toThrow();
|
||||
});
|
||||
|
||||
it("CreateCampaignSchema accepts a full body", { timeout: 5000 }, () => {
|
||||
const out = CreateCampaignSchema.parse({
|
||||
name: "Promo",
|
||||
type: "drip",
|
||||
channel: "sms",
|
||||
audienceConfig: {
|
||||
groupIds: ["g1"],
|
||||
excludeGroupIds: ["g2"],
|
||||
},
|
||||
templateId: "tpl1",
|
||||
templateData: { foo: 1 },
|
||||
schedule: { type: "immediate" },
|
||||
throttle: { messagesPerSecond: 5 },
|
||||
abTestConfig: { splitType: "even" },
|
||||
metadata: { campaignId: "X" },
|
||||
});
|
||||
expect(out.type).toBe("drip");
|
||||
expect(out.audienceConfig.groupIds).toEqual(["g1"]);
|
||||
});
|
||||
|
||||
it("UpdateCampaignSchema accepts a partial body", { timeout: 5000 }, () => {
|
||||
const out = UpdateCampaignSchema.parse({ name: "New" });
|
||||
expect(out.name).toBe("New");
|
||||
});
|
||||
|
||||
it("UpdateCampaignSchema rejects empty name", { timeout: 5000 }, () => {
|
||||
expect(() => UpdateCampaignSchema.parse({ name: "" })).toThrow();
|
||||
});
|
||||
|
||||
it("CampaignQuerySchema coerces query strings and applies defaults", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const out = CampaignQuerySchema.parse({
|
||||
status: "draft",
|
||||
type: "broadcast",
|
||||
limit: "25",
|
||||
offset: "5",
|
||||
});
|
||||
expect(out.limit).toBe(25);
|
||||
expect(out.offset).toBe(5);
|
||||
expect(out.status).toBe("draft");
|
||||
});
|
||||
|
||||
it("CampaignQuerySchema clamps limit between 1 and 200", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
expect(() => CampaignQuerySchema.parse({ limit: 0 })).toThrow();
|
||||
expect(() => CampaignQuerySchema.parse({ limit: 300 })).toThrow();
|
||||
});
|
||||
|
||||
it("CampaignResponseSchema accepts a minimally valid response", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const ok = CampaignResponseSchema.safeParse({
|
||||
id: "1",
|
||||
tenantId: "t",
|
||||
name: "x",
|
||||
status: "draft",
|
||||
type: "broadcast",
|
||||
channel: "email",
|
||||
audienceConfig: { groupIds: [] },
|
||||
templateData: {},
|
||||
metadata: {},
|
||||
stats: EMPTY_STATS,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
expect(ok.success).toBe(true);
|
||||
});
|
||||
|
||||
it("CampaignListResponseSchema wraps the campaign array", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const ok = CampaignListResponseSchema.safeParse({
|
||||
campaigns: [],
|
||||
total: 0,
|
||||
});
|
||||
expect(ok.success).toBe(true);
|
||||
});
|
||||
|
||||
it("EMPTY_STATS exposes every zero counter", { timeout: 5000 }, () => {
|
||||
expect(Object.values(EMPTY_STATS).every((v) => v === 0)).toBe(true);
|
||||
expect(Object.keys(EMPTY_STATS)).toHaveLength(9);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user