package main
import (
"net/http"
"net/http/httptest"
"testing"
"craftdesign.group/quarry/internal/ci"
)
// Drop into cmd/quarry. Both fail on 46b6caea1c00.
// windowEngine: a repo admin mints a group-scoped token (settings form,
// gated on OLTP caps, which still hold the row) after the revoke pass
// and before PurgeRepo. Simulated by minting on the first revoke.
type windowEngine struct{ *tokenEngine }
func (e windowEngine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
e.tokenEngine.ServeHTTP(w, req)
if req.Method == http.MethodDelete {
e.mu.Lock()
if len(e.tokens) < 2 {
e.tokens = append(e.tokens, ci.WorkerToken{ID: "late", WorkerGroups: []string{ci.GroupFor("gone")}})
}
e.mu.Unlock()
}
}
func TestTokenMintedDuringDeleteIsRevoked(t *testing.T) {
eng := &tokenEngine{tokens: []ci.WorkerToken{{ID: "own", WorkerGroups: []string{ci.GroupFor("gone")}}}}
rg, _, _, _ := deleteFixture(t, eng)
srv := httptest.NewServer(windowEngine{eng})
t.Cleanup(srv.Close)
rg.engine = ci.New(srv.URL)
rg.engine.SetAdminToken("admin")
if err := rg.Delete("gone", "gone"); err != nil {
t.Fatal(err)
}
revoked := map[string]bool{}
for _, id := range eng.revoked {
revoked[id] = true
}
for _, tk := range eng.tokens {
if !revoked[tk.ID] {
t.Errorf("FAIL: token %s scoped to gone's group is live after the delete", tk.ID)
}
}
}