...

Source file src/github.com/google/go-github/v55/github/orgs_members_test.go

Documentation: github.com/google/go-github/v55/github

     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  	"time"
    15  
    16  	"github.com/google/go-cmp/cmp"
    17  )
    18  
    19  func TestOrganizationsService_ListMembers(t *testing.T) {
    20  	client, mux, _, teardown := setup()
    21  	defer teardown()
    22  
    23  	mux.HandleFunc("/orgs/o/members", func(w http.ResponseWriter, r *http.Request) {
    24  		testMethod(t, r, "GET")
    25  		testFormValues(t, r, values{
    26  			"filter": "2fa_disabled",
    27  			"role":   "admin",
    28  			"page":   "2",
    29  		})
    30  		fmt.Fprint(w, `[{"id":1}]`)
    31  	})
    32  
    33  	opt := &ListMembersOptions{
    34  		PublicOnly:  false,
    35  		Filter:      "2fa_disabled",
    36  		Role:        "admin",
    37  		ListOptions: ListOptions{Page: 2},
    38  	}
    39  	ctx := context.Background()
    40  	members, _, err := client.Organizations.ListMembers(ctx, "o", opt)
    41  	if err != nil {
    42  		t.Errorf("Organizations.ListMembers returned error: %v", err)
    43  	}
    44  
    45  	want := []*User{{ID: Int64(1)}}
    46  	if !cmp.Equal(members, want) {
    47  		t.Errorf("Organizations.ListMembers returned %+v, want %+v", members, want)
    48  	}
    49  
    50  	const methodName = "ListMembers"
    51  	testBadOptions(t, methodName, func() (err error) {
    52  		_, _, err = client.Organizations.ListMembers(ctx, "\n", opt)
    53  		return err
    54  	})
    55  
    56  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
    57  		got, resp, err := client.Organizations.ListMembers(ctx, "o", opt)
    58  		if got != nil {
    59  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
    60  		}
    61  		return resp, err
    62  	})
    63  }
    64  
    65  func TestOrganizationsService_ListMembers_invalidOrg(t *testing.T) {
    66  	client, _, _, teardown := setup()
    67  	defer teardown()
    68  
    69  	ctx := context.Background()
    70  	_, _, err := client.Organizations.ListMembers(ctx, "%", nil)
    71  	testURLParseError(t, err)
    72  }
    73  
    74  func TestOrganizationsService_ListMembers_public(t *testing.T) {
    75  	client, mux, _, teardown := setup()
    76  	defer teardown()
    77  
    78  	mux.HandleFunc("/orgs/o/public_members", func(w http.ResponseWriter, r *http.Request) {
    79  		testMethod(t, r, "GET")
    80  		fmt.Fprint(w, `[{"id":1}]`)
    81  	})
    82  
    83  	opt := &ListMembersOptions{PublicOnly: true}
    84  	ctx := context.Background()
    85  	members, _, err := client.Organizations.ListMembers(ctx, "o", opt)
    86  	if err != nil {
    87  		t.Errorf("Organizations.ListMembers returned error: %v", err)
    88  	}
    89  
    90  	want := []*User{{ID: Int64(1)}}
    91  	if !cmp.Equal(members, want) {
    92  		t.Errorf("Organizations.ListMembers returned %+v, want %+v", members, want)
    93  	}
    94  }
    95  
    96  func TestOrganizationsService_IsMember(t *testing.T) {
    97  	client, mux, _, teardown := setup()
    98  	defer teardown()
    99  
   100  	mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
   101  		testMethod(t, r, "GET")
   102  		w.WriteHeader(http.StatusNoContent)
   103  	})
   104  
   105  	ctx := context.Background()
   106  	member, _, err := client.Organizations.IsMember(ctx, "o", "u")
   107  	if err != nil {
   108  		t.Errorf("Organizations.IsMember returned error: %v", err)
   109  	}
   110  	if want := true; member != want {
   111  		t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want)
   112  	}
   113  
   114  	const methodName = "IsMember"
   115  	testBadOptions(t, methodName, func() (err error) {
   116  		_, _, err = client.Organizations.IsMember(ctx, "\n", "\n")
   117  		return err
   118  	})
   119  
   120  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   121  		got, resp, err := client.Organizations.IsMember(ctx, "o", "u")
   122  		if got {
   123  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   124  		}
   125  		return resp, err
   126  	})
   127  }
   128  
   129  // ensure that a 404 response is interpreted as "false" and not an error
   130  func TestOrganizationsService_IsMember_notMember(t *testing.T) {
   131  	client, mux, _, teardown := setup()
   132  	defer teardown()
   133  
   134  	mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
   135  		testMethod(t, r, "GET")
   136  		w.WriteHeader(http.StatusNotFound)
   137  	})
   138  
   139  	ctx := context.Background()
   140  	member, _, err := client.Organizations.IsMember(ctx, "o", "u")
   141  	if err != nil {
   142  		t.Errorf("Organizations.IsMember returned error: %+v", err)
   143  	}
   144  	if want := false; member != want {
   145  		t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want)
   146  	}
   147  }
   148  
   149  // ensure that a 400 response is interpreted as an actual error, and not simply
   150  // as "false" like the above case of a 404
   151  func TestOrganizationsService_IsMember_error(t *testing.T) {
   152  	client, mux, _, teardown := setup()
   153  	defer teardown()
   154  
   155  	mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
   156  		testMethod(t, r, "GET")
   157  		http.Error(w, "BadRequest", http.StatusBadRequest)
   158  	})
   159  
   160  	ctx := context.Background()
   161  	member, _, err := client.Organizations.IsMember(ctx, "o", "u")
   162  	if err == nil {
   163  		t.Errorf("Expected HTTP 400 response")
   164  	}
   165  	if want := false; member != want {
   166  		t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want)
   167  	}
   168  }
   169  
   170  func TestOrganizationsService_IsMember_invalidOrg(t *testing.T) {
   171  	client, _, _, teardown := setup()
   172  	defer teardown()
   173  
   174  	ctx := context.Background()
   175  	_, _, err := client.Organizations.IsMember(ctx, "%", "u")
   176  	testURLParseError(t, err)
   177  }
   178  
   179  func TestOrganizationsService_IsPublicMember(t *testing.T) {
   180  	client, mux, _, teardown := setup()
   181  	defer teardown()
   182  
   183  	mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
   184  		testMethod(t, r, "GET")
   185  		w.WriteHeader(http.StatusNoContent)
   186  	})
   187  
   188  	ctx := context.Background()
   189  	member, _, err := client.Organizations.IsPublicMember(ctx, "o", "u")
   190  	if err != nil {
   191  		t.Errorf("Organizations.IsPublicMember returned error: %v", err)
   192  	}
   193  	if want := true; member != want {
   194  		t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want)
   195  	}
   196  
   197  	const methodName = "IsPublicMember"
   198  	testBadOptions(t, methodName, func() (err error) {
   199  		_, _, err = client.Organizations.IsPublicMember(ctx, "\n", "\n")
   200  		return err
   201  	})
   202  
   203  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   204  		got, resp, err := client.Organizations.IsPublicMember(ctx, "o", "u")
   205  		if got {
   206  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   207  		}
   208  		return resp, err
   209  	})
   210  }
   211  
   212  // ensure that a 404 response is interpreted as "false" and not an error
   213  func TestOrganizationsService_IsPublicMember_notMember(t *testing.T) {
   214  	client, mux, _, teardown := setup()
   215  	defer teardown()
   216  
   217  	mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
   218  		testMethod(t, r, "GET")
   219  		w.WriteHeader(http.StatusNotFound)
   220  	})
   221  
   222  	ctx := context.Background()
   223  	member, _, err := client.Organizations.IsPublicMember(ctx, "o", "u")
   224  	if err != nil {
   225  		t.Errorf("Organizations.IsPublicMember returned error: %v", err)
   226  	}
   227  	if want := false; member != want {
   228  		t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want)
   229  	}
   230  }
   231  
   232  // ensure that a 400 response is interpreted as an actual error, and not simply
   233  // as "false" like the above case of a 404
   234  func TestOrganizationsService_IsPublicMember_error(t *testing.T) {
   235  	client, mux, _, teardown := setup()
   236  	defer teardown()
   237  
   238  	mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
   239  		testMethod(t, r, "GET")
   240  		http.Error(w, "BadRequest", http.StatusBadRequest)
   241  	})
   242  
   243  	ctx := context.Background()
   244  	member, _, err := client.Organizations.IsPublicMember(ctx, "o", "u")
   245  	if err == nil {
   246  		t.Errorf("Expected HTTP 400 response")
   247  	}
   248  	if want := false; member != want {
   249  		t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want)
   250  	}
   251  }
   252  
   253  func TestOrganizationsService_IsPublicMember_invalidOrg(t *testing.T) {
   254  	client, _, _, teardown := setup()
   255  	defer teardown()
   256  
   257  	ctx := context.Background()
   258  	_, _, err := client.Organizations.IsPublicMember(ctx, "%", "u")
   259  	testURLParseError(t, err)
   260  }
   261  
   262  func TestOrganizationsService_RemoveMember(t *testing.T) {
   263  	client, mux, _, teardown := setup()
   264  	defer teardown()
   265  
   266  	mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
   267  		testMethod(t, r, "DELETE")
   268  	})
   269  
   270  	ctx := context.Background()
   271  	_, err := client.Organizations.RemoveMember(ctx, "o", "u")
   272  	if err != nil {
   273  		t.Errorf("Organizations.RemoveMember returned error: %v", err)
   274  	}
   275  
   276  	const methodName = "RemoveMember"
   277  	testBadOptions(t, methodName, func() (err error) {
   278  		_, err = client.Organizations.RemoveMember(ctx, "\n", "\n")
   279  		return err
   280  	})
   281  
   282  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   283  		return client.Organizations.RemoveMember(ctx, "o", "u")
   284  	})
   285  }
   286  
   287  func TestOrganizationsService_RemoveMember_invalidOrg(t *testing.T) {
   288  	client, _, _, teardown := setup()
   289  	defer teardown()
   290  
   291  	ctx := context.Background()
   292  	_, err := client.Organizations.RemoveMember(ctx, "%", "u")
   293  	testURLParseError(t, err)
   294  }
   295  
   296  func TestOrganizationsService_PublicizeMembership(t *testing.T) {
   297  	client, mux, _, teardown := setup()
   298  	defer teardown()
   299  
   300  	mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
   301  		testMethod(t, r, "PUT")
   302  	})
   303  
   304  	ctx := context.Background()
   305  	_, err := client.Organizations.PublicizeMembership(ctx, "o", "u")
   306  	if err != nil {
   307  		t.Errorf("Organizations.PublicizeMembership returned error: %v", err)
   308  	}
   309  
   310  	const methodName = "PublicizeMembership"
   311  	testBadOptions(t, methodName, func() (err error) {
   312  		_, err = client.Organizations.PublicizeMembership(ctx, "\n", "\n")
   313  		return err
   314  	})
   315  
   316  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   317  		return client.Organizations.PublicizeMembership(ctx, "o", "u")
   318  	})
   319  }
   320  
   321  func TestOrganizationsService_ConcealMembership(t *testing.T) {
   322  	client, mux, _, teardown := setup()
   323  	defer teardown()
   324  
   325  	mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
   326  		testMethod(t, r, "DELETE")
   327  	})
   328  
   329  	ctx := context.Background()
   330  	_, err := client.Organizations.ConcealMembership(ctx, "o", "u")
   331  	if err != nil {
   332  		t.Errorf("Organizations.ConcealMembership returned error: %v", err)
   333  	}
   334  
   335  	const methodName = "ConcealMembership"
   336  	testBadOptions(t, methodName, func() (err error) {
   337  		_, err = client.Organizations.ConcealMembership(ctx, "\n", "\n")
   338  		return err
   339  	})
   340  
   341  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   342  		return client.Organizations.ConcealMembership(ctx, "o", "u")
   343  	})
   344  }
   345  
   346  func TestOrganizationsService_ListOrgMemberships(t *testing.T) {
   347  	client, mux, _, teardown := setup()
   348  	defer teardown()
   349  
   350  	mux.HandleFunc("/user/memberships/orgs", func(w http.ResponseWriter, r *http.Request) {
   351  		testMethod(t, r, "GET")
   352  		testFormValues(t, r, values{
   353  			"state": "active",
   354  			"page":  "2",
   355  		})
   356  		fmt.Fprint(w, `[{"url":"u"}]`)
   357  	})
   358  
   359  	opt := &ListOrgMembershipsOptions{
   360  		State:       "active",
   361  		ListOptions: ListOptions{Page: 2},
   362  	}
   363  	ctx := context.Background()
   364  	memberships, _, err := client.Organizations.ListOrgMemberships(ctx, opt)
   365  	if err != nil {
   366  		t.Errorf("Organizations.ListOrgMemberships returned error: %v", err)
   367  	}
   368  
   369  	want := []*Membership{{URL: String("u")}}
   370  	if !cmp.Equal(memberships, want) {
   371  		t.Errorf("Organizations.ListOrgMemberships returned %+v, want %+v", memberships, want)
   372  	}
   373  
   374  	const methodName = "ListOrgMemberships"
   375  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   376  		got, resp, err := client.Organizations.ListOrgMemberships(ctx, opt)
   377  		if got != nil {
   378  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   379  		}
   380  		return resp, err
   381  	})
   382  }
   383  
   384  func TestOrganizationsService_GetOrgMembership_AuthenticatedUser(t *testing.T) {
   385  	client, mux, _, teardown := setup()
   386  	defer teardown()
   387  
   388  	mux.HandleFunc("/user/memberships/orgs/o", func(w http.ResponseWriter, r *http.Request) {
   389  		testMethod(t, r, "GET")
   390  		fmt.Fprint(w, `{"url":"u"}`)
   391  	})
   392  
   393  	ctx := context.Background()
   394  	membership, _, err := client.Organizations.GetOrgMembership(ctx, "", "o")
   395  	if err != nil {
   396  		t.Errorf("Organizations.GetOrgMembership returned error: %v", err)
   397  	}
   398  
   399  	want := &Membership{URL: String("u")}
   400  	if !cmp.Equal(membership, want) {
   401  		t.Errorf("Organizations.GetOrgMembership returned %+v, want %+v", membership, want)
   402  	}
   403  
   404  	const methodName = "GetOrgMembership"
   405  	testBadOptions(t, methodName, func() (err error) {
   406  		_, _, err = client.Organizations.GetOrgMembership(ctx, "\n", "\n")
   407  		return err
   408  	})
   409  
   410  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   411  		got, resp, err := client.Organizations.GetOrgMembership(ctx, "", "o")
   412  		if got != nil {
   413  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   414  		}
   415  		return resp, err
   416  	})
   417  }
   418  
   419  func TestOrganizationsService_GetOrgMembership_SpecifiedUser(t *testing.T) {
   420  	client, mux, _, teardown := setup()
   421  	defer teardown()
   422  
   423  	mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) {
   424  		testMethod(t, r, "GET")
   425  		fmt.Fprint(w, `{"url":"u"}`)
   426  	})
   427  
   428  	ctx := context.Background()
   429  	membership, _, err := client.Organizations.GetOrgMembership(ctx, "u", "o")
   430  	if err != nil {
   431  		t.Errorf("Organizations.GetOrgMembership returned error: %v", err)
   432  	}
   433  
   434  	want := &Membership{URL: String("u")}
   435  	if !cmp.Equal(membership, want) {
   436  		t.Errorf("Organizations.GetOrgMembership returned %+v, want %+v", membership, want)
   437  	}
   438  }
   439  
   440  func TestOrganizationsService_EditOrgMembership_AuthenticatedUser(t *testing.T) {
   441  	client, mux, _, teardown := setup()
   442  	defer teardown()
   443  
   444  	input := &Membership{State: String("active")}
   445  
   446  	mux.HandleFunc("/user/memberships/orgs/o", func(w http.ResponseWriter, r *http.Request) {
   447  		v := new(Membership)
   448  		json.NewDecoder(r.Body).Decode(v)
   449  
   450  		testMethod(t, r, "PATCH")
   451  		if !cmp.Equal(v, input) {
   452  			t.Errorf("Request body = %+v, want %+v", v, input)
   453  		}
   454  
   455  		fmt.Fprint(w, `{"url":"u"}`)
   456  	})
   457  
   458  	ctx := context.Background()
   459  	membership, _, err := client.Organizations.EditOrgMembership(ctx, "", "o", input)
   460  	if err != nil {
   461  		t.Errorf("Organizations.EditOrgMembership returned error: %v", err)
   462  	}
   463  
   464  	want := &Membership{URL: String("u")}
   465  	if !cmp.Equal(membership, want) {
   466  		t.Errorf("Organizations.EditOrgMembership returned %+v, want %+v", membership, want)
   467  	}
   468  
   469  	const methodName = "EditOrgMembership"
   470  	testBadOptions(t, methodName, func() (err error) {
   471  		_, _, err = client.Organizations.EditOrgMembership(ctx, "\n", "\n", input)
   472  		return err
   473  	})
   474  
   475  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   476  		got, resp, err := client.Organizations.EditOrgMembership(ctx, "", "o", input)
   477  		if got != nil {
   478  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   479  		}
   480  		return resp, err
   481  	})
   482  }
   483  
   484  func TestOrganizationsService_EditOrgMembership_SpecifiedUser(t *testing.T) {
   485  	client, mux, _, teardown := setup()
   486  	defer teardown()
   487  
   488  	input := &Membership{State: String("active")}
   489  
   490  	mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) {
   491  		v := new(Membership)
   492  		json.NewDecoder(r.Body).Decode(v)
   493  
   494  		testMethod(t, r, "PUT")
   495  		if !cmp.Equal(v, input) {
   496  			t.Errorf("Request body = %+v, want %+v", v, input)
   497  		}
   498  
   499  		fmt.Fprint(w, `{"url":"u"}`)
   500  	})
   501  
   502  	ctx := context.Background()
   503  	membership, _, err := client.Organizations.EditOrgMembership(ctx, "u", "o", input)
   504  	if err != nil {
   505  		t.Errorf("Organizations.EditOrgMembership returned error: %v", err)
   506  	}
   507  
   508  	want := &Membership{URL: String("u")}
   509  	if !cmp.Equal(membership, want) {
   510  		t.Errorf("Organizations.EditOrgMembership returned %+v, want %+v", membership, want)
   511  	}
   512  }
   513  
   514  func TestOrganizationsService_RemoveOrgMembership(t *testing.T) {
   515  	client, mux, _, teardown := setup()
   516  	defer teardown()
   517  
   518  	mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) {
   519  		testMethod(t, r, "DELETE")
   520  		w.WriteHeader(http.StatusNoContent)
   521  	})
   522  
   523  	ctx := context.Background()
   524  	_, err := client.Organizations.RemoveOrgMembership(ctx, "u", "o")
   525  	if err != nil {
   526  		t.Errorf("Organizations.RemoveOrgMembership returned error: %v", err)
   527  	}
   528  
   529  	const methodName = "RemoveOrgMembership"
   530  	testBadOptions(t, methodName, func() (err error) {
   531  		_, err = client.Organizations.RemoveOrgMembership(ctx, "\n", "\n")
   532  		return err
   533  	})
   534  
   535  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   536  		return client.Organizations.RemoveOrgMembership(ctx, "u", "o")
   537  	})
   538  }
   539  
   540  func TestOrganizationsService_ListPendingOrgInvitations(t *testing.T) {
   541  	client, mux, _, teardown := setup()
   542  	defer teardown()
   543  
   544  	mux.HandleFunc("/orgs/o/invitations", func(w http.ResponseWriter, r *http.Request) {
   545  		testMethod(t, r, "GET")
   546  		testFormValues(t, r, values{"page": "1"})
   547  		fmt.Fprint(w, `[
   548  				{
   549      					"id": 1,
   550      					"login": "monalisa",
   551      					"email": "octocat@github.com",
   552      					"role": "direct_member",
   553  					"created_at": "2017-01-21T00:00:00Z",
   554      					"inviter": {
   555        						"login": "other_user",
   556        						"id": 1,
   557        						"avatar_url": "https://github.com/images/error/other_user_happy.gif",
   558        						"gravatar_id": "",
   559        						"url": "https://api.github.com/users/other_user",
   560        						"html_url": "https://github.com/other_user",
   561        						"followers_url": "https://api.github.com/users/other_user/followers",
   562        						"following_url": "https://api.github.com/users/other_user/following/other_user",
   563        						"gists_url": "https://api.github.com/users/other_user/gists/gist_id",
   564        						"starred_url": "https://api.github.com/users/other_user/starred/owner/repo",
   565        						"subscriptions_url": "https://api.github.com/users/other_user/subscriptions",
   566        						"organizations_url": "https://api.github.com/users/other_user/orgs",
   567        						"repos_url": "https://api.github.com/users/other_user/repos",
   568        						"events_url": "https://api.github.com/users/other_user/events/privacy",
   569        						"received_events_url": "https://api.github.com/users/other_user/received_events/privacy",
   570        						"type": "User",
   571        						"site_admin": false
   572  						},
   573  						"team_count": 2,
   574  						"invitation_team_url": "https://api.github.com/organizations/2/invitations/1/teams"
   575    				}
   576  			]`)
   577  	})
   578  
   579  	opt := &ListOptions{Page: 1}
   580  	ctx := context.Background()
   581  	invitations, _, err := client.Organizations.ListPendingOrgInvitations(ctx, "o", opt)
   582  	if err != nil {
   583  		t.Errorf("Organizations.ListPendingOrgInvitations returned error: %v", err)
   584  	}
   585  
   586  	createdAt := time.Date(2017, time.January, 21, 0, 0, 0, 0, time.UTC)
   587  	want := []*Invitation{
   588  		{
   589  			ID:        Int64(1),
   590  			Login:     String("monalisa"),
   591  			Email:     String("octocat@github.com"),
   592  			Role:      String("direct_member"),
   593  			CreatedAt: &Timestamp{createdAt},
   594  			Inviter: &User{
   595  				Login:             String("other_user"),
   596  				ID:                Int64(1),
   597  				AvatarURL:         String("https://github.com/images/error/other_user_happy.gif"),
   598  				GravatarID:        String(""),
   599  				URL:               String("https://api.github.com/users/other_user"),
   600  				HTMLURL:           String("https://github.com/other_user"),
   601  				FollowersURL:      String("https://api.github.com/users/other_user/followers"),
   602  				FollowingURL:      String("https://api.github.com/users/other_user/following/other_user"),
   603  				GistsURL:          String("https://api.github.com/users/other_user/gists/gist_id"),
   604  				StarredURL:        String("https://api.github.com/users/other_user/starred/owner/repo"),
   605  				SubscriptionsURL:  String("https://api.github.com/users/other_user/subscriptions"),
   606  				OrganizationsURL:  String("https://api.github.com/users/other_user/orgs"),
   607  				ReposURL:          String("https://api.github.com/users/other_user/repos"),
   608  				EventsURL:         String("https://api.github.com/users/other_user/events/privacy"),
   609  				ReceivedEventsURL: String("https://api.github.com/users/other_user/received_events/privacy"),
   610  				Type:              String("User"),
   611  				SiteAdmin:         Bool(false),
   612  			},
   613  			TeamCount:         Int(2),
   614  			InvitationTeamURL: String("https://api.github.com/organizations/2/invitations/1/teams"),
   615  		}}
   616  
   617  	if !cmp.Equal(invitations, want) {
   618  		t.Errorf("Organizations.ListPendingOrgInvitations returned %+v, want %+v", invitations, want)
   619  	}
   620  
   621  	const methodName = "ListPendingOrgInvitations"
   622  	testBadOptions(t, methodName, func() (err error) {
   623  		_, _, err = client.Organizations.ListPendingOrgInvitations(ctx, "\n", opt)
   624  		return err
   625  	})
   626  
   627  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   628  		got, resp, err := client.Organizations.ListPendingOrgInvitations(ctx, "o", opt)
   629  		if got != nil {
   630  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   631  		}
   632  		return resp, err
   633  	})
   634  }
   635  
   636  func TestOrganizationsService_CreateOrgInvitation(t *testing.T) {
   637  	client, mux, _, teardown := setup()
   638  	defer teardown()
   639  	input := &CreateOrgInvitationOptions{
   640  		Email: String("octocat@github.com"),
   641  		Role:  String("direct_member"),
   642  		TeamID: []int64{
   643  			12,
   644  			26,
   645  		},
   646  	}
   647  
   648  	mux.HandleFunc("/orgs/o/invitations", func(w http.ResponseWriter, r *http.Request) {
   649  		v := new(CreateOrgInvitationOptions)
   650  		json.NewDecoder(r.Body).Decode(v)
   651  
   652  		testMethod(t, r, "POST")
   653  		if !cmp.Equal(v, input) {
   654  			t.Errorf("Request body = %+v, want %+v", v, input)
   655  		}
   656  
   657  		fmt.Fprintln(w, `{"email": "octocat@github.com"}`)
   658  	})
   659  
   660  	ctx := context.Background()
   661  	invitations, _, err := client.Organizations.CreateOrgInvitation(ctx, "o", input)
   662  	if err != nil {
   663  		t.Errorf("Organizations.CreateOrgInvitation returned error: %v", err)
   664  	}
   665  
   666  	want := &Invitation{Email: String("octocat@github.com")}
   667  	if !cmp.Equal(invitations, want) {
   668  		t.Errorf("Organizations.ListPendingOrgInvitations returned %+v, want %+v", invitations, want)
   669  	}
   670  
   671  	const methodName = "CreateOrgInvitation"
   672  	testBadOptions(t, methodName, func() (err error) {
   673  		_, _, err = client.Organizations.CreateOrgInvitation(ctx, "\n", input)
   674  		return err
   675  	})
   676  
   677  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   678  		got, resp, err := client.Organizations.CreateOrgInvitation(ctx, "o", input)
   679  		if got != nil {
   680  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   681  		}
   682  		return resp, err
   683  	})
   684  }
   685  
   686  func TestOrganizationsService_ListOrgInvitationTeams(t *testing.T) {
   687  	client, mux, _, teardown := setup()
   688  	defer teardown()
   689  
   690  	mux.HandleFunc("/orgs/o/invitations/22/teams", func(w http.ResponseWriter, r *http.Request) {
   691  		testMethod(t, r, "GET")
   692  		testFormValues(t, r, values{"page": "1"})
   693  		fmt.Fprint(w, `[
   694  			{
   695  				"id": 1,
   696  				"url": "https://api.github.com/teams/1",
   697  				"name": "Justice League",
   698  				"slug": "justice-league",
   699  				"description": "A great team.",
   700  				"privacy": "closed",
   701  				"permission": "admin",
   702  				"members_url": "https://api.github.com/teams/1/members{/member}",
   703  				"repositories_url": "https://api.github.com/teams/1/repos"
   704  			  }
   705  			]`)
   706  	})
   707  
   708  	opt := &ListOptions{Page: 1}
   709  	ctx := context.Background()
   710  	invitations, _, err := client.Organizations.ListOrgInvitationTeams(ctx, "o", "22", opt)
   711  	if err != nil {
   712  		t.Errorf("Organizations.ListOrgInvitationTeams returned error: %v", err)
   713  	}
   714  
   715  	want := []*Team{
   716  		{
   717  			ID:              Int64(1),
   718  			URL:             String("https://api.github.com/teams/1"),
   719  			Name:            String("Justice League"),
   720  			Slug:            String("justice-league"),
   721  			Description:     String("A great team."),
   722  			Privacy:         String("closed"),
   723  			Permission:      String("admin"),
   724  			MembersURL:      String("https://api.github.com/teams/1/members{/member}"),
   725  			RepositoriesURL: String("https://api.github.com/teams/1/repos"),
   726  		},
   727  	}
   728  
   729  	if !cmp.Equal(invitations, want) {
   730  		t.Errorf("Organizations.ListOrgInvitationTeams returned %+v, want %+v", invitations, want)
   731  	}
   732  
   733  	const methodName = "ListOrgInvitationTeams"
   734  	testBadOptions(t, methodName, func() (err error) {
   735  		_, _, err = client.Organizations.ListOrgInvitationTeams(ctx, "\n", "\n", opt)
   736  		return err
   737  	})
   738  
   739  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   740  		got, resp, err := client.Organizations.ListOrgInvitationTeams(ctx, "o", "22", opt)
   741  		if got != nil {
   742  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   743  		}
   744  		return resp, err
   745  	})
   746  }
   747  
   748  func TestOrganizationsService_ListFailedOrgInvitations(t *testing.T) {
   749  	client, mux, _, teardown := setup()
   750  	defer teardown()
   751  
   752  	mux.HandleFunc("/orgs/o/failed_invitations", func(w http.ResponseWriter, r *http.Request) {
   753  		testMethod(t, r, "GET")
   754  		testFormValues(t, r, values{"page": "2", "per_page": "1"})
   755  		fmt.Fprint(w, `[
   756  			{
   757  			   "id":1,
   758  			   "login":"monalisa",
   759  			   "node_id":"MDQ6VXNlcjE=",
   760  			   "email":"octocat@github.com",
   761  			   "role":"direct_member",
   762  			   "created_at":"2016-11-30T06:46:10Z",
   763  			   "failed_at":"2017-01-02T01:10:00Z",
   764  			   "failed_reason":"the reason",
   765  			   "inviter":{
   766  				  "login":"other_user",
   767  				  "id":1,
   768  				  "node_id":"MDQ6VXNlcjE=",
   769  				  "avatar_url":"https://github.com/images/error/other_user_happy.gif",
   770  				  "gravatar_id":"",
   771  				  "url":"https://api.github.com/users/other_user",
   772  				  "html_url":"https://github.com/other_user",
   773  				  "followers_url":"https://api.github.com/users/other_user/followers",
   774  				  "following_url":"https://api.github.com/users/other_user/following{/other_user}",
   775  				  "gists_url":"https://api.github.com/users/other_user/gists{/gist_id}",
   776  				  "starred_url":"https://api.github.com/users/other_user/starred{/owner}{/repo}",
   777  				  "subscriptions_url":"https://api.github.com/users/other_user/subscriptions",
   778  				  "organizations_url":"https://api.github.com/users/other_user/orgs",
   779  				  "repos_url":"https://api.github.com/users/other_user/repos",
   780  				  "events_url":"https://api.github.com/users/other_user/events{/privacy}",
   781  				  "received_events_url":"https://api.github.com/users/other_user/received_events",
   782  				  "type":"User",
   783  				  "site_admin":false
   784  			   },
   785  			   "team_count":2,
   786  			   "invitation_team_url":"https://api.github.com/organizations/2/invitations/1/teams"
   787  			}
   788  		]`)
   789  	})
   790  
   791  	opts := &ListOptions{Page: 2, PerPage: 1}
   792  	ctx := context.Background()
   793  	failedInvitations, _, err := client.Organizations.ListFailedOrgInvitations(ctx, "o", opts)
   794  	if err != nil {
   795  		t.Errorf("Organizations.ListFailedOrgInvitations returned error: %v", err)
   796  	}
   797  
   798  	createdAt := time.Date(2016, time.November, 30, 6, 46, 10, 0, time.UTC)
   799  	want := []*Invitation{
   800  		{
   801  			ID:           Int64(1),
   802  			Login:        String("monalisa"),
   803  			NodeID:       String("MDQ6VXNlcjE="),
   804  			Email:        String("octocat@github.com"),
   805  			Role:         String("direct_member"),
   806  			FailedAt:     &Timestamp{time.Date(2017, time.January, 2, 1, 10, 0, 0, time.UTC)},
   807  			FailedReason: String("the reason"),
   808  			CreatedAt:    &Timestamp{createdAt},
   809  			Inviter: &User{
   810  				Login:             String("other_user"),
   811  				ID:                Int64(1),
   812  				NodeID:            String("MDQ6VXNlcjE="),
   813  				AvatarURL:         String("https://github.com/images/error/other_user_happy.gif"),
   814  				GravatarID:        String(""),
   815  				URL:               String("https://api.github.com/users/other_user"),
   816  				HTMLURL:           String("https://github.com/other_user"),
   817  				FollowersURL:      String("https://api.github.com/users/other_user/followers"),
   818  				FollowingURL:      String("https://api.github.com/users/other_user/following{/other_user}"),
   819  				GistsURL:          String("https://api.github.com/users/other_user/gists{/gist_id}"),
   820  				StarredURL:        String("https://api.github.com/users/other_user/starred{/owner}{/repo}"),
   821  				SubscriptionsURL:  String("https://api.github.com/users/other_user/subscriptions"),
   822  				OrganizationsURL:  String("https://api.github.com/users/other_user/orgs"),
   823  				ReposURL:          String("https://api.github.com/users/other_user/repos"),
   824  				EventsURL:         String("https://api.github.com/users/other_user/events{/privacy}"),
   825  				ReceivedEventsURL: String("https://api.github.com/users/other_user/received_events"),
   826  				Type:              String("User"),
   827  				SiteAdmin:         Bool(false),
   828  			},
   829  			TeamCount:         Int(2),
   830  			InvitationTeamURL: String("https://api.github.com/organizations/2/invitations/1/teams"),
   831  		},
   832  	}
   833  
   834  	if !cmp.Equal(failedInvitations, want) {
   835  		t.Errorf("Organizations.ListFailedOrgInvitations returned %+v, want %+v", failedInvitations, want)
   836  	}
   837  
   838  	const methodName = "ListFailedOrgInvitations"
   839  	testBadOptions(t, methodName, func() error {
   840  		_, _, err := client.Organizations.ListFailedOrgInvitations(ctx, "\n", opts)
   841  		return err
   842  	})
   843  
   844  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   845  		got, resp, err := client.Organizations.ListFailedOrgInvitations(ctx, "o", opts)
   846  		if got != nil {
   847  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   848  		}
   849  		return resp, err
   850  	})
   851  }
   852  
   853  func TestMembership_Marshal(t *testing.T) {
   854  	testJSONMarshal(t, &Membership{}, "{}")
   855  
   856  	u := &Membership{
   857  		URL:             String("url"),
   858  		State:           String("state"),
   859  		Role:            String("email"),
   860  		OrganizationURL: String("orgurl"),
   861  		Organization: &Organization{
   862  			BillingEmail:                         String("be"),
   863  			Blog:                                 String("b"),
   864  			Company:                              String("c"),
   865  			Email:                                String("e"),
   866  			TwitterUsername:                      String("tu"),
   867  			Location:                             String("loc"),
   868  			Name:                                 String("n"),
   869  			Description:                          String("d"),
   870  			IsVerified:                           Bool(true),
   871  			HasOrganizationProjects:              Bool(true),
   872  			HasRepositoryProjects:                Bool(true),
   873  			DefaultRepoPermission:                String("drp"),
   874  			MembersCanCreateRepos:                Bool(true),
   875  			MembersCanCreateInternalRepos:        Bool(true),
   876  			MembersCanCreatePrivateRepos:         Bool(true),
   877  			MembersCanCreatePublicRepos:          Bool(false),
   878  			MembersAllowedRepositoryCreationType: String("marct"),
   879  			MembersCanCreatePages:                Bool(true),
   880  			MembersCanCreatePublicPages:          Bool(false),
   881  			MembersCanCreatePrivatePages:         Bool(true),
   882  		},
   883  		User: &User{
   884  			Login:     String("l"),
   885  			ID:        Int64(1),
   886  			NodeID:    String("n"),
   887  			URL:       String("u"),
   888  			ReposURL:  String("r"),
   889  			EventsURL: String("e"),
   890  			AvatarURL: String("a"),
   891  		},
   892  	}
   893  
   894  	want := `{
   895  		"url": "url",
   896  		"state": "state",
   897  		"role": "email",
   898  		"organization_url": "orgurl",
   899  		"organization": {
   900  			"name": "n",
   901  			"company": "c",
   902  			"blog": "b",
   903  			"location": "loc",
   904  			"email": "e",
   905  			"twitter_username": "tu",
   906  			"description": "d",
   907  			"billing_email": "be",
   908  			"is_verified": true,
   909  			"has_organization_projects": true,
   910  			"has_repository_projects": true,
   911  			"default_repository_permission": "drp",
   912  			"members_can_create_repositories": true,
   913  			"members_can_create_public_repositories": false,
   914  			"members_can_create_private_repositories": true,
   915  			"members_can_create_internal_repositories": true,
   916  			"members_allowed_repository_creation_type": "marct",
   917  			"members_can_create_pages": true,
   918  			"members_can_create_public_pages": false,
   919  			"members_can_create_private_pages": true
   920  		},
   921  		"user": {
   922  			"login": "l",
   923  			"id": 1,
   924  			"node_id": "n",
   925  			"avatar_url": "a",
   926  			"url": "u",
   927  			"events_url": "e",
   928  			"repos_url": "r"
   929  		}
   930  	}`
   931  
   932  	testJSONMarshal(t, u, want)
   933  }
   934  
   935  func TestCreateOrgInvitationOptions_Marshal(t *testing.T) {
   936  	testJSONMarshal(t, &CreateOrgInvitationOptions{}, "{}")
   937  
   938  	u := &CreateOrgInvitationOptions{
   939  		InviteeID: Int64(1),
   940  		Email:     String("email"),
   941  		Role:      String("role"),
   942  		TeamID:    []int64{1},
   943  	}
   944  
   945  	want := `{
   946  		"invitee_id": 1,
   947  		"email": "email",
   948  		"role": "role",
   949  		"team_ids": [
   950  			1
   951  		]
   952  	}`
   953  
   954  	testJSONMarshal(t, u, want)
   955  }
   956  

View as plain text