package internal import ( "context" "sync" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "homelab.lan/music-agregator/internal/eventbus" ) func TestRegistry_GetOrCreate_New(t *testing.T) { bus := eventbus.New() reg := NewWorkflowRegistry(bus) entry, created := reg.GetOrCreate(context.Background(), "album-1", "LOSSLESS") assert.True(t, created) require.NotNil(t, entry) assert.Equal(t, "album-1", entry.AlbumID) assert.Equal(t, "LOSSLESS", entry.Quality) assert.Equal(t, "album-1:LOSSLESS", entry.Topic) assert.NotNil(t, entry.Ctx) assert.NotNil(t, entry.Cancel) assert.NotNil(t, entry.Ready) } func TestRegistry_GetOrCreate_ExistingReturned(t *testing.T) { bus := eventbus.New() reg := NewWorkflowRegistry(bus) entry1, created1 := reg.GetOrCreate(context.Background(), "album-1", "LOSSLESS") assert.True(t, created1) entry2, created2 := reg.GetOrCreate(context.Background(), "album-1", "LOSSLESS") assert.False(t, created2) assert.Same(t, entry1, entry2) } func TestRegistry_GetOrCreate_DifferentQuality(t *testing.T) { bus := eventbus.New() reg := NewWorkflowRegistry(bus) entry1, created1 := reg.GetOrCreate(context.Background(), "album-1", "LOSSLESS") assert.True(t, created1) entry2, created2 := reg.GetOrCreate(context.Background(), "album-1", "LOSSY") assert.True(t, created2) assert.NotSame(t, entry1, entry2) } func TestRegistry_Remove(t *testing.T) { bus := eventbus.New() reg := NewWorkflowRegistry(bus) reg.GetOrCreate(context.Background(), "album-1", "LOSSLESS") reg.Remove("album-1", "LOSSLESS") _, ok := reg.Get("album-1", "LOSSLESS") assert.False(t, ok) entry, created := reg.GetOrCreate(context.Background(), "album-1", "LOSSLESS") assert.True(t, created) assert.NotNil(t, entry) } func TestRegistry_Get(t *testing.T) { bus := eventbus.New() reg := NewWorkflowRegistry(bus) _, ok := reg.Get("album-1", "LOSSLESS") assert.False(t, ok) reg.GetOrCreate(context.Background(), "album-1", "LOSSLESS") entry, ok := reg.Get("album-1", "LOSSLESS") assert.True(t, ok) assert.Equal(t, "album-1", entry.AlbumID) } func TestRegistry_ConcurrentGetOrCreate(t *testing.T) { bus := eventbus.New() reg := NewWorkflowRegistry(bus) var wg sync.WaitGroup results := make(chan bool, 20) for i := 0; i < 20; i++ { wg.Add(1) go func() { defer wg.Done() _, created := reg.GetOrCreate(context.Background(), "album-1", "LOSSLESS") results <- created }() } wg.Wait() close(results) createdCount := 0 for created := range results { if created { createdCount++ } } assert.Equal(t, 1, createdCount) } func TestRegistry_Shutdown(t *testing.T) { bus := eventbus.New() reg := NewWorkflowRegistry(bus) entry, _ := reg.GetOrCreate(context.Background(), "album-1", "LOSSLESS") reg.WaitGroup().Add(1) go func() { defer reg.WaitGroup().Done() <-entry.Ctx.Done() }() start := time.Now() reg.Shutdown(5 * time.Second) elapsed := time.Since(start) assert.Less(t, elapsed, 2*time.Second) assert.Error(t, entry.Ctx.Err()) } func TestRegistry_ShutdownTimeout(t *testing.T) { bus := eventbus.New() reg := NewWorkflowRegistry(bus) reg.WaitGroup().Add(1) start := time.Now() reg.Shutdown(100 * time.Millisecond) elapsed := time.Since(start) assert.GreaterOrEqual(t, elapsed, 100*time.Millisecond) assert.Less(t, elapsed, 500*time.Millisecond) reg.WaitGroup().Done() }