@knpkv/codecommit 0.5.5 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -9
- package/dist/package.json +15 -15
- package/dist/src/FilterService.d.ts +84 -0
- package/dist/src/FilterService.d.ts.map +1 -0
- package/dist/src/FilterService.js +85 -0
- package/dist/src/FilterService.js.map +1 -0
- package/dist/src/bin.js +135 -48
- package/dist/src/bin.js.map +1 -1
- package/dist/src/filterPresets.d.ts +24 -0
- package/dist/src/filterPresets.d.ts.map +1 -0
- package/dist/src/filterPresets.js +46 -0
- package/dist/src/filterPresets.js.map +1 -0
- package/dist/src/main.d.ts +3 -1
- package/dist/src/main.d.ts.map +1 -1
- package/dist/src/main.js +17 -5
- package/dist/src/main.js.map +1 -1
- package/dist/src/tui/App.d.ts.map +1 -1
- package/dist/src/tui/App.js +3 -2
- package/dist/src/tui/App.js.map +1 -1
- package/dist/src/tui/atoms/actions.d.ts +6 -6
- package/dist/src/tui/atoms/actions.d.ts.map +1 -1
- package/dist/src/tui/atoms/actions.js +30 -23
- package/dist/src/tui/atoms/actions.js.map +1 -1
- package/dist/src/tui/atoms/app.d.ts +7 -7
- package/dist/src/tui/atoms/app.d.ts.map +1 -1
- package/dist/src/tui/atoms/app.js +11 -12
- package/dist/src/tui/atoms/app.js.map +1 -1
- package/dist/src/tui/atoms/runtime.d.ts +3 -3
- package/dist/src/tui/atoms/runtime.d.ts.map +1 -1
- package/dist/src/tui/atoms/runtime.js +8 -8
- package/dist/src/tui/atoms/runtime.js.map +1 -1
- package/dist/src/tui/atoms/ui.d.ts +1 -1
- package/dist/src/tui/atoms/ui.d.ts.map +1 -1
- package/dist/src/tui/atoms/ui.js +1 -1
- package/dist/src/tui/atoms/ui.js.map +1 -1
- package/dist/src/tui/components/DetailsView.d.ts.map +1 -1
- package/dist/src/tui/components/DetailsView.js +8 -7
- package/dist/src/tui/components/DetailsView.js.map +1 -1
- package/dist/src/tui/components/Footer.js +1 -1
- package/dist/src/tui/components/Footer.js.map +1 -1
- package/dist/src/tui/components/Header.d.ts.map +1 -1
- package/dist/src/tui/components/Header.js +5 -4
- package/dist/src/tui/components/Header.js.map +1 -1
- package/dist/src/tui/components/ListItemRow.d.ts.map +1 -1
- package/dist/src/tui/components/ListItemRow.js +3 -3
- package/dist/src/tui/components/ListItemRow.js.map +1 -1
- package/dist/src/tui/components/MainList.d.ts.map +1 -1
- package/dist/src/tui/components/MainList.js +5 -4
- package/dist/src/tui/components/MainList.js.map +1 -1
- package/dist/src/tui/components/QuickFilters.d.ts.map +1 -1
- package/dist/src/tui/components/QuickFilters.js +3 -2
- package/dist/src/tui/components/QuickFilters.js.map +1 -1
- package/dist/src/tui/components/SettingsAccountsTab.js +1 -1
- package/dist/src/tui/components/SettingsAccountsTab.js.map +1 -1
- package/dist/src/tui/components/SettingsThemeTab.js +1 -1
- package/dist/src/tui/components/SettingsThemeTab.js.map +1 -1
- package/dist/src/tui/components/SettingsView.js +1 -1
- package/dist/src/tui/components/SettingsView.js.map +1 -1
- package/dist/src/tui/context/theme.js +1 -1
- package/dist/src/tui/context/theme.js.map +1 -1
- package/dist/src/tui/hooks/useKeyboardNav.d.ts.map +1 -1
- package/dist/src/tui/hooks/useKeyboardNav.js +5 -4
- package/dist/src/tui/hooks/useKeyboardNav.js.map +1 -1
- package/dist/src/tui/hooks/useListNavigation.js +1 -1
- package/dist/src/tui/hooks/useListNavigation.js.map +1 -1
- package/dist/src/tui/ui/DialogCommand.js +1 -1
- package/dist/src/tui/ui/DialogCommand.js.map +1 -1
- package/dist/src/tui/ui/DialogCreatePR.d.ts.map +1 -1
- package/dist/src/tui/ui/DialogCreatePR.js +5 -4
- package/dist/src/tui/ui/DialogCreatePR.js.map +1 -1
- package/dist/src/tui/utils/prTemplates.d.ts +2 -2
- package/dist/src/tui/utils/prTemplates.d.ts.map +1 -1
- package/dist/src/tui/utils/prTemplates.js +35 -36
- package/dist/src/tui/utils/prTemplates.js.map +1 -1
- package/dist/test/ConfigService.test.js +10 -7
- package/dist/test/ConfigService.test.js.map +1 -1
- package/dist/test/FilterService.test.d.ts +2 -0
- package/dist/test/FilterService.test.d.ts.map +1 -0
- package/dist/test/FilterService.test.js +209 -0
- package/dist/test/FilterService.test.js.map +1 -0
- package/dist/test/bin.test.d.ts +2 -0
- package/dist/test/bin.test.d.ts.map +1 -0
- package/dist/test/bin.test.js +36 -0
- package/dist/test/bin.test.js.map +1 -0
- package/dist/test/filterPresets.test.d.ts +2 -0
- package/dist/test/filterPresets.test.d.ts.map +1 -0
- package/dist/test/filterPresets.test.js +166 -0
- package/dist/test/filterPresets.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -17
- package/skills/codecommit/SKILL.md +69 -0
- package/skills/codecommit/agents/openai.yaml +4 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `FilterService` orchestration tests.
|
|
3
|
+
*
|
|
4
|
+
* `FilterService` (in `src/FilterService.ts`) holds the cross-account `--filter`
|
|
5
|
+
* fan-out that backs `pr list`: it resolves enabled targets from config, scans
|
|
6
|
+
* each `{ profile, region }` for OPEN PRs, applies the preset + repo/author
|
|
7
|
+
* predicates, and returns a structured `{ prs, failures, unresolvedProfiles }`.
|
|
8
|
+
*
|
|
9
|
+
* These tests drive the service through stub `AwsClient` and `ConfigService`
|
|
10
|
+
* layers (no network, no real config file) so the orchestration — failure
|
|
11
|
+
* collection, unresolved-identity tracking, and sort order — is verified
|
|
12
|
+
* deterministically. PRs are built with `Schema.decodeSync(PullRequest)` so the
|
|
13
|
+
* fixtures are real, branded domain objects (no casts).
|
|
14
|
+
*
|
|
15
|
+
* `bin.ts` is intentionally NOT imported — it boots the CLI/Bun runtime on load.
|
|
16
|
+
*/
|
|
17
|
+
import { describe, expect, it } from "@effect/vitest";
|
|
18
|
+
import { AwsClient, ConfigService, Errors } from "@knpkv/codecommit-core";
|
|
19
|
+
import { PullRequest } from "@knpkv/codecommit-core/Domain.js";
|
|
20
|
+
import { Effect, Layer, Option, Schema, Stream } from "effect";
|
|
21
|
+
import { FilterService, FilterServiceLive } from "../src/FilterService.js";
|
|
22
|
+
// ── Fixtures ─────────────────────────────────────────────────────────
|
|
23
|
+
const NOW = new Date("2024-06-19T12:00:00Z");
|
|
24
|
+
const mkPR = (o = {}) => Schema.decodeSync(PullRequest)({
|
|
25
|
+
id: o.id ?? "123",
|
|
26
|
+
title: "Add feature",
|
|
27
|
+
author: o.author ?? "alice",
|
|
28
|
+
repositoryName: o.repositoryName ?? "my-repo",
|
|
29
|
+
creationDate: new Date("2024-06-01"),
|
|
30
|
+
lastModifiedDate: o.lastModifiedDate ?? NOW,
|
|
31
|
+
link: "https://console.aws.amazon.com",
|
|
32
|
+
account: { profile: o.profile ?? "dev", region: o.region ?? "us-east-1" },
|
|
33
|
+
status: "OPEN",
|
|
34
|
+
sourceBranch: "feature/x",
|
|
35
|
+
destinationBranch: "main",
|
|
36
|
+
isMergeable: o.isMergeable ?? true,
|
|
37
|
+
isApproved: false,
|
|
38
|
+
approvedBy: [],
|
|
39
|
+
commentedBy: [],
|
|
40
|
+
approvalRules: []
|
|
41
|
+
});
|
|
42
|
+
const target = (profile, region = "us-east-1") => ({
|
|
43
|
+
profile: profile,
|
|
44
|
+
region: region
|
|
45
|
+
});
|
|
46
|
+
const opts = { repo: Option.none(), author: Option.none() };
|
|
47
|
+
/** A key identifying an account target, for routing stub responses. */
|
|
48
|
+
const key = (a) => `${a.profile}/${a.region}`;
|
|
49
|
+
const awsStub = (cfg) => Layer.succeed(AwsClient.AwsClient, AwsClient.AwsClient.of({
|
|
50
|
+
getPullRequests: (account, _options) => {
|
|
51
|
+
const k = key(account);
|
|
52
|
+
if (cfg.failTargets?.includes(k)) {
|
|
53
|
+
return Stream.fail(new Errors.AwsApiError({
|
|
54
|
+
operation: "getPullRequests",
|
|
55
|
+
profile: account.profile,
|
|
56
|
+
region: account.region,
|
|
57
|
+
cause: new Error("boom")
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
return Stream.fromIterable(cfg.prsByTarget?.[k] ?? []);
|
|
61
|
+
},
|
|
62
|
+
getCallerIdentity: (account) => {
|
|
63
|
+
const username = cfg.callerByProfile?.[account.profile];
|
|
64
|
+
if (username == null) {
|
|
65
|
+
return Effect.fail(new Errors.AwsApiError({
|
|
66
|
+
operation: "getCallerIdentity",
|
|
67
|
+
profile: account.profile,
|
|
68
|
+
region: account.region,
|
|
69
|
+
cause: new Error("no identity")
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
return Effect.succeed({ username, accountId: "123456789012" });
|
|
73
|
+
},
|
|
74
|
+
// Unused by FilterService — fail loudly if ever called.
|
|
75
|
+
createPullRequest: () => Effect.die("not implemented"),
|
|
76
|
+
listBranches: () => Effect.die("not implemented"),
|
|
77
|
+
getCommentsForPullRequest: () => Effect.die("not implemented"),
|
|
78
|
+
updatePullRequestTitle: () => Effect.die("not implemented"),
|
|
79
|
+
updatePullRequestDescription: () => Effect.die("not implemented"),
|
|
80
|
+
getPullRequest: () => Effect.die("not implemented"),
|
|
81
|
+
getDifferences: () => Effect.die("not implemented"),
|
|
82
|
+
createApprovalRule: () => Effect.die("not implemented"),
|
|
83
|
+
updateApprovalRule: () => Effect.die("not implemented"),
|
|
84
|
+
deleteApprovalRule: () => Effect.die("not implemented")
|
|
85
|
+
}));
|
|
86
|
+
const configStub = (accounts) => {
|
|
87
|
+
// Build a real, fully-defaulted TuiConfig via its Schema so the stub returns a
|
|
88
|
+
// genuine domain object (no `as any` on the config shape).
|
|
89
|
+
const config = Schema.decodeSync(ConfigService.TuiConfig)({
|
|
90
|
+
accounts: accounts.map((a) => ({ profile: a.profile, regions: a.regions, enabled: a.enabled }))
|
|
91
|
+
});
|
|
92
|
+
return Layer.succeed(ConfigService.ConfigService, ConfigService.ConfigService.of({
|
|
93
|
+
load: Effect.succeed(config),
|
|
94
|
+
save: () => Effect.die("not implemented"),
|
|
95
|
+
detectProfiles: Effect.die("not implemented"),
|
|
96
|
+
getConfigPath: Effect.die("not implemented"),
|
|
97
|
+
backup: Effect.die("not implemented"),
|
|
98
|
+
reset: Effect.die("not implemented"),
|
|
99
|
+
validate: Effect.die("not implemented")
|
|
100
|
+
}));
|
|
101
|
+
};
|
|
102
|
+
const provide = (aws, config) => FilterServiceLive.pipe(Layer.provide(Layer.mergeAll(aws, config)), Layer.orDie);
|
|
103
|
+
// ── resolveTargets ───────────────────────────────────────────────────
|
|
104
|
+
describe("FilterService / resolveTargets", () => {
|
|
105
|
+
// Disabled accounts are dropped; enabled accounts expand to one target per region.
|
|
106
|
+
it.effect("keeps only enabled accounts and flattens regions", () => Effect.gen(function* () {
|
|
107
|
+
const fs = yield* FilterService;
|
|
108
|
+
const targets = yield* fs.resolveTargets;
|
|
109
|
+
expect(targets.map(key)).toEqual([
|
|
110
|
+
"dev/us-east-1",
|
|
111
|
+
"dev/eu-west-1",
|
|
112
|
+
"stage/us-east-1"
|
|
113
|
+
]);
|
|
114
|
+
}).pipe(Effect.provide(provide(awsStub({}), configStub([
|
|
115
|
+
{ profile: "dev", regions: ["us-east-1", "eu-west-1"], enabled: true },
|
|
116
|
+
{ profile: "prod", regions: ["us-east-1"], enabled: false },
|
|
117
|
+
{ profile: "stage", regions: ["us-east-1"], enabled: true }
|
|
118
|
+
])))));
|
|
119
|
+
});
|
|
120
|
+
// ── collect: preset matching ─────────────────────────────────────────
|
|
121
|
+
describe("FilterService / collect — preset matching", () => {
|
|
122
|
+
// `conflicting` keeps only non-mergeable PRs.
|
|
123
|
+
it.effect("filters by preset (conflicting)", () => Effect.gen(function* () {
|
|
124
|
+
const fs = yield* FilterService;
|
|
125
|
+
const { failures, prs, unresolvedProfiles } = yield* fs.collect("conflicting", [target("dev")], opts, NOW);
|
|
126
|
+
expect(prs.map((p) => p.id)).toEqual(["2"]);
|
|
127
|
+
expect(failures).toEqual([]);
|
|
128
|
+
expect(unresolvedProfiles).toEqual([]);
|
|
129
|
+
}).pipe(Effect.provide(provide(awsStub({
|
|
130
|
+
prsByTarget: {
|
|
131
|
+
"dev/us-east-1": [mkPR({ id: "1", isMergeable: true }), mkPR({ id: "2", isMergeable: false })]
|
|
132
|
+
}
|
|
133
|
+
}), configStub([{ profile: "dev", regions: ["us-east-1"], enabled: true }])))));
|
|
134
|
+
// `mine` matches only PRs whose author equals the resolved caller for the profile.
|
|
135
|
+
it.effect("filters by preset (mine) using resolved caller identity", () => Effect.gen(function* () {
|
|
136
|
+
const fs = yield* FilterService;
|
|
137
|
+
const { prs, unresolvedProfiles } = yield* fs.collect("mine", [target("dev")], opts, NOW);
|
|
138
|
+
expect(prs.map((p) => p.id)).toEqual(["mine"]);
|
|
139
|
+
expect(unresolvedProfiles).toEqual([]);
|
|
140
|
+
}).pipe(Effect.provide(provide(awsStub({
|
|
141
|
+
prsByTarget: {
|
|
142
|
+
"dev/us-east-1": [mkPR({ id: "mine", author: "alice" }), mkPR({ id: "theirs", author: "bob" })]
|
|
143
|
+
},
|
|
144
|
+
callerByProfile: { dev: "alice" }
|
|
145
|
+
}), configStub([{ profile: "dev", regions: ["us-east-1"], enabled: true }])))));
|
|
146
|
+
});
|
|
147
|
+
// ── collect: per-account failure collection ──────────────────────────
|
|
148
|
+
describe("FilterService / collect — failure collection", () => {
|
|
149
|
+
// One account errors: it lands in `failures` with a profile/region prefix;
|
|
150
|
+
// the other account's PRs are still returned.
|
|
151
|
+
it.effect("collects per-account failures while returning healthy accounts", () => Effect.gen(function* () {
|
|
152
|
+
const fs = yield* FilterService;
|
|
153
|
+
const { failures, prs } = yield* fs.collect("conflicting", [target("dev"), target("prod")], opts, NOW);
|
|
154
|
+
expect(prs.map((p) => p.id)).toEqual(["ok"]);
|
|
155
|
+
expect(failures).toHaveLength(1);
|
|
156
|
+
expect(failures[0]).toMatch(/^prod\/us-east-1: /);
|
|
157
|
+
}).pipe(Effect.provide(provide(awsStub({
|
|
158
|
+
prsByTarget: { "dev/us-east-1": [mkPR({ id: "ok", profile: "dev", isMergeable: false })] },
|
|
159
|
+
failTargets: ["prod/us-east-1"]
|
|
160
|
+
}), configStub([
|
|
161
|
+
{ profile: "dev", regions: ["us-east-1"], enabled: true },
|
|
162
|
+
{ profile: "prod", regions: ["us-east-1"], enabled: true }
|
|
163
|
+
])))));
|
|
164
|
+
});
|
|
165
|
+
// ── collect: unresolved-identity tracking ────────────────────────────
|
|
166
|
+
describe("FilterService / collect — unresolved identity", () => {
|
|
167
|
+
// getCallerIdentity fails for `prod` → its profile appears in unresolvedProfiles,
|
|
168
|
+
// the scan continues, and the profile with a resolved caller still matches.
|
|
169
|
+
it.effect("tracks unresolved profiles and keeps scanning", () => Effect.gen(function* () {
|
|
170
|
+
const fs = yield* FilterService;
|
|
171
|
+
const { failures, prs, unresolvedProfiles } = yield* fs.collect("mine", [target("dev"), target("prod")], opts, NOW);
|
|
172
|
+
expect(prs.map((p) => p.id)).toEqual(["dev-mine"]);
|
|
173
|
+
expect(unresolvedProfiles).toEqual(["prod"]);
|
|
174
|
+
// The fetch itself did not fail — only identity resolution did.
|
|
175
|
+
expect(failures).toEqual([]);
|
|
176
|
+
}).pipe(Effect.provide(provide(awsStub({
|
|
177
|
+
prsByTarget: {
|
|
178
|
+
"dev/us-east-1": [mkPR({ id: "dev-mine", profile: "dev", author: "alice" })],
|
|
179
|
+
"prod/us-east-1": [mkPR({ id: "prod-pr", profile: "prod", author: "carol" })]
|
|
180
|
+
},
|
|
181
|
+
callerByProfile: { dev: "alice", prod: null }
|
|
182
|
+
}), configStub([
|
|
183
|
+
{ profile: "dev", regions: ["us-east-1"], enabled: true },
|
|
184
|
+
{ profile: "prod", regions: ["us-east-1"], enabled: true }
|
|
185
|
+
])))));
|
|
186
|
+
});
|
|
187
|
+
// ── collect: sort order ──────────────────────────────────────────────
|
|
188
|
+
describe("FilterService / collect — sort order", () => {
|
|
189
|
+
// Results are sorted by lastModifiedDate descending across all accounts.
|
|
190
|
+
it.effect("sorts merged results by lastModifiedDate descending", () => Effect.gen(function* () {
|
|
191
|
+
const fs = yield* FilterService;
|
|
192
|
+
const { prs } = yield* fs.collect("conflicting", [target("dev"), target("prod")], opts, NOW);
|
|
193
|
+
expect(prs.map((p) => p.id)).toEqual(["newest", "middle", "oldest"]);
|
|
194
|
+
}).pipe(Effect.provide(provide(awsStub({
|
|
195
|
+
prsByTarget: {
|
|
196
|
+
"dev/us-east-1": [
|
|
197
|
+
mkPR({ id: "oldest", profile: "dev", isMergeable: false, lastModifiedDate: new Date("2024-01-01") }),
|
|
198
|
+
mkPR({ id: "newest", profile: "dev", isMergeable: false, lastModifiedDate: new Date("2024-06-01") })
|
|
199
|
+
],
|
|
200
|
+
"prod/us-east-1": [
|
|
201
|
+
mkPR({ id: "middle", profile: "prod", isMergeable: false, lastModifiedDate: new Date("2024-03-01") })
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
}), configStub([
|
|
205
|
+
{ profile: "dev", regions: ["us-east-1"], enabled: true },
|
|
206
|
+
{ profile: "prod", regions: ["us-east-1"], enabled: true }
|
|
207
|
+
])))));
|
|
208
|
+
});
|
|
209
|
+
//# sourceMappingURL=FilterService.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterService.test.js","sourceRoot":"","sources":["../../test/FilterService.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.test.d.ts","sourceRoot":"","sources":["../../test/bin.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
const binPath = new URL("../src/bin.ts", import.meta.url);
|
|
4
|
+
const repoRoot = new URL("../../..", import.meta.url);
|
|
5
|
+
const runCodecommit = (args) => new Promise((resolve) => {
|
|
6
|
+
execFile("bash", ["-c", "bun \"$CODECOMMIT_BIN\" \"$@\"", "codecommit", ...args], {
|
|
7
|
+
cwd: repoRoot,
|
|
8
|
+
encoding: "utf8",
|
|
9
|
+
env: {
|
|
10
|
+
...process.env,
|
|
11
|
+
CODECOMMIT_BIN: binPath.pathname
|
|
12
|
+
},
|
|
13
|
+
timeout: 10_000
|
|
14
|
+
}, (error, stdout, stderr) => {
|
|
15
|
+
const code = typeof error?.code === "number" ? error.code : error ? 1 : 0;
|
|
16
|
+
resolve({ code, stderr, stdout });
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
const hasBun = () => new Promise((resolve) => {
|
|
20
|
+
execFile("bash", ["-c", "command -v bun"], { encoding: "utf8" }, (error) => {
|
|
21
|
+
resolve(error === null);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe("codecommit CLI", () => {
|
|
25
|
+
it("prints help without an Undici teardown crash", async () => {
|
|
26
|
+
if (!(await hasBun()))
|
|
27
|
+
return;
|
|
28
|
+
const result = await runCodecommit(["--help"]);
|
|
29
|
+
expect(result.code).toBe(0);
|
|
30
|
+
expect(result.stdout).toContain("USAGE");
|
|
31
|
+
expect(result.stdout).toContain("codecommit <subcommand> [flags]");
|
|
32
|
+
expect(result.stdout).not.toContain("dispatcher.destroy");
|
|
33
|
+
expect(result.stderr).toBe("");
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=bin.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.test.js","sourceRoot":"","sources":["../../test/bin.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAQ7C,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACzD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAErD,MAAM,aAAa,GAAG,CAAC,IAA2B,EAAsB,EAAE,CACxE,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;IACtB,QAAQ,CACN,MAAM,EACN,CAAC,IAAI,EAAE,gCAAgC,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,EAC/D;QACE,GAAG,EAAE,QAAQ;QACb,QAAQ,EAAE,MAAM;QAChB,GAAG,EAAE;YACH,GAAG,OAAO,CAAC,GAAG;YACd,cAAc,EAAE,OAAO,CAAC,QAAQ;SACjC;QACD,OAAO,EAAE,MAAM;KAChB,EACD,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QACxB,MAAM,IAAI,GAAG,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACzE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACnC,CAAC,CACF,CAAA;AACH,CAAC,CAAC,CAAA;AAEJ,MAAM,MAAM,GAAG,GAAqB,EAAE,CACpC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;IACtB,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE;QACzE,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEJ,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,IAAI,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC;YAAE,OAAM;QAE7B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;QAE9C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC3B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QACxC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAA;QAClE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAA;QACzD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filterPresets.test.d.ts","sourceRoot":"","sources":["../../test/filterPresets.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter-preset matching unit tests.
|
|
3
|
+
*
|
|
4
|
+
* `matchesPreset` (in `src/filterPresets.ts`) decides whether a PR belongs to a named
|
|
5
|
+
* `--filter` preset. It is pure given an injected `now` and a per-profile
|
|
6
|
+
* caller-identity map, so we can exercise every preset deterministically:
|
|
7
|
+
*
|
|
8
|
+
* - `mine` — author equals the resolved caller for the PR's profile
|
|
9
|
+
* - `needs-my-review` — caller is in an unsatisfied approval pool, not yet approved
|
|
10
|
+
* - `stale` — last activity strictly older than the 7-day boundary
|
|
11
|
+
* - `conflicting` — PR is not mergeable
|
|
12
|
+
*
|
|
13
|
+
* Fixtures are built with `Schema.decodeSync(PullRequest)` — the synchronous
|
|
14
|
+
* decoder for the `PullRequest` Schema.Class — so they are real branded domain
|
|
15
|
+
* objects (no casts), and `mkPR` is a plain synchronous helper.
|
|
16
|
+
*
|
|
17
|
+
* Uses `@effect/vitest` for consistency with the rest of the codebase.
|
|
18
|
+
*/
|
|
19
|
+
import { describe, expect, it } from "@effect/vitest";
|
|
20
|
+
import { identityMatches, PullRequest } from "@knpkv/codecommit-core/Domain.js";
|
|
21
|
+
import { Schema } from "effect";
|
|
22
|
+
import { matchesPreset } from "../src/filterPresets.js";
|
|
23
|
+
// ── Fixtures ─────────────────────────────────────────────────────────
|
|
24
|
+
const NOW = new Date("2024-06-19T12:00:00Z");
|
|
25
|
+
const STALE_MS = 86_400_000;
|
|
26
|
+
const mkPR = (o = {}) => Schema.decodeSync(PullRequest)({
|
|
27
|
+
id: "123",
|
|
28
|
+
title: "Add feature",
|
|
29
|
+
author: o.author ?? "alice",
|
|
30
|
+
repositoryName: "my-repo",
|
|
31
|
+
creationDate: new Date("2024-06-01"),
|
|
32
|
+
lastModifiedDate: o.lastModifiedDate ?? NOW,
|
|
33
|
+
link: "https://console.aws.amazon.com",
|
|
34
|
+
account: { profile: o.profile ?? "dev", region: "us-east-1" },
|
|
35
|
+
status: "OPEN",
|
|
36
|
+
sourceBranch: "feature/x",
|
|
37
|
+
destinationBranch: "main",
|
|
38
|
+
isMergeable: o.isMergeable ?? true,
|
|
39
|
+
isApproved: false,
|
|
40
|
+
approvedBy: o.approvedBy ?? [],
|
|
41
|
+
commentedBy: [],
|
|
42
|
+
approvalRules: o.approvalRules ?? []
|
|
43
|
+
});
|
|
44
|
+
const callers = (entries) => new Map(entries);
|
|
45
|
+
// ── mine ─────────────────────────────────────────────────────────────
|
|
46
|
+
describe("matchesPreset / mine", () => {
|
|
47
|
+
// Author equals the resolved caller for the PR's profile → match.
|
|
48
|
+
it("matches a PR authored by the resolved caller", () => {
|
|
49
|
+
const pr = mkPR({ profile: "dev", author: "alice" });
|
|
50
|
+
expect(matchesPreset("mine", pr, callers([["dev", "alice"]]), NOW)).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
// Author differs from the caller → no match.
|
|
53
|
+
it("does not match a PR authored by someone else", () => {
|
|
54
|
+
const pr = mkPR({ profile: "dev", author: "bob" });
|
|
55
|
+
expect(matchesPreset("mine", pr, callers([["dev", "alice"]]), NOW)).toBe(false);
|
|
56
|
+
});
|
|
57
|
+
// No resolved caller for the PR's profile (e.g. identity lookup failed) → no match.
|
|
58
|
+
it("does not match when the profile has no resolved caller", () => {
|
|
59
|
+
const pr = mkPR({ profile: "prod", author: "alice" });
|
|
60
|
+
expect(matchesPreset("mine", pr, callers([["dev", "alice"]]), NOW)).toBe(false);
|
|
61
|
+
});
|
|
62
|
+
// SSO: caller resolved to a full assumed-role ARN whose session segment is the author → match.
|
|
63
|
+
it("matches when the caller is an ARN whose final segment is the author (SSO)", () => {
|
|
64
|
+
const pr = mkPR({ profile: "dev", author: "alice" });
|
|
65
|
+
const me = "arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_Admin_abc123/alice";
|
|
66
|
+
expect(matchesPreset("mine", pr, callers([["dev", me]]), NOW)).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
// ── identityMatches (robust SSO/ARN comparison) ──────────────────────
|
|
70
|
+
describe("identityMatches", () => {
|
|
71
|
+
// Exact match still works (superset of the original strict comparison).
|
|
72
|
+
it("matches identical usernames", () => {
|
|
73
|
+
expect(identityMatches("alice", "alice")).toBe(true);
|
|
74
|
+
});
|
|
75
|
+
// Case-insensitive: IAM/SSO identities differ only in case.
|
|
76
|
+
it("matches case-insensitively", () => {
|
|
77
|
+
expect(identityMatches("Alice", "alice")).toBe(true);
|
|
78
|
+
expect(identityMatches("ALICE@CORP.COM", "alice@corp.com")).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
// Caller is a full assumed-role ARN; author is the bare session-name/username.
|
|
81
|
+
it("matches an ARN whose final segment equals the author", () => {
|
|
82
|
+
expect(identityMatches("arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_Admin_abc/alice", "alice")).toBe(true);
|
|
83
|
+
});
|
|
84
|
+
// Author is the AWSReservedSSO role-session form; caller is the bare username.
|
|
85
|
+
it("matches when the author carries the role-session-name form", () => {
|
|
86
|
+
expect(identityMatches("alice", "AWSReservedSSO_Admin_abc/alice")).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
// A clearly-different user must NOT match, even with shared ARN structure.
|
|
89
|
+
it("does not match a different user", () => {
|
|
90
|
+
expect(identityMatches("alice", "bob")).toBe(false);
|
|
91
|
+
expect(identityMatches("arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_Admin_abc/alice", "bob")).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
// Empty inputs never match (guards against null/empty identity resolving to a match).
|
|
94
|
+
it("does not match on empty inputs", () => {
|
|
95
|
+
expect(identityMatches("", "alice")).toBe(false);
|
|
96
|
+
expect(identityMatches("alice", "")).toBe(false);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
// ── needs-my-review ──────────────────────────────────────────────────
|
|
100
|
+
describe("matchesPreset / needs-my-review", () => {
|
|
101
|
+
// Caller is in an unsatisfied approval pool and has not approved → match.
|
|
102
|
+
it("matches when caller is in an unsatisfied approval pool", () => {
|
|
103
|
+
const pr = mkPR({
|
|
104
|
+
profile: "dev",
|
|
105
|
+
approvalRules: [{ ruleName: "R1", requiredApprovals: 1, poolMembers: ["alice"], satisfied: false }]
|
|
106
|
+
});
|
|
107
|
+
expect(matchesPreset("needs-my-review", pr, callers([["dev", "alice"]]), NOW)).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
// Caller already approved → no match.
|
|
110
|
+
it("does not match when caller already approved", () => {
|
|
111
|
+
const pr = mkPR({
|
|
112
|
+
profile: "dev",
|
|
113
|
+
approvedBy: ["alice"],
|
|
114
|
+
approvalRules: [{ ruleName: "R1", requiredApprovals: 1, poolMembers: ["alice"], satisfied: false }]
|
|
115
|
+
});
|
|
116
|
+
expect(matchesPreset("needs-my-review", pr, callers([["dev", "alice"]]), NOW)).toBe(false);
|
|
117
|
+
});
|
|
118
|
+
// Caller is not in any pool → no match.
|
|
119
|
+
it("does not match when caller is not in any approval pool", () => {
|
|
120
|
+
const pr = mkPR({
|
|
121
|
+
profile: "dev",
|
|
122
|
+
approvalRules: [{ ruleName: "R1", requiredApprovals: 1, poolMembers: ["bob"], satisfied: false }]
|
|
123
|
+
});
|
|
124
|
+
expect(matchesPreset("needs-my-review", pr, callers([["dev", "alice"]]), NOW)).toBe(false);
|
|
125
|
+
});
|
|
126
|
+
// No resolved caller for the profile → no match (needsMyReview returns false for undefined).
|
|
127
|
+
it("does not match when the profile has no resolved caller", () => {
|
|
128
|
+
const pr = mkPR({
|
|
129
|
+
profile: "prod",
|
|
130
|
+
approvalRules: [{ ruleName: "R1", requiredApprovals: 1, poolMembers: ["alice"], satisfied: false }]
|
|
131
|
+
});
|
|
132
|
+
expect(matchesPreset("needs-my-review", pr, callers([["dev", "alice"]]), NOW)).toBe(false);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
// ── stale (7-day boundary) ───────────────────────────────────────────
|
|
136
|
+
describe("matchesPreset / stale", () => {
|
|
137
|
+
// Just over 7 days (7 days + 1ms) of inactivity → stale.
|
|
138
|
+
it("matches a PR just past the 7-day boundary", () => {
|
|
139
|
+
const pr = mkPR({ lastModifiedDate: new Date(NOW.getTime() - (7 * STALE_MS + 1)) });
|
|
140
|
+
expect(matchesPreset("stale", pr, callers([]), NOW)).toBe(true);
|
|
141
|
+
});
|
|
142
|
+
// Exactly 7 days is NOT stale — the predicate is strictly greater than 7.
|
|
143
|
+
it("does not match a PR at exactly the 7-day boundary", () => {
|
|
144
|
+
const pr = mkPR({ lastModifiedDate: new Date(NOW.getTime() - 7 * STALE_MS) });
|
|
145
|
+
expect(matchesPreset("stale", pr, callers([]), NOW)).toBe(false);
|
|
146
|
+
});
|
|
147
|
+
// Recently modified → not stale.
|
|
148
|
+
it("does not match a freshly modified PR", () => {
|
|
149
|
+
const pr = mkPR({ lastModifiedDate: NOW });
|
|
150
|
+
expect(matchesPreset("stale", pr, callers([]), NOW)).toBe(false);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
// ── conflicting ──────────────────────────────────────────────────────
|
|
154
|
+
describe("matchesPreset / conflicting", () => {
|
|
155
|
+
// Not mergeable → conflicting.
|
|
156
|
+
it("matches a non-mergeable PR", () => {
|
|
157
|
+
const pr = mkPR({ isMergeable: false });
|
|
158
|
+
expect(matchesPreset("conflicting", pr, callers([]), NOW)).toBe(true);
|
|
159
|
+
});
|
|
160
|
+
// Mergeable → not conflicting.
|
|
161
|
+
it("does not match a mergeable PR", () => {
|
|
162
|
+
const pr = mkPR({ isMergeable: true });
|
|
163
|
+
expect(matchesPreset("conflicting", pr, callers([]), NOW)).toBe(false);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
//# sourceMappingURL=filterPresets.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filterPresets.test.js","sourceRoot":"","sources":["../../test/filterPresets.test.ts"],"names":[],"mappings":"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"}
|