Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ Newest first. `Unreleased` is what is on `main` and not yet tagged.
`code_required` (below). A server and a computer must be upgraded together: an older computer has
no `/sign-in/code`.

### A repeated minute in a routine's schedule is described once

A schedule like `0,30,0 9 * * *` fires at 09:00 and 09:30, but the routines page and the model were
told "Every day at 09:00, 09:00 and 09:30". Repeated minutes are now said once, as repeated weekdays
already were.

### The Bot's screen opens only when there is something to watch

Asking a Bot a question it answered in words could still open its computer beside the conversation,
Expand Down
4 changes: 3 additions & 1 deletion server/src/routines/schedule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,9 @@ export function describeCron(cron: string): string {
.split(",")
.map((part) => parsePlainInt(part, 0, 59));
if (minutes.every((value): value is number => value !== null)) {
const times = [...minutes]
// De-duplicated like `weekdays`: cron fires once for `0,0`, so it must not read as
// "09:00 and 09:00".
const times = [...new Set(minutes)]
.sort((a, b) => a - b)
.map((value) => `${pad2(hour)}:${pad2(value)}`);
return `Every day at ${joinWords(times)}`;
Expand Down
6 changes: 6 additions & 0 deletions server/tests/routine-schedule.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,12 @@ describe("describeCron", () => {
expect(describeCron("0,30 9 * * *")).toBe("Every day at 09:00 and 09:30");
});

// cron fires once per distinct minute, so a repeated minute must not be described twice.
test("a repeated minute in the list is described once", () => {
expect(describeCron("0,30,0 9 * * *")).toBe("Every day at 09:00 and 09:30");
expect(describeCron("15,15 9 * * *")).toBe("Every day at 09:15");
});

test("falls through to the raw expression when it is stranger than words", () => {
expect(describeCron("*/7 3,4 * * *")).toBe("*/7 3,4 * * *");
});
Expand Down