Skip to content

Commit 02b16c7

Browse files
rootcursoragent
andcommitted
Gracefully skip suggestion enrichment when REST client unavailable
Also add a fixture test with real Copilot diff data that includes DELETION lines, verifying replacement suggestion text excludes removed lines while preserving context and additions. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 094b3ff commit 02b16c7

2 files changed

Lines changed: 23 additions & 4 deletions

File tree

pkg/github/pullrequests.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -484,11 +484,9 @@ func GetPullRequestReviewComments(ctx context.Context, gqlClient *githubv4.Clien
484484

485485
response := convertToMinimalReviewThreadsResponse(query)
486486

487-
client, err := deps.GetClient(ctx)
488-
if err != nil {
489-
return nil, fmt.Errorf("failed to get GitHub client for review suggestions: %w", err)
487+
if client, err := deps.GetClient(ctx); err == nil {
488+
enrichReviewThreadsWithSuggestions(ctx, client, owner, repo, pullNumber, response.ReviewThreads)
490489
}
491-
enrichReviewThreadsWithSuggestions(ctx, client, owner, repo, pullNumber, response.ReviewThreads)
492490

493491
return MarshalledTextResult(response), nil
494492
}

pkg/github/review_suggestions_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,24 @@ func TestParseAutomatedSuggestionsFromHTML(t *testing.T) {
8080
assert.Equal(t, 10, *suggestions[0].StartLine)
8181
}
8282

83+
func TestParseAutomatedSuggestionsFromHTMLWithDeletions(t *testing.T) {
84+
t.Parallel()
85+
86+
html := `<html><body>` + automatedSuggestionWithDeletionsFixture + `</body></html>`
87+
suggestions, err := parseAutomatedSuggestionsFromHTML(html)
88+
require.NoError(t, err)
89+
require.Len(t, suggestions, 1)
90+
91+
s := suggestions[0]
92+
assert.Equal(t, suggestionSourceAutomated, s.Source)
93+
assert.Equal(t, "glmocr/tests/test_layout_device.py", s.Path)
94+
assert.NotContains(t, s.Suggestion, "from glmocr.layout.layout_detector import PPDocLayoutDetector")
95+
assert.Contains(t, s.Suggestion, "from glmocr import layout as layout_mod")
96+
assert.Contains(t, s.Suggestion, "pytest.skip")
97+
require.NotNil(t, s.StartLine)
98+
assert.Equal(t, 132, *s.StartLine)
99+
}
100+
83101
func TestFetchAutomatedSuggestionsForThread(t *testing.T) {
84102
t.Parallel()
85103

@@ -140,3 +158,6 @@ func TestEnrichReviewThreadsWithSuggestions(t *testing.T) {
140158
}
141159

142160
const automatedSuggestionHTMLFixture = `<script type="application/json" data-target="react-partial.embeddedData">{"props":{"comment":{"automatedComment":{"suggestion":{"diffEntries":[{"path":"glmocr/cli.py","diffLines":[{"type":"HUNK","text":"@@ -9,6 +9,7 @@","left":8,"right":8},{"type":"CONTEXT","text":"from pathlib import Path","left":10,"right":10},{"type":"ADDITION","text":"import re","left":11,"right":12}]}]}}}}}</script>`
161+
162+
// Fixture derived from a real Copilot review thread partial (zai-org/GLM-OCR#131).
163+
const automatedSuggestionWithDeletionsFixture = `<script type="application/json" data-target="react-partial.embeddedData">{"props":{"comment":{"automatedComment":{"suggestion":{"diffEntries":[{"path":"glmocr/tests/test_layout_device.py","diffLines":[{"type":"HUNK","text":"@@ -132,7 +132,11 @@","left":131,"right":131},{"type":"CONTEXT","text":" def _mock_detector(self, device_val):","left":132,"right":132},{"type":"CONTEXT","text":" from glmocr.config import LayoutConfig","left":134,"right":134},{"type":"DELETION","text":" from glmocr.layout.layout_detector import PPDocLayoutDetector","left":135,"right":134},{"type":"ADDITION","text":" try:","left":135,"right":135},{"type":"ADDITION","text":" from glmocr import layout as layout_mod","left":135,"right":136},{"type":"ADDITION","text":" PPDocLayoutDetector = layout_mod.PPDocLayoutDetector # type: ignore[attr-defined]","left":135,"right":137},{"type":"ADDITION","text":" except Exception:","left":135,"right":138},{"type":"ADDITION","text":" pytest.skip(\"PPDocLayoutDetector (and optional layout deps) not available; skipping mocked detector tests.\")","left":135,"right":139},{"type":"CONTEXT","text":" cfg = LayoutConfig(device=device_val, **self._MOCK_LAYOUT_KWARGS)","left":137,"right":141}]}]}}}}}</script>`

0 commit comments

Comments
 (0)