package handlers import ( "bytes" "encoding/json" "errors" "net/http" "net/http/httptest" "testing" "github.com/stretchr/testify/assert" ) type mockStorageService struct { generateUploadURLFunc func(key string, contentType string, expiryMinutes int) (string, error) generateDownloadURLFunc func(key string, expiryMinutes int) (string, error) getPublicURLFunc func(key string) string deleteObjectFunc func(key string) error } func (m *mockStorageService) GenerateUploadURL(key string, contentType string, expiryMinutes int) (string, error) { if m.generateUploadURLFunc != nil { return m.generateUploadURLFunc(key, contentType, expiryMinutes) } return "https://s3.amazonaws.com/upload?sig=123", nil } func (m *mockStorageService) GenerateDownloadURL(key string, expiryMinutes int) (string, error) { if m.generateDownloadURLFunc != nil { return m.generateDownloadURLFunc(key, expiryMinutes) } return "https://s3.amazonaws.com/download?sig=123", nil } func (m *mockStorageService) GetPublicURL(key string) string { if m.getPublicURLFunc != nil { return m.getPublicURLFunc(key) } return "https://cdn.example.com/" + key } func (m *mockStorageService) DeleteObject(key string) error { if m.deleteObjectFunc != nil { return m.deleteObjectFunc(key) } return nil } func TestGenerateUploadURL_Success(t *testing.T) { mockStorage := &mockStorageService{} handler := NewStorageHandler(mockStorage) reqBody := map[string]string{ "filename": "test.jpg", "contentType": "image/jpeg", "folder": "logos", } body, _ := json.Marshal(reqBody) req := httptest.NewRequest("POST", "/storage/upload-url", bytes.NewReader(body)) rr := httptest.NewRecorder() handler.GenerateUploadURL(rr, req) assert.Equal(t, http.StatusOK, rr.Code) var resp map[string]interface{} json.Unmarshal(rr.Body.Bytes(), &resp) assert.Contains(t, resp, "uploadUrl") assert.Contains(t, resp, "key") assert.Contains(t, resp, "publicUrl") } func TestGenerateUploadURL_MissingFilename(t *testing.T) { mockStorage := &mockStorageService{} handler := NewStorageHandler(mockStorage) reqBody := map[string]string{ "contentType": "image/jpeg", } body, _ := json.Marshal(reqBody) req := httptest.NewRequest("POST", "/storage/upload-url", bytes.NewReader(body)) rr := httptest.NewRecorder() handler.GenerateUploadURL(rr, req) assert.Equal(t, http.StatusBadRequest, rr.Code) } func TestGenerateDownloadURL_Success(t *testing.T) { mockStorage := &mockStorageService{} handler := NewStorageHandler(mockStorage) reqBody := map[string]string{ "key": "test/file.pdf", } body, _ := json.Marshal(reqBody) req := httptest.NewRequest("POST", "/storage/download-url", bytes.NewReader(body)) rr := httptest.NewRecorder() handler.GenerateDownloadURL(rr, req) assert.Equal(t, http.StatusOK, rr.Code) var resp map[string]interface{} json.Unmarshal(rr.Body.Bytes(), &resp) assert.Contains(t, resp, "downloadUrl") } func TestDeleteFile_Success(t *testing.T) { mockStorage := &mockStorageService{} handler := NewStorageHandler(mockStorage) req := httptest.NewRequest("DELETE", "/storage/files?key=test.jpg", nil) rr := httptest.NewRecorder() handler.DeleteFile(rr, req) assert.Equal(t, http.StatusNoContent, rr.Code) } func TestDeleteFile_Error(t *testing.T) { mockStorage := &mockStorageService{ deleteObjectFunc: func(key string) error { return errors.New("delete failed") }, } handler := NewStorageHandler(mockStorage) req := httptest.NewRequest("DELETE", "/storage/files?key=test.jpg", nil) rr := httptest.NewRecorder() handler.DeleteFile(rr, req) assert.Equal(t, http.StatusInternalServerError, rr.Code) }