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")
}