@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.
@@ -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.createPullReview.mockResolvedValue({});
329
+ gitProvider.createIssueComment.mockResolvedValue({});
321
330
 
322
331
  await service.execute(context);
323
332
 
324
- expect(gitProvider.createPullReview).toHaveBeenCalledWith(
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.createPullReview.mockResolvedValue({});
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.createPullReview).toHaveBeenCalled();
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 not filter if existing issue is not valid", () => {
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(1);
1423
- expect(result.skippedCount).toBe(0);
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.listPullReviews.mockResolvedValue([{ body: "normal review" }] as any);
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.listPullReviews.mockResolvedValue([
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.listPullReviews.mockRejectedValue(new Error("API error"));
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 handle error gracefully", async () => {
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.listPullReviews.mockResolvedValue([] as any);
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.createPullReview.mockResolvedValue({} as any);
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.createPullReview).toHaveBeenCalled();
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.listPullReviews.mockResolvedValue([] as any);
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.createPullReview.mockResolvedValue({} as any);
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 createPullReview error gracefully", async () => {
1783
+ it("should handle createIssueComment error gracefully", async () => {
1751
1784
  const configReader = (service as any).configReader;
1752
1785
  configReader.getPluginConfig.mockReturnValue({});
1753
- gitProvider.listPullReviews.mockResolvedValue([] as any);
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.createPullReview.mockRejectedValue(new Error("fail") as any);
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.listPullReviews.mockResolvedValue([] as any);
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.listPullReviews.mockResolvedValue([
1796
- { id: 1, body: "<!-- spaceflow-review --> content" },
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 resolved comments with no resolver", async () => {
1807
- mockReviewSpecService.parseLineRange = vi.fn().mockReturnValue([10]);
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 when no AI review found", async () => {
1820
- gitProvider.listPullReviews.mockResolvedValue([{ id: 1, body: "normal review" }] as any);
1821
- const result = { issues: [{ file: "test.ts", line: "10", fixed: false }] };
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).toBe(false);
1851
+ expect((result.issues[0] as any).fixed).toBeUndefined();
1824
1852
  });
1825
1853
 
1826
1854
  it("should handle error gracefully", async () => {
1827
- gitProvider.listPullReviews.mockRejectedValue(new Error("fail"));
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.listPullReviews.mockResolvedValue([
1895
- { id: 1, body: "<!-- spaceflow-review --> content" },
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.createPullReview.mockResolvedValue({} as any);
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.createPullReview.mockResolvedValue({} as any);
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.createPullReview).toHaveBeenCalled();
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.getIssueCommentReactions.mockResolvedValue([
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.getIssueCommentReactions.mockResolvedValue([
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.getIssueCommentReactions.mockResolvedValue([] as any);
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.getIssueCommentReactions.mockResolvedValue([
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.getIssueCommentReactions.mockResolvedValue([
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.listPullReviews.mockResolvedValue([
2721
- { id: 1, body: "<!-- spaceflow-review --> content" },
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.createPullReview.mockResolvedValue({} as any);
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.createPullReview).toHaveBeenCalled();
2792
+ expect(gitProvider.updateIssueComment).toHaveBeenCalled();
2733
2793
  });
2734
2794
  });
2735
2795