Skip to content

g1t/apps/web/app/lib/dependency-updates.test.ts

89 lines3,521 bytesCodeBlame
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import type { UpdatePull, VersionUpdateEntry } from "@g1t/contracts";
5
6import { conditionText, entryStatus, groupText, ignoreText, livePulls, timeUntil, utc } from "./dependency-updates.ts";
7
8const NOW = Date.parse("2026-10-07T12:00:00Z");
9
10test("a next run is said as a time ahead", () => {
11 assert.equal(timeUntil("2026-10-07T15:30:00Z", NOW), "in 3h");
12 assert.equal(timeUntil("2026-10-09T12:00:00Z", NOW), "in 2d");
13 assert.equal(timeUntil("2026-10-07T12:20:00Z", NOW), "in 20m");
14 assert.equal(timeUntil("2026-10-07T11:00:00Z", NOW), "due now");
15 assert.equal(utc("2026-10-12T05:00:00.000Z"), "2026-10-12 05:00 UTC");
16});
17
18const entry: VersionUpdateEntry = {
19 id: "npm:/",
20 ecosystem: "npm",
21 directories: ["/"],
22 supported: true,
23 interval: "weekly",
24 schedule: "Mondays at 05:00 (UTC)",
25 openPullRequestsLimit: 5,
26 targetBranch: null,
27 multiEcosystemGroup: null,
28 groups: [],
29 ignore: [],
30 allow: [],
31 labels: null,
32 assignees: [],
33 reviewers: [],
34 milestone: null,
35 versioningStrategy: null,
36 options: {},
37 notes: [],
38 nextRunAt: "2026-10-12T05:00:00Z",
39 lastCheckedAt: null,
40 lastResult: null,
41 lastError: null,
42};
43
44test("an entry's status", () => {
45 assert.deepEqual(entryStatus(entry), { label: "Active", tone: "accent" });
46 assert.equal(entryStatus({ ...entry, supported: false }).label, "Not updated yet");
47 assert.equal(entryStatus({ ...entry, openPullRequestsLimit: 0 }).label, "Off");
48 assert.equal(entryStatus({ ...entry, nextRunAt: null }).label, "Not scheduled");
49 assert.equal(entryStatus({ ...entry, lastError: "boom" }).label, "Last check failed");
50});
51
52test("rules read as one line", () => {
53 assert.equal(
54 groupText({ name: "lint", appliesTo: "version-updates", patterns: ["eslint*"], excludePatterns: ["eslint-old"], updateTypes: ["minor"], dependencyType: "development", groupBy: null }),
55 "lint: eslint* · not eslint-old · development · minor",
56 );
57 assert.equal(
58 groupText({ name: "fixes", appliesTo: "security-updates", patterns: [], excludePatterns: [], updateTypes: [], dependencyType: null, groupBy: null }),
59 "fixes: every dependency · security updates",
60 );
61 assert.equal(ignoreText({ dependency: "react", versions: [">=19"], updateTypes: [] }), "react >=19");
62 assert.equal(ignoreText({ dependency: "*", versions: [], updateTypes: ["version-update:semver-major"] }), "* major");
63 assert.equal(ignoreText({ dependency: "left-pad", versions: [], updateTypes: [] }), "left-pad (every version)");
64 const condition = { ecosystem: "npm", dependency: "react", versions: null, updateType: null, by: "ana", pull: 4, at: "" };
65 assert.equal(conditionText(condition), "every version");
66 assert.equal(conditionText({ ...condition, versions: ">= 19.a, < 20" }), ">= 19.a, < 20");
67 assert.equal(conditionText({ ...condition, updateType: "version-update:semver-minor" }), "minor versions");
68});
69
70test("only live update pull requests are listed", () => {
71 const pull = (state: UpdatePull["state"]): UpdatePull => ({
72 kind: "version",
73 entry: "npm:/",
74 ecosystem: "npm",
75 group: null,
76 branch: "g1t/npm_and_yarn/x",
77 title: "Bump x",
78 state,
79 pull: 1,
80 dependencies: [],
81 mergeRequestedBy: null,
82 error: null,
83 updatedAt: "",
84 });
85 assert.deepEqual(
86 livePulls([pull("open"), pull("merged"), pull("requested"), pull("superseded"), pull("needs_code")]).map((p) => p.state),
87 ["open", "requested", "needs_code"],
88 );
89});