Files
narratio/internal/manifest/semantic_fingerprint_test.go

66 lines
2.4 KiB
Go

package manifest
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
const testSemanticDigest = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
func TestSemanticConfigFingerprintRoundTripsAndRemainsOptional(t *testing.T) {
ctx := context.Background()
store := &LocalStore{}
dir := t.TempDir()
fingerprint := &SemanticConfigFingerprint{Version: 3, Digest: testSemanticDigest}
session := New("session", time.Now().UTC())
session.MarkStageSucceeded("prepare", time.Now().UTC(), nil)
session.Stages["prepare"].SemanticConfig = fingerprint
sessionPath := filepath.Join(dir, "session.json")
if err := store.Save(ctx, sessionPath, session); err != nil {
t.Fatal(err)
}
loadedSession, err := store.Load(ctx, sessionPath)
if err != nil {
t.Fatal(err)
}
if loadedSession.Stages["prepare"].SemanticConfig == nil || !loadedSession.Stages["prepare"].SemanticConfig.Equal(*fingerprint) {
t.Fatalf("session fingerprint = %#v", loadedSession.Stages["prepare"].SemanticConfig)
}
path := filepath.Join(dir, "without-fingerprint.json")
data := `{"schema_version":"narratio.session-manifest.v1","session_id":"session","created_at":"2026-01-01T00:00:00Z","updated_at":"2026-01-01T00:00:00Z","stages":{"prepare":{"name":"prepare","status":"succeeded","created_at":"2026-01-01T00:00:00Z","updated_at":"2026-01-01T00:00:00Z"}}}`
if err := os.WriteFile(path, []byte(data), 0o644); err != nil {
t.Fatal(err)
}
loadedWithoutFingerprint, err := store.Load(ctx, path)
if err != nil {
t.Fatal(err)
}
if loadedWithoutFingerprint.Stages["prepare"].SemanticConfig != nil {
t.Fatalf("fingerprint = %#v, want nil", loadedWithoutFingerprint.Stages["prepare"].SemanticConfig)
}
}
func TestSemanticConfigFingerprintValidation(t *testing.T) {
for _, test := range []struct {
name string
value SemanticConfigFingerprint
want string
}{
{name: "zero version", value: SemanticConfigFingerprint{Digest: testSemanticDigest}, want: "positive"},
{name: "uppercase digest", value: SemanticConfigFingerprint{Version: 1, Digest: strings.ToUpper(testSemanticDigest)}, want: "lowercase"},
{name: "short digest", value: SemanticConfigFingerprint{Version: 1, Digest: "abcd"}, want: "lowercase"},
} {
t.Run(test.name, func(t *testing.T) {
if err := test.value.Validate(); err == nil || !strings.Contains(err.Error(), test.want) {
t.Fatalf("Validate() error = %v, want %q", err, test.want)
}
})
}
}