Skip to content

Commit 89ac0a1

Browse files
Share cloud task domain policies
Generated-By: PostHog Code Task-Id: 40c57a59-b4e1-4760-8e56-ecd03e9c2f0f
1 parent 9932264 commit 89ac0a1

20 files changed

Lines changed: 1659 additions & 6 deletions
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
import { describe, expect, it } from "vitest";
2+
import {
3+
type AutomationScheduleDraft,
4+
buildCronExpression,
5+
createDefaultScheduleDraft,
6+
deriveAutomationName,
7+
formatAutomationScheduleSummary,
8+
formatScheduleSummary,
9+
parseCronExpression,
10+
sanitizeHour,
11+
sanitizeMinute,
12+
WEEKDAY_OPTIONS,
13+
} from "./automationSchedule";
14+
15+
describe("automationSchedule", () => {
16+
it("creates the default daily schedule draft", () => {
17+
expect(createDefaultScheduleDraft()).toEqual({
18+
mode: "daily",
19+
hour: "09",
20+
minute: "00",
21+
weekday: "1",
22+
rawCron: "0 9 * * *",
23+
});
24+
});
25+
26+
it("provides cron weekday values in display order", () => {
27+
expect(WEEKDAY_OPTIONS).toEqual([
28+
{ value: "1", label: "Mon" },
29+
{ value: "2", label: "Tue" },
30+
{ value: "3", label: "Wed" },
31+
{ value: "4", label: "Thu" },
32+
{ value: "5", label: "Fri" },
33+
{ value: "6", label: "Sat" },
34+
{ value: "0", label: "Sun" },
35+
]);
36+
});
37+
38+
it.each([
39+
["", ""],
40+
["a", ""],
41+
["7", "07"],
42+
["09", "09"],
43+
["2x3", "23"],
44+
["24", "23"],
45+
["999", "23"],
46+
])("sanitizes hour input %j to %j", (input, expected) => {
47+
expect(sanitizeHour(input)).toBe(expected);
48+
});
49+
50+
it.each([
51+
["", ""],
52+
["a", ""],
53+
["7", "07"],
54+
["09", "09"],
55+
["5x9", "59"],
56+
["60", "59"],
57+
["999", "59"],
58+
])("sanitizes minute input %j to %j", (input, expected) => {
59+
expect(sanitizeMinute(input)).toBe(expected);
60+
});
61+
62+
it.each<{
63+
name: string;
64+
changes: Partial<AutomationScheduleDraft>;
65+
expected: string;
66+
}>([
67+
{
68+
name: "hourly",
69+
changes: { mode: "hourly", minute: "15" },
70+
expected: "15 * * * *",
71+
},
72+
{
73+
name: "daily",
74+
changes: { mode: "daily", hour: "09", minute: "15" },
75+
expected: "15 9 * * *",
76+
},
77+
{
78+
name: "weekdays",
79+
changes: { mode: "weekdays", hour: "10", minute: "00" },
80+
expected: "0 10 * * 1-5",
81+
},
82+
{
83+
name: "weekly",
84+
changes: {
85+
mode: "weekly",
86+
hour: "11",
87+
minute: "30",
88+
weekday: "4",
89+
},
90+
expected: "30 11 * * 4",
91+
},
92+
{
93+
name: "weekly with a missing weekday",
94+
changes: { mode: "weekly", weekday: "" },
95+
expected: "0 9 * * 1",
96+
},
97+
{
98+
name: "preset with missing time values",
99+
changes: { mode: "daily", hour: "", minute: "" },
100+
expected: "0 9 * * *",
101+
},
102+
{
103+
name: "custom",
104+
changes: { mode: "custom", rawCron: " */15 * * * * " },
105+
expected: "*/15 * * * *",
106+
},
107+
])("builds the $name cron expression", ({ changes, expected }) => {
108+
expect(
109+
buildCronExpression({ ...createDefaultScheduleDraft(), ...changes }),
110+
).toBe(expected);
111+
});
112+
113+
it.each([
114+
[
115+
"15 * * * *",
116+
{
117+
mode: "hourly",
118+
hour: "09",
119+
minute: "15",
120+
weekday: "*",
121+
rawCron: "15 * * * *",
122+
},
123+
],
124+
[
125+
"0 9 * * *",
126+
{
127+
mode: "daily",
128+
hour: "09",
129+
minute: "00",
130+
weekday: "*",
131+
rawCron: "0 9 * * *",
132+
},
133+
],
134+
[
135+
"0 9 * * 1-5",
136+
{
137+
mode: "weekdays",
138+
hour: "09",
139+
minute: "00",
140+
weekday: "1",
141+
rawCron: "0 9 * * 1-5",
142+
},
143+
],
144+
[
145+
"30 14 * * 2",
146+
{
147+
mode: "weekly",
148+
hour: "14",
149+
minute: "30",
150+
weekday: "2",
151+
rawCron: "30 14 * * 2",
152+
},
153+
],
154+
] as const)("parses %s into a schedule draft", (cron, expected) => {
155+
expect(parseCronExpression(cron)).toEqual(expected);
156+
});
157+
158+
it.each(["*/15 * * * *", "0 9 1 * *", "0 9 * 1 *", "0 9 * * 1,3"])(
159+
"keeps unsupported cron expression %s in custom mode",
160+
(cron) => {
161+
expect(parseCronExpression(cron)).toMatchObject({
162+
mode: "custom",
163+
rawCron: cron,
164+
});
165+
},
166+
);
167+
168+
it("normalizes surrounding and repeated cron whitespace", () => {
169+
expect(parseCronExpression(" 5 8 * * * ")).toEqual({
170+
mode: "daily",
171+
hour: "08",
172+
minute: "05",
173+
weekday: "*",
174+
rawCron: "5 8 * * *",
175+
});
176+
});
177+
178+
it("uses default draft fields for a cron expression with the wrong arity", () => {
179+
expect(parseCronExpression("0 9 * *")).toEqual({
180+
mode: "custom",
181+
hour: "09",
182+
minute: "00",
183+
weekday: "1",
184+
rawCron: "0 9 * *",
185+
});
186+
});
187+
188+
it("derives a compact name from the first non-empty prompt line", () => {
189+
expect(
190+
deriveAutomationName(
191+
"\n Review every open PostHog PR for stale comments \nIgnore this line",
192+
),
193+
).toBe("Review every open PostHog PR for stale comments");
194+
});
195+
196+
it("returns an empty name for a blank prompt", () => {
197+
expect(deriveAutomationName(" \n\t\n ")).toBe("");
198+
});
199+
200+
it("limits derived names to 80 characters", () => {
201+
expect(deriveAutomationName("a".repeat(100))).toBe("a".repeat(80));
202+
});
203+
204+
it.each([
205+
["15 * * * *", "Europe/London", "Every hour at :15 · Europe/London"],
206+
["0 9 * * *", null, "Daily at 09:00"],
207+
["0 9 * * 1-5", "UTC", "Weekdays at 09:00 · UTC"],
208+
["30 14 * * 2", undefined, "Tue at 14:30"],
209+
["30 14 * * 7", "UTC", "Weekly at 14:30 · UTC"],
210+
["*/15 * * * *", "UTC", "Custom schedule · UTC"],
211+
])("formats %s with timezone %j", (cronExpression, timezone, expected) => {
212+
expect(formatScheduleSummary(cronExpression, timezone)).toBe(expected);
213+
});
214+
215+
it("formats a schedule from an automation-shaped input", () => {
216+
expect(
217+
formatAutomationScheduleSummary({
218+
cron_expression: "0 18 * * 0",
219+
timezone: "America/New_York",
220+
}),
221+
).toBe("Sun at 18:00 · America/New_York");
222+
});
223+
});

0 commit comments

Comments
 (0)