package storage import ( "context" "strings" "testing" "gitea.maximumdirect.net/eric/narratio/internal/config" ) func TestNewObjectStoreFromConfigBuildsS3WhenBackendIsS3(t *testing.T) { original := newS3Client t.Cleanup(func() { newS3Client = original }) newS3Client = func(_ context.Context, _ s3ClientOptions) (s3API, error) { return &fakeS3API{}, nil } store, err := NewObjectStoreFromConfig(context.Background(), &config.Config{ Pipeline: &config.PipelineConfig{ Storage: config.StorageConfig{ Backend: "s3", S3: &config.StorageS3Config{ Bucket: "my-archive", }, }, }, }) if err != nil { t.Fatalf("NewObjectStoreFromConfig() error = %v", err) } if _, ok := store.(*S3Backend); !ok { t.Fatalf("store type = %T, want *S3Backend", store) } } func TestNewObjectStoreFromConfigRequiresS3ConfigWhenBackendIsS3(t *testing.T) { _, err := NewObjectStoreFromConfig(context.Background(), &config.Config{ Pipeline: &config.PipelineConfig{ Storage: config.StorageConfig{Backend: "s3"}, }, }) if err == nil || !strings.Contains(err.Error(), "pipeline.storage.s3 is required") { t.Fatalf("NewObjectStoreFromConfig() error = %v, want missing storage.s3 error", err) } } func TestNewObjectStoreFromConfigNoRemoteBackendConfigured(t *testing.T) { _, err := NewObjectStoreFromConfig(context.Background(), &config.Config{ Pipeline: &config.PipelineConfig{ Storage: config.StorageConfig{Backend: "local"}, }, }) if err == nil || !strings.Contains(err.Error(), "no remote object store backend is configured") { t.Fatalf("NewObjectStoreFromConfig() error = %v, want no-backend error", err) } } func TestNewObjectStoreFromConfigDoesNotInferS3FromProviderFields(t *testing.T) { called := false original := newS3Client t.Cleanup(func() { newS3Client = original }) newS3Client = func(_ context.Context, _ s3ClientOptions) (s3API, error) { called = true return &fakeS3API{}, nil } _, err := NewObjectStoreFromConfig(context.Background(), &config.Config{ Pipeline: &config.PipelineConfig{Storage: config.StorageConfig{ Backend: config.StorageBackendLocal, S3: &config.StorageS3Config{Bucket: "my-archive"}, }}, }) if err == nil || !strings.Contains(err.Error(), "no remote object store backend is configured") { t.Fatalf("NewObjectStoreFromConfig() error = %v, want no-backend error", err) } if called { t.Fatal("NewObjectStoreFromConfig() constructed S3 from incidental provider fields") } } func TestNewObjectStoreFromConfigRejectsUnknownBackend(t *testing.T) { _, err := NewObjectStoreFromConfig(context.Background(), &config.Config{ Pipeline: &config.PipelineConfig{Storage: config.StorageConfig{Backend: "s33"}}, }) if err == nil || !strings.Contains(err.Error(), "unsupported pipeline.storage.backend") { t.Fatalf("NewObjectStoreFromConfig() error = %v, want unsupported-backend error", err) } }