package apimeta import ( "encoding/base64" "encoding/json" "net/http" "net/http/httptest" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "sourcecraft.dev/bigbes/sr-ht-core/crypto" "sourcecraft.dev/bigbes/sr-ht-ecore/ecoretest" ) func TestMain(m *testing.M) { ecoretest.InitCrypto() m.Run() } func serve(t *testing.T, scopes ...string) (*httptest.ResponseRecorder, Meta) { t.Helper() rec := httptest.NewRecorder() Handler(scopes...).ServeHTTP(rec, httptest.NewRequest(http.MethodGet, Path, nil)) var got Meta require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &got)) return rec, got } func TestHandlerPublishesTheScopesAndTheWebhookKey(t *testing.T) { rec, got := serve(t, "repos") require.Equal(t, http.StatusOK, rec.Code) assert.Equal(t, "application/json", rec.Header().Get("Content-Type")) assert.Equal(t, []string{"repos"}, got.Scopes) want := base64.StdEncoding.EncodeToString(crypto.WebhookPubkey) assert.Equal(t, want, got.WebhookPubkey) assert.NotEmpty(t, got.WebhookPubkey, "the instance's webhook key is what a consumer verifies payloads with") } // The failure this guards is not this service's: meta.sr.ht iterates every // discovered service's scopes on one page, so a null here 500s the // personal-token page for the whole instance. It is checked on the wire and not // on the struct, because it is the JSON that travels. func TestNoScopesIsAnEmptyListAndNeverNull(t *testing.T) { for _, tc := range []struct { name string scopes []string }{ {"no arguments at all", nil}, {"an explicitly empty slice", []string{}}, } { t.Run(tc.name, func(t *testing.T) { rec, got := serve(t, tc.scopes...) assert.NotContains(t, rec.Body.String(), "null") assert.Contains(t, rec.Body.String(), `"scopes":[]`) assert.NotNil(t, got.Scopes) assert.Empty(t, got.Scopes) }) } } func TestHandlerAnswersEveryRequestIdentically(t *testing.T) { h := Handler("repos", "objects") var bodies []string for range 3 { rec := httptest.NewRecorder() h.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, Path, nil)) require.Equal(t, http.StatusOK, rec.Code) bodies = append(bodies, rec.Body.String()) } assert.Equal(t, bodies[0], bodies[1]) assert.Equal(t, bodies[1], bodies[2]) assert.Contains(t, bodies[0], `"scopes":["repos","objects"]`, "the scopes keep the order they were declared in") }