github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/repo/create/http_test.go (about)

     1  package create
     2  
     3  import (
     4  	"net/http"
     5  	"testing"
     6  
     7  	"github.com/ungtb10d/cli/v2/internal/ghrepo"
     8  	"github.com/ungtb10d/cli/v2/pkg/httpmock"
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func Test_repoCreate(t *testing.T) {
    13  	tests := []struct {
    14  		name     string
    15  		hostname string
    16  		input    repoCreateInput
    17  		stubs    func(t *testing.T, r *httpmock.Registry)
    18  		wantErr  bool
    19  		wantRepo string
    20  	}{
    21  		{
    22  			name:     "create personal repository",
    23  			hostname: "github.com",
    24  			input: repoCreateInput{
    25  				Name:             "winter-foods",
    26  				Description:      "roasted chestnuts",
    27  				HomepageURL:      "http://example.com",
    28  				Visibility:       "public",
    29  				HasIssuesEnabled: true,
    30  				HasWikiEnabled:   true,
    31  			},
    32  			stubs: func(t *testing.T, r *httpmock.Registry) {
    33  				r.Register(
    34  					httpmock.GraphQL(`mutation RepositoryCreate\b`),
    35  					httpmock.GraphQLMutation(
    36  						`{
    37  							"data": {
    38  								"createRepository": {
    39  									"repository": {
    40  										"id": "REPOID",
    41  										"name": "REPO",
    42  										"owner": {"login":"OWNER"},
    43  										"url": "the://URL"
    44  									}
    45  								}
    46  							}
    47  						}`,
    48  						func(inputs map[string]interface{}) {
    49  							assert.Equal(t, map[string]interface{}{
    50  								"name":             "winter-foods",
    51  								"description":      "roasted chestnuts",
    52  								"homepageUrl":      "http://example.com",
    53  								"visibility":       "PUBLIC",
    54  								"hasIssuesEnabled": true,
    55  								"hasWikiEnabled":   true,
    56  							}, inputs)
    57  						}),
    58  				)
    59  			},
    60  			wantRepo: "https://github.com/OWNER/REPO",
    61  		},
    62  		{
    63  			name:     "create Enterprise repository",
    64  			hostname: "example.com",
    65  			input: repoCreateInput{
    66  				Name:             "winter-foods",
    67  				Description:      "roasted chestnuts",
    68  				HomepageURL:      "http://example.com",
    69  				Visibility:       "public",
    70  				HasIssuesEnabled: true,
    71  				HasWikiEnabled:   true,
    72  			},
    73  			stubs: func(t *testing.T, r *httpmock.Registry) {
    74  				r.Register(
    75  					httpmock.GraphQL(`mutation RepositoryCreate\b`),
    76  					httpmock.GraphQLMutation(
    77  						`{
    78  							"data": {
    79  								"createRepository": {
    80  									"repository": {
    81  										"id": "REPOID",
    82  										"name": "REPO",
    83  										"owner": {"login":"OWNER"},
    84  										"url": "the://URL"
    85  									}
    86  								}
    87  							}
    88  						}`,
    89  						func(inputs map[string]interface{}) {
    90  							assert.Equal(t, map[string]interface{}{
    91  								"name":             "winter-foods",
    92  								"description":      "roasted chestnuts",
    93  								"homepageUrl":      "http://example.com",
    94  								"visibility":       "PUBLIC",
    95  								"hasIssuesEnabled": true,
    96  								"hasWikiEnabled":   true,
    97  							}, inputs)
    98  						}),
    99  				)
   100  			},
   101  			wantRepo: "https://example.com/OWNER/REPO",
   102  		},
   103  		{
   104  			name:     "create in organization",
   105  			hostname: "github.com",
   106  			input: repoCreateInput{
   107  				Name:             "crisps",
   108  				Visibility:       "internal",
   109  				OwnerLogin:       "snacks-inc",
   110  				HasIssuesEnabled: true,
   111  				HasWikiEnabled:   true,
   112  			},
   113  			stubs: func(t *testing.T, r *httpmock.Registry) {
   114  				r.Register(
   115  					httpmock.REST("GET", "users/snacks-inc"),
   116  					httpmock.StringResponse(`{ "node_id": "ORGID", "type": "Organization" }`))
   117  				r.Register(
   118  					httpmock.GraphQL(`mutation RepositoryCreate\b`),
   119  					httpmock.GraphQLMutation(
   120  						`{
   121  							"data": {
   122  								"createRepository": {
   123  									"repository": {
   124  										"id": "REPOID",
   125  										"name": "REPO",
   126  										"owner": {"login":"OWNER"},
   127  										"url": "the://URL"
   128  									}
   129  								}
   130  							}
   131  						}`,
   132  						func(inputs map[string]interface{}) {
   133  							assert.Equal(t, map[string]interface{}{
   134  								"name":             "crisps",
   135  								"visibility":       "INTERNAL",
   136  								"ownerId":          "ORGID",
   137  								"hasIssuesEnabled": true,
   138  								"hasWikiEnabled":   true,
   139  							}, inputs)
   140  						}),
   141  				)
   142  			},
   143  			wantRepo: "https://github.com/OWNER/REPO",
   144  		},
   145  		{
   146  			name:     "create for team",
   147  			hostname: "github.com",
   148  			input: repoCreateInput{
   149  				Name:             "crisps",
   150  				Visibility:       "internal",
   151  				OwnerLogin:       "snacks-inc",
   152  				TeamSlug:         "munchies",
   153  				HasIssuesEnabled: true,
   154  				HasWikiEnabled:   true,
   155  			},
   156  			stubs: func(t *testing.T, r *httpmock.Registry) {
   157  				r.Register(
   158  					httpmock.REST("GET", "orgs/snacks-inc/teams/munchies"),
   159  					httpmock.StringResponse(`{ "node_id": "TEAMID", "id": 1234, "organization": {"node_id": "ORGID"} }`))
   160  				r.Register(
   161  					httpmock.GraphQL(`mutation RepositoryCreate\b`),
   162  					httpmock.GraphQLMutation(
   163  						`{
   164  							"data": {
   165  								"createRepository": {
   166  									"repository": {
   167  										"id": "REPOID",
   168  										"name": "REPO",
   169  										"owner": {"login":"OWNER"},
   170  										"url": "the://URL"
   171  									}
   172  								}
   173  							}
   174  						}`,
   175  						func(inputs map[string]interface{}) {
   176  							assert.Equal(t, map[string]interface{}{
   177  								"name":             "crisps",
   178  								"visibility":       "INTERNAL",
   179  								"ownerId":          "ORGID",
   180  								"teamId":           "TEAMID",
   181  								"hasIssuesEnabled": true,
   182  								"hasWikiEnabled":   true,
   183  							}, inputs)
   184  						}),
   185  				)
   186  			},
   187  			wantRepo: "https://github.com/OWNER/REPO",
   188  		},
   189  		{
   190  			name:     "create personal repo from template repo",
   191  			hostname: "github.com",
   192  			input: repoCreateInput{
   193  				Name:                 "gen-project",
   194  				Description:          "my generated project",
   195  				Visibility:           "private",
   196  				TemplateRepositoryID: "TPLID",
   197  				HasIssuesEnabled:     true,
   198  				HasWikiEnabled:       true,
   199  				IncludeAllBranches:   false,
   200  			},
   201  			stubs: func(t *testing.T, r *httpmock.Registry) {
   202  				r.Register(
   203  					httpmock.GraphQL(`query UserCurrent\b`),
   204  					httpmock.StringResponse(`{"data": {"viewer": {"id":"USERID"} } }`))
   205  				r.Register(
   206  					httpmock.GraphQL(`mutation CloneTemplateRepository\b`),
   207  					httpmock.GraphQLMutation(
   208  						`{
   209  							"data": {
   210  								"cloneTemplateRepository": {
   211  									"repository": {
   212  										"id": "REPOID",
   213  										"name": "REPO",
   214  										"owner": {"login":"OWNER"},
   215  										"url": "the://URL"
   216  									}
   217  								}
   218  							}
   219  						}`,
   220  						func(inputs map[string]interface{}) {
   221  							assert.Equal(t, map[string]interface{}{
   222  								"name":               "gen-project",
   223  								"description":        "my generated project",
   224  								"visibility":         "PRIVATE",
   225  								"ownerId":            "USERID",
   226  								"repositoryId":       "TPLID",
   227  								"includeAllBranches": false,
   228  							}, inputs)
   229  						}),
   230  				)
   231  			},
   232  			wantRepo: "https://github.com/OWNER/REPO",
   233  		},
   234  		{
   235  			name:     "create org repo from template repo",
   236  			hostname: "github.com",
   237  			input: repoCreateInput{
   238  				Name:                 "gen-project",
   239  				Description:          "my generated project",
   240  				Visibility:           "internal",
   241  				OwnerLogin:           "myorg",
   242  				TemplateRepositoryID: "TPLID",
   243  				HasIssuesEnabled:     true,
   244  				HasWikiEnabled:       true,
   245  				IncludeAllBranches:   false,
   246  			},
   247  			stubs: func(t *testing.T, r *httpmock.Registry) {
   248  				r.Register(
   249  					httpmock.REST("GET", "users/myorg"),
   250  					httpmock.StringResponse(`{ "node_id": "ORGID", "type": "Organization" }`))
   251  				r.Register(
   252  					httpmock.GraphQL(`mutation CloneTemplateRepository\b`),
   253  					httpmock.GraphQLMutation(
   254  						`{
   255  							"data": {
   256  								"cloneTemplateRepository": {
   257  									"repository": {
   258  										"id": "REPOID",
   259  										"name": "REPO",
   260  										"owner": {"login":"OWNER"},
   261  										"url": "the://URL"
   262  									}
   263  								}
   264  							}
   265  						}`,
   266  						func(inputs map[string]interface{}) {
   267  							assert.Equal(t, map[string]interface{}{
   268  								"name":               "gen-project",
   269  								"description":        "my generated project",
   270  								"visibility":         "INTERNAL",
   271  								"ownerId":            "ORGID",
   272  								"repositoryId":       "TPLID",
   273  								"includeAllBranches": false,
   274  							}, inputs)
   275  						}),
   276  				)
   277  			},
   278  			wantRepo: "https://github.com/OWNER/REPO",
   279  		},
   280  		{
   281  			name:     "create with license and gitignore",
   282  			hostname: "github.com",
   283  			input: repoCreateInput{
   284  				Name:              "crisps",
   285  				Visibility:        "private",
   286  				LicenseTemplate:   "lgpl-3.0",
   287  				GitIgnoreTemplate: "Go",
   288  				HasIssuesEnabled:  true,
   289  				HasWikiEnabled:    true,
   290  			},
   291  			stubs: func(t *testing.T, r *httpmock.Registry) {
   292  				r.Register(
   293  					httpmock.REST("POST", "user/repos"),
   294  					httpmock.RESTPayload(201, `{"name":"crisps", "owner":{"login": "snacks-inc"}, "html_url":"the://URL"}`, func(payload map[string]interface{}) {
   295  						assert.Equal(t, map[string]interface{}{
   296  							"name":               "crisps",
   297  							"private":            true,
   298  							"gitignore_template": "Go",
   299  							"license_template":   "lgpl-3.0",
   300  							"has_issues":         true,
   301  							"has_wiki":           true,
   302  						}, payload)
   303  					}))
   304  			},
   305  			wantRepo: "https://github.com/snacks-inc/crisps",
   306  		},
   307  		{
   308  			name:     "create with README",
   309  			hostname: "github.com",
   310  			input: repoCreateInput{
   311  				Name:       "crisps",
   312  				InitReadme: true,
   313  			},
   314  			stubs: func(t *testing.T, r *httpmock.Registry) {
   315  				r.Register(
   316  					httpmock.REST("POST", "user/repos"),
   317  					httpmock.RESTPayload(201, `{"name":"crisps", "owner":{"login": "snacks-inc"}, "html_url":"the://URL"}`, func(payload map[string]interface{}) {
   318  						assert.Equal(t, map[string]interface{}{
   319  							"name":       "crisps",
   320  							"private":    false,
   321  							"has_issues": false,
   322  							"has_wiki":   false,
   323  							"auto_init":  true,
   324  						}, payload)
   325  					}))
   326  			},
   327  			wantRepo: "https://github.com/snacks-inc/crisps",
   328  		},
   329  		{
   330  			name:     "create with license and gitignore on Enterprise",
   331  			hostname: "example.com",
   332  			input: repoCreateInput{
   333  				Name:              "crisps",
   334  				Visibility:        "private",
   335  				LicenseTemplate:   "lgpl-3.0",
   336  				GitIgnoreTemplate: "Go",
   337  				HasIssuesEnabled:  true,
   338  				HasWikiEnabled:    true,
   339  			},
   340  			stubs: func(t *testing.T, r *httpmock.Registry) {
   341  				r.Register(
   342  					httpmock.REST("POST", "api/v3/user/repos"),
   343  					httpmock.RESTPayload(201, `{"name":"crisps", "owner":{"login": "snacks-inc"}, "html_url":"the://URL"}`, func(payload map[string]interface{}) {
   344  						assert.Equal(t, map[string]interface{}{
   345  							"name":               "crisps",
   346  							"private":            true,
   347  							"gitignore_template": "Go",
   348  							"license_template":   "lgpl-3.0",
   349  							"has_issues":         true,
   350  							"has_wiki":           true,
   351  						}, payload)
   352  					}))
   353  			},
   354  			wantRepo: "https://example.com/snacks-inc/crisps",
   355  		},
   356  		{
   357  			name:     "create with license and gitignore in org",
   358  			hostname: "github.com",
   359  			input: repoCreateInput{
   360  				Name:              "crisps",
   361  				Visibility:        "INTERNAL",
   362  				OwnerLogin:        "snacks-inc",
   363  				LicenseTemplate:   "lgpl-3.0",
   364  				GitIgnoreTemplate: "Go",
   365  				HasIssuesEnabled:  true,
   366  				HasWikiEnabled:    true,
   367  			},
   368  			stubs: func(t *testing.T, r *httpmock.Registry) {
   369  				r.Register(
   370  					httpmock.REST("GET", "users/snacks-inc"),
   371  					httpmock.StringResponse(`{ "node_id": "ORGID", "type": "Organization" }`))
   372  				r.Register(
   373  					httpmock.REST("POST", "orgs/snacks-inc/repos"),
   374  					httpmock.RESTPayload(201, `{"name":"crisps", "owner":{"login": "snacks-inc"}, "html_url":"the://URL"}`, func(payload map[string]interface{}) {
   375  						assert.Equal(t, map[string]interface{}{
   376  							"name":               "crisps",
   377  							"private":            false,
   378  							"visibility":         "internal",
   379  							"gitignore_template": "Go",
   380  							"license_template":   "lgpl-3.0",
   381  							"has_issues":         true,
   382  							"has_wiki":           true,
   383  						}, payload)
   384  					}))
   385  			},
   386  			wantRepo: "https://github.com/snacks-inc/crisps",
   387  		},
   388  		{
   389  			name:     "create with license and gitignore for team",
   390  			hostname: "github.com",
   391  			input: repoCreateInput{
   392  				Name:              "crisps",
   393  				Visibility:        "internal",
   394  				OwnerLogin:        "snacks-inc",
   395  				TeamSlug:          "munchies",
   396  				LicenseTemplate:   "lgpl-3.0",
   397  				GitIgnoreTemplate: "Go",
   398  				HasIssuesEnabled:  true,
   399  				HasWikiEnabled:    true,
   400  			},
   401  			stubs: func(t *testing.T, r *httpmock.Registry) {
   402  				r.Register(
   403  					httpmock.REST("GET", "orgs/snacks-inc/teams/munchies"),
   404  					httpmock.StringResponse(`{ "node_id": "TEAMID", "id": 1234, "organization": {"node_id": "ORGID"} }`))
   405  				r.Register(
   406  					httpmock.REST("POST", "orgs/snacks-inc/repos"),
   407  					httpmock.RESTPayload(201, `{"name":"crisps", "owner":{"login": "snacks-inc"}, "html_url":"the://URL"}`, func(payload map[string]interface{}) {
   408  						assert.Equal(t, map[string]interface{}{
   409  							"name":               "crisps",
   410  							"private":            false,
   411  							"visibility":         "internal",
   412  							"gitignore_template": "Go",
   413  							"license_template":   "lgpl-3.0",
   414  							"team_id":            float64(1234),
   415  							"has_issues":         true,
   416  							"has_wiki":           true,
   417  						}, payload)
   418  					}))
   419  			},
   420  			wantRepo: "https://github.com/snacks-inc/crisps",
   421  		},
   422  	}
   423  	for _, tt := range tests {
   424  		t.Run(tt.name, func(t *testing.T) {
   425  			reg := &httpmock.Registry{}
   426  			defer reg.Verify(t)
   427  			tt.stubs(t, reg)
   428  			httpClient := &http.Client{Transport: reg}
   429  			r, err := repoCreate(httpClient, tt.hostname, tt.input)
   430  			if tt.wantErr {
   431  				assert.Error(t, err)
   432  				return
   433  			} else {
   434  				assert.NoError(t, err)
   435  			}
   436  			assert.Equal(t, tt.wantRepo, ghrepo.GenerateRepoURL(r, ""))
   437  		})
   438  	}
   439  }