Call sites used to mutate the response with EndpointNeedsScopes before converting it to an error. Request converts internally, so WithEndpointScopes has to reproduce that suggestion.
(t *testing.T)
| 211 | // Call sites used to mutate the response with EndpointNeedsScopes before converting it to an error. |
| 212 | // Request converts internally, so WithEndpointScopes has to reproduce that suggestion. |
| 213 | func TestRequestWithEndpointScopes(t *testing.T) { |
| 214 | tests := []struct { |
| 215 | name string |
| 216 | statusCode int |
| 217 | acceptedScopes string |
| 218 | wantSuggestion string |
| 219 | }{ |
| 220 | { |
| 221 | name: "adds scopes the endpoint did not report", |
| 222 | statusCode: 403, |
| 223 | acceptedScopes: "", |
| 224 | wantSuggestion: "delete_repo", |
| 225 | }, |
| 226 | { |
| 227 | name: "appends to scopes the endpoint did report", |
| 228 | statusCode: 403, |
| 229 | acceptedScopes: "repo", |
| 230 | wantSuggestion: "delete_repo", |
| 231 | }, |
| 232 | { |
| 233 | name: "leaves 5xx errors alone", |
| 234 | statusCode: 500, |
| 235 | acceptedScopes: "", |
| 236 | wantSuggestion: "", |
| 237 | }, |
| 238 | } |
| 239 | |
| 240 | for _, tt := range tests { |
| 241 | t.Run(tt.name, func(t *testing.T) { |
| 242 | reg := &httpmock.Registry{} |
| 243 | defer reg.Verify(t) |
| 244 | client := newTestClient(reg) |
| 245 | |
| 246 | reg.Register(httpmock.MatchAny, func(req *http.Request) (*http.Response, error) { |
| 247 | header := map[string][]string{ |
| 248 | "Content-Type": {"application/json; charset=utf-8"}, |
| 249 | "X-Oauth-Scopes": {"repo"}, |
| 250 | } |
| 251 | if tt.acceptedScopes != "" { |
| 252 | header["X-Accepted-Oauth-Scopes"] = []string{tt.acceptedScopes} |
| 253 | } |
| 254 | return &http.Response{ |
| 255 | Request: req, |
| 256 | StatusCode: tt.statusCode, |
| 257 | Body: io.NopCloser(bytes.NewBufferString(`{"message": "Forbidden"}`)), |
| 258 | Header: header, |
| 259 | }, nil |
| 260 | }) |
| 261 | |
| 262 | _, err := client.Request("github.com", http.MethodDelete, "repos/OWNER/REPO", nil, |
| 263 | WithEndpointScopes("delete_repo")) |
| 264 | |
| 265 | var httpErr HTTPError |
| 266 | require.ErrorAs(t, err, &httpErr) |
| 267 | if tt.wantSuggestion == "" { |
| 268 | assert.Empty(t, httpErr.ScopesSuggestion()) |
| 269 | } else { |
| 270 | assert.Contains(t, httpErr.ScopesSuggestion(), tt.wantSuggestion) |
nothing calls this directly
no test coverage detected