| 1 | import assert from "node:assert/strict"; |
| 2 | import { test } from "node:test"; |
| 3 | |
| 4 | import type { UpdatePull, VersionUpdateEntry } from "@g1t/contracts"; |
| 5 | |
| 6 | import { conditionText, entryStatus, groupText, ignoreText, livePulls, timeUntil, utc } from "./dependency-updates.ts"; |
| 7 | |
| 8 | const NOW = Date.parse("2026-10-07T12:00:00Z"); |
| 9 | |
| 10 | test("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 | |
| 18 | const 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 | |
| 44 | test("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 | |
| 52 | test("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 | |
| 70 | test("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 | }); |