package artifacts import ( "strings" "testing" "gitea.maximumdirect.net/eric/narratio/internal/config" "gitea.maximumdirect.net/eric/narratio/internal/manifest" ) func TestResolvePublishBucketPrefersManifestThenConfig(t *testing.T) { cfg := &config.Config{ Pipeline: &config.PipelineConfig{ Storage: config.StorageConfig{ S3: &config.StorageS3Config{Bucket: "cfg-bucket"}, }, }, } if got := ResolvePublishBucket(cfg, &manifest.Manifest{S3Bucket: "manifest-bucket"}); got != "manifest-bucket" { t.Fatalf("bucket = %q, want manifest-bucket", got) } if got := ResolvePublishBucket(cfg, &manifest.Manifest{}); got != "cfg-bucket" { t.Fatalf("bucket = %q, want cfg-bucket", got) } } func TestResolvePublishSessionPrefixPrefersManifestThenConfig(t *testing.T) { cfg := &config.Config{ Pipeline: &config.PipelineConfig{ Storage: config.StorageConfig{ S3: &config.StorageS3Config{RootPrefix: "dnd"}, }, }, Session: &config.SessionConfig{ SessionID: "2026-04-19", Campaign: "forsaken", }, } m := &manifest.Manifest{S3SessionPrefix: "manifest/session/prefix/"} got, err := ResolvePublishSessionPrefix(cfg, m) if err != nil { t.Fatalf("ResolvePublishSessionPrefix() error = %v", err) } if got != "manifest/session/prefix/" { t.Fatalf("session prefix = %q, want manifest/session/prefix/", got) } got, err = ResolvePublishSessionPrefix(cfg, &manifest.Manifest{}) if err != nil { t.Fatalf("ResolvePublishSessionPrefix() error = %v", err) } want := "dnd/campaigns/forsaken/sessions/2026-04-19/" if got != want { t.Fatalf("session prefix = %q, want %q", got, want) } } func TestResolvePublishRunPrefixPrefersManifestThenDerived(t *testing.T) { cfg := &config.Config{ Pipeline: &config.PipelineConfig{ Storage: config.StorageConfig{ S3: &config.StorageS3Config{RootPrefix: "dnd"}, }, }, Session: &config.SessionConfig{ SessionID: "2026-04-19", Campaign: "forsaken", }, } m := &manifest.Manifest{ RunID: "20260516T010203Z-1a2b3c4d", S3RunPrefix: "manifest/run/prefix/", } got, err := ResolvePublishRunPrefix(cfg, m) if err != nil { t.Fatalf("ResolvePublishRunPrefix() error = %v", err) } if got != "manifest/run/prefix/" { t.Fatalf("run prefix = %q, want manifest/run/prefix/", got) } m = &manifest.Manifest{ RunID: "20260516T010203Z-1a2b3c4d", } got, err = ResolvePublishRunPrefix(cfg, m) if err != nil { t.Fatalf("ResolvePublishRunPrefix() error = %v", err) } want := "dnd/campaigns/forsaken/sessions/2026-04-19/runs/20260516T010203Z-1a2b3c4d/" if got != want { t.Fatalf("run prefix = %q, want %q", got, want) } } func TestResolvePublishIdentityErrorsAreDeterministic(t *testing.T) { cfgNoS3 := &config.Config{ Pipeline: &config.PipelineConfig{}, Session: &config.SessionConfig{SessionID: "2026-04-19", Campaign: "forsaken"}, } _, err := ResolvePublishSessionPrefix(cfgNoS3, &manifest.Manifest{}) if err == nil || !strings.Contains(err.Error(), "pipeline.storage.s3 configuration is required") { t.Fatalf("error = %v, want missing storage.s3", err) } cfg := &config.Config{ Pipeline: &config.PipelineConfig{ Storage: config.StorageConfig{ S3: &config.StorageS3Config{RootPrefix: "dnd"}, }, }, Session: &config.SessionConfig{SessionID: "2026-04-19", Campaign: "forsaken"}, } _, err = ResolvePublishRunPrefix(cfg, &manifest.Manifest{}) if err == nil || !strings.Contains(err.Error(), "run id is required") { t.Fatalf("error = %v, want missing run id", err) } } func TestResolveCurrentStateKeys(t *testing.T) { manifestKey, runIDKey := ResolveCurrentStateKeys("dnd/campaigns/forsaken/sessions/2026-04-19/") if manifestKey != "dnd/campaigns/forsaken/sessions/2026-04-19/current/manifest.json" { t.Fatalf("manifest key = %q", manifestKey) } if runIDKey != "dnd/campaigns/forsaken/sessions/2026-04-19/current/run_id.txt" { t.Fatalf("run id key = %q", runIDKey) } }