mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-10-20 06:27:53 +02:00
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.
82 lines
3.0 KiB
Go
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")
|
|
}
|
|
}
|