Preserve page creation outcomes through recovery

This commit is contained in:
2026-10-06 00:53:33 +00:00
parent a1ee067b53
commit 91712fd900
6 changed files with 116 additions and 16 deletions

View File

@@ -339,3 +339,57 @@ func failureKind(t *testing.T, err error) FailureKind {
func contains(value, substring string) bool {
return len(substring) > 0 && len(value) >= len(substring) && strings.Contains(value, substring)
}
func TestEnsureReleaseReconcilesInconsistentSuccessfulCreate(t *testing.T) {
for _, mode := range []string{"matching", "conflicting", "unavailable"} {
t.Run(mode, func(t *testing.T) {
posts, lookups := 0, 0
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case strings.Contains(r.URL.Path, "/tags/") && !strings.Contains(r.URL.Path, "/releases/"):
writeTag(t, w, testCommit)
case strings.Contains(r.URL.Path, "/releases/tags/"):
lookups++
if posts == 0 {
http.NotFound(w, r)
return
}
if mode == "unavailable" {
http.Error(w, "unavailable", 503)
return
}
body := testNote
if mode == "conflicting" {
body = "other content"
}
writeRelease(t, w, releaseFixture{title: "Example v1.2.3", body: body})
case r.Method == http.MethodPost:
posts++
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(releaseResponse{ID: 10, TagName: "v1.2.3", Name: "inconsistent title", Body: testNote})
default:
t.Errorf("unexpected request %s", r.URL.Path)
}
}))
defer server.Close()
result, err := testClient(server).EnsureRelease(context.Background(), testRequest(server.URL))
if posts != 1 || lookups != 2 {
t.Fatalf("posts=%d lookups=%d", posts, lookups)
}
switch mode {
case "matching":
if err != nil || !result.WriteAttempted {
t.Fatalf("result=%#v err=%v", result, err)
}
case "conflicting":
if failureKind(t, err) != FailureConflict {
t.Fatal(err)
}
case "unavailable":
if failureKind(t, err) != FailureUnknown {
t.Fatal(err)
}
}
})
}
}