package webrtc import ( "sync" "testing" ) // mockSource implements the minimum Source-like shape needed by the registry. // The real Source type is defined in Task 5; the registry only needs a // stable type to store and retrieve. type mockSource struct { id string } func (m *mockSource) ID() string { return m.id } func TestRegistry_RegisterAndLookup(t *testing.T) { r := NewRegistry() src := &mockSource{id: "streamA"} if err := r.Register("streamA", src); err != nil { t.Fatalf("Register returned error: %v", err) } got, ok := r.Lookup("streamA") if !ok { t.Fatal("Lookup(streamA) returned ok=false, want true") } if got != src { t.Errorf("Lookup returned %v, want %v", got, src) } } func TestRegistry_LookupMissing(t *testing.T) { r := NewRegistry() _, ok := r.Lookup("nope") if ok { t.Error("Lookup on empty registry returned ok=true, want false") } } func TestRegistry_DuplicateRegister(t *testing.T) { r := NewRegistry() _ = r.Register("streamA", &mockSource{id: "streamA"}) if err := r.Register("streamA", &mockSource{id: "streamA"}); err == nil { t.Error("duplicate Register should return error, got nil") } } func TestRegistry_Deregister(t *testing.T) { r := NewRegistry() _ = r.Register("streamA", &mockSource{id: "streamA"}) r.Deregister("streamA") if _, ok := r.Lookup("streamA"); ok { t.Error("after Deregister, Lookup should return ok=false") } } func TestRegistry_ConcurrentAccess(t *testing.T) { r := NewRegistry() var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(3) id := string(rune('a' + (i % 26))) go func() { defer wg.Done(); _ = r.Register(id, &mockSource{id: id}) }() go func() { defer wg.Done(); _, _ = r.Lookup(id) }() go func() { defer wg.Done(); r.Deregister(id) }() } wg.Wait() // No assertion — test passes if -race doesn't flag anything. }