package ws import ( "context" "testing" "time" "github.com/alicebob/miniredis/v2" wspkg "github.com/gochat/gochat/internal/ws" "github.com/redis/go-redis/v9" "github.com/stretchr/testify/require" ) func TestHubDisconnectUserClosesOnlyAgentConnections(t *testing.T) { hub := NewHubSimple() agent := NewClient(7, 1, nil, hub) contact := NewClient(7, 1, nil, hub) contact.IsContact = true hub.Register(agent) hub.Register(contact) hub.DisconnectUser(7) hub.mu.RLock() defer hub.mu.RUnlock() require.NotContains(t, hub.clients, agent.ID) require.Contains(t, hub.clients, contact.ID) } func TestUserDisconnectBroadcastClosesConnectionOnAnotherInstance(t *testing.T) { mr := miniredis.RunT(t) rdbA := redis.NewClient(&redis.Options{Addr: mr.Addr()}) rdbB := redis.NewClient(&redis.Options{Addr: mr.Addr()}) t.Cleanup(func() { require.NoError(t, rdbA.Close()) require.NoError(t, rdbB.Close()) }) hubA := NewHubSimple() hubB := NewHubSimple() relayA := wspkg.NewBroadcastRelay(rdbA, hubA) relayB := wspkg.NewBroadcastRelay(rdbB, hubB) ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(func() { cancel() require.NoError(t, relayA.Stop()) require.NoError(t, relayB.Stop()) }) require.NoError(t, relayA.Start(ctx)) require.NoError(t, relayB.Start(ctx)) remoteAgent := NewClient(7, 1, nil, hubB) hubB.Register(remoteAgent) require.NoError(t, relayA.PublishUserDisconnect(ctx, 7)) require.Eventually(t, func() bool { hubB.mu.RLock() defer hubB.mu.RUnlock() _, connected := hubB.clients[remoteAgent.ID] return !connected }, time.Second, 10*time.Millisecond) }