@renfeng/kiro-code-review 1.9.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/LICENSE +21 -0
- package/README.md +69 -0
- package/dist/api/gitlab-api.d.ts +122 -0
- package/dist/api/gitlab-api.d.ts.map +1 -0
- package/dist/api/gitlab-api.js +334 -0
- package/dist/api/gitlab-api.js.map +1 -0
- package/dist/bin/index.d.ts +11 -0
- package/dist/bin/index.d.ts.map +1 -0
- package/dist/bin/index.js +67 -0
- package/dist/bin/index.js.map +1 -0
- package/dist/config/glab-config.loader.d.ts +14 -0
- package/dist/config/glab-config.loader.d.ts.map +1 -0
- package/dist/config/glab-config.loader.js +87 -0
- package/dist/config/glab-config.loader.js.map +1 -0
- package/dist/errors/error-handler.d.ts +45 -0
- package/dist/errors/error-handler.d.ts.map +1 -0
- package/dist/errors/error-handler.js +134 -0
- package/dist/errors/error-handler.js.map +1 -0
- package/dist/logging/index.d.ts +2 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +2 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.service.d.ts +34 -0
- package/dist/logging/logger.service.d.ts.map +1 -0
- package/dist/logging/logger.service.js +91 -0
- package/dist/logging/logger.service.js.map +1 -0
- package/dist/servers/general-server.d.ts +18 -0
- package/dist/servers/general-server.d.ts.map +1 -0
- package/dist/servers/general-server.js +73 -0
- package/dist/servers/general-server.js.map +1 -0
- package/dist/servers/git-server.d.ts +17 -0
- package/dist/servers/git-server.d.ts.map +1 -0
- package/dist/servers/git-server.js +74 -0
- package/dist/servers/git-server.js.map +1 -0
- package/dist/servers/gitlab-server.d.ts +18 -0
- package/dist/servers/gitlab-server.d.ts.map +1 -0
- package/dist/servers/gitlab-server.js +139 -0
- package/dist/servers/gitlab-server.js.map +1 -0
- package/dist/services/__tests__/batch-retro.service.test.d.ts +9 -0
- package/dist/services/__tests__/batch-retro.service.test.d.ts.map +1 -0
- package/dist/services/__tests__/batch-retro.service.test.js +235 -0
- package/dist/services/__tests__/batch-retro.service.test.js.map +1 -0
- package/dist/services/__tests__/general-save-diffs.test.d.ts +5 -0
- package/dist/services/__tests__/general-save-diffs.test.d.ts.map +1 -0
- package/dist/services/__tests__/general-save-diffs.test.js +99 -0
- package/dist/services/__tests__/general-save-diffs.test.js.map +1 -0
- package/dist/services/__tests__/git-diff-files.test.d.ts +8 -0
- package/dist/services/__tests__/git-diff-files.test.d.ts.map +1 -0
- package/dist/services/__tests__/git-diff-files.test.js +64 -0
- package/dist/services/__tests__/git-diff-files.test.js.map +1 -0
- package/dist/services/__tests__/review-tools.service.test.d.ts +8 -0
- package/dist/services/__tests__/review-tools.service.test.d.ts.map +1 -0
- package/dist/services/__tests__/review-tools.service.test.js +169 -0
- package/dist/services/__tests__/review-tools.service.test.js.map +1 -0
- package/dist/services/__tests__/review-utils.service.test.d.ts +8 -0
- package/dist/services/__tests__/review-utils.service.test.d.ts.map +1 -0
- package/dist/services/__tests__/review-utils.service.test.js +306 -0
- package/dist/services/__tests__/review-utils.service.test.js.map +1 -0
- package/dist/services/anchor-resolver.d.ts +29 -0
- package/dist/services/anchor-resolver.d.ts.map +1 -0
- package/dist/services/anchor-resolver.js +97 -0
- package/dist/services/anchor-resolver.js.map +1 -0
- package/dist/services/general.service.d.ts +42 -0
- package/dist/services/general.service.d.ts.map +1 -0
- package/dist/services/general.service.js +157 -0
- package/dist/services/general.service.js.map +1 -0
- package/dist/services/git-tools.service.d.ts +123 -0
- package/dist/services/git-tools.service.d.ts.map +1 -0
- package/dist/services/git-tools.service.js +231 -0
- package/dist/services/git-tools.service.js.map +1 -0
- package/dist/services/review-tools.service.d.ts +130 -0
- package/dist/services/review-tools.service.d.ts.map +1 -0
- package/dist/services/review-tools.service.js +902 -0
- package/dist/services/review-tools.service.js.map +1 -0
- package/dist/tools/general-tools.d.ts +9 -0
- package/dist/tools/general-tools.d.ts.map +1 -0
- package/dist/tools/general-tools.js +99 -0
- package/dist/tools/general-tools.js.map +1 -0
- package/dist/tools/git-tools.d.ts +8 -0
- package/dist/tools/git-tools.d.ts.map +1 -0
- package/dist/tools/git-tools.js +175 -0
- package/dist/tools/git-tools.js.map +1 -0
- package/dist/tools/gitlab-tools.d.ts +8 -0
- package/dist/tools/gitlab-tools.d.ts.map +1 -0
- package/dist/tools/gitlab-tools.js +348 -0
- package/dist/tools/gitlab-tools.js.map +1 -0
- package/dist/types.d.ts +294 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for GeneralService.savePerFileDiffs and GitToolsService.diff with files param.
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
5
|
+
import { readFileSync, mkdtempSync, rmSync, existsSync } from 'fs';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { tmpdir } from 'os';
|
|
8
|
+
import { GeneralService } from '../general.service.js';
|
|
9
|
+
import { GitToolsService } from '../git-tools.service.js';
|
|
10
|
+
import { Logger, LogLevel } from '../../logging/logger.service.js';
|
|
11
|
+
describe('GeneralService.savePerFileDiffs', () => {
|
|
12
|
+
let service;
|
|
13
|
+
let gitTools;
|
|
14
|
+
let logger;
|
|
15
|
+
let tmpDir;
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
logger = new Logger('test', LogLevel.ERROR);
|
|
18
|
+
gitTools = new GitToolsService(logger);
|
|
19
|
+
service = new GeneralService(logger, gitTools);
|
|
20
|
+
tmpDir = mkdtempSync(join(tmpdir(), 'save-diffs-'));
|
|
21
|
+
});
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
24
|
+
vi.restoreAllMocks();
|
|
25
|
+
});
|
|
26
|
+
it('saves per-file diffs to disk', async () => {
|
|
27
|
+
const diffSpy = vi.spyOn(gitTools, 'diff');
|
|
28
|
+
// First call: name-only
|
|
29
|
+
diffSpy.mockResolvedValueOnce({ diff: 'src/a.ts\nsrc/b.ts\n' });
|
|
30
|
+
// Per-file diffs
|
|
31
|
+
diffSpy.mockResolvedValueOnce({ diff: 'diff --git a/src/a.ts b/src/a.ts\n+added line\n' });
|
|
32
|
+
diffSpy.mockResolvedValueOnce({ diff: 'diff --git a/src/b.ts b/src/b.ts\n-removed line\n' });
|
|
33
|
+
const outputDir = join(tmpDir, 'diffs');
|
|
34
|
+
const result = await service.savePerFileDiffs({
|
|
35
|
+
repoDir: '/fake/repo', mergeBase: 'abc123', outputDir,
|
|
36
|
+
});
|
|
37
|
+
expect(result.files).toEqual(['src/a.ts', 'src/b.ts']);
|
|
38
|
+
expect(result.totalFiles).toBe(2);
|
|
39
|
+
expect(result.errors).toEqual([]);
|
|
40
|
+
// Verify files on disk
|
|
41
|
+
expect(readFileSync(join(outputDir, 'src/a.ts.diff'), 'utf-8')).toContain('+added line');
|
|
42
|
+
expect(readFileSync(join(outputDir, 'src/b.ts.diff'), 'utf-8')).toContain('-removed line');
|
|
43
|
+
// Verify diff() was called with correct params
|
|
44
|
+
expect(diffSpy).toHaveBeenCalledWith({
|
|
45
|
+
repoDir: '/fake/repo', base: 'abc123', head: 'HEAD', mode: 'name-only',
|
|
46
|
+
});
|
|
47
|
+
expect(diffSpy).toHaveBeenCalledWith({
|
|
48
|
+
repoDir: '/fake/repo', base: 'abc123', head: 'HEAD', mode: 'full', files: ['src/a.ts'],
|
|
49
|
+
});
|
|
50
|
+
expect(diffSpy).toHaveBeenCalledWith({
|
|
51
|
+
repoDir: '/fake/repo', base: 'abc123', head: 'HEAD', mode: 'full', files: ['src/b.ts'],
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
it('handles empty diff (no changed files)', async () => {
|
|
55
|
+
vi.spyOn(gitTools, 'diff').mockResolvedValueOnce({ diff: '\n' });
|
|
56
|
+
const result = await service.savePerFileDiffs({
|
|
57
|
+
repoDir: '/fake/repo', mergeBase: 'abc123', outputDir: join(tmpDir, 'diffs'),
|
|
58
|
+
});
|
|
59
|
+
expect(result.files).toEqual([]);
|
|
60
|
+
expect(result.totalFiles).toBe(0);
|
|
61
|
+
expect(result.errors).toEqual([]);
|
|
62
|
+
});
|
|
63
|
+
it('continues on per-file error and reports failures', async () => {
|
|
64
|
+
const diffSpy = vi.spyOn(gitTools, 'diff');
|
|
65
|
+
// name-only returns 3 files
|
|
66
|
+
diffSpy.mockResolvedValueOnce({ diff: 'good.ts\nbad.bin\nalso-good.ts\n' });
|
|
67
|
+
// good.ts succeeds
|
|
68
|
+
diffSpy.mockResolvedValueOnce({ diff: 'diff for good.ts' });
|
|
69
|
+
// bad.bin fails
|
|
70
|
+
diffSpy.mockRejectedValueOnce(new Error('binary file'));
|
|
71
|
+
// also-good.ts succeeds
|
|
72
|
+
diffSpy.mockResolvedValueOnce({ diff: 'diff for also-good.ts' });
|
|
73
|
+
const outputDir = join(tmpDir, 'diffs');
|
|
74
|
+
const result = await service.savePerFileDiffs({
|
|
75
|
+
repoDir: '/fake/repo', mergeBase: 'abc123', outputDir,
|
|
76
|
+
});
|
|
77
|
+
expect(result.files).toEqual(['good.ts', 'also-good.ts']);
|
|
78
|
+
expect(result.totalFiles).toBe(2);
|
|
79
|
+
expect(result.errors).toEqual([{ file: 'bad.bin', error: 'binary file' }]);
|
|
80
|
+
// good files saved, bad file not
|
|
81
|
+
expect(existsSync(join(outputDir, 'good.ts.diff'))).toBe(true);
|
|
82
|
+
expect(existsSync(join(outputDir, 'bad.bin.diff'))).toBe(false);
|
|
83
|
+
expect(existsSync(join(outputDir, 'also-good.ts.diff'))).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
it('creates nested directories for deep file paths', async () => {
|
|
86
|
+
const diffSpy = vi.spyOn(gitTools, 'diff');
|
|
87
|
+
diffSpy.mockResolvedValueOnce({ diff: 'libs/orders/store/src/effects.ts\n' });
|
|
88
|
+
diffSpy.mockResolvedValueOnce({ diff: 'deep nested diff content' });
|
|
89
|
+
const outputDir = join(tmpDir, 'diffs');
|
|
90
|
+
const result = await service.savePerFileDiffs({
|
|
91
|
+
repoDir: '/fake/repo', mergeBase: 'abc123', outputDir,
|
|
92
|
+
});
|
|
93
|
+
expect(result.files).toEqual(['libs/orders/store/src/effects.ts']);
|
|
94
|
+
const savedPath = join(outputDir, 'libs/orders/store/src/effects.ts.diff');
|
|
95
|
+
expect(existsSync(savedPath)).toBe(true);
|
|
96
|
+
expect(readFileSync(savedPath, 'utf-8')).toBe('deep nested diff content');
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
//# sourceMappingURL=general-save-diffs.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"general-save-diffs.test.js","sourceRoot":"","sources":["../../../src/services/__tests__/general-save-diffs.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for GitToolsService.diff with the files parameter.
|
|
3
|
+
*
|
|
4
|
+
* Uses a real temp directory for repoDir (to pass path validation),
|
|
5
|
+
* then mocks runGit to verify correct argument construction.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=git-diff-files.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-diff-files.test.d.ts","sourceRoot":"","sources":["../../../src/services/__tests__/git-diff-files.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for GitToolsService.diff with the files parameter.
|
|
3
|
+
*
|
|
4
|
+
* Uses a real temp directory for repoDir (to pass path validation),
|
|
5
|
+
* then mocks runGit to verify correct argument construction.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
8
|
+
import { mkdtempSync, rmSync } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import { tmpdir } from 'os';
|
|
11
|
+
import { GitToolsService } from '../git-tools.service.js';
|
|
12
|
+
import { Logger, LogLevel } from '../../logging/logger.service.js';
|
|
13
|
+
describe('GitToolsService.diff files parameter', () => {
|
|
14
|
+
let gitTools;
|
|
15
|
+
let runGitSpy;
|
|
16
|
+
let repoDir;
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
const logger = new Logger('test', LogLevel.ERROR);
|
|
19
|
+
gitTools = new GitToolsService(logger);
|
|
20
|
+
repoDir = mkdtempSync(join(tmpdir(), 'git-diff-test-'));
|
|
21
|
+
runGitSpy = vi.spyOn(gitTools, 'runGit').mockResolvedValue('mock diff output');
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
rmSync(repoDir, { recursive: true, force: true });
|
|
25
|
+
vi.restoreAllMocks();
|
|
26
|
+
});
|
|
27
|
+
it('appends -- and file paths when files param is provided', async () => {
|
|
28
|
+
await gitTools.diff({
|
|
29
|
+
repoDir, base: 'abc123', head: 'HEAD', mode: 'full', files: ['src/a.ts'],
|
|
30
|
+
});
|
|
31
|
+
expect(runGitSpy).toHaveBeenCalledWith(repoDir, ['diff', 'abc123', 'HEAD', '--', 'src/a.ts']);
|
|
32
|
+
});
|
|
33
|
+
it('appends multiple file paths', async () => {
|
|
34
|
+
await gitTools.diff({
|
|
35
|
+
repoDir, base: 'abc123', head: 'HEAD', mode: 'full', files: ['src/a.ts', 'src/b.ts'],
|
|
36
|
+
});
|
|
37
|
+
expect(runGitSpy).toHaveBeenCalledWith(repoDir, ['diff', 'abc123', 'HEAD', '--', 'src/a.ts', 'src/b.ts']);
|
|
38
|
+
});
|
|
39
|
+
it('does not append -- when files is empty', async () => {
|
|
40
|
+
await gitTools.diff({
|
|
41
|
+
repoDir, base: 'abc123', head: 'HEAD', mode: 'full', files: [],
|
|
42
|
+
});
|
|
43
|
+
expect(runGitSpy).toHaveBeenCalledWith(repoDir, ['diff', 'abc123', 'HEAD']);
|
|
44
|
+
});
|
|
45
|
+
it('does not append -- when files is undefined', async () => {
|
|
46
|
+
await gitTools.diff({
|
|
47
|
+
repoDir, base: 'abc123', head: 'HEAD', mode: 'full',
|
|
48
|
+
});
|
|
49
|
+
expect(runGitSpy).toHaveBeenCalledWith(repoDir, ['diff', 'abc123', 'HEAD']);
|
|
50
|
+
});
|
|
51
|
+
it('combines files with stat mode', async () => {
|
|
52
|
+
await gitTools.diff({
|
|
53
|
+
repoDir, base: 'abc123', mode: 'stat', files: ['src/a.ts'],
|
|
54
|
+
});
|
|
55
|
+
expect(runGitSpy).toHaveBeenCalledWith(repoDir, ['diff', 'abc123', '--stat', '--', 'src/a.ts']);
|
|
56
|
+
});
|
|
57
|
+
it('combines files with name-only mode', async () => {
|
|
58
|
+
await gitTools.diff({
|
|
59
|
+
repoDir, base: 'abc123', mode: 'name-only', files: ['src/a.ts'],
|
|
60
|
+
});
|
|
61
|
+
expect(runGitSpy).toHaveBeenCalledWith(repoDir, ['diff', 'abc123', '--name-only', '--', 'src/a.ts']);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=git-diff-files.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-diff-files.test.js","sourceRoot":"","sources":["../../../src/services/__tests__/git-diff-files.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for ReviewToolsService.postDraftNotes inline anchor resolution.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that when repoDir and mergeBase are provided, anchor-based
|
|
5
|
+
* findings are resolved to line numbers before posting to GitLab.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=review-tools.service.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-tools.service.test.d.ts","sourceRoot":"","sources":["../../../src/services/__tests__/review-tools.service.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for ReviewToolsService.postDraftNotes inline anchor resolution.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that when repoDir and mergeBase are provided, anchor-based
|
|
5
|
+
* findings are resolved to line numbers before posting to GitLab.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
8
|
+
import { ReviewToolsService } from '../review-tools.service.js';
|
|
9
|
+
import { Logger, LogLevel } from '../../logging/logger.service.js';
|
|
10
|
+
// Mock GitLabAPI to capture posted draft notes
|
|
11
|
+
const mockPostDraftNote = vi.fn().mockResolvedValue({ id: 1, line_code: 'abc' });
|
|
12
|
+
const mockDeleteDraftNote = vi.fn().mockResolvedValue({});
|
|
13
|
+
vi.mock('../../api/gitlab-api.js', () => ({
|
|
14
|
+
GitLabAPI: class MockGitLabAPI {
|
|
15
|
+
postDraftNote = mockPostDraftNote;
|
|
16
|
+
deleteDraftNote = mockDeleteDraftNote;
|
|
17
|
+
constructor() { }
|
|
18
|
+
},
|
|
19
|
+
}));
|
|
20
|
+
// Mock GitToolsService.runGit to supply synthetic diffs
|
|
21
|
+
vi.mock('../git-tools.service.js', () => ({
|
|
22
|
+
GitToolsService: class MockGitToolsService {
|
|
23
|
+
constructor() { }
|
|
24
|
+
runGit(_repoDir, args) {
|
|
25
|
+
const filePath = args[args.length - 1];
|
|
26
|
+
if (filePath === 'file.ts') {
|
|
27
|
+
return Promise.resolve([
|
|
28
|
+
'diff --git a/file.ts b/file.ts',
|
|
29
|
+
'index abc..def 100644',
|
|
30
|
+
'--- a/file.ts',
|
|
31
|
+
'+++ b/file.ts',
|
|
32
|
+
'@@ -10,4 +10,5 @@',
|
|
33
|
+
' const existing = true;',
|
|
34
|
+
'+const added = false;',
|
|
35
|
+
'-const removed = "old";',
|
|
36
|
+
' const kept = 42;',
|
|
37
|
+
].join('\n'));
|
|
38
|
+
}
|
|
39
|
+
return Promise.reject(new Error('no diff'));
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
}));
|
|
43
|
+
describe('ReviewToolsService.postDraftNotes anchor resolution', () => {
|
|
44
|
+
let service;
|
|
45
|
+
beforeEach(() => {
|
|
46
|
+
vi.clearAllMocks();
|
|
47
|
+
const logger = new Logger('test', LogLevel.ERROR);
|
|
48
|
+
service = new ReviewToolsService(logger);
|
|
49
|
+
});
|
|
50
|
+
const baseParams = {
|
|
51
|
+
project: 'group/repo',
|
|
52
|
+
mergeRequestIid: 1,
|
|
53
|
+
headSha: 'head123',
|
|
54
|
+
baseSha: 'base123',
|
|
55
|
+
startSha: 'start123',
|
|
56
|
+
repoDir: '/fake/repo',
|
|
57
|
+
mergeBase: 'merge-base-sha',
|
|
58
|
+
};
|
|
59
|
+
it('resolves anchor-based finding to line number before posting', async () => {
|
|
60
|
+
const result = await service.postDraftNotes({
|
|
61
|
+
...baseParams,
|
|
62
|
+
findings: {
|
|
63
|
+
comments: [{
|
|
64
|
+
file: 'file.ts',
|
|
65
|
+
anchor: 'const added = false;',
|
|
66
|
+
blocking: true,
|
|
67
|
+
note: 'Review this addition',
|
|
68
|
+
}],
|
|
69
|
+
summary: 'test',
|
|
70
|
+
verdict: 'request_changes',
|
|
71
|
+
},
|
|
72
|
+
}, 'https://gitlab.example.com', 'fake-token');
|
|
73
|
+
expect(result.posted).toBe(1);
|
|
74
|
+
expect(result.errors).toHaveLength(0);
|
|
75
|
+
// Verify the draft was posted with resolved position
|
|
76
|
+
const postedBody = mockPostDraftNote.mock.calls[0][2];
|
|
77
|
+
expect(postedBody.position).toBeDefined();
|
|
78
|
+
expect(postedBody.position.new_line).toBe(11);
|
|
79
|
+
expect(postedBody.position.old_line).toBeNull();
|
|
80
|
+
});
|
|
81
|
+
it('resolves OLD: anchor to old_line', async () => {
|
|
82
|
+
const result = await service.postDraftNotes({
|
|
83
|
+
...baseParams,
|
|
84
|
+
findings: {
|
|
85
|
+
comments: [{
|
|
86
|
+
file: 'file.ts',
|
|
87
|
+
anchor: 'OLD:const removed = "old";',
|
|
88
|
+
blocking: true,
|
|
89
|
+
note: 'This was removed',
|
|
90
|
+
}],
|
|
91
|
+
summary: 'test',
|
|
92
|
+
verdict: 'request_changes',
|
|
93
|
+
},
|
|
94
|
+
}, 'https://gitlab.example.com', 'fake-token');
|
|
95
|
+
expect(result.posted).toBe(1);
|
|
96
|
+
const postedBody = mockPostDraftNote.mock.calls[0][2];
|
|
97
|
+
expect(postedBody.position).toBeDefined();
|
|
98
|
+
expect(postedBody.position.old_line).toBe(11);
|
|
99
|
+
expect(postedBody.position.new_line).toBeNull();
|
|
100
|
+
});
|
|
101
|
+
it('falls back to general when anchor cannot be resolved', async () => {
|
|
102
|
+
const result = await service.postDraftNotes({
|
|
103
|
+
...baseParams,
|
|
104
|
+
findings: {
|
|
105
|
+
comments: [{
|
|
106
|
+
file: 'missing.ts',
|
|
107
|
+
anchor: 'nonexistent line',
|
|
108
|
+
blocking: true,
|
|
109
|
+
note: 'Cannot find this',
|
|
110
|
+
}],
|
|
111
|
+
summary: 'test',
|
|
112
|
+
verdict: 'request_changes',
|
|
113
|
+
},
|
|
114
|
+
}, 'https://gitlab.example.com', 'fake-token');
|
|
115
|
+
expect(result.posted).toBe(1);
|
|
116
|
+
// Should be posted as general (no position)
|
|
117
|
+
const postedBody = mockPostDraftNote.mock.calls[0][2];
|
|
118
|
+
expect(postedBody.position).toBeUndefined();
|
|
119
|
+
expect(postedBody.note).toBe('**`missing.ts`** ([link](https://gitlab.example.com/group/repo/-/blob/head123/missing.ts))\n\nCannot find this');
|
|
120
|
+
});
|
|
121
|
+
it('skips resolution for findings that already have line numbers', async () => {
|
|
122
|
+
const result = await service.postDraftNotes({
|
|
123
|
+
...baseParams,
|
|
124
|
+
findings: {
|
|
125
|
+
comments: [{
|
|
126
|
+
file: 'file.ts',
|
|
127
|
+
anchor: 'const added = false;',
|
|
128
|
+
line: 99,
|
|
129
|
+
changed: 'new',
|
|
130
|
+
blocking: true,
|
|
131
|
+
note: 'Already resolved',
|
|
132
|
+
}],
|
|
133
|
+
summary: 'test',
|
|
134
|
+
verdict: 'request_changes',
|
|
135
|
+
},
|
|
136
|
+
}, 'https://gitlab.example.com', 'fake-token');
|
|
137
|
+
expect(result.posted).toBe(1);
|
|
138
|
+
// Should use the pre-existing line number, not re-resolve
|
|
139
|
+
const postedBody = mockPostDraftNote.mock.calls[0][2];
|
|
140
|
+
expect(postedBody.position.new_line).toBe(99);
|
|
141
|
+
});
|
|
142
|
+
it('does not resolve anchors when repoDir is not provided', async () => {
|
|
143
|
+
const result = await service.postDraftNotes({
|
|
144
|
+
project: 'group/repo',
|
|
145
|
+
mergeRequestIid: 1,
|
|
146
|
+
headSha: 'head123',
|
|
147
|
+
baseSha: 'base123',
|
|
148
|
+
startSha: 'start123',
|
|
149
|
+
// No repoDir or mergeBase
|
|
150
|
+
findings: {
|
|
151
|
+
comments: [{
|
|
152
|
+
file: 'file.ts',
|
|
153
|
+
anchor: 'const added = false;',
|
|
154
|
+
blocking: true,
|
|
155
|
+
note: 'No resolution',
|
|
156
|
+
}],
|
|
157
|
+
summary: 'test',
|
|
158
|
+
verdict: 'request_changes',
|
|
159
|
+
},
|
|
160
|
+
}, 'https://gitlab.example.com', 'fake-token');
|
|
161
|
+
expect(result.posted).toBe(1);
|
|
162
|
+
// Without repoDir, anchor is ignored — no line/old_line means general comment
|
|
163
|
+
const postedBody = mockPostDraftNote.mock.calls[0][2];
|
|
164
|
+
expect(postedBody.position).toBeUndefined();
|
|
165
|
+
// File-link fallback should prepend file context to the note body
|
|
166
|
+
expect(postedBody.note).toBe('**`file.ts`** ([link](https://gitlab.example.com/group/repo/-/blob/head123/file.ts))\n\nNo resolution');
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
//# sourceMappingURL=review-tools.service.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-tools.service.test.js","sourceRoot":"","sources":["../../../src/services/__tests__/review-tools.service.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for ReviewService anchor resolution.
|
|
3
|
+
*
|
|
4
|
+
* These tests mock GitToolsService.runGit to supply synthetic diffs,
|
|
5
|
+
* then verify that resolveAnchors correctly maps anchors to line numbers.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=review-utils.service.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-utils.service.test.d.ts","sourceRoot":"","sources":["../../../src/services/__tests__/review-utils.service.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|