package archive import ( "bytes" "fmt" "net/http" "testing" "github.com/cli/cli/v2/internal/ghrepo" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/httpmock" "github.com/cli/cli/v2/pkg/iostreams" "github.com/cli/cli/v2/pkg/prompt" "github.com/google/shlex" "github.com/stretchr/testify/assert" ) func TestNewCmdArchive(t *testing.T) { tests := []struct { name string input string wantErr bool output ArchiveOptions errMsg string }{ { name: "no arguments no tty", input: "", errMsg: "--confirm required when not running interactively", wantErr: true, }, { name: "repo argument tty", input: "OWNER/REPO --confirm", output: ArchiveOptions{RepoArg: "OWNER/REPO", Confirmed: true}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ios, _, _, _ := iostreams.Test() f := &cmdutil.Factory{ IOStreams: ios, } argv, err := shlex.Split(tt.input) assert.NoError(t, err) var gotOpts *ArchiveOptions cmd := NewCmdArchive(f, func(opts *ArchiveOptions) error { gotOpts = opts return nil }) cmd.SetArgs(argv) cmd.SetIn(&bytes.Buffer{}) cmd.SetOut(&bytes.Buffer{}) cmd.SetErr(&bytes.Buffer{}) _, err = cmd.ExecuteC() if tt.wantErr { assert.Error(t, err) return } assert.NoError(t, err) assert.Equal(t, tt.output.RepoArg, gotOpts.RepoArg) assert.Equal(t, tt.output.Confirmed, gotOpts.Confirmed) }) } } func Test_ArchiveRun(t *testing.T) { queryResponse := `{ "data": { "repository": { "id": "THE-ID","isArchived": %s} } }` tests := []struct { name string opts ArchiveOptions httpStubs func(*httpmock.Registry) askStubs func(*prompt.AskStubber) isTTY bool wantStdout string wantStderr string }{ { name: "unarchived repo tty", wantStdout: "✓ Archived repository OWNER/REPO\n", askStubs: func(q *prompt.AskStubber) { //nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt q.StubOne(true) }, isTTY: true, opts: ArchiveOptions{RepoArg: "OWNER/REPO"}, httpStubs: func(reg *httpmock.Registry) { reg.Register( httpmock.GraphQL(`query RepositoryInfo\b`), httpmock.StringResponse(fmt.Sprintf(queryResponse, "false"))) reg.Register( httpmock.GraphQL(`mutation ArchiveRepository\b`), httpmock.StringResponse(`{}`)) }, }, { name: "infer base repo", wantStdout: "✓ Archived repository OWNER/REPO\n", opts: ArchiveOptions{}, askStubs: func(q *prompt.AskStubber) { //nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt q.StubOne(true) }, isTTY: true, httpStubs: func(reg *httpmock.Registry) { reg.Register( httpmock.GraphQL(`query RepositoryInfo\b`), httpmock.StringResponse(fmt.Sprintf(queryResponse, "false"))) reg.Register( httpmock.GraphQL(`mutation ArchiveRepository\b`), httpmock.StringResponse(`{}`)) }, }, { name: "archived repo tty", wantStderr: "! Repository OWNER/REPO is already archived\n", opts: ArchiveOptions{RepoArg: "OWNER/REPO"}, httpStubs: func(reg *httpmock.Registry) { reg.Register( httpmock.GraphQL(`query RepositoryInfo\b`), httpmock.StringResponse(fmt.Sprintf(queryResponse, "true"))) }, }, } for _, tt := range tests { repo, _ := ghrepo.FromFullName("OWNER/REPO") reg := &httpmock.Registry{} if tt.httpStubs != nil { tt.httpStubs(reg) } tt.opts.BaseRepo = func() (ghrepo.Interface, error) { return repo, nil } tt.opts.HttpClient = func() (*http.Client, error) { return &http.Client{Transport: reg}, nil } ios, _, stdout, stderr := iostreams.Test() tt.opts.IO = ios //nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber q, teardown := prompt.InitAskStubber() defer teardown() if tt.askStubs != nil { tt.askStubs(q) } t.Run(tt.name, func(t *testing.T) { defer reg.Verify(t) ios.SetStdoutTTY(tt.isTTY) ios.SetStderrTTY(tt.isTTY) err := archiveRun(&tt.opts) assert.NoError(t, err) assert.Equal(t, tt.wantStdout, stdout.String()) assert.Equal(t, tt.wantStderr, stderr.String()) }) } }