Skip to content

Commit 0dc86d3

Browse files
coopernetesGitHub Copilot
andcommitted
test: add unit tests for core validation, filters, and hooks
- AuthorEmailCheck: domain allow/block, local-part block, deduplication - CommitMessageCheck: blocked literals/patterns, empty message, multi-commit - ValidationContext: issue collection, order, immutability - CheckEmptyBranchHook: new/existing branch, DELETE skipped, PASS step recorded - ValidationSummaryFilter: REJECTED sends error, PENDING passes, multi-step count - AllowApprovedPushFilter: pre-approved lookup, service URL stamped, blank commitTo - CheckEmptyBranchFilter: commits present passes, no-commit cases blocked - SmartHttpErrorFilter: 4xx/5xx → 200, 401 passes through, non-git untouched - InMemoryPushStore: save/find/delete, query filters, approve/reject/cancel Jacoco: wire check → jacocoTestReport in core; add jacocoAggregation deps in server and dashboard so testCodeCoverageReport includes core (and server) classes Co-authored-by: GitHub Copilot <copilot@github.com>
1 parent 8435685 commit 0dc86d3

13 files changed

Lines changed: 1381 additions & 3 deletions

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,13 @@ allprojects {
1414
repositories {
1515
mavenCentral()
1616
maven {
17-
url 'https://repo.eclipse.org/content/groups/releases/'
17+
url = 'https://repo.eclipse.org/content/groups/releases/'
1818
}
1919
}
2020
dependencyCheck {
2121
nvd.apiKey = System.getenv("NVD_API_KEY")
2222
failBuildOnCVSS = 5
2323
suppressionFile = rootProject.file('gradle-suppressions.xml').toString()
24-
2524
}
2625
}
2726

