Skip to content

Commit 56d53a3

Browse files
committed
Prevent decimals in next check text
1 parent 1696d36 commit 56d53a3

File tree

2 files changed

+80
-1
lines changed

2 files changed

+80
-1
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import dayjs from "dayjs";
2+
import duration from "dayjs/plugin/duration";
3+
import relativeTime from "dayjs/plugin/relativeTime";
4+
import {
5+
getEffectiveRefreshRateSeconds,
6+
formatRefreshRateSeconds,
7+
getNextCheckText,
8+
} from "./formatRefreshRateSeconds";
9+
10+
dayjs.extend(duration);
11+
dayjs.extend(relativeTime);
12+
13+
describe("getEffectiveRefreshRateSeconds", () => {
14+
it("returns userRefreshRateSeconds when set", () => {
15+
expect(
16+
getEffectiveRefreshRateSeconds({ userRefreshRateSeconds: 120, refreshRateSeconds: 600 }),
17+
).toBe(120);
18+
});
19+
20+
it("falls back to refreshRateSeconds when userRefreshRateSeconds is undefined", () => {
21+
expect(getEffectiveRefreshRateSeconds({ refreshRateSeconds: 600 })).toBe(600);
22+
});
23+
24+
it("falls back to refreshRateSeconds when userRefreshRateSeconds is 0", () => {
25+
expect(
26+
getEffectiveRefreshRateSeconds({ userRefreshRateSeconds: 0, refreshRateSeconds: 600 }),
27+
).toBe(600);
28+
});
29+
});
30+
31+
describe("formatRefreshRateSeconds", () => {
32+
it("formats seconds for values under 60", () => {
33+
expect(formatRefreshRateSeconds(30)).toBe("30 seconds");
34+
});
35+
36+
it("formats minutes for values 60 and above", () => {
37+
expect(formatRefreshRateSeconds(60)).toBe("1 minute");
38+
expect(formatRefreshRateSeconds(120)).toBe("2 minutes");
39+
expect(formatRefreshRateSeconds(600)).toBe("10 minutes");
40+
});
41+
42+
it("formats hours for values 3600 and above", () => {
43+
expect(formatRefreshRateSeconds(3600)).toBe("1 hour");
44+
expect(formatRefreshRateSeconds(7200)).toBe("2 hours");
45+
});
46+
});
47+
48+
describe("getNextCheckText", () => {
49+
it("returns empty string when lastRequestAtUnix is undefined", () => {
50+
expect(getNextCheckText(undefined, 600)).toBe("");
51+
});
52+
53+
it("returns 'expected shortly' when overdue", () => {
54+
const fifteenMinutesAgo = Date.now() / 1000 - 900;
55+
expect(getNextCheckText(fifteenMinutesAgo, 600)).toBe("Next check expected shortly.");
56+
});
57+
58+
it("returns 'expected shortly' when exactly at refresh rate", () => {
59+
const tenMinutesAgo = Date.now() / 1000 - 600;
60+
expect(getNextCheckText(tenMinutesAgo, 600)).toBe("Next check expected shortly.");
61+
});
62+
63+
it("returns humanized time remaining when within refresh window", () => {
64+
const twoMinutesAgo = Date.now() / 1000 - 120;
65+
const result = getNextCheckText(twoMinutesAgo, 600);
66+
expect(result).toMatch(/^Next check expected in about .+\.$/);
67+
expect(result).not.toContain("shortly");
68+
});
69+
70+
it("returns humanized time for short remaining duration", () => {
71+
const nineMinutesAgo = Date.now() / 1000 - 540;
72+
const result = getNextCheckText(nineMinutesAgo, 600);
73+
expect(result).toMatch(/^Next check expected in about .+\.$/);
74+
});
75+
});

services/backend-api/client/src/utils/formatRefreshRateSeconds.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import dayjs from "dayjs";
2+
13
export const getEffectiveRefreshRateSeconds = (feed: {
24
userRefreshRateSeconds?: number;
35
refreshRateSeconds: number;
@@ -33,5 +35,7 @@ export const getNextCheckText = (
3335
return "Next check expected shortly.";
3436
}
3537

36-
return `Next check expected in about ${formatRefreshRateSeconds(Math.ceil(secondsRemaining))}.`;
38+
const humanized = dayjs.duration(secondsRemaining, "seconds").humanize();
39+
40+
return `Next check expected in about ${humanized}.`;
3741
};

0 commit comments

Comments
 (0)