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