package storage import ( "bytes" "context" "io" "os" "path/filepath" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestLocalStorage(t *testing.T) { // Create a temporary directory for testing tempDir, err := os.MkdirTemp("", "storage_test_*") require.NoError(t, err) defer os.RemoveAll(tempDir) // Create a new LocalStorage instance storage, err := NewLocalStorage(tempDir) require.NoError(t, err) ctx := context.Background() t.Run("Save and Get", func(t *testing.T) { content := []byte("test content") reader := bytes.NewReader(content) // Save the file fileInfo, err := storage.Save(ctx, "test.txt", "text/plain", reader) require.NoError(t, err) assert.NotEmpty(t, fileInfo.ID) assert.Equal(t, "test.txt", fileInfo.Name) assert.Equal(t, int64(len(content)), fileInfo.Size) assert.Equal(t, "text/plain", fileInfo.ContentType) assert.False(t, fileInfo.CreatedAt.IsZero()) // Get the file readCloser, info, err := storage.Get(ctx, fileInfo.ID) require.NoError(t, err) defer readCloser.Close() data, err := io.ReadAll(readCloser) require.NoError(t, err) assert.Equal(t, content, data) assert.Equal(t, fileInfo.ID, info.ID) assert.Equal(t, fileInfo.Name, info.Name) assert.Equal(t, fileInfo.Size, info.Size) }) t.Run("List", func(t *testing.T) { // Clear the directory first dirEntries, err := os.ReadDir(tempDir) require.NoError(t, err) for _, entry := range dirEntries { if entry.Name() != ".meta" { os.Remove(filepath.Join(tempDir, entry.Name())) } } // Save multiple files testFiles := []struct { name string content string }{ {"test1.txt", "content1"}, {"test2.txt", "content2"}, {"other.txt", "content3"}, } for _, f := range testFiles { reader := bytes.NewReader([]byte(f.content)) _, err := storage.Save(ctx, f.name, "text/plain", reader) require.NoError(t, err) } // List all files allFiles, err := storage.List(ctx, "", 10, 0) require.NoError(t, err) assert.Len(t, allFiles, 3) // List files with prefix filesWithPrefix, err := storage.List(ctx, "test", 10, 0) require.NoError(t, err) assert.Len(t, filesWithPrefix, 2) for _, f := range filesWithPrefix { assert.True(t, strings.HasPrefix(f.Name, "test")) } // Test pagination pagedFiles, err := storage.List(ctx, "", 2, 1) require.NoError(t, err) assert.Len(t, pagedFiles, 2) }) t.Run("Exists", func(t *testing.T) { // Save a file content := []byte("test content") reader := bytes.NewReader(content) fileInfo, err := storage.Save(ctx, "exists.txt", "text/plain", reader) require.NoError(t, err) // Check if file exists exists, err := storage.Exists(ctx, fileInfo.ID) require.NoError(t, err) assert.True(t, exists) // Check non-existent file exists, err = storage.Exists(ctx, "non-existent") require.NoError(t, err) assert.False(t, exists) }) t.Run("Delete", func(t *testing.T) { // Save a file content := []byte("test content") reader := bytes.NewReader(content) fileInfo, err := storage.Save(ctx, "delete.txt", "text/plain", reader) require.NoError(t, err) // Delete the file err = storage.Delete(ctx, fileInfo.ID) require.NoError(t, err) // Verify file is deleted exists, err := storage.Exists(ctx, fileInfo.ID) require.NoError(t, err) assert.False(t, exists) // Try to delete non-existent file err = storage.Delete(ctx, "non-existent") assert.Error(t, err) }) t.Run("Invalid operations", func(t *testing.T) { // Try to get non-existent file _, _, err := storage.Get(ctx, "non-existent") assert.Error(t, err) assert.Contains(t, err.Error(), "file not found") // Try to save file with nil reader _, err = storage.Save(ctx, "test.txt", "text/plain", nil) assert.Error(t, err) assert.Contains(t, err.Error(), "reader cannot be nil") // Try to delete non-existent file err = storage.Delete(ctx, "non-existent") assert.Error(t, err) assert.Contains(t, err.Error(), "file not found") }) }