package web
import (
"net/http"
"net/http/httptest"
"net/url"
"testing"
"craftdesign.group/quarry/internal/api"
"craftdesign.group/quarry/internal/ops"
)
// A repository that is no longer served — being deleted, which stops
// serving it first — mints no worker token. The settings form is gated
// on caps, which still hold until the delete purges them, so without
// this a token minted in that window outlived the repository and ran
// the next one of its name's CI (quarry#294).
func TestNoWorkerTokenForARepositoryNotServed(t *testing.T) {
repos := api.NewRepos(map[string]*api.Repo{"alpha": {}})
r := ops.NewRegistry()
if err := api.RegisterAll(r, api.Deps{Version: "v", Repos: repos}); err != nil {
t.Fatal(err)
}
eng := &mintRecorder{}
verify := Verify(func(string, string, string, ops.Auth) api.Decision { return api.Allowed })
srv := httptest.NewServer(HandlerWith(r, nil, nil, []Option{
WithSessions(fakeSessions{user: "dan", roles: map[string]ops.Auth{"alpha": ops.Admin}}),
WithCaps(stubCaps{letters: "a8i"}),
WithEngine(eng),
}, verify))
t.Cleanup(srv.Close)
if resp := postAsDan(t, srv, "/r/alpha/settings/worker-tokens", url.Values{"label": {"r"}}); resp.StatusCode != http.StatusSeeOther {
t.Fatalf("FAIL: minting on a served repository answered %d", resp.StatusCode)
}
repos.Delete("alpha")
if resp := postAsDan(t, srv, "/r/alpha/settings/worker-tokens", url.Values{"label": {"r"}}); resp.StatusCode == http.StatusSeeOther {
t.Error("FAIL: minting on a repository no longer served was accepted")
}
eng.mu.Lock()
defer eng.mu.Unlock()
if eng.minted != 1 {
t.Errorf("FAIL: the engine minted %d tokens, want only the one for the served repository", eng.minted)
}
}