package storage import ( "context" "fmt" "io" "os" "strings" "testing" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/stretchr/testify/assert" ) func TestNew(t *testing.T) { type args struct { bucket string } tests := []struct { name string args args setup func() func() wantErr bool }{ { name: "invalid AWS config", args: args{}, setup: func() func() { _ = os.Setenv("AWS_MAX_ATTEMPTS", "invalid") return func() { _ = os.Unsetenv("AWS_MAX_ATTEMPTS") } }, wantErr: true, }, { name: "success", args: args{}, setup: func() func() { return func() { } }, wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { defer tt.setup()() _, err := New(tt.args.bucket) if (err != nil) != tt.wantErr { t.Errorf("New() error = %v, wantErr %v", err, tt.wantErr) return } }) } } func TestS3_Store(t *testing.T) { type fields struct { bucket string svc func(t *testing.T) Uploader } type args struct { path string content io.Reader } tests := []struct { name string fields fields args args wantErr bool }{ { name: "upload error", fields: fields{ bucket: "some-bucket", svc: func(t *testing.T) Uploader { return &mock{ upload: func(ctx context.Context, input *s3.PutObjectInput, f ...func(*manager.Uploader)) (*manager.UploadOutput, error) { assert.Equal(t, aws.String("some-bucket"), input.Bucket) assert.Equal(t, aws.String("/some/path"), input.Key) buff, err := io.ReadAll(input.Body) assert.NoError(t, err) assert.Equal(t, "some content", string(buff)) return nil, fmt.Errorf("error") }, } }, }, args: args{ path: "/some/path", content: strings.NewReader("some content"), }, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var svc Uploader if tt.fields.svc != nil { svc = tt.fields.svc(t) } s := &S3{ bucket: tt.fields.bucket, svc: svc, } if err := s.Store(tt.args.path, tt.args.content); (err != nil) != tt.wantErr { t.Errorf("Store() error = %v, wantErr %v", err, tt.wantErr) } }) } } type mock struct { upload func(ctx context.Context, input *s3.PutObjectInput, f ...func(*manager.Uploader)) (*manager.UploadOutput, error) } func (m *mock) Upload(ctx context.Context, input *s3.PutObjectInput, f ...func(*manager.Uploader)) (*manager.UploadOutput, error) { if m.upload != nil { return m.upload(ctx, input, f...) } return nil, nil } var _ Uploader = &mock{}