Files
CyberStrikeAI/internal/database/project_legacy_update_test.go
T
Sycun 983c981b92 fix: preserve human intent through planning and restart while keeping legacy edits
Mark generated execution prompts, populate deterministic user sections from actual human entries, preserve canonical ledger on overflow/transient restarts, fit long human entries under their formatted budget, and keep unchanged historical keys editable. Add real reduction-to-snapshot Cookie recovery and production entry-point regression tests.
2026-10-12 19:34:24 +08:00

82 lines
3.0 KiB
Go

package database
import (
"path/filepath"
"testing"
"go.uber.org/zap"
)
func TestLegacyPaddedFactCanUpdateWithoutChangingIdentity(t *testing.T) {
db, err := NewDB(filepath.Join(t.TempDir(), "legacy-update.db"), zap.NewNop())
if err != nil {
t.Fatal(err)
}
defer db.Close()
p, err := db.CreateProject(&Project{Name: "legacy"})
if err != nil {
t.Fatal(err)
}
other, err := db.CreateProject(&Project{Name: "other"})
if err != nil {
t.Fatal(err)
}
f, err := db.UpsertProjectFact(&ProjectFact{ProjectID: p.ID, FactKey: "finding/legacy", Summary: "before", Body: "original evidence"})
if err != nil {
t.Fatal(err)
}
legacyKey := "\u3000 finding/legacy \t"
if _, err := db.Exec("UPDATE project_facts SET fact_key=? WHERE id=?", legacyKey, f.ID); err != nil {
t.Fatal(err)
}
loaded, err := db.GetProjectFact(f.ID)
if err != nil {
t.Fatal(err)
}
loaded.Summary = "after"
loaded.Body = ""
updated, err := db.UpsertProjectFact(loaded)
if err != nil {
t.Fatal(err)
}
if updated.ID != f.ID || updated.FactKey != legacyKey || updated.Summary != "after" || updated.Body != "original evidence" {
t.Fatalf("legacy edit changed identity or evidence: %+v", updated)
}
stored, err := db.GetProjectFactByKey(p.ID, legacyKey)
if err != nil || stored.ID != f.ID || stored.FactKey != legacyKey || stored.Summary != "after" {
t.Fatalf("legacy key was rewritten: %+v %v", stored, err)
}
for name, candidate := range map[string]*ProjectFact{
"new key": {ProjectID: p.ID, FactKey: " finding/new ", Summary: "new"},
"existing key only": {ProjectID: p.ID, FactKey: legacyKey, Summary: "overwrite"},
"wrong record": {ID: "not-the-stored-id", ProjectID: p.ID, FactKey: legacyKey, Summary: "overwrite"},
"wrong project": {ID: f.ID, ProjectID: other.ID, FactKey: legacyKey, Summary: "overwrite"},
"changed key": {ID: f.ID, ProjectID: p.ID, FactKey: " finding/new ", Summary: "overwrite"},
"invalid core": {ID: f.ID, ProjectID: p.ID, FactKey: " finding/invalid? ", Summary: "overwrite"},
} {
t.Run(name, func(t *testing.T) {
if _, err := db.UpsertProjectFact(candidate); err == nil {
t.Fatal("legacy exception accepted a new or mismatched key")
}
})
}
stored, err = db.GetProjectFact(f.ID)
if err != nil || stored.FactKey != legacyKey || stored.Summary != "after" || stored.Body != "original evidence" {
t.Fatalf("rejected write modified stored evidence: %+v %v", stored, err)
}
// Padding was accepted by the old validator, but arbitrary invalid keys
// were not. A stored malformed core must not widen this compatibility path.
malformed, err := db.UpsertProjectFact(&ProjectFact{ProjectID: p.ID, FactKey: "finding/malformed", Summary: "untouched"})
if err != nil {
t.Fatal(err)
}
malformed.FactKey = " finding/invalid? "
if _, err := db.Exec("UPDATE project_facts SET fact_key=? WHERE id=?", malformed.FactKey, malformed.ID); err != nil {
t.Fatal(err)
}
malformed.Summary = "overwrite"
if _, err := db.UpsertProjectFact(malformed); err == nil {
t.Fatal("compatibility exception accepted an invalid trimmed key")
}
}