github.com/google/go-github/v71@v71.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.Fprintf(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.Fprintf(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  }