@spaceflow/review 0.30.0 → 0.32.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/CHANGELOG.md +90 -0
- package/dist/index.js +161 -52
- package/package.json +3 -3
- package/src/index.ts +7 -2
- package/src/locales/en/review.json +1 -0
- package/src/locales/zh-cn/review.json +1 -0
- package/src/review.config.ts +2 -0
- package/src/review.service.spec.ts +123 -63
- package/src/review.service.ts +159 -58
|
@@ -60,14 +60,22 @@ describe("ReviewService", () => {
|
|
|
60
60
|
getPullRequestCommits: vi.fn(),
|
|
61
61
|
getPullRequestFiles: vi.fn(),
|
|
62
62
|
getFileContent: vi.fn(),
|
|
63
|
-
listPullReviews: vi.fn(),
|
|
64
|
-
createPullReview: vi.fn(),
|
|
65
|
-
deletePullReview: vi.fn(),
|
|
63
|
+
listPullReviews: vi.fn().mockResolvedValue([]),
|
|
64
|
+
createPullReview: vi.fn().mockResolvedValue({}),
|
|
65
|
+
deletePullReview: vi.fn().mockResolvedValue(undefined),
|
|
66
|
+
deletePullReviewComment: vi.fn().mockResolvedValue(undefined),
|
|
67
|
+
listResolvedThreads: vi.fn().mockResolvedValue([]),
|
|
66
68
|
editPullRequest: vi.fn(),
|
|
67
69
|
getCommitDiff: vi.fn(),
|
|
68
70
|
listPullReviewComments: vi.fn(),
|
|
69
71
|
searchUsers: vi.fn().mockResolvedValue([]),
|
|
70
72
|
getIssueCommentReactions: vi.fn().mockResolvedValue([]),
|
|
73
|
+
getPullReviewCommentReactions: vi.fn().mockResolvedValue([]),
|
|
74
|
+
listIssueComments: vi.fn().mockResolvedValue([]),
|
|
75
|
+
createIssueComment: vi.fn().mockResolvedValue({}),
|
|
76
|
+
updateIssueComment: vi.fn().mockResolvedValue({}),
|
|
77
|
+
deleteIssueComment: vi.fn().mockResolvedValue(undefined),
|
|
78
|
+
updatePullReview: vi.fn().mockResolvedValue({}),
|
|
71
79
|
};
|
|
72
80
|
|
|
73
81
|
configService = {
|
|
@@ -316,12 +324,13 @@ describe("ReviewService", () => {
|
|
|
316
324
|
gitProvider.getPullRequestCommits.mockResolvedValue(mockCommits);
|
|
317
325
|
gitProvider.getPullRequestFiles.mockResolvedValue(mockFiles);
|
|
318
326
|
gitProvider.getFileContent.mockResolvedValue("const test = 1;");
|
|
327
|
+
gitProvider.listIssueComments.mockResolvedValue([]);
|
|
319
328
|
gitProvider.listPullReviews.mockResolvedValue([]);
|
|
320
|
-
gitProvider.
|
|
329
|
+
gitProvider.createIssueComment.mockResolvedValue({});
|
|
321
330
|
|
|
322
331
|
await service.execute(context);
|
|
323
332
|
|
|
324
|
-
expect(gitProvider.
|
|
333
|
+
expect(gitProvider.createIssueComment).toHaveBeenCalledWith(
|
|
325
334
|
"owner",
|
|
326
335
|
"repo",
|
|
327
336
|
123,
|
|
@@ -501,14 +510,15 @@ describe("ReviewService", () => {
|
|
|
501
510
|
gitProvider.getPullRequest.mockResolvedValue(mockPR as any);
|
|
502
511
|
gitProvider.getPullRequestCommits.mockResolvedValue([]);
|
|
503
512
|
gitProvider.getPullRequestFiles.mockResolvedValue([]);
|
|
513
|
+
gitProvider.listIssueComments.mockResolvedValue([]);
|
|
504
514
|
gitProvider.listPullReviews.mockResolvedValue([]);
|
|
505
|
-
gitProvider.
|
|
515
|
+
gitProvider.createIssueComment.mockResolvedValue({});
|
|
506
516
|
|
|
507
517
|
const result = await service.execute(context);
|
|
508
518
|
|
|
509
519
|
expect(result.success).toBe(true);
|
|
510
520
|
expect(mockDeletionImpactService.analyzeDeletionImpact).toHaveBeenCalled();
|
|
511
|
-
expect(gitProvider.
|
|
521
|
+
expect(gitProvider.createIssueComment).toHaveBeenCalled();
|
|
512
522
|
});
|
|
513
523
|
});
|
|
514
524
|
|
|
@@ -1415,12 +1425,12 @@ describe("ReviewService", () => {
|
|
|
1415
1425
|
expect(result.skippedCount).toBe(1);
|
|
1416
1426
|
});
|
|
1417
1427
|
|
|
1418
|
-
it("should
|
|
1428
|
+
it("should also filter invalid existing issues to prevent repeated reporting", () => {
|
|
1419
1429
|
const newIssues = [{ file: "a.ts", line: "1", ruleId: "R1" }];
|
|
1420
1430
|
const existingIssues = [{ file: "a.ts", line: "1", ruleId: "R1", valid: "false" }];
|
|
1421
1431
|
const result = (service as any).filterDuplicateIssues(newIssues, existingIssues);
|
|
1422
|
-
expect(result.filteredIssues).toHaveLength(
|
|
1423
|
-
expect(result.skippedCount).toBe(
|
|
1432
|
+
expect(result.filteredIssues).toHaveLength(0);
|
|
1433
|
+
expect(result.skippedCount).toBe(1);
|
|
1424
1434
|
});
|
|
1425
1435
|
});
|
|
1426
1436
|
|
|
@@ -1457,7 +1467,7 @@ describe("ReviewService", () => {
|
|
|
1457
1467
|
|
|
1458
1468
|
describe("ReviewService.getExistingReviewResult", () => {
|
|
1459
1469
|
it("should return null when no AI review exists", async () => {
|
|
1460
|
-
gitProvider.
|
|
1470
|
+
gitProvider.listIssueComments.mockResolvedValue([{ body: "normal comment" }] as any);
|
|
1461
1471
|
const result = await (service as any).getExistingReviewResult("o", "r", 1);
|
|
1462
1472
|
expect(result).toBeNull();
|
|
1463
1473
|
});
|
|
@@ -1466,7 +1476,7 @@ describe("ReviewService", () => {
|
|
|
1466
1476
|
const mockResult = { issues: [], summary: [] };
|
|
1467
1477
|
const mockReviewReportService = (service as any).reviewReportService;
|
|
1468
1478
|
mockReviewReportService.parseMarkdown.mockReturnValue({ result: mockResult });
|
|
1469
|
-
gitProvider.
|
|
1479
|
+
gitProvider.listIssueComments.mockResolvedValue([
|
|
1470
1480
|
{ body: "<!-- spaceflow-review --> review content" },
|
|
1471
1481
|
] as any);
|
|
1472
1482
|
const result = await (service as any).getExistingReviewResult("o", "r", 1);
|
|
@@ -1474,26 +1484,49 @@ describe("ReviewService", () => {
|
|
|
1474
1484
|
});
|
|
1475
1485
|
|
|
1476
1486
|
it("should return null on error", async () => {
|
|
1477
|
-
gitProvider.
|
|
1487
|
+
gitProvider.listIssueComments.mockRejectedValue(new Error("API error"));
|
|
1478
1488
|
const result = await (service as any).getExistingReviewResult("o", "r", 1);
|
|
1479
1489
|
expect(result).toBeNull();
|
|
1480
1490
|
});
|
|
1481
1491
|
});
|
|
1482
1492
|
|
|
1483
1493
|
describe("ReviewService.deleteExistingAiReviews", () => {
|
|
1484
|
-
it("should delete AI reviews", async () => {
|
|
1494
|
+
it("should delete AI reviews via review API", async () => {
|
|
1485
1495
|
gitProvider.listPullReviews.mockResolvedValue([
|
|
1486
1496
|
{ id: 1, body: "<!-- spaceflow-review --> old review" },
|
|
1487
1497
|
{ id: 2, body: "normal review" },
|
|
1488
1498
|
] as any);
|
|
1499
|
+
gitProvider.listIssueComments.mockResolvedValue([] as any);
|
|
1489
1500
|
gitProvider.deletePullReview.mockResolvedValue(undefined as any);
|
|
1490
1501
|
await (service as any).deleteExistingAiReviews("o", "r", 1);
|
|
1491
1502
|
expect(gitProvider.deletePullReview).toHaveBeenCalledWith("o", "r", 1, 1);
|
|
1492
1503
|
expect(gitProvider.deletePullReview).toHaveBeenCalledTimes(1);
|
|
1493
1504
|
});
|
|
1494
1505
|
|
|
1495
|
-
it("should
|
|
1506
|
+
it("should delete AI reviews via issue comment API", async () => {
|
|
1507
|
+
gitProvider.listPullReviews.mockResolvedValue([] as any);
|
|
1508
|
+
gitProvider.listIssueComments.mockResolvedValue([
|
|
1509
|
+
{ id: 10, body: "<!-- spaceflow-review --> old comment" },
|
|
1510
|
+
{ id: 11, body: "normal comment" },
|
|
1511
|
+
] as any);
|
|
1512
|
+
gitProvider.deleteIssueComment.mockResolvedValue(undefined as any);
|
|
1513
|
+
await (service as any).deleteExistingAiReviews("o", "r", 1);
|
|
1514
|
+
expect(gitProvider.deleteIssueComment).toHaveBeenCalledWith("o", "r", 10);
|
|
1515
|
+
expect(gitProvider.deleteIssueComment).toHaveBeenCalledTimes(1);
|
|
1516
|
+
});
|
|
1517
|
+
|
|
1518
|
+
it("should handle review API error gracefully", async () => {
|
|
1496
1519
|
gitProvider.listPullReviews.mockRejectedValue(new Error("fail"));
|
|
1520
|
+
gitProvider.listIssueComments.mockResolvedValue([] as any);
|
|
1521
|
+
const consoleSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
1522
|
+
await (service as any).deleteExistingAiReviews("o", "r", 1);
|
|
1523
|
+
expect(consoleSpy).toHaveBeenCalled();
|
|
1524
|
+
consoleSpy.mockRestore();
|
|
1525
|
+
});
|
|
1526
|
+
|
|
1527
|
+
it("should handle issue comment API error gracefully", async () => {
|
|
1528
|
+
gitProvider.listPullReviews.mockResolvedValue([] as any);
|
|
1529
|
+
gitProvider.listIssueComments.mockRejectedValue(new Error("fail"));
|
|
1497
1530
|
const consoleSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
1498
1531
|
await (service as any).deleteExistingAiReviews("o", "r", 1);
|
|
1499
1532
|
expect(consoleSpy).toHaveBeenCalled();
|
|
@@ -1725,35 +1758,35 @@ describe("ReviewService", () => {
|
|
|
1725
1758
|
it("should post review comment", async () => {
|
|
1726
1759
|
const configReader = (service as any).configReader;
|
|
1727
1760
|
configReader.getPluginConfig.mockReturnValue({});
|
|
1728
|
-
gitProvider.
|
|
1761
|
+
gitProvider.listIssueComments.mockResolvedValue([] as any);
|
|
1729
1762
|
gitProvider.listPullReviewComments.mockResolvedValue([] as any);
|
|
1730
1763
|
gitProvider.getPullRequest.mockResolvedValue({ head: { sha: "abc123" } } as any);
|
|
1731
|
-
gitProvider.
|
|
1764
|
+
gitProvider.createIssueComment.mockResolvedValue({} as any);
|
|
1732
1765
|
const result = { issues: [], summary: [], round: 1 };
|
|
1733
1766
|
await (service as any).postOrUpdateReviewComment("o", "r", 1, result);
|
|
1734
|
-
expect(gitProvider.
|
|
1767
|
+
expect(gitProvider.createIssueComment).toHaveBeenCalled();
|
|
1735
1768
|
});
|
|
1736
1769
|
|
|
1737
1770
|
it("should update PR title when autoUpdatePrTitle enabled", async () => {
|
|
1738
1771
|
const configReader = (service as any).configReader;
|
|
1739
1772
|
configReader.getPluginConfig.mockReturnValue({ autoUpdatePrTitle: true });
|
|
1740
|
-
gitProvider.
|
|
1773
|
+
gitProvider.listIssueComments.mockResolvedValue([] as any);
|
|
1741
1774
|
gitProvider.listPullReviewComments.mockResolvedValue([] as any);
|
|
1742
1775
|
gitProvider.editPullRequest.mockResolvedValue({} as any);
|
|
1743
1776
|
gitProvider.getPullRequest.mockResolvedValue({ head: { sha: "abc123" } } as any);
|
|
1744
|
-
gitProvider.
|
|
1777
|
+
gitProvider.createIssueComment.mockResolvedValue({} as any);
|
|
1745
1778
|
const result = { issues: [], summary: [], round: 1, title: "New Title" };
|
|
1746
1779
|
await (service as any).postOrUpdateReviewComment("o", "r", 1, result);
|
|
1747
1780
|
expect(gitProvider.editPullRequest).toHaveBeenCalledWith("o", "r", 1, { title: "New Title" });
|
|
1748
1781
|
});
|
|
1749
1782
|
|
|
1750
|
-
it("should handle
|
|
1783
|
+
it("should handle createIssueComment error gracefully", async () => {
|
|
1751
1784
|
const configReader = (service as any).configReader;
|
|
1752
1785
|
configReader.getPluginConfig.mockReturnValue({});
|
|
1753
|
-
gitProvider.
|
|
1786
|
+
gitProvider.listIssueComments.mockResolvedValue([] as any);
|
|
1754
1787
|
gitProvider.listPullReviewComments.mockResolvedValue([] as any);
|
|
1755
1788
|
gitProvider.getPullRequest.mockResolvedValue({ head: { sha: "abc123" } } as any);
|
|
1756
|
-
gitProvider.
|
|
1789
|
+
gitProvider.createIssueComment.mockRejectedValue(new Error("fail") as any);
|
|
1757
1790
|
const consoleSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
1758
1791
|
const result = { issues: [], summary: [], round: 1 };
|
|
1759
1792
|
await (service as any).postOrUpdateReviewComment("o", "r", 1, result);
|
|
@@ -1765,9 +1798,10 @@ describe("ReviewService", () => {
|
|
|
1765
1798
|
const configReader = (service as any).configReader;
|
|
1766
1799
|
configReader.getPluginConfig.mockReturnValue({ lineComments: true });
|
|
1767
1800
|
mockReviewSpecService.parseLineRange = vi.fn().mockReturnValue([10]);
|
|
1768
|
-
gitProvider.
|
|
1801
|
+
gitProvider.listIssueComments.mockResolvedValue([] as any);
|
|
1769
1802
|
gitProvider.listPullReviewComments.mockResolvedValue([] as any);
|
|
1770
1803
|
gitProvider.getPullRequest.mockResolvedValue({ head: { sha: "abc123" } } as any);
|
|
1804
|
+
gitProvider.createIssueComment.mockResolvedValue({} as any);
|
|
1771
1805
|
gitProvider.createPullReview.mockResolvedValue({} as any);
|
|
1772
1806
|
const result = {
|
|
1773
1807
|
issues: [
|
|
@@ -1784,6 +1818,7 @@ describe("ReviewService", () => {
|
|
|
1784
1818
|
round: 1,
|
|
1785
1819
|
};
|
|
1786
1820
|
await (service as any).postOrUpdateReviewComment("o", "r", 1, result);
|
|
1821
|
+
expect(gitProvider.createPullReview.mock.calls.length).toBeGreaterThan(0);
|
|
1787
1822
|
const callArgs = gitProvider.createPullReview.mock.calls[0];
|
|
1788
1823
|
expect(callArgs[3].comments.length).toBeGreaterThan(0);
|
|
1789
1824
|
});
|
|
@@ -1792,39 +1827,32 @@ describe("ReviewService", () => {
|
|
|
1792
1827
|
describe("ReviewService.syncResolvedComments", () => {
|
|
1793
1828
|
it("should mark matched issues as fixed", async () => {
|
|
1794
1829
|
mockReviewSpecService.parseLineRange = vi.fn().mockReturnValue([10]);
|
|
1795
|
-
gitProvider.
|
|
1796
|
-
{
|
|
1797
|
-
] as any);
|
|
1798
|
-
gitProvider.listPullReviewComments.mockResolvedValue([
|
|
1799
|
-
{ path: "test.ts", position: 10, resolver: { login: "user1" } },
|
|
1830
|
+
gitProvider.listResolvedThreads.mockResolvedValue([
|
|
1831
|
+
{ path: "test.ts", line: 10, resolvedBy: { login: "user1" } },
|
|
1800
1832
|
] as any);
|
|
1801
1833
|
const result = { issues: [{ file: "test.ts", line: "10" }] };
|
|
1802
1834
|
await (service as any).syncResolvedComments("o", "r", 1, result);
|
|
1803
1835
|
expect((result.issues[0] as any).fixed).toBeDefined();
|
|
1804
1836
|
});
|
|
1805
1837
|
|
|
1806
|
-
it("should skip
|
|
1807
|
-
|
|
1808
|
-
gitProvider.listPullReviews.mockResolvedValue([
|
|
1809
|
-
{ id: 1, body: "<!-- spaceflow-review --> content" },
|
|
1810
|
-
] as any);
|
|
1811
|
-
gitProvider.listPullReviewComments.mockResolvedValue([
|
|
1812
|
-
{ path: "test.ts", position: 10, resolver: null },
|
|
1813
|
-
] as any);
|
|
1838
|
+
it("should skip when no resolved threads", async () => {
|
|
1839
|
+
gitProvider.listResolvedThreads.mockResolvedValue([] as any);
|
|
1814
1840
|
const result = { issues: [{ file: "test.ts", line: "10" }] };
|
|
1815
1841
|
await (service as any).syncResolvedComments("o", "r", 1, result);
|
|
1816
1842
|
expect((result.issues[0] as any).fixed).toBeUndefined();
|
|
1817
1843
|
});
|
|
1818
1844
|
|
|
1819
|
-
it("should skip
|
|
1820
|
-
gitProvider.
|
|
1821
|
-
|
|
1845
|
+
it("should skip threads without path", async () => {
|
|
1846
|
+
gitProvider.listResolvedThreads.mockResolvedValue([
|
|
1847
|
+
{ path: undefined, line: 10, resolvedBy: { login: "user1" } },
|
|
1848
|
+
] as any);
|
|
1849
|
+
const result = { issues: [{ file: "test.ts", line: "10" }] };
|
|
1822
1850
|
await (service as any).syncResolvedComments("o", "r", 1, result);
|
|
1823
|
-
expect(result.issues[0].fixed).
|
|
1851
|
+
expect((result.issues[0] as any).fixed).toBeUndefined();
|
|
1824
1852
|
});
|
|
1825
1853
|
|
|
1826
1854
|
it("should handle error gracefully", async () => {
|
|
1827
|
-
gitProvider.
|
|
1855
|
+
gitProvider.listResolvedThreads.mockRejectedValue(new Error("fail"));
|
|
1828
1856
|
const consoleSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
1829
1857
|
const result = { issues: [] };
|
|
1830
1858
|
await (service as any).syncResolvedComments("o", "r", 1, result);
|
|
@@ -1891,9 +1919,10 @@ describe("ReviewService", () => {
|
|
|
1891
1919
|
const mockReviewReportService = (service as any).reviewReportService;
|
|
1892
1920
|
mockReviewReportService.parseMarkdown.mockReturnValue({ result: mockResult });
|
|
1893
1921
|
mockReviewReportService.formatStatsTerminal = vi.fn().mockReturnValue("stats");
|
|
1894
|
-
gitProvider.
|
|
1895
|
-
{ id:
|
|
1922
|
+
gitProvider.listIssueComments.mockResolvedValue([
|
|
1923
|
+
{ id: 10, body: "<!-- spaceflow-review --> content" },
|
|
1896
1924
|
] as any);
|
|
1925
|
+
gitProvider.listPullReviews.mockResolvedValue([] as any);
|
|
1897
1926
|
gitProvider.listPullReviewComments.mockResolvedValue([] as any);
|
|
1898
1927
|
gitProvider.getPullRequestCommits.mockResolvedValue([] as any);
|
|
1899
1928
|
gitProvider.getPullRequest.mockResolvedValue({} as any);
|
|
@@ -1904,6 +1933,34 @@ describe("ReviewService", () => {
|
|
|
1904
1933
|
});
|
|
1905
1934
|
});
|
|
1906
1935
|
|
|
1936
|
+
describe("ReviewService.execute - flush mode", () => {
|
|
1937
|
+
it("should route to executeCollectOnly when flush is true", async () => {
|
|
1938
|
+
const mockResult = { issues: [{ file: "a.ts", line: "1", ruleId: "R1" }], summary: [] };
|
|
1939
|
+
const mockReviewReportService = (service as any).reviewReportService;
|
|
1940
|
+
mockReviewReportService.parseMarkdown.mockReturnValue({ result: mockResult });
|
|
1941
|
+
mockReviewReportService.formatStatsTerminal = vi.fn().mockReturnValue("stats");
|
|
1942
|
+
gitProvider.listIssueComments.mockResolvedValue([
|
|
1943
|
+
{ id: 10, body: "<!-- spaceflow-review --> content" },
|
|
1944
|
+
] as any);
|
|
1945
|
+
gitProvider.listPullReviews.mockResolvedValue([] as any);
|
|
1946
|
+
gitProvider.listPullReviewComments.mockResolvedValue([] as any);
|
|
1947
|
+
gitProvider.getPullRequestCommits.mockResolvedValue([] as any);
|
|
1948
|
+
gitProvider.getPullRequest.mockResolvedValue({} as any);
|
|
1949
|
+
const context = {
|
|
1950
|
+
owner: "o",
|
|
1951
|
+
repo: "r",
|
|
1952
|
+
prNumber: 1,
|
|
1953
|
+
ci: false,
|
|
1954
|
+
dryRun: false,
|
|
1955
|
+
flush: true,
|
|
1956
|
+
specSources: [],
|
|
1957
|
+
};
|
|
1958
|
+
const result = await service.execute(context as any);
|
|
1959
|
+
expect(result.issues).toHaveLength(1);
|
|
1960
|
+
expect(result.stats).toBeDefined();
|
|
1961
|
+
});
|
|
1962
|
+
});
|
|
1963
|
+
|
|
1907
1964
|
describe("ReviewService.executeDeletionOnly", () => {
|
|
1908
1965
|
it("should throw when no llmMode", async () => {
|
|
1909
1966
|
const context = { owner: "o", repo: "r", prNumber: 1, ci: false, dryRun: false };
|
|
@@ -1925,10 +1982,11 @@ describe("ReviewService", () => {
|
|
|
1925
1982
|
gitProvider.getPullRequestFiles.mockResolvedValue([
|
|
1926
1983
|
{ filename: "a.ts", status: "modified" },
|
|
1927
1984
|
] as any);
|
|
1985
|
+
gitProvider.listIssueComments.mockResolvedValue([] as any);
|
|
1928
1986
|
gitProvider.listPullReviews.mockResolvedValue([] as any);
|
|
1929
1987
|
gitProvider.listPullReviewComments.mockResolvedValue([] as any);
|
|
1930
1988
|
gitProvider.getPullRequest.mockResolvedValue({ head: { sha: "abc" } } as any);
|
|
1931
|
-
gitProvider.
|
|
1989
|
+
gitProvider.createIssueComment.mockResolvedValue({} as any);
|
|
1932
1990
|
const configReader = (service as any).configReader;
|
|
1933
1991
|
configReader.getPluginConfig.mockReturnValue({});
|
|
1934
1992
|
const context = {
|
|
@@ -1959,10 +2017,11 @@ describe("ReviewService", () => {
|
|
|
1959
2017
|
gitProvider.getPullRequestFiles.mockResolvedValue([
|
|
1960
2018
|
{ filename: "a.ts", status: "modified" },
|
|
1961
2019
|
] as any);
|
|
2020
|
+
gitProvider.listIssueComments.mockResolvedValue([] as any);
|
|
1962
2021
|
gitProvider.listPullReviews.mockResolvedValue([] as any);
|
|
1963
2022
|
gitProvider.listPullReviewComments.mockResolvedValue([] as any);
|
|
1964
2023
|
gitProvider.getPullRequest.mockResolvedValue({ head: { sha: "abc" } } as any);
|
|
1965
|
-
gitProvider.
|
|
2024
|
+
gitProvider.createIssueComment.mockResolvedValue({} as any);
|
|
1966
2025
|
const configReader = (service as any).configReader;
|
|
1967
2026
|
configReader.getPluginConfig.mockReturnValue({});
|
|
1968
2027
|
const context = {
|
|
@@ -1977,7 +2036,7 @@ describe("ReviewService", () => {
|
|
|
1977
2036
|
};
|
|
1978
2037
|
const result = await (service as any).executeDeletionOnly(context);
|
|
1979
2038
|
expect(result.success).toBe(true);
|
|
1980
|
-
expect(gitProvider.
|
|
2039
|
+
expect(gitProvider.createIssueComment).toHaveBeenCalled();
|
|
1981
2040
|
});
|
|
1982
2041
|
});
|
|
1983
2042
|
|
|
@@ -2141,21 +2200,21 @@ describe("ReviewService", () => {
|
|
|
2141
2200
|
expect(consoleSpy).toHaveBeenCalled();
|
|
2142
2201
|
consoleSpy.mockRestore();
|
|
2143
2202
|
});
|
|
2144
|
-
|
|
2145
2203
|
it("should mark issue as invalid on thumbs down from reviewer", async () => {
|
|
2146
2204
|
mockReviewSpecService.parseLineRange = vi.fn().mockReturnValue([10]);
|
|
2147
2205
|
gitProvider.listPullReviews.mockResolvedValue([
|
|
2148
|
-
{ id: 1, body: "<!-- spaceflow-review --> content", user: { login: "bot" } },
|
|
2206
|
+
{ id: 1, body: "<!-- spaceflow-review-lines --> content", user: { login: "bot" } },
|
|
2149
2207
|
{ id: 2, body: "LGTM", user: { login: "reviewer1" } },
|
|
2150
2208
|
] as any);
|
|
2151
2209
|
gitProvider.getPullRequest.mockResolvedValue({
|
|
2210
|
+
head: { sha: "abc" },
|
|
2152
2211
|
requested_reviewers: [],
|
|
2153
2212
|
requested_reviewers_teams: [],
|
|
2154
2213
|
} as any);
|
|
2155
2214
|
gitProvider.listPullReviewComments.mockResolvedValue([
|
|
2156
2215
|
{ id: 100, path: "test.ts", position: 10 },
|
|
2157
2216
|
] as any);
|
|
2158
|
-
gitProvider.
|
|
2217
|
+
gitProvider.getPullReviewCommentReactions.mockResolvedValue([
|
|
2159
2218
|
{ content: "-1", user: { login: "reviewer1" } },
|
|
2160
2219
|
] as any);
|
|
2161
2220
|
const result = { issues: [{ file: "test.ts", line: "10", valid: "true" }] };
|
|
@@ -2166,7 +2225,7 @@ describe("ReviewService", () => {
|
|
|
2166
2225
|
it("should add requested_reviewers to reviewers set", async () => {
|
|
2167
2226
|
mockReviewSpecService.parseLineRange = vi.fn().mockReturnValue([10]);
|
|
2168
2227
|
gitProvider.listPullReviews.mockResolvedValue([
|
|
2169
|
-
{ id: 1, body: "<!-- spaceflow-review --> content", user: { login: "bot" } },
|
|
2228
|
+
{ id: 1, body: "<!-- spaceflow-review-lines --> content", user: { login: "bot" } },
|
|
2170
2229
|
] as any);
|
|
2171
2230
|
gitProvider.getPullRequest.mockResolvedValue({
|
|
2172
2231
|
requested_reviewers: [{ login: "req-reviewer" }],
|
|
@@ -2175,7 +2234,7 @@ describe("ReviewService", () => {
|
|
|
2175
2234
|
gitProvider.listPullReviewComments.mockResolvedValue([
|
|
2176
2235
|
{ id: 100, path: "test.ts", position: 10 },
|
|
2177
2236
|
] as any);
|
|
2178
|
-
gitProvider.
|
|
2237
|
+
gitProvider.getPullReviewCommentReactions.mockResolvedValue([
|
|
2179
2238
|
{ content: "-1", user: { login: "req-reviewer" } },
|
|
2180
2239
|
] as any);
|
|
2181
2240
|
const result = { issues: [{ file: "test.ts", line: "10", valid: "true" }] };
|
|
@@ -2186,7 +2245,7 @@ describe("ReviewService", () => {
|
|
|
2186
2245
|
it("should skip comments without id", async () => {
|
|
2187
2246
|
mockReviewSpecService.parseLineRange = vi.fn().mockReturnValue([10]);
|
|
2188
2247
|
gitProvider.listPullReviews.mockResolvedValue([
|
|
2189
|
-
{ id: 1, body: "<!-- spaceflow-review --> content" },
|
|
2248
|
+
{ id: 1, body: "<!-- spaceflow-review-lines --> content" },
|
|
2190
2249
|
] as any);
|
|
2191
2250
|
gitProvider.getPullRequest.mockResolvedValue({
|
|
2192
2251
|
requested_reviewers: [],
|
|
@@ -2203,7 +2262,7 @@ describe("ReviewService", () => {
|
|
|
2203
2262
|
it("should skip when reactions are empty", async () => {
|
|
2204
2263
|
mockReviewSpecService.parseLineRange = vi.fn().mockReturnValue([10]);
|
|
2205
2264
|
gitProvider.listPullReviews.mockResolvedValue([
|
|
2206
|
-
{ id: 1, body: "<!-- spaceflow-review --> content" },
|
|
2265
|
+
{ id: 1, body: "<!-- spaceflow-review-lines --> content" },
|
|
2207
2266
|
] as any);
|
|
2208
2267
|
gitProvider.getPullRequest.mockResolvedValue({
|
|
2209
2268
|
requested_reviewers: [],
|
|
@@ -2212,7 +2271,7 @@ describe("ReviewService", () => {
|
|
|
2212
2271
|
gitProvider.listPullReviewComments.mockResolvedValue([
|
|
2213
2272
|
{ id: 100, path: "test.ts", position: 10 },
|
|
2214
2273
|
] as any);
|
|
2215
|
-
gitProvider.
|
|
2274
|
+
gitProvider.getPullReviewCommentReactions.mockResolvedValue([] as any);
|
|
2216
2275
|
const result = { issues: [{ file: "test.ts", line: "10", reactions: [] }] };
|
|
2217
2276
|
await (service as any).syncReactionsToIssues("o", "r", 1, result);
|
|
2218
2277
|
expect(result.issues[0].reactions).toHaveLength(0);
|
|
@@ -2221,7 +2280,7 @@ describe("ReviewService", () => {
|
|
|
2221
2280
|
it("should store multiple reaction types", async () => {
|
|
2222
2281
|
mockReviewSpecService.parseLineRange = vi.fn().mockReturnValue([10]);
|
|
2223
2282
|
gitProvider.listPullReviews.mockResolvedValue([
|
|
2224
|
-
{ id: 1, body: "<!-- spaceflow-review --> content" },
|
|
2283
|
+
{ id: 1, body: "<!-- spaceflow-review-lines --> content" },
|
|
2225
2284
|
] as any);
|
|
2226
2285
|
gitProvider.getPullRequest.mockResolvedValue({
|
|
2227
2286
|
requested_reviewers: [],
|
|
@@ -2230,7 +2289,7 @@ describe("ReviewService", () => {
|
|
|
2230
2289
|
gitProvider.listPullReviewComments.mockResolvedValue([
|
|
2231
2290
|
{ id: 100, path: "test.ts", position: 10 },
|
|
2232
2291
|
] as any);
|
|
2233
|
-
gitProvider.
|
|
2292
|
+
gitProvider.getPullReviewCommentReactions.mockResolvedValue([
|
|
2234
2293
|
{ content: "+1", user: { login: "user1" } },
|
|
2235
2294
|
{ content: "+1", user: { login: "user2" } },
|
|
2236
2295
|
{ content: "heart", user: { login: "user1" } },
|
|
@@ -2243,7 +2302,7 @@ describe("ReviewService", () => {
|
|
|
2243
2302
|
it("should not mark as invalid when thumbs down from non-reviewer", async () => {
|
|
2244
2303
|
mockReviewSpecService.parseLineRange = vi.fn().mockReturnValue([10]);
|
|
2245
2304
|
gitProvider.listPullReviews.mockResolvedValue([
|
|
2246
|
-
{ id: 1, body: "<!-- spaceflow-review --> content" },
|
|
2305
|
+
{ id: 1, body: "<!-- spaceflow-review-lines --> content" },
|
|
2247
2306
|
] as any);
|
|
2248
2307
|
gitProvider.getPullRequest.mockResolvedValue({
|
|
2249
2308
|
requested_reviewers: [],
|
|
@@ -2252,7 +2311,7 @@ describe("ReviewService", () => {
|
|
|
2252
2311
|
gitProvider.listPullReviewComments.mockResolvedValue([
|
|
2253
2312
|
{ id: 100, path: "test.ts", position: 10 },
|
|
2254
2313
|
] as any);
|
|
2255
|
-
gitProvider.
|
|
2314
|
+
gitProvider.getPullReviewCommentReactions.mockResolvedValue([
|
|
2256
2315
|
{ content: "-1", user: { login: "random-user" } },
|
|
2257
2316
|
] as any);
|
|
2258
2317
|
const result = { issues: [{ file: "test.ts", line: "10", valid: "true", reactions: [] }] };
|
|
@@ -2717,19 +2776,20 @@ describe("ReviewService", () => {
|
|
|
2717
2776
|
mockReviewReportService.parseMarkdown.mockReturnValue({ result: mockResult });
|
|
2718
2777
|
mockReviewReportService.formatStatsTerminal = vi.fn().mockReturnValue("stats");
|
|
2719
2778
|
mockReviewReportService.formatMarkdown.mockReturnValue("report");
|
|
2720
|
-
gitProvider.
|
|
2721
|
-
{ id:
|
|
2779
|
+
gitProvider.listIssueComments.mockResolvedValue([
|
|
2780
|
+
{ id: 10, body: "<!-- spaceflow-review --> content" },
|
|
2722
2781
|
] as any);
|
|
2782
|
+
gitProvider.listPullReviews.mockResolvedValue([] as any);
|
|
2723
2783
|
gitProvider.listPullReviewComments.mockResolvedValue([] as any);
|
|
2724
2784
|
gitProvider.getPullRequestCommits.mockResolvedValue([] as any);
|
|
2725
2785
|
gitProvider.getPullRequest.mockResolvedValue({ head: { sha: "abc" } } as any);
|
|
2726
|
-
gitProvider.
|
|
2786
|
+
gitProvider.updateIssueComment.mockResolvedValue({} as any);
|
|
2727
2787
|
const configReader = (service as any).configReader;
|
|
2728
2788
|
configReader.getPluginConfig.mockReturnValue({});
|
|
2729
2789
|
const context = { owner: "o", repo: "r", prNumber: 1, ci: true, dryRun: false, verbose: 1 };
|
|
2730
2790
|
const result = await (service as any).executeCollectOnly(context);
|
|
2731
2791
|
expect(result.issues).toHaveLength(1);
|
|
2732
|
-
expect(gitProvider.
|
|
2792
|
+
expect(gitProvider.updateIssueComment).toHaveBeenCalled();
|
|
2733
2793
|
});
|
|
2734
2794
|
});
|
|
2735
2795
|
|