github.com/google/go-github/v74@v74.0.0/github/users_test.go (about) 1 // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "context" 10 "encoding/json" 11 "fmt" 12 "net/http" 13 "testing" 14 15 "github.com/google/go-cmp/cmp" 16 ) 17 18 func TestUser_Marshal(t *testing.T) { 19 t.Parallel() 20 testJSONMarshal(t, &User{}, "{}") 21 22 u := &User{ 23 Login: Ptr("l"), 24 ID: Ptr(int64(1)), 25 URL: Ptr("u"), 26 AvatarURL: Ptr("a"), 27 GravatarID: Ptr("g"), 28 Name: Ptr("n"), 29 Company: Ptr("c"), 30 Blog: Ptr("b"), 31 Location: Ptr("l"), 32 Email: Ptr("e"), 33 Hireable: Ptr(true), 34 Bio: Ptr("b"), 35 TwitterUsername: Ptr("t"), 36 PublicRepos: Ptr(1), 37 Followers: Ptr(1), 38 Following: Ptr(1), 39 CreatedAt: &Timestamp{referenceTime}, 40 SuspendedAt: &Timestamp{referenceTime}, 41 } 42 want := `{ 43 "login": "l", 44 "id": 1, 45 "avatar_url": "a", 46 "gravatar_id": "g", 47 "name": "n", 48 "company": "c", 49 "blog": "b", 50 "location": "l", 51 "email": "e", 52 "hireable": true, 53 "bio": "b", 54 "twitter_username": "t", 55 "public_repos": 1, 56 "followers": 1, 57 "following": 1, 58 "created_at": ` + referenceTimeStr + `, 59 "suspended_at": ` + referenceTimeStr + `, 60 "url": "u" 61 }` 62 testJSONMarshal(t, u, want) 63 64 u2 := &User{ 65 Login: Ptr("testLogin"), 66 ID: Ptr(int64(1)), 67 NodeID: Ptr("testNode123"), 68 AvatarURL: Ptr("https://www.my-avatar.com"), 69 HTMLURL: Ptr("https://www.test-url.com"), 70 GravatarID: Ptr("testGravatar123"), 71 Name: Ptr("myName"), 72 Company: Ptr("testCompany"), 73 Blog: Ptr("test Blog"), 74 Location: Ptr("test location"), 75 Email: Ptr("test@test.com"), 76 Hireable: Ptr(true), 77 Bio: Ptr("my good bio"), 78 TwitterUsername: Ptr("https://www.twitter.com/test"), 79 PublicRepos: Ptr(1), 80 PublicGists: Ptr(2), 81 Followers: Ptr(100), 82 Following: Ptr(29), 83 CreatedAt: &Timestamp{referenceTime}, 84 UpdatedAt: &Timestamp{referenceTime}, 85 SuspendedAt: &Timestamp{referenceTime}, 86 Type: Ptr("test type"), 87 SiteAdmin: Ptr(false), 88 TotalPrivateRepos: Ptr(int64(2)), 89 OwnedPrivateRepos: Ptr(int64(1)), 90 PrivateGists: Ptr(1), 91 DiskUsage: Ptr(1), 92 Collaborators: Ptr(1), 93 TwoFactorAuthentication: Ptr(false), 94 Plan: &Plan{ 95 Name: Ptr("silver"), 96 Space: Ptr(1024), 97 Collaborators: Ptr(10), 98 PrivateRepos: Ptr(int64(4)), 99 FilledSeats: Ptr(24), 100 Seats: Ptr(1), 101 }, 102 LdapDn: Ptr("test ldap"), 103 } 104 105 want2 := `{ 106 "login": "testLogin", 107 "id": 1, 108 "node_id":"testNode123", 109 "avatar_url": "https://www.my-avatar.com", 110 "html_url":"https://www.test-url.com", 111 "gravatar_id": "testGravatar123", 112 "name": "myName", 113 "company": "testCompany", 114 "blog": "test Blog", 115 "location": "test location", 116 "email": "test@test.com", 117 "hireable": true, 118 "bio": "my good bio", 119 "twitter_username": "https://www.twitter.com/test", 120 "public_repos": 1, 121 "public_gists":2, 122 "followers": 100, 123 "following": 29, 124 "created_at": ` + referenceTimeStr + `, 125 "suspended_at": ` + referenceTimeStr + `, 126 "updated_at": ` + referenceTimeStr + `, 127 "type": "test type", 128 "site_admin": false, 129 "total_private_repos": 2, 130 "owned_private_repos": 1, 131 "private_gists": 1, 132 "disk_usage": 1, 133 "collaborators": 1, 134 "two_factor_authentication": false, 135 "plan": { 136 "name": "silver", 137 "space": 1024, 138 "collaborators": 10, 139 "private_repos": 4, 140 "filled_seats": 24, 141 "seats": 1 142 }, 143 "ldap_dn": "test ldap" 144 }` 145 testJSONMarshal(t, u2, want2) 146 } 147 148 func TestUsersService_Get_authenticatedUser(t *testing.T) { 149 t.Parallel() 150 client, mux, _ := setup(t) 151 152 mux.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) { 153 testMethod(t, r, "GET") 154 fmt.Fprint(w, `{"id":1}`) 155 }) 156 157 ctx := context.Background() 158 user, _, err := client.Users.Get(ctx, "") 159 if err != nil { 160 t.Errorf("Users.Get returned error: %v", err) 161 } 162 163 want := &User{ID: Ptr(int64(1))} 164 if !cmp.Equal(user, want) { 165 t.Errorf("Users.Get returned %+v, want %+v", user, want) 166 } 167 168 const methodName = "Get" 169 testBadOptions(t, methodName, func() (err error) { 170 _, _, err = client.Users.Get(ctx, "\n") 171 return err 172 }) 173 174 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 175 got, resp, err := client.Users.Get(ctx, "") 176 if got != nil { 177 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 178 } 179 return resp, err 180 }) 181 } 182 183 func TestUsersService_Get_specifiedUser(t *testing.T) { 184 t.Parallel() 185 client, mux, _ := setup(t) 186 187 mux.HandleFunc("/users/u", func(w http.ResponseWriter, r *http.Request) { 188 testMethod(t, r, "GET") 189 fmt.Fprint(w, `{"id":1}`) 190 }) 191 192 ctx := context.Background() 193 user, _, err := client.Users.Get(ctx, "u") 194 if err != nil { 195 t.Errorf("Users.Get returned error: %v", err) 196 } 197 198 want := &User{ID: Ptr(int64(1))} 199 if !cmp.Equal(user, want) { 200 t.Errorf("Users.Get returned %+v, want %+v", user, want) 201 } 202 } 203 204 func TestUsersService_Get_invalidUser(t *testing.T) { 205 t.Parallel() 206 client, _, _ := setup(t) 207 208 ctx := context.Background() 209 _, _, err := client.Users.Get(ctx, "%") 210 testURLParseError(t, err) 211 } 212 213 func TestUsersService_GetByID(t *testing.T) { 214 t.Parallel() 215 client, mux, _ := setup(t) 216 217 mux.HandleFunc("/user/1", func(w http.ResponseWriter, r *http.Request) { 218 testMethod(t, r, "GET") 219 fmt.Fprint(w, `{"id":1}`) 220 }) 221 222 ctx := context.Background() 223 user, _, err := client.Users.GetByID(ctx, 1) 224 if err != nil { 225 t.Fatalf("Users.GetByID returned error: %v", err) 226 } 227 228 want := &User{ID: Ptr(int64(1))} 229 if !cmp.Equal(user, want) { 230 t.Errorf("Users.GetByID returned %+v, want %+v", user, want) 231 } 232 233 const methodName = "GetByID" 234 testBadOptions(t, methodName, func() (err error) { 235 _, _, err = client.Users.GetByID(ctx, -1) 236 return err 237 }) 238 239 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 240 got, resp, err := client.Users.GetByID(ctx, 1) 241 if got != nil { 242 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 243 } 244 return resp, err 245 }) 246 } 247 248 func TestUsersService_Edit(t *testing.T) { 249 t.Parallel() 250 client, mux, _ := setup(t) 251 252 input := &User{Name: Ptr("n")} 253 254 mux.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) { 255 v := new(User) 256 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 257 258 testMethod(t, r, "PATCH") 259 if !cmp.Equal(v, input) { 260 t.Errorf("Request body = %+v, want %+v", v, input) 261 } 262 263 fmt.Fprint(w, `{"id":1}`) 264 }) 265 266 ctx := context.Background() 267 user, _, err := client.Users.Edit(ctx, input) 268 if err != nil { 269 t.Errorf("Users.Edit returned error: %v", err) 270 } 271 272 want := &User{ID: Ptr(int64(1))} 273 if !cmp.Equal(user, want) { 274 t.Errorf("Users.Edit returned %+v, want %+v", user, want) 275 } 276 277 const methodName = "Edit" 278 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 279 got, resp, err := client.Users.Edit(ctx, input) 280 if got != nil { 281 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 282 } 283 return resp, err 284 }) 285 } 286 287 func TestUsersService_GetHovercard(t *testing.T) { 288 t.Parallel() 289 client, mux, _ := setup(t) 290 291 mux.HandleFunc("/users/u/hovercard", func(w http.ResponseWriter, r *http.Request) { 292 testMethod(t, r, "GET") 293 testFormValues(t, r, values{"subject_type": "repository", "subject_id": "20180408"}) 294 fmt.Fprint(w, `{"contexts": [{"message":"Owns this repository", "octicon": "repo"}]}`) 295 }) 296 297 opt := &HovercardOptions{SubjectType: "repository", SubjectID: "20180408"} 298 ctx := context.Background() 299 hovercard, _, err := client.Users.GetHovercard(ctx, "u", opt) 300 if err != nil { 301 t.Errorf("Users.GetHovercard returned error: %v", err) 302 } 303 304 want := &Hovercard{Contexts: []*UserContext{{Message: Ptr("Owns this repository"), Octicon: Ptr("repo")}}} 305 if !cmp.Equal(hovercard, want) { 306 t.Errorf("Users.GetHovercard returned %+v, want %+v", hovercard, want) 307 } 308 309 const methodName = "GetHovercard" 310 testBadOptions(t, methodName, func() (err error) { 311 _, _, err = client.Users.GetHovercard(ctx, "\n", opt) 312 return err 313 }) 314 315 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 316 got, resp, err := client.Users.GetHovercard(ctx, "u", opt) 317 if got != nil { 318 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 319 } 320 return resp, err 321 }) 322 } 323 324 func TestUsersService_ListAll(t *testing.T) { 325 t.Parallel() 326 client, mux, _ := setup(t) 327 328 mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { 329 testMethod(t, r, "GET") 330 testFormValues(t, r, values{"since": "1", "page": "2"}) 331 fmt.Fprint(w, `[{"id":2}]`) 332 }) 333 334 opt := &UserListOptions{1, ListOptions{Page: 2}} 335 ctx := context.Background() 336 users, _, err := client.Users.ListAll(ctx, opt) 337 if err != nil { 338 t.Errorf("Users.Get returned error: %v", err) 339 } 340 341 want := []*User{{ID: Ptr(int64(2))}} 342 if !cmp.Equal(users, want) { 343 t.Errorf("Users.ListAll returned %+v, want %+v", users, want) 344 } 345 346 const methodName = "ListAll" 347 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 348 got, resp, err := client.Users.ListAll(ctx, opt) 349 if got != nil { 350 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 351 } 352 return resp, err 353 }) 354 } 355 356 func TestUsersService_ListInvitations(t *testing.T) { 357 t.Parallel() 358 client, mux, _ := setup(t) 359 360 mux.HandleFunc("/user/repository_invitations", func(w http.ResponseWriter, r *http.Request) { 361 testMethod(t, r, "GET") 362 fmt.Fprint(w, `[{"id":1}, {"id":2}]`) 363 }) 364 365 ctx := context.Background() 366 got, _, err := client.Users.ListInvitations(ctx, nil) 367 if err != nil { 368 t.Errorf("Users.ListInvitations returned error: %v", err) 369 } 370 371 want := []*RepositoryInvitation{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}} 372 if !cmp.Equal(got, want) { 373 t.Errorf("Users.ListInvitations = %+v, want %+v", got, want) 374 } 375 376 const methodName = "ListInvitations" 377 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 378 got, resp, err := client.Users.ListInvitations(ctx, nil) 379 if got != nil { 380 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 381 } 382 return resp, err 383 }) 384 } 385 386 func TestUsersService_ListInvitations_withOptions(t *testing.T) { 387 t.Parallel() 388 client, mux, _ := setup(t) 389 390 mux.HandleFunc("/user/repository_invitations", func(w http.ResponseWriter, r *http.Request) { 391 testMethod(t, r, "GET") 392 testFormValues(t, r, values{ 393 "page": "2", 394 }) 395 fmt.Fprint(w, `[{"id":1}, {"id":2}]`) 396 }) 397 398 ctx := context.Background() 399 _, _, err := client.Users.ListInvitations(ctx, &ListOptions{Page: 2}) 400 if err != nil { 401 t.Errorf("Users.ListInvitations returned error: %v", err) 402 } 403 } 404 405 func TestUsersService_AcceptInvitation(t *testing.T) { 406 t.Parallel() 407 client, mux, _ := setup(t) 408 409 mux.HandleFunc("/user/repository_invitations/1", func(w http.ResponseWriter, r *http.Request) { 410 testMethod(t, r, "PATCH") 411 w.WriteHeader(http.StatusNoContent) 412 }) 413 414 ctx := context.Background() 415 if _, err := client.Users.AcceptInvitation(ctx, 1); err != nil { 416 t.Errorf("Users.AcceptInvitation returned error: %v", err) 417 } 418 419 const methodName = "AcceptInvitation" 420 testBadOptions(t, methodName, func() (err error) { 421 _, err = client.Users.AcceptInvitation(ctx, -1) 422 return err 423 }) 424 425 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 426 return client.Users.AcceptInvitation(ctx, 1) 427 }) 428 } 429 430 func TestUsersService_DeclineInvitation(t *testing.T) { 431 t.Parallel() 432 client, mux, _ := setup(t) 433 434 mux.HandleFunc("/user/repository_invitations/1", func(w http.ResponseWriter, r *http.Request) { 435 testMethod(t, r, "DELETE") 436 w.WriteHeader(http.StatusNoContent) 437 }) 438 439 ctx := context.Background() 440 if _, err := client.Users.DeclineInvitation(ctx, 1); err != nil { 441 t.Errorf("Users.DeclineInvitation returned error: %v", err) 442 } 443 444 const methodName = "DeclineInvitation" 445 testBadOptions(t, methodName, func() (err error) { 446 _, err = client.Users.DeclineInvitation(ctx, -1) 447 return err 448 }) 449 450 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 451 return client.Users.DeclineInvitation(ctx, 1) 452 }) 453 } 454 455 func TestUserContext_Marshal(t *testing.T) { 456 t.Parallel() 457 testJSONMarshal(t, &UserContext{}, "{}") 458 459 u := &UserContext{ 460 Message: Ptr("message"), 461 Octicon: Ptr("message"), 462 } 463 464 want := `{ 465 "message" : "message", 466 "octicon" : "message" 467 }` 468 469 testJSONMarshal(t, u, want) 470 } 471 472 func TestHovercard_Marshal(t *testing.T) { 473 t.Parallel() 474 testJSONMarshal(t, &Hovercard{}, "{}") 475 476 h := &Hovercard{ 477 Contexts: []*UserContext{ 478 { 479 Message: Ptr("someMessage"), 480 Octicon: Ptr("someOcticon"), 481 }, 482 }, 483 } 484 485 want := `{ 486 "contexts" : [ 487 { 488 "message" : "someMessage", 489 "octicon" : "someOcticon" 490 } 491 ] 492 }` 493 494 testJSONMarshal(t, h, want) 495 } 496 497 func TestUserListOptions_Marshal(t *testing.T) { 498 t.Parallel() 499 testJSONMarshal(t, &UserListOptions{}, "{}") 500 501 u := &UserListOptions{ 502 Since: int64(1900), 503 ListOptions: ListOptions{ 504 Page: int(1), 505 PerPage: int(10), 506 }, 507 } 508 509 want := `{ 510 "since" : 1900, 511 "page": 1, 512 "perPage": 10 513 }` 514 515 testJSONMarshal(t, u, want) 516 } 517 518 func TestHovercardOptions_Marshal(t *testing.T) { 519 t.Parallel() 520 testJSONMarshal(t, &HovercardOptions{}, "{}") 521 522 u := &HovercardOptions{ 523 SubjectType: "subjectType", 524 SubjectID: "subjectID", 525 } 526 527 want := `{ 528 "SubjectType" : "subjectType", 529 "SubjectID" : "subjectID" 530 }` 531 532 testJSONMarshal(t, u, want) 533 }