github.com/google/go-github/v33@v33.0.0/github/orgs_members_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 "reflect" 14 "testing" 15 "time" 16 ) 17 18 func TestOrganizationsService_ListMembers(t *testing.T) { 19 client, mux, _, teardown := setup() 20 defer teardown() 21 22 mux.HandleFunc("/orgs/o/members", func(w http.ResponseWriter, r *http.Request) { 23 testMethod(t, r, "GET") 24 testFormValues(t, r, values{ 25 "filter": "2fa_disabled", 26 "role": "admin", 27 "page": "2", 28 }) 29 fmt.Fprint(w, `[{"id":1}]`) 30 }) 31 32 opt := &ListMembersOptions{ 33 PublicOnly: false, 34 Filter: "2fa_disabled", 35 Role: "admin", 36 ListOptions: ListOptions{Page: 2}, 37 } 38 members, _, err := client.Organizations.ListMembers(context.Background(), "o", opt) 39 if err != nil { 40 t.Errorf("Organizations.ListMembers returned error: %v", err) 41 } 42 43 want := []*User{{ID: Int64(1)}} 44 if !reflect.DeepEqual(members, want) { 45 t.Errorf("Organizations.ListMembers returned %+v, want %+v", members, want) 46 } 47 } 48 49 func TestOrganizationsService_ListMembers_invalidOrg(t *testing.T) { 50 client, _, _, teardown := setup() 51 defer teardown() 52 53 _, _, err := client.Organizations.ListMembers(context.Background(), "%", nil) 54 testURLParseError(t, err) 55 } 56 57 func TestOrganizationsService_ListMembers_public(t *testing.T) { 58 client, mux, _, teardown := setup() 59 defer teardown() 60 61 mux.HandleFunc("/orgs/o/public_members", func(w http.ResponseWriter, r *http.Request) { 62 testMethod(t, r, "GET") 63 fmt.Fprint(w, `[{"id":1}]`) 64 }) 65 66 opt := &ListMembersOptions{PublicOnly: true} 67 members, _, err := client.Organizations.ListMembers(context.Background(), "o", opt) 68 if err != nil { 69 t.Errorf("Organizations.ListMembers returned error: %v", err) 70 } 71 72 want := []*User{{ID: Int64(1)}} 73 if !reflect.DeepEqual(members, want) { 74 t.Errorf("Organizations.ListMembers returned %+v, want %+v", members, want) 75 } 76 } 77 78 func TestOrganizationsService_IsMember(t *testing.T) { 79 client, mux, _, teardown := setup() 80 defer teardown() 81 82 mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) { 83 testMethod(t, r, "GET") 84 w.WriteHeader(http.StatusNoContent) 85 }) 86 87 member, _, err := client.Organizations.IsMember(context.Background(), "o", "u") 88 if err != nil { 89 t.Errorf("Organizations.IsMember returned error: %v", err) 90 } 91 if want := true; member != want { 92 t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want) 93 } 94 } 95 96 // ensure that a 404 response is interpreted as "false" and not an error 97 func TestOrganizationsService_IsMember_notMember(t *testing.T) { 98 client, mux, _, teardown := setup() 99 defer teardown() 100 101 mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) { 102 testMethod(t, r, "GET") 103 w.WriteHeader(http.StatusNotFound) 104 }) 105 106 member, _, err := client.Organizations.IsMember(context.Background(), "o", "u") 107 if err != nil { 108 t.Errorf("Organizations.IsMember returned error: %+v", err) 109 } 110 if want := false; member != want { 111 t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want) 112 } 113 } 114 115 // ensure that a 400 response is interpreted as an actual error, and not simply 116 // as "false" like the above case of a 404 117 func TestOrganizationsService_IsMember_error(t *testing.T) { 118 client, mux, _, teardown := setup() 119 defer teardown() 120 121 mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) { 122 testMethod(t, r, "GET") 123 http.Error(w, "BadRequest", http.StatusBadRequest) 124 }) 125 126 member, _, err := client.Organizations.IsMember(context.Background(), "o", "u") 127 if err == nil { 128 t.Errorf("Expected HTTP 400 response") 129 } 130 if want := false; member != want { 131 t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want) 132 } 133 } 134 135 func TestOrganizationsService_IsMember_invalidOrg(t *testing.T) { 136 client, _, _, teardown := setup() 137 defer teardown() 138 139 _, _, err := client.Organizations.IsMember(context.Background(), "%", "u") 140 testURLParseError(t, err) 141 } 142 143 func TestOrganizationsService_IsPublicMember(t *testing.T) { 144 client, mux, _, teardown := setup() 145 defer teardown() 146 147 mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) { 148 testMethod(t, r, "GET") 149 w.WriteHeader(http.StatusNoContent) 150 }) 151 152 member, _, err := client.Organizations.IsPublicMember(context.Background(), "o", "u") 153 if err != nil { 154 t.Errorf("Organizations.IsPublicMember returned error: %v", err) 155 } 156 if want := true; member != want { 157 t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want) 158 } 159 } 160 161 // ensure that a 404 response is interpreted as "false" and not an error 162 func TestOrganizationsService_IsPublicMember_notMember(t *testing.T) { 163 client, mux, _, teardown := setup() 164 defer teardown() 165 166 mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) { 167 testMethod(t, r, "GET") 168 w.WriteHeader(http.StatusNotFound) 169 }) 170 171 member, _, err := client.Organizations.IsPublicMember(context.Background(), "o", "u") 172 if err != nil { 173 t.Errorf("Organizations.IsPublicMember returned error: %v", err) 174 } 175 if want := false; member != want { 176 t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want) 177 } 178 } 179 180 // ensure that a 400 response is interpreted as an actual error, and not simply 181 // as "false" like the above case of a 404 182 func TestOrganizationsService_IsPublicMember_error(t *testing.T) { 183 client, mux, _, teardown := setup() 184 defer teardown() 185 186 mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) { 187 testMethod(t, r, "GET") 188 http.Error(w, "BadRequest", http.StatusBadRequest) 189 }) 190 191 member, _, err := client.Organizations.IsPublicMember(context.Background(), "o", "u") 192 if err == nil { 193 t.Errorf("Expected HTTP 400 response") 194 } 195 if want := false; member != want { 196 t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want) 197 } 198 } 199 200 func TestOrganizationsService_IsPublicMember_invalidOrg(t *testing.T) { 201 client, _, _, teardown := setup() 202 defer teardown() 203 204 _, _, err := client.Organizations.IsPublicMember(context.Background(), "%", "u") 205 testURLParseError(t, err) 206 } 207 208 func TestOrganizationsService_RemoveMember(t *testing.T) { 209 client, mux, _, teardown := setup() 210 defer teardown() 211 212 mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) { 213 testMethod(t, r, "DELETE") 214 }) 215 216 _, err := client.Organizations.RemoveMember(context.Background(), "o", "u") 217 if err != nil { 218 t.Errorf("Organizations.RemoveMember returned error: %v", err) 219 } 220 } 221 222 func TestOrganizationsService_RemoveMember_invalidOrg(t *testing.T) { 223 client, _, _, teardown := setup() 224 defer teardown() 225 226 _, err := client.Organizations.RemoveMember(context.Background(), "%", "u") 227 testURLParseError(t, err) 228 } 229 230 func TestOrganizationsService_ListOrgMemberships(t *testing.T) { 231 client, mux, _, teardown := setup() 232 defer teardown() 233 234 mux.HandleFunc("/user/memberships/orgs", func(w http.ResponseWriter, r *http.Request) { 235 testMethod(t, r, "GET") 236 testFormValues(t, r, values{ 237 "state": "active", 238 "page": "2", 239 }) 240 fmt.Fprint(w, `[{"url":"u"}]`) 241 }) 242 243 opt := &ListOrgMembershipsOptions{ 244 State: "active", 245 ListOptions: ListOptions{Page: 2}, 246 } 247 memberships, _, err := client.Organizations.ListOrgMemberships(context.Background(), opt) 248 if err != nil { 249 t.Errorf("Organizations.ListOrgMemberships returned error: %v", err) 250 } 251 252 want := []*Membership{{URL: String("u")}} 253 if !reflect.DeepEqual(memberships, want) { 254 t.Errorf("Organizations.ListOrgMemberships returned %+v, want %+v", memberships, want) 255 } 256 } 257 258 func TestOrganizationsService_GetOrgMembership_AuthenticatedUser(t *testing.T) { 259 client, mux, _, teardown := setup() 260 defer teardown() 261 262 mux.HandleFunc("/user/memberships/orgs/o", func(w http.ResponseWriter, r *http.Request) { 263 testMethod(t, r, "GET") 264 fmt.Fprint(w, `{"url":"u"}`) 265 }) 266 267 membership, _, err := client.Organizations.GetOrgMembership(context.Background(), "", "o") 268 if err != nil { 269 t.Errorf("Organizations.GetOrgMembership returned error: %v", err) 270 } 271 272 want := &Membership{URL: String("u")} 273 if !reflect.DeepEqual(membership, want) { 274 t.Errorf("Organizations.GetOrgMembership returned %+v, want %+v", membership, want) 275 } 276 } 277 278 func TestOrganizationsService_GetOrgMembership_SpecifiedUser(t *testing.T) { 279 client, mux, _, teardown := setup() 280 defer teardown() 281 282 mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) { 283 testMethod(t, r, "GET") 284 fmt.Fprint(w, `{"url":"u"}`) 285 }) 286 287 membership, _, err := client.Organizations.GetOrgMembership(context.Background(), "u", "o") 288 if err != nil { 289 t.Errorf("Organizations.GetOrgMembership returned error: %v", err) 290 } 291 292 want := &Membership{URL: String("u")} 293 if !reflect.DeepEqual(membership, want) { 294 t.Errorf("Organizations.GetOrgMembership returned %+v, want %+v", membership, want) 295 } 296 } 297 298 func TestOrganizationsService_EditOrgMembership_AuthenticatedUser(t *testing.T) { 299 client, mux, _, teardown := setup() 300 defer teardown() 301 302 input := &Membership{State: String("active")} 303 304 mux.HandleFunc("/user/memberships/orgs/o", func(w http.ResponseWriter, r *http.Request) { 305 v := new(Membership) 306 json.NewDecoder(r.Body).Decode(v) 307 308 testMethod(t, r, "PATCH") 309 if !reflect.DeepEqual(v, input) { 310 t.Errorf("Request body = %+v, want %+v", v, input) 311 } 312 313 fmt.Fprint(w, `{"url":"u"}`) 314 }) 315 316 membership, _, err := client.Organizations.EditOrgMembership(context.Background(), "", "o", input) 317 if err != nil { 318 t.Errorf("Organizations.EditOrgMembership returned error: %v", err) 319 } 320 321 want := &Membership{URL: String("u")} 322 if !reflect.DeepEqual(membership, want) { 323 t.Errorf("Organizations.EditOrgMembership returned %+v, want %+v", membership, want) 324 } 325 } 326 327 func TestOrganizationsService_EditOrgMembership_SpecifiedUser(t *testing.T) { 328 client, mux, _, teardown := setup() 329 defer teardown() 330 331 input := &Membership{State: String("active")} 332 333 mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) { 334 v := new(Membership) 335 json.NewDecoder(r.Body).Decode(v) 336 337 testMethod(t, r, "PUT") 338 if !reflect.DeepEqual(v, input) { 339 t.Errorf("Request body = %+v, want %+v", v, input) 340 } 341 342 fmt.Fprint(w, `{"url":"u"}`) 343 }) 344 345 membership, _, err := client.Organizations.EditOrgMembership(context.Background(), "u", "o", input) 346 if err != nil { 347 t.Errorf("Organizations.EditOrgMembership returned error: %v", err) 348 } 349 350 want := &Membership{URL: String("u")} 351 if !reflect.DeepEqual(membership, want) { 352 t.Errorf("Organizations.EditOrgMembership returned %+v, want %+v", membership, want) 353 } 354 } 355 356 func TestOrganizationsService_RemoveOrgMembership(t *testing.T) { 357 client, mux, _, teardown := setup() 358 defer teardown() 359 360 mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) { 361 testMethod(t, r, "DELETE") 362 w.WriteHeader(http.StatusNoContent) 363 }) 364 365 _, err := client.Organizations.RemoveOrgMembership(context.Background(), "u", "o") 366 if err != nil { 367 t.Errorf("Organizations.RemoveOrgMembership returned error: %v", err) 368 } 369 } 370 371 func TestOrganizationsService_ListPendingOrgInvitations(t *testing.T) { 372 client, mux, _, teardown := setup() 373 defer teardown() 374 375 mux.HandleFunc("/orgs/o/invitations", func(w http.ResponseWriter, r *http.Request) { 376 testMethod(t, r, "GET") 377 testFormValues(t, r, values{"page": "1"}) 378 fmt.Fprint(w, `[ 379 { 380 "id": 1, 381 "login": "monalisa", 382 "email": "octocat@github.com", 383 "role": "direct_member", 384 "created_at": "2017-01-21T00:00:00Z", 385 "inviter": { 386 "login": "other_user", 387 "id": 1, 388 "avatar_url": "https://github.com/images/error/other_user_happy.gif", 389 "gravatar_id": "", 390 "url": "https://api.github.com/users/other_user", 391 "html_url": "https://github.com/other_user", 392 "followers_url": "https://api.github.com/users/other_user/followers", 393 "following_url": "https://api.github.com/users/other_user/following/other_user", 394 "gists_url": "https://api.github.com/users/other_user/gists/gist_id", 395 "starred_url": "https://api.github.com/users/other_user/starred/owner/repo", 396 "subscriptions_url": "https://api.github.com/users/other_user/subscriptions", 397 "organizations_url": "https://api.github.com/users/other_user/orgs", 398 "repos_url": "https://api.github.com/users/other_user/repos", 399 "events_url": "https://api.github.com/users/other_user/events/privacy", 400 "received_events_url": "https://api.github.com/users/other_user/received_events/privacy", 401 "type": "User", 402 "site_admin": false 403 }, 404 "team_count": 2, 405 "invitation_team_url": "https://api.github.com/organizations/2/invitations/1/teams" 406 } 407 ]`) 408 }) 409 410 opt := &ListOptions{Page: 1} 411 invitations, _, err := client.Organizations.ListPendingOrgInvitations(context.Background(), "o", opt) 412 if err != nil { 413 t.Errorf("Organizations.ListPendingOrgInvitations returned error: %v", err) 414 } 415 416 createdAt := time.Date(2017, time.January, 21, 0, 0, 0, 0, time.UTC) 417 want := []*Invitation{ 418 { 419 ID: Int64(1), 420 Login: String("monalisa"), 421 Email: String("octocat@github.com"), 422 Role: String("direct_member"), 423 CreatedAt: &createdAt, 424 Inviter: &User{ 425 Login: String("other_user"), 426 ID: Int64(1), 427 AvatarURL: String("https://github.com/images/error/other_user_happy.gif"), 428 GravatarID: String(""), 429 URL: String("https://api.github.com/users/other_user"), 430 HTMLURL: String("https://github.com/other_user"), 431 FollowersURL: String("https://api.github.com/users/other_user/followers"), 432 FollowingURL: String("https://api.github.com/users/other_user/following/other_user"), 433 GistsURL: String("https://api.github.com/users/other_user/gists/gist_id"), 434 StarredURL: String("https://api.github.com/users/other_user/starred/owner/repo"), 435 SubscriptionsURL: String("https://api.github.com/users/other_user/subscriptions"), 436 OrganizationsURL: String("https://api.github.com/users/other_user/orgs"), 437 ReposURL: String("https://api.github.com/users/other_user/repos"), 438 EventsURL: String("https://api.github.com/users/other_user/events/privacy"), 439 ReceivedEventsURL: String("https://api.github.com/users/other_user/received_events/privacy"), 440 Type: String("User"), 441 SiteAdmin: Bool(false), 442 }, 443 TeamCount: Int(2), 444 InvitationTeamURL: String("https://api.github.com/organizations/2/invitations/1/teams"), 445 }} 446 447 if !reflect.DeepEqual(invitations, want) { 448 t.Errorf("Organizations.ListPendingOrgInvitations returned %+v, want %+v", invitations, want) 449 } 450 } 451 452 func TestOrganizationsService_CreateOrgInvitation(t *testing.T) { 453 client, mux, _, teardown := setup() 454 defer teardown() 455 input := &CreateOrgInvitationOptions{ 456 Email: String("octocat@github.com"), 457 Role: String("direct_member"), 458 TeamID: []int64{ 459 12, 460 26, 461 }, 462 } 463 464 mux.HandleFunc("/orgs/o/invitations", func(w http.ResponseWriter, r *http.Request) { 465 v := new(CreateOrgInvitationOptions) 466 json.NewDecoder(r.Body).Decode(v) 467 468 testMethod(t, r, "POST") 469 if !reflect.DeepEqual(v, input) { 470 t.Errorf("Request body = %+v, want %+v", v, input) 471 } 472 473 fmt.Fprintln(w, `{"email": "octocat@github.com"}`) 474 475 }) 476 477 invitations, _, err := client.Organizations.CreateOrgInvitation(context.Background(), "o", input) 478 if err != nil { 479 t.Errorf("Organizations.CreateOrgInvitation returned error: %v", err) 480 } 481 482 want := &Invitation{Email: String("octocat@github.com")} 483 if !reflect.DeepEqual(invitations, want) { 484 t.Errorf("Organizations.ListPendingOrgInvitations returned %+v, want %+v", invitations, want) 485 } 486 } 487 488 func TestOrganizationsService_ListOrgInvitationTeams(t *testing.T) { 489 client, mux, _, teardown := setup() 490 defer teardown() 491 492 mux.HandleFunc("/orgs/o/invitations/22/teams", func(w http.ResponseWriter, r *http.Request) { 493 testMethod(t, r, "GET") 494 testFormValues(t, r, values{"page": "1"}) 495 fmt.Fprint(w, `[ 496 { 497 "id": 1, 498 "url": "https://api.github.com/teams/1", 499 "name": "Justice League", 500 "slug": "justice-league", 501 "description": "A great team.", 502 "privacy": "closed", 503 "permission": "admin", 504 "members_url": "https://api.github.com/teams/1/members{/member}", 505 "repositories_url": "https://api.github.com/teams/1/repos" 506 } 507 ]`) 508 }) 509 510 opt := &ListOptions{Page: 1} 511 invitations, _, err := client.Organizations.ListOrgInvitationTeams(context.Background(), "o", "22", opt) 512 if err != nil { 513 t.Errorf("Organizations.ListOrgInvitationTeams returned error: %v", err) 514 } 515 516 want := []*Team{ 517 { 518 ID: Int64(1), 519 URL: String("https://api.github.com/teams/1"), 520 Name: String("Justice League"), 521 Slug: String("justice-league"), 522 Description: String("A great team."), 523 Privacy: String("closed"), 524 Permission: String("admin"), 525 MembersURL: String("https://api.github.com/teams/1/members{/member}"), 526 RepositoriesURL: String("https://api.github.com/teams/1/repos"), 527 }, 528 } 529 530 if !reflect.DeepEqual(invitations, want) { 531 t.Errorf("Organizations.ListOrgInvitationTeams returned %+v, want %+v", invitations, want) 532 } 533 }