refac: missing mutation tests, spa specs, checks shown to pass, touch targets, catalogue entry, production code

This commit is contained in:
Florian Sylvain committed 2026-11-04 03:04:35 +01:00
1 parent 7c15206170
commit 3e02e14da4
48 files changed
+2173 -83

No files matched your search

+60
View File
@@ -0,0 +1,60 @@
package test
import (
"RenewCMS/api/pkg/apperr"
"net/http"
"strconv"
"sync"
"testing"
)
const concurrentSaveRounds = 20
func TestArticleConcurrentSavesHTTP(t *testing.T) {
t.Run("Two saves of the same article with the same if_revision: one wins, the other conflicts", func(t *testing.T) {
for round := 0; round < concurrentSaveRounds; round++ {
w := newStoryWorld(t)
revision, _ := revisionsOf(w, 10)
bodies := []string{"<p>Mine</p>", "<p>Theirs</p>"}
responses := make([]storyResponse, len(bodies))
start := make(chan struct{})
var saves sync.WaitGroup
for i, body := range bodies {
saves.Add(1)
go func() {
defer saves.Done()
<-start
responses[i] = w.send(storyUpdater, http.MethodPatch, "/v1/article/10", `{"body":"`+body+`","if_revision":`+strconv.FormatUint(uint64(revision), 10)+`}`)
}()
}
close(start)
saves.Wait()
winners, losers := 0, 0
var winningBody string
for i, response := range responses {
switch response.Code {
case http.StatusOK:
winners++
winningBody = bodies[i]
case http.StatusConflict:
losers++
if response.text() != apperr.RevisionConflictErrorMessage+"\n" {
t.Fatalf("conflict body %q", response.text())
}
if response.header(apperr.CurrentRevisionHeader) != strconv.FormatUint(uint64(revision+1), 10) {
t.Fatalf("current revision header %q", response.header(apperr.CurrentRevisionHeader))
}
default:
t.Fatalf("unexpected %d %q", response.Code, response.text())
}
}
if winners != 1 || losers != 1 {
t.Fatalf("round %d: %d saved, %d conflicted", round, winners, losers)
}
if stored, _ := revisionsOf(w, 10); stored != revision+1 || w.stored(10).Body != winningBody {
t.Fatalf("round %d: stored revision %d body %q, the winner sent %q", round, stored, w.stored(10).Body, winningBody)
}
}
})
}