github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/label/create_test.go (about)

     1  package label
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"io"
     7  	"net/http"
     8  	"testing"
     9  
    10  	"github.com/ungtb10d/cli/v2/internal/ghrepo"
    11  	"github.com/ungtb10d/cli/v2/pkg/cmdutil"
    12  	"github.com/ungtb10d/cli/v2/pkg/httpmock"
    13  	"github.com/ungtb10d/cli/v2/pkg/iostreams"
    14  	"github.com/google/shlex"
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  func TestNewCmdCreate(t *testing.T) {
    19  	tests := []struct {
    20  		name    string
    21  		input   string
    22  		output  createOptions
    23  		wantErr bool
    24  		errMsg  string
    25  	}{
    26  		{
    27  			name:    "no argument",
    28  			input:   "",
    29  			wantErr: true,
    30  			errMsg:  "cannot create label: name argument required",
    31  		},
    32  		{
    33  			name:   "name argument",
    34  			input:  "test",
    35  			output: createOptions{Name: "test"},
    36  		},
    37  		{
    38  			name:   "description flag",
    39  			input:  "test --description 'some description'",
    40  			output: createOptions{Name: "test", Description: "some description"},
    41  		},
    42  		{
    43  			name:   "color flag",
    44  			input:  "test --color FFFFFF",
    45  			output: createOptions{Name: "test", Color: "FFFFFF"},
    46  		},
    47  		{
    48  			name:   "color flag with pound sign",
    49  			input:  "test --color '#AAAAAA'",
    50  			output: createOptions{Name: "test", Color: "AAAAAA"},
    51  		},
    52  	}
    53  
    54  	for _, tt := range tests {
    55  		t.Run(tt.name, func(t *testing.T) {
    56  			ios, _, _, _ := iostreams.Test()
    57  			f := &cmdutil.Factory{
    58  				IOStreams: ios,
    59  			}
    60  			argv, err := shlex.Split(tt.input)
    61  			assert.NoError(t, err)
    62  			var gotOpts *createOptions
    63  			cmd := newCmdCreate(f, func(opts *createOptions) error {
    64  				gotOpts = opts
    65  				return nil
    66  			})
    67  			cmd.SetArgs(argv)
    68  			cmd.SetIn(&bytes.Buffer{})
    69  			cmd.SetOut(&bytes.Buffer{})
    70  			cmd.SetErr(&bytes.Buffer{})
    71  
    72  			_, err = cmd.ExecuteC()
    73  			if tt.wantErr {
    74  				assert.EqualError(t, err, tt.errMsg)
    75  				return
    76  			}
    77  
    78  			assert.NoError(t, err)
    79  			assert.Equal(t, tt.output.Color, gotOpts.Color)
    80  			assert.Equal(t, tt.output.Description, gotOpts.Description)
    81  			assert.Equal(t, tt.output.Name, gotOpts.Name)
    82  		})
    83  	}
    84  }
    85  
    86  func TestCreateRun(t *testing.T) {
    87  	tests := []struct {
    88  		name       string
    89  		tty        bool
    90  		opts       *createOptions
    91  		httpStubs  func(*httpmock.Registry)
    92  		wantStdout string
    93  	}{
    94  		{
    95  			name: "creates label",
    96  			tty:  true,
    97  			opts: &createOptions{Name: "test", Description: "some description"},
    98  			httpStubs: func(reg *httpmock.Registry) {
    99  				reg.Register(
   100  					httpmock.REST("POST", "repos/OWNER/REPO/labels"),
   101  					httpmock.StatusStringResponse(201, "{}"),
   102  				)
   103  			},
   104  			wantStdout: "✓ Label \"test\" created in OWNER/REPO\n",
   105  		},
   106  		{
   107  			name: "creates label notty",
   108  			tty:  false,
   109  			opts: &createOptions{Name: "test", Description: "some description"},
   110  			httpStubs: func(reg *httpmock.Registry) {
   111  				reg.Register(
   112  					httpmock.REST("POST", "repos/OWNER/REPO/labels"),
   113  					httpmock.StatusStringResponse(201, "{}"),
   114  				)
   115  			},
   116  			wantStdout: "",
   117  		},
   118  		{
   119  			name: "creates existing label",
   120  			opts: &createOptions{Name: "test", Description: "some description", Force: true},
   121  			httpStubs: func(reg *httpmock.Registry) {
   122  				reg.Register(
   123  					httpmock.REST("POST", "repos/OWNER/REPO/labels"),
   124  					httpmock.WithHeader(
   125  						httpmock.StatusStringResponse(422, `{"message":"Validation Failed","errors":[{"resource":"Label","code":"already_exists","field":"name"}]}`),
   126  						"Content-Type",
   127  						"application/json",
   128  					),
   129  				)
   130  				reg.Register(
   131  					httpmock.REST("PATCH", "repos/OWNER/REPO/labels/test"),
   132  					httpmock.StatusStringResponse(201, "{}"),
   133  				)
   134  			},
   135  		},
   136  	}
   137  
   138  	for _, tt := range tests {
   139  		t.Run(tt.name, func(t *testing.T) {
   140  			reg := &httpmock.Registry{}
   141  			if tt.httpStubs != nil {
   142  				tt.httpStubs(reg)
   143  			}
   144  			tt.opts.HttpClient = func() (*http.Client, error) {
   145  				return &http.Client{Transport: reg}, nil
   146  			}
   147  			ios, _, stdout, _ := iostreams.Test()
   148  			ios.SetStdoutTTY(tt.tty)
   149  			ios.SetStdinTTY(tt.tty)
   150  			ios.SetStderrTTY(tt.tty)
   151  			tt.opts.IO = ios
   152  			tt.opts.BaseRepo = func() (ghrepo.Interface, error) {
   153  				return ghrepo.New("OWNER", "REPO"), nil
   154  			}
   155  			defer reg.Verify(t)
   156  			err := createRun(tt.opts)
   157  			assert.NoError(t, err)
   158  			assert.Equal(t, tt.wantStdout, stdout.String())
   159  
   160  			bodyBytes, _ := io.ReadAll(reg.Requests[0].Body)
   161  			reqBody := map[string]string{}
   162  			err = json.Unmarshal(bodyBytes, &reqBody)
   163  			assert.NoError(t, err)
   164  			assert.NotEqual(t, "", reqBody["color"])
   165  			assert.Equal(t, "some description", reqBody["description"])
   166  			assert.Equal(t, "test", reqBody["name"])
   167  		})
   168  	}
   169  }