package watcher_test import ( "context" "log/slog" "os" "path/filepath" "testing" "time" "git.savin.nyc/alex/go-iar-notificator/bus" "git.savin.nyc/alex/go-iar-notificator/watcher" ) func TestWatchDirectory_NewMP3File(t *testing.T) { // Create a temporary directory tempDir := t.TempDir() // Create event bus eb := bus.NewCustomEventBus() // Channel to capture published events eventReceived := make(chan string, 1) // Subscribe to new_mp3 event eb.Subscribe("new_mp3", "test_handler", func(data any) { if path, ok := data.(string); ok { eventReceived <- path } }) // Create logger (discard output) logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) // Start watcher in a goroutine ctx, cancel := context.WithCancel(context.Background()) go watcher.WatchDirectory(ctx, tempDir, eb, logger) // Give watcher time to start time.Sleep(100 * time.Millisecond) // Create a new MP3 file mp3File := filepath.Join(tempDir, "test.mp3") err := os.WriteFile(mp3File, []byte("fake mp3 data"), 0644) if err != nil { t.Fatalf("Failed to create MP3 file: %v", err) } // Wait for the event select { case receivedPath := <-eventReceived: if receivedPath != mp3File { t.Errorf("Expected path %s, got %s", mp3File, receivedPath) } case <-time.After(2 * time.Second): t.Error("Event was not received within timeout") } // Clean up cancel() } func TestWatchDirectory_NonMP3File(t *testing.T) { // Create a temporary directory tempDir := t.TempDir() // Create event bus eb := bus.NewCustomEventBus() // Channel to capture published events eventReceived := make(chan string, 1) // Subscribe to new_mp3 event eb.Subscribe("new_mp3", "test_handler", func(data any) { if path, ok := data.(string); ok { eventReceived <- path } }) // Create logger logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) // Start watcher ctx, cancel := context.WithCancel(context.Background()) go watcher.WatchDirectory(ctx, tempDir, eb, logger) // Give watcher time to start time.Sleep(100 * time.Millisecond) // Create a non-MP3 file txtFile := filepath.Join(tempDir, "test.txt") err := os.WriteFile(txtFile, []byte("text data"), 0644) if err != nil { t.Fatalf("Failed to create text file: %v", err) } // Wait a bit and check no event was received time.Sleep(500 * time.Millisecond) select { case <-eventReceived: t.Error("Event should not be received for non-MP3 file") default: // Expected: no event } // Clean up cancel() } func TestWatchDirectory_DirectoryCreation(t *testing.T) { // Use a non-existent directory path tempDir := t.TempDir() nonExistentDir := filepath.Join(tempDir, "new_dir") // Create event bus eb := bus.NewCustomEventBus() // Create logger logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) // Start watcher (should create the directory) ctx, cancel := context.WithCancel(context.Background()) go watcher.WatchDirectory(ctx, nonExistentDir, eb, logger) // Give time for directory creation time.Sleep(200 * time.Millisecond) // Check if directory was created if _, err := os.Stat(nonExistentDir); os.IsNotExist(err) { t.Error("Directory should have been created") } // Clean up cancel() } func TestWatchDirectory_WriteEvent(t *testing.T) { // Create a temporary directory tempDir := t.TempDir() // Create event bus eb := bus.NewCustomEventBus() // Channel to capture published events eventReceived := make(chan string, 1) // Subscribe to new_mp3 event eb.Subscribe("new_mp3", "test_handler", func(data any) { if path, ok := data.(string); ok { eventReceived <- path } }) // Create logger logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) // Start watcher ctx, cancel := context.WithCancel(context.Background()) go watcher.WatchDirectory(ctx, tempDir, eb, logger) // Give watcher time to start time.Sleep(100 * time.Millisecond) // Create and then write to an MP3 file (simulating save) mp3File := filepath.Join(tempDir, "test.mp3") err := os.WriteFile(mp3File, []byte("initial data"), 0644) if err != nil { t.Fatalf("Failed to create MP3 file: %v", err) } // Wait for initial event select { case <-eventReceived: // Expected case <-time.After(1 * time.Second): t.Error("Initial event was not received") } // Now write again (should trigger again) err = os.WriteFile(mp3File, []byte("updated data"), 0644) if err != nil { t.Fatalf("Failed to update MP3 file: %v", err) } // Wait for second event select { case <-eventReceived: // Expected case <-time.After(1 * time.Second): t.Error("Second event was not received") } // Clean up cancel() }