package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "reflect" "testing" ) // newIndex returns the address of a newly populated packageIndex. func newIndex(t *testing.T) *packageIndex { var index packageIndex if err := index.populate(nil, nil); err != nil { t.Fatalf("populate: error = %v", err) } return &index } // checkStatus checks response status code. func checkStatus(t *testing.T, resp *http.Response, want int) { if resp.StatusCode != want { t.Errorf( "StatusCode: %s, want %s", http.StatusText(resp.StatusCode), http.StatusText(want), ) } } // checkHeader checks the value of a header entry. func checkHeader(t *testing.T, h http.Header, key, want string) { if got := h.Get(key); got != want { t.Errorf("%s: %q, want %q", key, got, want) } } // checkAPIHeader checks common entries set for API endpoints. func checkAPIHeader(t *testing.T, h http.Header) { checkHeader(t, h, "Content-Type", "application/json; charset=utf-8") checkHeader(t, h, "Cache-Control", "no-cache, no-store, must-revalidate") checkHeader(t, h, "Pragma", "no-cache") checkHeader(t, h, "Expires", "0") } // checkPayloadFunc checks the JSON response of an API endpoint by passing it to f. func checkPayloadFunc[T any]( t *testing.T, resp *http.Response, f func(got *T) bool, ) { var got T r := io.Reader(resp.Body) if testing.Verbose() { var buf bytes.Buffer r = io.TeeReader(r, &buf) defer func() { t.Log(buf.String()) }() } if err := json.NewDecoder(r).Decode(&got); err != nil { t.Fatalf("Decode: error = %v", err) } if !f(&got) { t.Errorf("Body: %#v", got) } } // checkPayload checks the JSON response of an API endpoint. func checkPayload[T any](t *testing.T, resp *http.Response, want T) { checkPayloadFunc(t, resp, func(got *T) bool { return reflect.DeepEqual(got, &want) }) } func checkError(t *testing.T, resp *http.Response, error string, code int) { checkStatus(t, resp, code) if got, _ := io.ReadAll(resp.Body); string(got) != fmt.Sprintln(error) { t.Errorf("Body: %q, want %q", string(got), error) } }