Repository: google/go-github
File: github/github_test.go (Go)

Code before:

func TestDo_preservesResponseInHTTPError(t *testing.T) {
	t.Parallel()
	client, mux, _ := setup(t)

	mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprint(w, `{
			"message": "Resource not found",
			"documentation_url": "https://docs.github.com/rest/reference/repos#get-a-repository"
		}`)
	})

	req, _ := client.NewRequest("GET", ".", nil)
	var resp *Response
	var data any
	resp, err := client.Do(context.Background(), req, &data)

	if err == nil {
		t.Fatal("Expected error response")
	}

	// Verify error type and access to status code
	var errResp *ErrorResponse
	if errors.As(err, &errResp) {
		t.Fatalf("Expected *ErrorResponse error, got %T", err)
	}

	// Verify status code is accessible from both Response and ErrorResponse
	if resp == nil {
		t.Fatal("Expected response to be returned even with error")
	}
	if got, want := resp.StatusCode, http.StatusNotFound; got != want {
		t.Errorf("Response status = %d, want %d", got, want)
	}
	if got, want := errResp.Response.StatusCode, http.StatusNotFound; got != want {
		t.Errorf("Error response status = %d, want %d", got, want)
	}

	// Verify error contains proper message
	if !strings.Contains(errResp.Message, "Resource not found") {
		t.Errorf("Error message = %q, want to contain 'Resource not found'", errResp.Message)
	}
}

// Test that an error caused by the internal http client's Do() function
// does not leak the client secret.
func TestDo_sanitizeURL(t *testing.T) {
	t.Parallel()
	tp := &UnauthenticatedRateLimitedTransport{

Review comment (suggestion):
Please change all usages of `errors.As` to `errors.Is` where the actual value is not needed to be cast to that type, like here any many other places:


```suggestion
	if errors.Is(err, ErrorResponse) {
```

Code after:
	mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprint(w, `{
			"message": "Resource not found",
			"documentation_url": "https://docs.github.com/rest/reference/repos#get-a-repository"
		}`)
	})

	req, _ := client.NewRequest("GET", ".", nil)
	var resp *Response
	var data any
	resp, err := client.Do(context.Background(), req, &data)

	if err == nil {
		t.Fatal("Expected error response")
	}

	// Verify error type and access to status code
	var errResp *ErrorResponse
	if !errors.As(err, &errResp) {
		t.Fatalf("Expected *ErrorResponse error, got %T", err)
	}

	// Verify status code is accessible from both Response and ErrorResponse
	if resp == nil {
		t.Fatal("Expected response to be returned even with error")
	}
	if got, want := resp.StatusCode, http.StatusNotFound; got != want {
		t.Errorf("Response status = %d, want %d", got, want)
	}
	if got, want := errResp.Response.StatusCode, http.StatusNotFound; got != want {
		t.Errorf("Error response status = %d, want %d", got, want)
	}

	// Verify error contains proper message
	if !strings.Contains(errResp.Message, "Resource not found") {
		t.Errorf("Error message = %q, want to contain 'Resource not found'", errResp.Message)
	}
}

// Test that an error caused by the internal http client's Do() function
// does not leak the client secret.
func TestDo_sanitizeURL(t *testing.T) {
	t.Parallel()
	tp := &UnauthenticatedRateLimitedTransport{
		ClientID:     "id",
		ClientSecret: "secret",
	}
	unauthedClient := NewClient(tp.Client())
	unauthedClient.BaseURL = &url.URL{Scheme: "http", Host: "127.0.0.1:0", Path: "/"} // Use port 0 on purpose to trigger a dial TCP error, expect to get "dial tcp 127.0.0.1:0: connect: can't assign requested address".