github.com/google/go-github/v74@v74.0.0/github/orgs_personal_access_tokens_test.go (about) 1 // Copyright 2023 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_ListFineGrainedPersonalAccessTokens(t *testing.T) { 20 t.Parallel() 21 client, mux, _ := setup(t) 22 23 mux.HandleFunc("/orgs/o/personal-access-tokens", func(w http.ResponseWriter, r *http.Request) { 24 testMethod(t, r, "GET") 25 expectedQuery := map[string][]string{ 26 "per_page": {"2"}, 27 "page": {"2"}, 28 "sort": {"created_at"}, 29 "direction": {"desc"}, 30 "owner[]": {"octocat", "octodog", "otherbot"}, 31 } 32 33 query := r.URL.Query() 34 for key, expectedValues := range expectedQuery { 35 actualValues := query[key] 36 if len(actualValues) != len(expectedValues) { 37 t.Errorf("Expected %d values for query param %s, got %d", len(expectedValues), key, len(actualValues)) 38 } 39 for i, expectedValue := range expectedValues { 40 if actualValues[i] != expectedValue { 41 t.Errorf("Expected query param %s to be %s, got %s", key, expectedValue, actualValues[i]) 42 } 43 } 44 } 45 46 fmt.Fprint(w, ` 47 [ 48 { 49 "id": 25381, 50 "owner": { 51 "login": "octocat", 52 "id": 1, 53 "node_id": "MDQ6VXNlcjE=", 54 "avatar_url": "https://github.com/images/error/octocat_happy.gif", 55 "gravatar_id": "", 56 "url": "https://api.github.com/users/octocat", 57 "html_url": "https://github.com/octocat", 58 "followers_url": "https://api.github.com/users/octocat/followers", 59 "following_url": "https://api.github.com/users/octocat/following{/other_user}", 60 "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", 61 "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", 62 "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", 63 "organizations_url": "https://api.github.com/users/octocat/orgs", 64 "repos_url": "https://api.github.com/users/octocat/repos", 65 "events_url": "https://api.github.com/users/octocat/events{/privacy}", 66 "received_events_url": "https://api.github.com/users/octocat/received_events", 67 "type": "User", 68 "site_admin": false 69 }, 70 "repository_selection": "all", 71 "repositories_url": "https://api.github.com/organizations/652551/personal-access-tokens/25381/repositories", 72 "permissions": { 73 "organization": { 74 "members": "read" 75 }, 76 "repository": { 77 "metadata": "read" 78 } 79 }, 80 "access_granted_at": "2023-05-16T08:47:09.000-07:00", 81 "token_expired": false, 82 "token_expires_at": "2023-11-16T08:47:09.000-07:00", 83 "token_last_used_at": null 84 } 85 ]`) 86 }) 87 88 opts := &ListFineGrainedPATOptions{ 89 ListOptions: ListOptions{Page: 2, PerPage: 2}, 90 Sort: "created_at", 91 Direction: "desc", 92 Owner: []string{"octocat", "octodog", "otherbot"}, 93 } 94 ctx := context.Background() 95 tokens, resp, err := client.Organizations.ListFineGrainedPersonalAccessTokens(ctx, "o", opts) 96 if err != nil { 97 t.Errorf("Organizations.ListFineGrainedPersonalAccessTokens returned error: %v", err) 98 } 99 100 want := []*PersonalAccessToken{ 101 { 102 ID: Ptr(int64(25381)), 103 Owner: &User{ 104 Login: Ptr("octocat"), 105 ID: Ptr(int64(1)), 106 NodeID: Ptr("MDQ6VXNlcjE="), 107 AvatarURL: Ptr("https://github.com/images/error/octocat_happy.gif"), 108 GravatarID: Ptr(""), 109 URL: Ptr("https://api.github.com/users/octocat"), 110 HTMLURL: Ptr("https://github.com/octocat"), 111 FollowersURL: Ptr("https://api.github.com/users/octocat/followers"), 112 FollowingURL: Ptr("https://api.github.com/users/octocat/following{/other_user}"), 113 GistsURL: Ptr("https://api.github.com/users/octocat/gists{/gist_id}"), 114 StarredURL: Ptr("https://api.github.com/users/octocat/starred{/owner}{/repo}"), 115 SubscriptionsURL: Ptr("https://api.github.com/users/octocat/subscriptions"), 116 OrganizationsURL: Ptr("https://api.github.com/users/octocat/orgs"), 117 ReposURL: Ptr("https://api.github.com/users/octocat/repos"), 118 EventsURL: Ptr("https://api.github.com/users/octocat/events{/privacy}"), 119 ReceivedEventsURL: Ptr("https://api.github.com/users/octocat/received_events"), 120 Type: Ptr("User"), 121 SiteAdmin: Ptr(false), 122 }, 123 RepositorySelection: Ptr("all"), 124 RepositoriesURL: Ptr("https://api.github.com/organizations/652551/personal-access-tokens/25381/repositories"), 125 Permissions: &PersonalAccessTokenPermissions{ 126 Org: map[string]string{"members": "read"}, 127 Repo: map[string]string{"metadata": "read"}, 128 }, 129 AccessGrantedAt: &Timestamp{time.Date(2023, time.May, 16, 8, 47, 9, 0, time.FixedZone("PDT", -7*60*60))}, 130 TokenExpired: Ptr(false), 131 TokenExpiresAt: &Timestamp{time.Date(2023, time.November, 16, 8, 47, 9, 0, time.FixedZone("PDT", -7*60*60))}, 132 TokenLastUsedAt: nil, 133 }, 134 } 135 if !cmp.Equal(tokens, want) { 136 t.Errorf("Organizations.ListFineGrainedPersonalAccessTokens returned %+v, want %+v", tokens, want) 137 } 138 139 if resp == nil { 140 t.Error("Organizations.ListFineGrainedPersonalAccessTokens returned nil response") 141 } 142 143 const methodName = "ListFineGrainedPersonalAccessTokens" 144 testBadOptions(t, methodName, func() (err error) { 145 _, _, err = client.Organizations.ListFineGrainedPersonalAccessTokens(ctx, "\n", opts) 146 return err 147 }) 148 149 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 150 got, resp, err := client.Organizations.ListFineGrainedPersonalAccessTokens(ctx, "o", opts) 151 if got != nil { 152 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 153 } 154 return resp, err 155 }) 156 } 157 158 func TestOrganizationsService_ReviewPersonalAccessTokenRequest(t *testing.T) { 159 t.Parallel() 160 client, mux, _ := setup(t) 161 162 input := ReviewPersonalAccessTokenRequestOptions{ 163 Action: "a", 164 Reason: Ptr("r"), 165 } 166 167 mux.HandleFunc("/orgs/o/personal-access-token-requests/1", func(w http.ResponseWriter, r *http.Request) { 168 v := new(ReviewPersonalAccessTokenRequestOptions) 169 assertNilError(t, json.NewDecoder(r.Body).Decode(v)) 170 171 testMethod(t, r, http.MethodPost) 172 if !cmp.Equal(v, &input) { 173 t.Errorf("Request body = %+v, want %+v", v, input) 174 } 175 176 w.WriteHeader(http.StatusNoContent) 177 }) 178 179 ctx := context.Background() 180 res, err := client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", 1, input) 181 if err != nil { 182 t.Errorf("Organizations.ReviewPersonalAccessTokenRequest returned error: %v", err) 183 } 184 185 if res.StatusCode != http.StatusNoContent { 186 t.Errorf("Organizations.ReviewPersonalAccessTokenRequest returned %v, want %v", res.StatusCode, http.StatusNoContent) 187 } 188 189 const methodName = "ReviewPersonalAccessTokenRequest" 190 testBadOptions(t, methodName, func() (err error) { 191 _, err = client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "\n", 0, input) 192 return err 193 }) 194 195 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 196 return client.Organizations.ReviewPersonalAccessTokenRequest(ctx, "o", 1, input) 197 }) 198 } 199 200 func TestReviewPersonalAccessTokenRequestOptions_Marshal(t *testing.T) { 201 t.Parallel() 202 testJSONMarshal(t, &ReviewPersonalAccessTokenRequestOptions{}, "{}") 203 204 u := &ReviewPersonalAccessTokenRequestOptions{ 205 Action: "a", 206 Reason: Ptr("r"), 207 } 208 209 want := `{ 210 "action": "a", 211 "reason": "r" 212 }` 213 214 testJSONMarshal(t, u, want) 215 }