@@ -37,6 +36,7 @@ tasks.register('installGitHooks') {
3736

3837
subprojects {
3938
apply plugin: 'com.diffplug.spotless'
39+
apply plugin: 'jacoco-report-aggregation'
4040

4141
spotless {
4242
java {

jgit-proxy-core/build.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ java {
2020
repositories {
2121
mavenCentral()
2222
maven {
23-
url 'https://repo.eclipse.org/content/groups/releases/'
23+
url = 'https://repo.eclipse.org/content/groups/releases/'
2424
}
2525
}
2626

@@ -107,6 +107,10 @@ tasks.named('test') {
107107
useJUnitPlatform()
108108
}
109109

110+
tasks.named('check') {
111+
dependsOn jacocoTestReport
112+
}
113+
110114
// ---------------------------------------------------------------------------
111115
// Hermetic gitleaks bundling
112116
// ---------------------------------------------------------------------------
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
package org.finos.gitproxy.db.memory;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import java.util.List;
6+
import java.util.Optional;
7+
import org.finos.gitproxy.db.model.Attestation;
8+
import org.finos.gitproxy.db.model.PushQuery;
9+
import org.finos.gitproxy.db.model.PushRecord;
10+
import org.finos.gitproxy.db.model.PushStatus;
11+
import org.junit.jupiter.api.BeforeEach;
12+
import org.junit.jupiter.api.Test;
13+
14+
class InMemoryPushStoreTest {
15+
16+
InMemoryPushStore store;
17+
18+
@BeforeEach
19+
void setUp() {
20+
store = new InMemoryPushStore();
21+
}
22+
23+
private static PushRecord record(String commitTo, String branch, String repoName) {
24+
return PushRecord.builder()
25+
.commitTo(commitTo)
26+
.branch(branch)
27+
.repoName(repoName)
28+
.user("dev")
29+
.authorEmail("dev@example.com")
30+
.build();
31+
}
32+
33+
private static Attestation approvalFor(String pushId) {
34+
return Attestation.builder()
35+
.pushId(pushId)
36+
.type(Attestation.Type.APPROVAL)
37+
.reviewerUsername("reviewer")
38+
.build();
39+
}
40+
41+
// ---- save / findById ----
42+
43+
@Test
44+
void saveAndFindById_returnsRecord() {
45+
PushRecord r = record("abc", "refs/heads/main", "repo");
46+
store.save(r);
47+
Optional<PushRecord> found = store.findById(r.getId());
48+
assertTrue(found.isPresent());
49+
assertEquals(r.getId(), found.get().getId());
50+
}
51+
52+
@Test
53+
void findById_unknownId_returnsEmpty() {
54+
assertTrue(store.findById("does-not-exist").isEmpty());
55+
}
56+
57+
@Test
58+
void save_overwritesExistingRecord() {
59+
PushRecord r = record("abc", "refs/heads/main", "repo");
60+
store.save(r);
61+
r.setUser("updated-user");
62+
store.save(r);
63+
assertEquals("updated-user", store.findById(r.getId()).get().getUser());
64+
}
65+
66+
// ---- delete ----
67+
68+
@Test
69+
void delete_removesRecord() {
70+
PushRecord r = record("abc", "refs/heads/main", "repo");
71+
store.save(r);
72+
store.delete(r.getId());
73+
assertTrue(store.findById(r.getId()).isEmpty());
74+
}
75+
76+
// ---- find with query ----
77+
78+
@Test
79+
void find_byStatus_returnsMatchingRecords() {
80+
PushRecord pending = record("a", "refs/heads/main", "repo");
81+
PushRecord approved = record("b", "refs/heads/main", "repo");
82+
store.save(pending);
83+
store.save(approved);
84+
store.approve(approved.getId(), approvalFor(approved.getId()));
85+
86+
List<PushRecord> results =
87+
store.find(PushQuery.builder().status(PushStatus.APPROVED).build());
88+
assertEquals(1, results.size());
89+
assertEquals(approved.getId(), results.get(0).getId());
90+
}
91+
92+
@Test
93+
void find_byRepoName_returnsMatchingRecords() {
94+
store.save(record("a", "refs/heads/main", "repoA"));
95+
store.save(record("b", "refs/heads/main", "repoB"));
96+
97+
List<PushRecord> results =
98+
store.find(PushQuery.builder().repoName("repoA").build());
99+
assertEquals(1, results.size());
100+
assertEquals("repoA", results.get(0).getRepoName());
101+
}
102+
103+
@Test
104+
void find_byBranch_returnsMatchingRecords() {
105+
store.save(record("a", "refs/heads/feature", "repo"));
106+
store.save(record("b", "refs/heads/main", "repo"));
107+
108+
List<PushRecord> results =
109+
store.find(PushQuery.builder().branch("refs/heads/feature").build());
110+
assertEquals(1, results.size());
111+
}
112+
113+
@Test
114+
void find_byCommitTo_returnsMatchingRecord() {
115+
store.save(record("commitXYZ", "refs/heads/main", "repo"));
116+
store.save(record("commitABC", "refs/heads/main", "repo"));
117+
118+
List<PushRecord> results =
119+
store.find(PushQuery.builder().commitTo("commitXYZ").build());
120+
assertEquals(1, results.size());
121+
assertEquals("commitXYZ", results.get(0).getCommitTo());
122+
}
123+
124+
@Test
125+
void find_withLimit_returnsAtMostLimitRecords() {
126+
for (int i = 0; i < 10; i++) {
127+
store.save(record("commit" + i, "refs/heads/main", "repo"));
128+
}
129+
List<PushRecord> results = store.find(PushQuery.builder().limit(3).build());
130+
assertEquals(3, results.size());
131+
}
132+
133+
@Test
134+
void find_emptyStore_returnsEmptyList() {
135+
assertTrue(store.find(PushQuery.builder().build()).isEmpty());
136+
}
137+
138+
// ---- approve / reject / cancel ----
139+
140+
@Test
141+
void approve_changesStatusToApproved() {
142+
PushRecord r = record("abc", "refs/heads/main", "repo");
143+
store.save(r);
144+
145+
PushRecord updated = store.approve(r.getId(), approvalFor(r.getId()));
146+
147+
assertEquals(PushStatus.APPROVED, updated.getStatus());
148+
assertEquals(PushStatus.APPROVED, store.findById(r.getId()).get().getStatus());
149+
}
150+
151+
@Test
152+
void reject_changesStatusToRejected() {
153+
PushRecord r = record("abc", "refs/heads/main", "repo");
154+
store.save(r);
155+
156+
Attestation rejection = Attestation.builder()
157+
.pushId(r.getId())
158+
.type(Attestation.Type.REJECTION)
159+
.reviewerUsername("reviewer")
160+
.reason("Policy violation")
161+
.build();
162+
PushRecord updated = store.reject(r.getId(), rejection);
163+
164+
assertEquals(PushStatus.REJECTED, updated.getStatus());
165+
}
166+
167+
@Test
168+
void cancel_changesStatusToCanceled() {
169+
PushRecord r = record("abc", "refs/heads/main", "repo");
170+
store.save(r);
171+
172+
Attestation cancellation = Attestation.builder()
173+
.pushId(r.getId())
174+
.type(Attestation.Type.CANCELLATION)
175+
.reviewerUsername("dev")
176+
.build();
177+
PushRecord updated = store.cancel(r.getId(), cancellation);
178+
179+
assertEquals(PushStatus.CANCELED, updated.getStatus());
180+
}
181+
182+
@Test
183+
void approve_unknownId_throwsException() {
184+
assertThrows(Exception.class, () -> store.approve("not-a-real-id", approvalFor("not-a-real-id")));
185+
}
186+
187+
// ---- initialize (no-op for in-memory) ----
188+
189+
@Test
190+
void initialize_doesNotThrow() {
191+
assertDoesNotThrow(() -> store.initialize());
192+
}
193+
194+
// ---- concurrent safety (basic) ----
195+
196+
@Test
197+
void multipleSaves_allVisible() {
198+
for (int i = 0; i < 20; i++) {
199+
store.save(record("commit" + i, "refs/heads/main", "repo"));
200+
}
201+
List<PushRecord> all = store.find(PushQuery.builder().limit(100).build());
202+
assertEquals(20, all.size());
203+
}
204+
}

0 commit comments

Comments
 (0)