From c708e58f694090ea21be84ee9fd1c54b9a9637e2 Mon Sep 17 00:00:00 2001 From: "Babak K. Shandiz" Date: Thu, 4 Sep 2025 19:33:47 +0100 Subject: [PATCH] test(agent-task list): use `CapiClientMock` Signed-off-by: Babak K. Shandiz --- pkg/cmd/agent-task/list/list_test.go | 906 ++++++++++----------------- 1 file changed, 324 insertions(+), 582 deletions(-) diff --git a/pkg/cmd/agent-task/list/list_test.go b/pkg/cmd/agent-task/list/list_test.go index 2185c5393..5ed0d097d 100644 --- a/pkg/cmd/agent-task/list/list_test.go +++ b/pkg/cmd/agent-task/list/list_test.go @@ -103,12 +103,14 @@ func TestNewCmdList(t *testing.T) { } func Test_listRun(t *testing.T) { - createdAt := time.Now().Add(-6 * time.Hour).Format(time.RFC3339) // 6h ago + sampleDate := time.Now().Add(-6 * time.Hour) // 6h ago + sampleDateString := sampleDate.Format(time.RFC3339) tests := []struct { name string tty bool stubs func(*httpmock.Registry) + capiStubs func(*testing.T, *capi.CapiClientMock) baseRepo ghrepo.Interface baseRepoErr error limit int @@ -119,90 +121,347 @@ func Test_listRun(t *testing.T) { wantBrowserURL string }{ { - name: "no sessions", - tty: true, - stubs: func(reg *httpmock.Registry) { registerEmptySessionsMock(reg) }, + name: "viewer-scoped no sessions", + tty: true, + capiStubs: func(t *testing.T, m *capi.CapiClientMock) { + m.ListSessionsForViewerFunc = func(ctx context.Context, limit int) ([]*capi.Session, error) { + return nil, nil + } + }, wantErr: cmdutil.NewNoResultsError("no agent tasks found"), }, { - name: "limit truncates sessions", + name: "viewer-scoped respects --limit", tty: true, - limit: 3, - stubs: func(reg *httpmock.Registry) { registerManySessionsMock(reg, createdAt) }, + limit: 999, + capiStubs: func(t *testing.T, m *capi.CapiClientMock) { + m.ListSessionsForViewerFunc = func(ctx context.Context, limit int) ([]*capi.Session, error) { + assert.Equal(t, 999, limit) + return nil, nil + } + }, + wantErr: cmdutil.NewNoResultsError("no agent tasks found"), // not important + }, + { + name: "viewer-scoped single session (tty)", + tty: true, + capiStubs: func(t *testing.T, m *capi.CapiClientMock) { + m.ListSessionsForViewerFunc = func(ctx context.Context, limit int) ([]*capi.Session, error) { + return []*capi.Session{ + { + ID: "s1", + State: "completed", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 101, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + }, nil + } + }, wantOut: heredoc.Doc(` - SESSION ID PULL REQUEST REPO SESSION STATE CREATED - s1 #101 OWNER/REPO completed about 6 hours ago - s2 #102 OWNER/REPO failed about 6 hours ago - s3 #103 OWNER/REPO in_progress about 6 hours ago + SESSION ID PULL REQUEST REPO SESSION STATE CREATED + s1 #101 OWNER/REPO completed about 6 hours ago `), }, { - name: "single session (tty)", - tty: true, - stubs: func(reg *httpmock.Registry) { registerSingleSessionMock(reg, createdAt) }, + name: "viewer-scoped single session (nontty)", + tty: false, + capiStubs: func(t *testing.T, m *capi.CapiClientMock) { + m.ListSessionsForViewerFunc = func(ctx context.Context, limit int) ([]*capi.Session, error) { + return []*capi.Session{ + { + ID: "s1", + State: "completed", + ResourceType: "pull", + CreatedAt: sampleDate, + PullRequest: &api.PullRequest{ + Number: 101, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + }, nil + } + }, + wantOut: "s1\t#101\tOWNER/REPO\tcompleted\t" + sampleDateString + "\n", // header omitted for non-tty + }, + { + name: "viewer-scoped many sessions (tty)", + tty: true, + capiStubs: func(t *testing.T, m *capi.CapiClientMock) { + m.ListSessionsForViewerFunc = func(ctx context.Context, limit int) ([]*capi.Session, error) { + return []*capi.Session{ + { + ID: "s1", + State: "completed", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 101, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + { + ID: "s2", + State: "failed", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 102, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + { + ID: "s3", + State: "in_progress", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 103, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + { + ID: "s4", + State: "queued", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 104, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + { + ID: "s5", + State: "canceled", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 105, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + { + ID: "s6", + State: "mystery", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 106, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + }, nil + } + }, wantOut: heredoc.Doc(` - SESSION ID PULL REQUEST REPO SESSION STATE CREATED - sess1 #42 OWNER/REPO completed about 6 hours ago + SESSION ID PULL REQUEST REPO SESSION STATE CREATED + s1 #101 OWNER/REPO completed about 6 hours ago + s2 #102 OWNER/REPO failed about 6 hours ago + s3 #103 OWNER/REPO in_progress about 6 hours ago + s4 #104 OWNER/REPO queued about 6 hours ago + s5 #105 OWNER/REPO canceled about 6 hours ago + s6 #106 OWNER/REPO mystery about 6 hours ago `), }, { - name: "single session (nontty)", - tty: false, - stubs: func(reg *httpmock.Registry) { registerSingleSessionMock(reg, createdAt) }, - wantOut: "sess1\t#42\tOWNER/REPO\tcompleted\t" + createdAt + "\n", // header omitted for non-tty - }, - { - name: "many sessions (tty)", - tty: true, - stubs: func(reg *httpmock.Registry) { registerManySessionsMock(reg, createdAt) }, - wantOut: heredoc.Doc(` - SESSION ID PULL REQUEST REPO SESSION STATE CREATED - s1 #101 OWNER/REPO completed about 6 hours ago - s2 #102 OWNER/REPO failed about 6 hours ago - s3 #103 OWNER/REPO in_progress about 6 hours ago - s4 #104 OWNER/REPO queued about 6 hours ago - s5 #105 OWNER/REPO canceled about 6 hours ago - s6 #106 OWNER/REPO mystery about 6 hours ago - `), - }, - { - name: "repo scoped single session", + name: "repo-scoped no sessions", tty: true, - stubs: func(reg *httpmock.Registry) { registerRepoSingleSessionMock(reg, createdAt, "OWNER", "REPO") }, baseRepo: ghrepo.New("OWNER", "REPO"), + capiStubs: func(t *testing.T, m *capi.CapiClientMock) { + m.ListSessionsForRepoFunc = func(ctx context.Context, owner, repo string, limit int) ([]*capi.Session, error) { + return nil, nil + } + }, + wantErr: cmdutil.NewNoResultsError("no agent tasks found"), + }, + { + name: "repo-scoped respects --limit/--repo", + tty: true, + limit: 999, + baseRepo: ghrepo.New("OWNER", "REPO"), + capiStubs: func(t *testing.T, m *capi.CapiClientMock) { + m.ListSessionsForRepoFunc = func(ctx context.Context, owner, repo string, limit int) ([]*capi.Session, error) { + assert.Equal(t, 999, limit) + assert.Equal(t, "OWNER", owner) + assert.Equal(t, "REPO", repo) + return nil, nil + } + }, + wantErr: cmdutil.NewNoResultsError("no agent tasks found"), // not important + }, + { + name: "repo-scoped single session (tty)", + tty: true, + baseRepo: ghrepo.New("OWNER", "REPO"), + capiStubs: func(t *testing.T, m *capi.CapiClientMock) { + m.ListSessionsForRepoFunc = func(ctx context.Context, owner, repo string, limit int) ([]*capi.Session, error) { + return []*capi.Session{ + { + ID: "s1", + State: "completed", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 101, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + }, nil + } + }, wantOut: heredoc.Doc(` - SESSION ID PULL REQUEST REPO SESSION STATE CREATED - sessR1 #55 OWNER/REPO completed about 6 hours ago + SESSION ID PULL REQUEST REPO SESSION STATE CREATED + s1 #101 OWNER/REPO completed about 6 hours ago `), }, { - name: "repo scoped no sessions", - tty: true, - stubs: func(reg *httpmock.Registry) { registerRepoEmptySessionsMock(reg, "OWNER", "REPO") }, + name: "repo-scoped single session (nontty)", + tty: false, baseRepo: ghrepo.New("OWNER", "REPO"), - wantErr: cmdutil.NewNoResultsError("no agent tasks found"), + capiStubs: func(t *testing.T, m *capi.CapiClientMock) { + m.ListSessionsForRepoFunc = func(ctx context.Context, owner, repo string, limit int) ([]*capi.Session, error) { + return []*capi.Session{ + { + ID: "s1", + State: "completed", + ResourceType: "pull", + CreatedAt: sampleDate, + PullRequest: &api.PullRequest{ + Number: 101, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + }, nil + } + }, + wantOut: "s1\t#101\tOWNER/REPO\tcompleted\t" + sampleDateString + "\n", // header omitted for non-tty + }, + { + name: "repo-scoped many sessions (tty)", + tty: true, + baseRepo: ghrepo.New("OWNER", "REPO"), + capiStubs: func(t *testing.T, m *capi.CapiClientMock) { + m.ListSessionsForRepoFunc = func(ctx context.Context, owner, repo string, limit int) ([]*capi.Session, error) { + return []*capi.Session{ + { + ID: "s1", + State: "completed", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 101, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + { + ID: "s2", + State: "failed", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 102, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + { + ID: "s3", + State: "in_progress", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 103, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + { + ID: "s4", + State: "queued", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 104, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + { + ID: "s5", + State: "canceled", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 105, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + { + ID: "s6", + State: "mystery", + CreatedAt: sampleDate, + ResourceType: "pull", + PullRequest: &api.PullRequest{ + Number: 106, + Repository: &api.PRRepository{ + NameWithOwner: "OWNER/REPO", + }, + }, + }, + }, nil + } + }, + wantOut: heredoc.Doc(` + SESSION ID PULL REQUEST REPO SESSION STATE CREATED + s1 #101 OWNER/REPO completed about 6 hours ago + s2 #102 OWNER/REPO failed about 6 hours ago + s3 #103 OWNER/REPO in_progress about 6 hours ago + s4 #104 OWNER/REPO queued about 6 hours ago + s5 #105 OWNER/REPO canceled about 6 hours ago + s6 #106 OWNER/REPO mystery about 6 hours ago + `), }, { name: "repo resolution error does not surface", tty: true, baseRepoErr: errors.New("ambiguous repo"), - wantErr: cmdutil.NewNoResultsError("no agent tasks found"), - stubs: func(reg *httpmock.Registry) { registerEmptySessionsMock(reg) }, - }, - { - name: "repo scoped many sessions (tty)", - tty: true, - stubs: func(reg *httpmock.Registry) { registerRepoManySessionsMock(reg, createdAt, "OWNER", "REPO") }, - baseRepo: ghrepo.New("OWNER", "REPO"), - wantOut: heredoc.Doc(` - SESSION ID PULL REQUEST REPO SESSION STATE CREATED - r1 #301 OWNER/REPO completed about 6 hours ago - r2 #302 OWNER/REPO failed about 6 hours ago - r3 #303 OWNER/REPO in_progress about 6 hours ago - r4 #304 OWNER/REPO queued about 6 hours ago - r5 #305 OWNER/REPO canceled about 6 hours ago - r6 #306 OWNER/REPO mystery about 6 hours ago - `), + capiStubs: func(t *testing.T, m *capi.CapiClientMock) { + // We expect a viewer-scoped fetch request: + m.ListSessionsForViewerFunc = func(ctx context.Context, limit int) ([]*capi.Session, error) { + return nil, nil + } + }, + wantErr: cmdutil.NewNoResultsError("no agent tasks found"), }, { name: "web mode", @@ -225,15 +484,11 @@ func Test_listRun(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - reg := &httpmock.Registry{} - if tt.stubs != nil { - tt.stubs(reg) + capiClientMock := &capi.CapiClientMock{} + if tt.capiStubs != nil { + tt.capiStubs(t, capiClientMock) } - cfg := config.NewBlankConfig() - cfg.Set("github.com", "oauth_token", "OTOKEN") - authCfg := cfg.Authentication() - ios, _, stdout, stderr := iostreams.Test() ios.SetStdoutTTY(tt.tty) @@ -242,11 +497,8 @@ func Test_listRun(t *testing.T) { br = &browser.Stub{} } - httpClient := &http.Client{Transport: reg} - capiClient := capi.NewCAPIClient(httpClient, authCfg) opts := &ListOptions{ IO: ios, - Config: func() (gh.Config, error) { return cfg, nil }, Limit: tt.limit, Web: tt.web, Browser: br, @@ -254,7 +506,7 @@ func Test_listRun(t *testing.T) { if tt.web { require.FailNow(t, "CapiClient was called with --web") } - return capiClient, nil + return capiClientMock, nil }, } if tt.baseRepo != nil || tt.baseRepoErr != nil { @@ -276,516 +528,6 @@ func Test_listRun(t *testing.T) { if tt.web { br.Verify(t, tt.wantBrowserURL) } - reg.Verify(t) }) } } - -// registerRepoSingleSessionMock mocks repo-scoped endpoint with one session and hydration. -func registerRepoSingleSessionMock(reg *httpmock.Registry, createdAt, owner, repo string) { - reg.Register( - httpmock.WithHost(httpmock.REST("GET", "agents/sessions/nwo/"+owner+"/"+repo), "api.githubcopilot.com"), - httpmock.StringResponse(heredoc.Docf(`{ - "sessions": [ - { - "id": "sessR1", - "name": "Repo build", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "completed", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 3000, - "created_at": "%[1]s" - } - ] - }`, createdAt)), - ) - // Second page empty (pagination end) - reg.Register( - httpmock.WithHost(httpmock.REST("GET", "agents/sessions/nwo/"+owner+"/"+repo), "api.githubcopilot.com"), - httpmock.StringResponse(heredoc.Doc(`{ - "sessions": [] - }`)), - ) - // Hydration - reg.Register( - httpmock.GraphQL(`query FetchPRs`), - httpmock.StringResponse(heredoc.Docf(`{ - "data": { - "nodes": [ - { - "id": "PR_nodeR1", - "fullDatabaseId": "3000", - "number": 55, - "title": "Improve build", - "state": "OPEN", - "url": "https://github.com/%[2]s/%[3]s/pull/55", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { "nameWithOwner": "%[2]s/%[3]s" } - } - ] - } -}`, createdAt, owner, repo)), - ) -} - -// registerRepoEmptySessionsMock mocks repo-scoped endpoint returning no sessions. -func registerRepoEmptySessionsMock(reg *httpmock.Registry, owner, repo string) { - reg.Register( - httpmock.WithHost(httpmock.REST("GET", "agents/sessions/nwo/"+owner+"/"+repo), "api.githubcopilot.com"), - httpmock.StringResponse(heredoc.Doc(`{ - "sessions": [] -}`)), - ) -} - -// registerRepoManySessionsMock mirrors registerManySessionsMock but for repo-scoped endpoint -func registerRepoManySessionsMock(reg *httpmock.Registry, createdAt, owner, repo string) { - reg.Register( - httpmock.WithHost(httpmock.REST("GET", "agents/sessions/nwo/"+owner+"/"+repo), "api.githubcopilot.com"), - httpmock.StringResponse(heredoc.Docf(`{ - "sessions": [ - { - "id": "r1", - "name": "A", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "completed", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 3001, - "created_at": "%[1]s" - }, - { - "id": "r2", - "name": "B", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "failed", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 3002, - "created_at": "%[1]s" - }, - { - "id": "r3", - "name": "C", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "in_progress", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 3003, - "created_at": "%[1]s" - }, - { - "id": "r4", - "name": "D", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "queued", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 3004, - "created_at": "%[1]s" - }, - { - "id": "r5", - "name": "E", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "canceled", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 3005, - "created_at": "%[1]s" - }, - { - "id": "r6", - "name": "F", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "mystery", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 3006, - "created_at": "%[1]s" - } - ] - }`, createdAt)), - ) - reg.Register( - httpmock.WithHost(httpmock.REST("GET", "agents/sessions/nwo/"+owner+"/"+repo), "api.githubcopilot.com"), - httpmock.StringResponse(heredoc.Doc(`{ - "sessions": [] - }`)), - ) - reg.Register( - httpmock.GraphQL(`query FetchPRs`), - httpmock.StringResponse(heredoc.Docf(`{ - "data": { - "nodes": [ - { - "id": "PR_r1", - "fullDatabaseId": "3001", - "number": 301, - "title": "PR 301", - "state": "OPEN", - "url": "https://github.com/%[2]s/%[3]s/pull/301", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "%[2]s/%[3]s" - } - }, - { - "id": "PR_r2", - "fullDatabaseId": "3002", - "number": 302, - "title": "PR 302", - "state": "OPEN", - "url": "https://github.com/%[2]s/%[3]s/pull/302", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "%[2]s/%[3]s" - } - }, - { - "id": "PR_r3", - "fullDatabaseId": "3003", - "number": 303, - "title": "PR 303", - "state": "OPEN", - "url": "https://github.com/%[2]s/%[3]s/pull/303", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "%[2]s/%[3]s" - } - }, - { - "id": "PR_r4", - "fullDatabaseId": "3004", - "number": 304, - "title": "PR 304", - "state": "OPEN", - "url": "https://github.com/%[2]s/%[3]s/pull/304", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "%[2]s/%[3]s" - } - }, - { - "id": "PR_r5", - "fullDatabaseId": "3005", - "number": 305, - "title": "PR 305", - "state": "OPEN", - "url": "https://github.com/%[2]s/%[3]s/pull/305", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "%[2]s/%[3]s" - } - }, - { - "id": "PR_r6", - "fullDatabaseId": "3006", - "number": 306, - "title": "PR 306", - "state": "OPEN", - "url": "https://github.com/%[2]s/%[3]s/pull/306", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "%[2]s/%[3]s" - } - } - ] - } - }`, createdAt, owner, repo)), - ) -} - -// registerEmptySessionsMock registers a single empty page of sessions -func registerEmptySessionsMock(reg *httpmock.Registry) { - reg.Register( - httpmock.WithHost(httpmock.REST("GET", "agents/sessions"), "api.githubcopilot.com"), - httpmock.StringResponse(heredoc.Doc(`{ - "sessions": [] - }`)), - ) -} - -// registerSingleSessionMock registers two REST pages (one with a session, one empty) and GraphQL hydration for that session's PR -func registerSingleSessionMock(reg *httpmock.Registry, createdAt string) { - // First page with one session - reg.Register( - httpmock.WithHost(httpmock.REST("GET", "agents/sessions"), "api.githubcopilot.com"), - httpmock.StringResponse(heredoc.Docf(`{ - "sessions": [ - { - "id": "sess1", - "name": "Build artifacts", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "completed", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 2000, - "created_at": "%[1]s" - } - ] -}`, createdAt)), - ) - // Second page empty to terminate pagination - reg.Register( - httpmock.WithHost(httpmock.REST("GET", "agents/sessions"), "api.githubcopilot.com"), - httpmock.StringResponse(heredoc.Doc(`{ - "sessions": [] - }`)), - ) - // GraphQL hydration - reg.Register( - httpmock.GraphQL(`query FetchPRs`), - httpmock.StringResponse(heredoc.Docf(`{ - "data": { - "nodes": [ - { - "id": "PR_node", - "fullDatabaseId": "2000", - "number": 42, - "title": "Improve docs", - "state": "OPEN", - "url": "https://github.com/OWNER/REPO/pull/42", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "OWNER/REPO" - } - } - ] - } - }`, createdAt)), - ) -} - -// registerManySessionsMock registers multiple sessions covering various states -// States covered: completed, failed, in_progress, queued, canceled, (unknown -> treated as muted) -func registerManySessionsMock(reg *httpmock.Registry, createdAt string) { - // First page returns six sessions - reg.Register( - httpmock.WithHost(httpmock.REST("GET", "agents/sessions"), "api.githubcopilot.com"), - httpmock.StringResponse(heredoc.Docf(`{ - "sessions": [ - { - "id": "s1", - "name": "A", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "completed", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 2000, - "created_at": "%[1]s" - }, - { - "id": "s2", - "name": "B", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "failed", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 2001, - "created_at": "%[1]s" - }, - { - "id": "s3", - "name": "C", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "in_progress", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 2002, - "created_at": "%[1]s" - }, - { - "id": "s4", - "name": "D", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "queued", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 2003, - "created_at": "%[1]s" - }, - { - "id": "s5", - "name": "E", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "canceled", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 2004, - "created_at": "%[1]s" - }, - { - "id": "s6", - "name": "F", - "user_id": 1, - "agent_id": 2, - "logs": "", - "state": "mystery", - "owner_id": 10, - "repo_id": 1000, - "resource_type": "pull", - "resource_id": 2005, - "created_at": "%[1]s" - } - ] -}`, createdAt)), - ) - // Second page empty - reg.Register( - httpmock.WithHost(httpmock.REST("GET", "agents/sessions"), "api.githubcopilot.com"), - httpmock.StringResponse(heredoc.Doc(`{ - "sessions": [] - }`)), - ) - // GraphQL hydration for 6 PRs - reg.Register( - httpmock.GraphQL(`query FetchPRs`), - httpmock.StringResponse(heredoc.Docf(`{ - "data": { - "nodes": [ - { - "id": "PR_node1", - "fullDatabaseId": "2000", - "number": 101, - "title": "PR 101", - "state": "OPEN", - "url": "https://github.com/OWNER/REPO/pull/101", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "OWNER/REPO" - } - }, - { - "id": "PR_node2", - "fullDatabaseId": "2001", - "number": 102, - "title": "PR 102", - "state": "OPEN", - "url": "https://github.com/OWNER/REPO/pull/102", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "OWNER/REPO" - } - }, - { - "id": "PR_node3", - "fullDatabaseId": "2002", - "number": 103, - "title": "PR 103", - "state": "OPEN", - "url": "https://github.com/OWNER/REPO/pull/103", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "OWNER/REPO" - } - }, - { - "id": "PR_node4", - "fullDatabaseId": "2003", - "number": 104, - "title": "PR 104", - "state": "OPEN", - "url": "https://github.com/OWNER/REPO/pull/104", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "OWNER/REPO" - } - }, - { - "id": "PR_node5", - "fullDatabaseId": "2004", - "number": 105, - "title": "PR 105", - "state": "OPEN", - "url": "https://github.com/OWNER/REPO/pull/105", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "OWNER/REPO" - } - }, - { - "id": "PR_node6", - "fullDatabaseId": "2005", - "number": 106, - "title": "PR 106", - "state": "OPEN", - "url": "https://github.com/OWNER/REPO/pull/106", - "body": "", - "createdAt": "%[1]s", - "updatedAt": "%[1]s", - "repository": { - "nameWithOwner": "OWNER/REPO" - } - } - ] - } - }`, createdAt)), - ) -}