Skip to content

Commit 9048814

Browse files
Thomas StrombergThomas Stromberg
authored andcommitted
Add outdated states to review comments
1 parent ff90692 commit 9048814

File tree

3 files changed

+169
-2
lines changed

3 files changed

+169
-2
lines changed

pkg/prx/events.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,5 @@ type Event struct {
123123
TargetIsBot bool `json:"target_is_bot,omitempty"`
124124
Question bool `json:"question,omitempty"`
125125
Required bool `json:"required,omitempty"`
126+
Outdated bool `json:"outdated,omitempty"` // For review comments: indicates comment is on outdated code
126127
}

pkg/prx/graphql_complete.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ query($owner: String!, $repo: String!, $number: Int!, $prCursor: String, $review
219219
id
220220
body
221221
createdAt
222+
outdated
222223
authorAssociation
223224
author {
224225
__typename
@@ -949,6 +950,7 @@ type graphQLPullRequestComplete struct {
949950
Author graphQLActor `json:"author"`
950951
ID string `json:"id"`
951952
Body string `json:"body"`
953+
Outdated bool `json:"outdated"`
952954
AuthorAssociation string `json:"authorAssociation"`
953955
} `json:"nodes"`
954956
} `json:"comments"`
@@ -1220,8 +1222,10 @@ func (c *Client) convertGraphQLToEventsComplete(ctx context.Context, data *graph
12201222
}
12211223

12221224
// Review comments
1223-
for _, thread := range data.ReviewThreads.Nodes {
1224-
for _, comment := range thread.Comments.Nodes {
1225+
for i := range data.ReviewThreads.Nodes {
1226+
thread := &data.ReviewThreads.Nodes[i]
1227+
for j := range thread.Comments.Nodes {
1228+
comment := &thread.Comments.Nodes[j]
12251229
event := Event{
12261230
Kind: "review_comment",
12271231
Timestamp: comment.CreatedAt,
@@ -1230,6 +1234,7 @@ func (c *Client) convertGraphQLToEventsComplete(ctx context.Context, data *graph
12301234
Question: containsQuestion(comment.Body),
12311235
Bot: isBot(comment.Author),
12321236
WriteAccess: c.writeAccessFromAssociation(ctx, owner, repo, comment.Author.Login, comment.AuthorAssociation),
1237+
Outdated: comment.Outdated,
12331238
}
12341239
events = append(events, event)
12351240
}

pkg/prx/graphql_complete_test.go

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package prx
22

33
import (
4+
"context"
5+
"log/slog"
46
"testing"
7+
"time"
58
)
69

710
func TestIsBot(t *testing.T) {
@@ -133,3 +136,161 @@ func TestGraphQLPageInfo(t *testing.T) {
133136
t.Errorf("Expected empty HasNextPage to be false")
134137
}
135138
}
139+
140+
func TestConvertGraphQLReviewCommentsWithOutdated(t *testing.T) {
141+
client := &Client{
142+
logger: slog.Default(),
143+
collaboratorsCache: &collaboratorsCache{
144+
memory: make(map[string]collaboratorsEntry),
145+
},
146+
}
147+
ctx := context.Background()
148+
149+
// Create test data with review threads containing outdated comments
150+
data := &graphQLPullRequestComplete{
151+
ReviewThreads: struct {
152+
Nodes []struct {
153+
Comments struct {
154+
Nodes []struct {
155+
CreatedAt time.Time `json:"createdAt"`
156+
Author graphQLActor `json:"author"`
157+
ID string `json:"id"`
158+
Body string `json:"body"`
159+
Outdated bool `json:"outdated"`
160+
AuthorAssociation string `json:"authorAssociation"`
161+
} `json:"nodes"`
162+
} `json:"comments"`
163+
IsResolved bool `json:"isResolved"`
164+
IsOutdated bool `json:"isOutdated"`
165+
} `json:"nodes"`
166+
}{
167+
Nodes: []struct {
168+
Comments struct {
169+
Nodes []struct {
170+
CreatedAt time.Time `json:"createdAt"`
171+
Author graphQLActor `json:"author"`
172+
ID string `json:"id"`
173+
Body string `json:"body"`
174+
Outdated bool `json:"outdated"`
175+
AuthorAssociation string `json:"authorAssociation"`
176+
} `json:"nodes"`
177+
} `json:"comments"`
178+
IsResolved bool `json:"isResolved"`
179+
IsOutdated bool `json:"isOutdated"`
180+
}{
181+
{
182+
IsOutdated: true,
183+
IsResolved: true,
184+
Comments: struct {
185+
Nodes []struct {
186+
CreatedAt time.Time `json:"createdAt"`
187+
Author graphQLActor `json:"author"`
188+
ID string `json:"id"`
189+
Body string `json:"body"`
190+
Outdated bool `json:"outdated"`
191+
AuthorAssociation string `json:"authorAssociation"`
192+
} `json:"nodes"`
193+
}{
194+
Nodes: []struct {
195+
CreatedAt time.Time `json:"createdAt"`
196+
Author graphQLActor `json:"author"`
197+
ID string `json:"id"`
198+
Body string `json:"body"`
199+
Outdated bool `json:"outdated"`
200+
AuthorAssociation string `json:"authorAssociation"`
201+
}{
202+
{
203+
ID: "comment1",
204+
Body: "Should be Unlock() I think?",
205+
CreatedAt: time.Date(2025, 7, 18, 16, 46, 27, 0, time.UTC),
206+
Outdated: true,
207+
Author: graphQLActor{Login: "reviewer1"},
208+
AuthorAssociation: "CONTRIBUTOR",
209+
},
210+
{
211+
ID: "comment2",
212+
Body: "eh yeah, absolutely! Good catch!",
213+
CreatedAt: time.Date(2025, 7, 18, 16, 50, 21, 0, time.UTC),
214+
Outdated: true,
215+
Author: graphQLActor{Login: "author1"},
216+
AuthorAssociation: "OWNER",
217+
},
218+
},
219+
},
220+
},
221+
{
222+
IsOutdated: false,
223+
IsResolved: false,
224+
Comments: struct {
225+
Nodes []struct {
226+
CreatedAt time.Time `json:"createdAt"`
227+
Author graphQLActor `json:"author"`
228+
ID string `json:"id"`
229+
Body string `json:"body"`
230+
Outdated bool `json:"outdated"`
231+
AuthorAssociation string `json:"authorAssociation"`
232+
} `json:"nodes"`
233+
}{
234+
Nodes: []struct {
235+
CreatedAt time.Time `json:"createdAt"`
236+
Author graphQLActor `json:"author"`
237+
ID string `json:"id"`
238+
Body string `json:"body"`
239+
Outdated bool `json:"outdated"`
240+
AuthorAssociation string `json:"authorAssociation"`
241+
}{
242+
{
243+
ID: "comment3",
244+
Body: "This looks good to me",
245+
CreatedAt: time.Date(2025, 7, 19, 10, 0, 0, 0, time.UTC),
246+
Outdated: false,
247+
Author: graphQLActor{Login: "reviewer2"},
248+
AuthorAssociation: "MEMBER",
249+
},
250+
},
251+
},
252+
},
253+
},
254+
},
255+
}
256+
257+
// Convert GraphQL data to events
258+
events := client.convertGraphQLToEventsComplete(ctx, data, "testowner", "testrepo")
259+
260+
// Filter to only review_comment events
261+
var reviewComments []Event
262+
for _, event := range events {
263+
if event.Kind == "review_comment" {
264+
reviewComments = append(reviewComments, event)
265+
}
266+
}
267+
268+
// Verify we got 3 review comments
269+
if len(reviewComments) != 3 {
270+
t.Fatalf("Expected 3 review comments, got %d", len(reviewComments))
271+
}
272+
273+
// Verify first comment is outdated
274+
if !reviewComments[0].Outdated {
275+
t.Errorf("Expected first comment to be outdated")
276+
}
277+
if reviewComments[0].Body != "Should be Unlock() I think?" {
278+
t.Errorf("Expected first comment body 'Should be Unlock() I think?', got '%s'", reviewComments[0].Body)
279+
}
280+
281+
// Verify second comment is outdated
282+
if !reviewComments[1].Outdated {
283+
t.Errorf("Expected second comment to be outdated")
284+
}
285+
if reviewComments[1].Body != "eh yeah, absolutely! Good catch!" {
286+
t.Errorf("Expected second comment body 'eh yeah, absolutely! Good catch!', got '%s'", reviewComments[1].Body)
287+
}
288+
289+
// Verify third comment is NOT outdated
290+
if reviewComments[2].Outdated {
291+
t.Errorf("Expected third comment to NOT be outdated")
292+
}
293+
if reviewComments[2].Body != "This looks good to me" {
294+
t.Errorf("Expected third comment body 'This looks good to me', got '%s'", reviewComments[2].Body)
295+
}
296+
}

0 commit comments

Comments
 (0)