557629d2bf
gates / gates (push) Successful in 2m3s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
99 lines
3.7 KiB
Go
99 lines
3.7 KiB
Go
package web
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"sync/atomic"
|
|
"testing"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-hub/internal/gitea"
|
|
)
|
|
|
|
// R-292: the artifact save names the cause of a checksum failure. One flash used to cover "version
|
|
// missing", "registry unreachable" and "bad typed sha" — and the operator acts differently on each.
|
|
//
|
|
// These drive resolveArtifactSHA through the real handler. The installability gate is passed by a
|
|
// registry that serves the tag and the download; ONLY the sha metadata route is varied.
|
|
func shaRegistry(t *testing.T, metaStatus int, metaBody string) *gitea.Client {
|
|
t.Helper()
|
|
var hits int32
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
atomic.AddInt32(&hits, 1)
|
|
p := strings.TrimPrefix(r.URL.Path, "/")
|
|
if strings.HasPrefix(p, "api/v1/packages/") && strings.HasSuffix(p, "/files") {
|
|
if metaStatus != http.StatusOK {
|
|
w.WriteHeader(metaStatus)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(metaBody))
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK) // tag probe + package download: installable
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
return gitea.New(srv.URL, "admin", "", "")
|
|
}
|
|
|
|
func TestArtifactSave_FlashNamesTheCause(t *testing.T) {
|
|
sha := strings.Repeat("c", 64)
|
|
for _, tc := range []struct {
|
|
name string
|
|
metaStatus int
|
|
metaBody string
|
|
want string
|
|
}{
|
|
{"version not found", http.StatusNotFound, "", "artifact_version_missing"},
|
|
{"registry failing", http.StatusBadGateway, "", "artifact_unverifiable"},
|
|
{"no sha listed", http.StatusOK, `[{"name":"x","sha256":""}]`, "artifact_sha_missing"},
|
|
{"healthy", http.StatusOK, `[{"name":"x","sha256":"` + sha + `"}]`, "artifacts_set"},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
s, _ := newTestServer(t)
|
|
s.SetGiteaClient(shaRegistry(t, tc.metaStatus, tc.metaBody))
|
|
if got := flashOf(saveArtifacts(t, s)); got != tc.want {
|
|
t.Fatalf("flash = %q, want %q", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// The manual path (no Gitea client): a malformed typed sha is the ONE case artifact_sha_invalid means.
|
|
func TestArtifactSave_BadTypedSHAIsShaInvalid(t *testing.T) {
|
|
s, st := newTestServer(t)
|
|
form := url.Values{"agent_version": {"0.128.0"}, "agent_sha256": {"not-a-sha"}}
|
|
r := httptest.NewRequest(http.MethodPost, "/configuration/artifacts", strings.NewReader(form.Encode()))
|
|
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
w := httptest.NewRecorder()
|
|
s.handleSetArtifacts(w, r)
|
|
if got := flashOf(w); got != "artifact_sha_invalid" {
|
|
t.Fatalf("flash = %q, want artifact_sha_invalid", got)
|
|
}
|
|
assertUnchanged(t, st, "bad typed sha")
|
|
}
|
|
|
|
// Every flash the save can redirect to renders its own message (seam: a flash with no template branch
|
|
// shows the operator nothing). The sha_invalid text no longer claims a lookup failure.
|
|
func TestArtifactFlashes_EachRendersItsOwnText(t *testing.T) {
|
|
s, _ := newRenderServer(t)
|
|
for flash, want := range map[string]string{
|
|
"artifact_version_missing": "the registry has no such version",
|
|
"artifact_sha_missing": "no checksum for a chosen version",
|
|
"artifact_unverifiable": "could not verify",
|
|
"artifact_sha_invalid": "a checksum you typed is not valid",
|
|
} {
|
|
req := httptest.NewRequest(http.MethodGet, "/configuration?flash="+flash, nil)
|
|
rr := httptest.NewRecorder()
|
|
s.handleConfiguration(rr, req)
|
|
body := rr.Body.String()
|
|
if !strings.Contains(body, want) {
|
|
t.Errorf("flash %s: page does not render %q", flash, want)
|
|
}
|
|
if flash == "artifact_sha_invalid" && strings.Contains(body, "Gitea unreachable") {
|
|
t.Error("artifact_sha_invalid still conflates an unreachable registry with a bad sha")
|
|
}
|
|
}
|
|
}
|