github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/pr/ready/ready_test.go (about)

     1  package ready
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"net/http"
     7  	"testing"
     8  
     9  	"github.com/ungtb10d/cli/v2/api"
    10  	"github.com/ungtb10d/cli/v2/internal/ghrepo"
    11  	"github.com/ungtb10d/cli/v2/pkg/cmd/pr/shared"
    12  	"github.com/ungtb10d/cli/v2/pkg/cmdutil"
    13  	"github.com/ungtb10d/cli/v2/pkg/httpmock"
    14  	"github.com/ungtb10d/cli/v2/pkg/iostreams"
    15  	"github.com/ungtb10d/cli/v2/test"
    16  	"github.com/google/shlex"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func Test_NewCmdReady(t *testing.T) {
    22  	tests := []struct {
    23  		name    string
    24  		args    string
    25  		isTTY   bool
    26  		want    ReadyOptions
    27  		wantErr string
    28  	}{
    29  		{
    30  			name:  "number argument",
    31  			args:  "123",
    32  			isTTY: true,
    33  			want: ReadyOptions{
    34  				SelectorArg: "123",
    35  			},
    36  		},
    37  		{
    38  			name:  "no argument",
    39  			args:  "",
    40  			isTTY: true,
    41  			want: ReadyOptions{
    42  				SelectorArg: "",
    43  			},
    44  		},
    45  		{
    46  			name:    "no argument with --repo override",
    47  			args:    "-R owner/repo",
    48  			isTTY:   true,
    49  			wantErr: "argument required when using the --repo flag",
    50  		},
    51  	}
    52  	for _, tt := range tests {
    53  		t.Run(tt.name, func(t *testing.T) {
    54  			ios, _, _, _ := iostreams.Test()
    55  			ios.SetStdoutTTY(tt.isTTY)
    56  			ios.SetStdinTTY(tt.isTTY)
    57  			ios.SetStderrTTY(tt.isTTY)
    58  
    59  			f := &cmdutil.Factory{
    60  				IOStreams: ios,
    61  			}
    62  
    63  			var opts *ReadyOptions
    64  			cmd := NewCmdReady(f, func(o *ReadyOptions) error {
    65  				opts = o
    66  				return nil
    67  			})
    68  			cmd.PersistentFlags().StringP("repo", "R", "", "")
    69  
    70  			argv, err := shlex.Split(tt.args)
    71  			require.NoError(t, err)
    72  			cmd.SetArgs(argv)
    73  
    74  			cmd.SetIn(&bytes.Buffer{})
    75  			cmd.SetOut(io.Discard)
    76  			cmd.SetErr(io.Discard)
    77  
    78  			_, err = cmd.ExecuteC()
    79  			if tt.wantErr != "" {
    80  				require.EqualError(t, err, tt.wantErr)
    81  				return
    82  			} else {
    83  				require.NoError(t, err)
    84  			}
    85  
    86  			assert.Equal(t, tt.want.SelectorArg, opts.SelectorArg)
    87  		})
    88  	}
    89  }
    90  
    91  func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
    92  	ios, _, stdout, stderr := iostreams.Test()
    93  	ios.SetStdoutTTY(isTTY)
    94  	ios.SetStdinTTY(isTTY)
    95  	ios.SetStderrTTY(isTTY)
    96  
    97  	factory := &cmdutil.Factory{
    98  		IOStreams: ios,
    99  		HttpClient: func() (*http.Client, error) {
   100  			return &http.Client{Transport: rt}, nil
   101  		},
   102  	}
   103  
   104  	cmd := NewCmdReady(factory, nil)
   105  
   106  	argv, err := shlex.Split(cli)
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	cmd.SetArgs(argv)
   111  
   112  	cmd.SetIn(&bytes.Buffer{})
   113  	cmd.SetOut(io.Discard)
   114  	cmd.SetErr(io.Discard)
   115  
   116  	_, err = cmd.ExecuteC()
   117  	return &test.CmdOut{
   118  		OutBuf: stdout,
   119  		ErrBuf: stderr,
   120  	}, err
   121  }
   122  
   123  func TestPRReady(t *testing.T) {
   124  	http := &httpmock.Registry{}
   125  	defer http.Verify(t)
   126  
   127  	shared.RunCommandFinder("123", &api.PullRequest{
   128  		ID:      "THE-ID",
   129  		Number:  123,
   130  		State:   "OPEN",
   131  		IsDraft: true,
   132  	}, ghrepo.New("OWNER", "REPO"))
   133  
   134  	http.Register(
   135  		httpmock.GraphQL(`mutation PullRequestReadyForReview\b`),
   136  		httpmock.GraphQLMutation(`{"id": "THE-ID"}`,
   137  			func(inputs map[string]interface{}) {
   138  				assert.Equal(t, inputs["pullRequestId"], "THE-ID")
   139  			}),
   140  	)
   141  
   142  	output, err := runCommand(http, true, "123")
   143  	assert.NoError(t, err)
   144  	assert.Equal(t, "", output.String())
   145  	assert.Equal(t, "✓ Pull request #123 is marked as \"ready for review\"\n", output.Stderr())
   146  }
   147  
   148  func TestPRReady_alreadyReady(t *testing.T) {
   149  	http := &httpmock.Registry{}
   150  	defer http.Verify(t)
   151  
   152  	shared.RunCommandFinder("123", &api.PullRequest{
   153  		ID:      "THE-ID",
   154  		Number:  123,
   155  		State:   "OPEN",
   156  		IsDraft: false,
   157  	}, ghrepo.New("OWNER", "REPO"))
   158  
   159  	output, err := runCommand(http, true, "123")
   160  	assert.NoError(t, err)
   161  	assert.Equal(t, "", output.String())
   162  	assert.Equal(t, "! Pull request #123 is already \"ready for review\"\n", output.Stderr())
   163  }
   164  
   165  func TestPRReadyUndo(t *testing.T) {
   166  	http := &httpmock.Registry{}
   167  	defer http.Verify(t)
   168  
   169  	shared.RunCommandFinder("123", &api.PullRequest{
   170  		ID:      "THE-ID",
   171  		Number:  123,
   172  		State:   "OPEN",
   173  		IsDraft: false,
   174  	}, ghrepo.New("OWNER", "REPO"))
   175  
   176  	http.Register(
   177  		httpmock.GraphQL(`mutation ConvertPullRequestToDraft\b`),
   178  		httpmock.GraphQLMutation(`{"id": "THE-ID"}`,
   179  			func(inputs map[string]interface{}) {
   180  				assert.Equal(t, inputs["pullRequestId"], "THE-ID")
   181  			}),
   182  	)
   183  
   184  	output, err := runCommand(http, true, "123 --undo")
   185  	assert.NoError(t, err)
   186  	assert.Equal(t, "", output.String())
   187  	assert.Equal(t, "✓ Pull request #123 is converted to \"draft\"\n", output.Stderr())
   188  }
   189  
   190  func TestPRReadyUndo_alreadyDraft(t *testing.T) {
   191  	http := &httpmock.Registry{}
   192  	defer http.Verify(t)
   193  
   194  	shared.RunCommandFinder("123", &api.PullRequest{
   195  		ID:      "THE-ID",
   196  		Number:  123,
   197  		State:   "OPEN",
   198  		IsDraft: true,
   199  	}, ghrepo.New("OWNER", "REPO"))
   200  
   201  	output, err := runCommand(http, true, "123 --undo")
   202  	assert.NoError(t, err)
   203  	assert.Equal(t, "", output.String())
   204  	assert.Equal(t, "! Pull request #123 is already \"in draft\"\n", output.Stderr())
   205  }
   206  
   207  func TestPRReady_closed(t *testing.T) {
   208  	http := &httpmock.Registry{}
   209  	defer http.Verify(t)
   210  
   211  	shared.RunCommandFinder("123", &api.PullRequest{
   212  		ID:      "THE-ID",
   213  		Number:  123,
   214  		State:   "CLOSED",
   215  		IsDraft: true,
   216  	}, ghrepo.New("OWNER", "REPO"))
   217  
   218  	output, err := runCommand(http, true, "123")
   219  	assert.EqualError(t, err, "SilentError")
   220  	assert.Equal(t, "", output.String())
   221  	assert.Equal(t, "X Pull request #123 is closed. Only draft pull requests can be marked as \"ready for review\"\n", output.Stderr())
   222  }