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 }