770 lines
19 KiB
Go
770 lines
19 KiB
Go
package list
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/MakeNowJust/heredoc"
|
|
"github.com/cli/cli/v2/internal/browser"
|
|
"github.com/cli/cli/v2/internal/config"
|
|
"github.com/cli/cli/v2/internal/gh"
|
|
"github.com/cli/cli/v2/internal/ghrepo"
|
|
"github.com/cli/cli/v2/pkg/cmd/agent-task/capi"
|
|
"github.com/cli/cli/v2/pkg/cmdutil"
|
|
"github.com/cli/cli/v2/pkg/httpmock"
|
|
"github.com/cli/cli/v2/pkg/iostreams"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestNewCmdList(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
args string
|
|
wantOpts ListOptions
|
|
wantErr string
|
|
}{
|
|
{
|
|
name: "no arguments",
|
|
wantOpts: ListOptions{
|
|
Limit: defaultLimit,
|
|
},
|
|
},
|
|
{
|
|
name: "custom limit",
|
|
args: "--limit 15",
|
|
wantOpts: ListOptions{
|
|
Limit: 15,
|
|
},
|
|
},
|
|
{
|
|
name: "invalid limit",
|
|
args: "--limit 0",
|
|
wantErr: "invalid limit: 0",
|
|
},
|
|
{
|
|
name: "negative limit",
|
|
args: "--limit -5",
|
|
wantErr: "invalid limit: -5",
|
|
},
|
|
{
|
|
name: "web flag",
|
|
args: "--web",
|
|
wantOpts: ListOptions{
|
|
Limit: defaultLimit,
|
|
Web: true,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := &cmdutil.Factory{}
|
|
var gotOpts *ListOptions
|
|
cmd := NewCmdList(f, func(opts *ListOptions) error { gotOpts = opts; return nil })
|
|
if tt.args != "" {
|
|
cmd.SetArgs(strings.Split(tt.args, " "))
|
|
}
|
|
_, err := cmd.ExecuteC()
|
|
if tt.wantErr != "" {
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), tt.wantErr)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.wantOpts.Limit, gotOpts.Limit)
|
|
assert.Equal(t, tt.wantOpts.Web, gotOpts.Web)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_listRun(t *testing.T) {
|
|
createdAt := time.Now().Add(-6 * time.Hour).Format(time.RFC3339) // 6h ago
|
|
|
|
tests := []struct {
|
|
name string
|
|
tty bool
|
|
stubs func(*httpmock.Registry)
|
|
baseRepo ghrepo.Interface
|
|
baseRepoErr error
|
|
limit int
|
|
web bool
|
|
wantOut string
|
|
wantErr error
|
|
wantStderr string
|
|
wantBrowserURL string
|
|
}{
|
|
{
|
|
name: "no sessions",
|
|
tty: true,
|
|
stubs: func(reg *httpmock.Registry) { registerEmptySessionsMock(reg) },
|
|
wantErr: cmdutil.NewNoResultsError("no agent tasks found"),
|
|
},
|
|
{
|
|
name: "limit truncates sessions",
|
|
tty: true,
|
|
limit: 3,
|
|
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
|
|
`),
|
|
},
|
|
{
|
|
name: "single session (tty)",
|
|
tty: true,
|
|
stubs: func(reg *httpmock.Registry) { registerSingleSessionMock(reg, createdAt) },
|
|
wantOut: heredoc.Doc(`
|
|
SESSION ID PULL REQUEST REPO SESSION STATE CREATED
|
|
sess1 #42 OWNER/REPO completed 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",
|
|
tty: true,
|
|
stubs: func(reg *httpmock.Registry) { registerRepoSingleSessionMock(reg, createdAt, "OWNER", "REPO") },
|
|
baseRepo: ghrepo.New("OWNER", "REPO"),
|
|
wantOut: heredoc.Doc(`
|
|
SESSION ID PULL REQUEST REPO SESSION STATE CREATED
|
|
sessR1 #55 OWNER/REPO completed about 6 hours ago
|
|
`),
|
|
},
|
|
{
|
|
name: "repo scoped no sessions",
|
|
tty: true,
|
|
stubs: func(reg *httpmock.Registry) { registerRepoEmptySessionsMock(reg, "OWNER", "REPO") },
|
|
baseRepo: ghrepo.New("OWNER", "REPO"),
|
|
wantErr: cmdutil.NewNoResultsError("no agent tasks found"),
|
|
},
|
|
{
|
|
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
|
|
`),
|
|
},
|
|
{
|
|
name: "web mode",
|
|
tty: true,
|
|
web: true,
|
|
wantOut: "",
|
|
wantStderr: "Opening https://github.com/copilot/agents in your browser.\n",
|
|
wantBrowserURL: "https://github.com/copilot/agents",
|
|
},
|
|
{
|
|
name: "web mode with repo still uses global URL, even when --repo is set",
|
|
tty: true,
|
|
web: true,
|
|
baseRepo: ghrepo.New("OWNER", "REPO"),
|
|
wantOut: "",
|
|
wantStderr: "Opening https://github.com/copilot/agents in your browser.\n",
|
|
wantBrowserURL: "https://github.com/copilot/agents",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
reg := &httpmock.Registry{}
|
|
if tt.stubs != nil {
|
|
tt.stubs(reg)
|
|
}
|
|
|
|
cfg := config.NewBlankConfig()
|
|
cfg.Set("github.com", "oauth_token", "OTOKEN")
|
|
authCfg := cfg.Authentication()
|
|
|
|
ios, _, stdout, stderr := iostreams.Test()
|
|
ios.SetStdoutTTY(tt.tty)
|
|
|
|
var br *browser.Stub
|
|
if tt.web {
|
|
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,
|
|
CapiClient: func() (capi.CapiClient, error) {
|
|
if tt.web {
|
|
require.FailNow(t, "CapiClient was called with --web")
|
|
}
|
|
return capiClient, nil
|
|
},
|
|
}
|
|
if tt.baseRepo != nil || tt.baseRepoErr != nil {
|
|
baseRepo := tt.baseRepo
|
|
baseRepoErr := tt.baseRepoErr
|
|
opts.BaseRepo = func() (ghrepo.Interface, error) { return baseRepo, baseRepoErr }
|
|
}
|
|
|
|
err := listRun(opts)
|
|
if tt.wantErr != nil {
|
|
assert.Error(t, err)
|
|
require.EqualError(t, err, tt.wantErr.Error())
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
got := stdout.String()
|
|
require.Equal(t, tt.wantOut, got)
|
|
require.Equal(t, tt.wantStderr, stderr.String())
|
|
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)),
|
|
)
|
|
}
|