@@ -47,7 +47,10 @@ import io.getstream.android.core.api.socket.StreamConnectionIdHolder
4747import io.getstream.android.core.api.socket.StreamWebSocketFactory
4848import io.getstream.android.core.api.socket.listeners.StreamClientListener
4949import io.getstream.android.core.api.socket.monitor.StreamHealthMonitor
50+ import io.getstream.android.core.api.subscribe.StreamSubscription
5051import io.getstream.android.core.api.subscribe.StreamSubscriptionManager
52+ import io.getstream.android.core.api.watcher.StreamCidRewatchListener
53+ import io.getstream.android.core.api.watcher.StreamCidWatcher
5154import io.getstream.android.core.internal.client.StreamClientImpl
5255import io.getstream.android.core.internal.http.interceptor.StreamApiKeyInterceptor
5356import io.getstream.android.core.internal.http.interceptor.StreamAuthInterceptor
@@ -60,7 +63,9 @@ import io.getstream.android.core.internal.socket.StreamWebSocketImpl
6063import io.getstream.android.core.internal.subscribe.StreamSubscriptionManagerImpl
6164import io.getstream.android.core.testutil.assertFieldEquals
6265import io.getstream.android.core.testutil.readPrivateField
66+ import io.mockk.every
6367import io.mockk.mockk
68+ import io.mockk.verify
6469import kotlin.test.assertEquals
6570import kotlin.test.assertNotSame
6671import kotlin.test.assertTrue
@@ -111,66 +116,88 @@ internal class StreamClientFactoryTest {
111116 val connectionRecoveryEvaluator : StreamConnectionRecoveryEvaluator ,
112117 )
113118
119+ private fun createDependencies (): Dependencies =
120+ Dependencies (
121+ apiKey = StreamApiKey .fromString(" key123" ),
122+ user = StreamUser (id = StreamUserId .fromString(" user-123" )),
123+ wsUrl = StreamWsUrl .fromString(" wss://test.stream/video" ),
124+ clientInfo =
125+ StreamHttpClientInfoHeader .create(
126+ product = " android" ,
127+ productVersion = " 1.0" ,
128+ os = " android" ,
129+ apiLevel = 33 ,
130+ deviceModel = " Pixel" ,
131+ app = " test-app" ,
132+ appVersion = " 1.0.0" ,
133+ ),
134+ clientSubscriptionManager = mockk(relaxed = true ),
135+ tokenProvider = mockk(relaxed = true ),
136+ tokenManager = mockk(relaxed = true ),
137+ singleFlight = mockk(relaxed = true ),
138+ serialQueue = mockk(relaxed = true ),
139+ retryProcessor = mockk(relaxed = true ),
140+ connectionIdHolder = mockk(relaxed = true ),
141+ socketFactory = mockk(relaxed = true ),
142+ healthMonitor = mockk(relaxed = true ),
143+ batcher = mockk(relaxed = true ),
144+ lifecycleMonitor = mockk(relaxed = true ),
145+ networkMonitor = mockk(relaxed = true ),
146+ connectionRecoveryEvaluator = mockk(relaxed = true ),
147+ )
148+
149+ private fun buildClient (
150+ deps : Dependencies ,
151+ httpConfig : StreamHttpConfig ? = null,
152+ watchListener : StreamCidRewatchListener ? = null,
153+ cidWatcher : StreamCidWatcher ? = null,
154+ ): StreamClient {
155+ val watcher =
156+ cidWatcher
157+ ? : StreamCidWatcher (
158+ scope = testScope,
159+ logger = logProvider.taggedLogger(" SCCidRewatcher" ),
160+ streamRewatchSubscriptionManager =
161+ StreamSubscriptionManager (
162+ logger = logProvider.taggedLogger(" SCRewatchSubscriptionManager" )
163+ ),
164+ streamClientSubscriptionManager = deps.clientSubscriptionManager,
165+ )
166+
167+ return StreamClient (
168+ context = mockk(relaxed = true ),
169+ apiKey = deps.apiKey,
170+ user = deps.user,
171+ wsUrl = deps.wsUrl,
172+ products = listOf (" feeds" ),
173+ clientInfoHeader = deps.clientInfo,
174+ clientSubscriptionManager = deps.clientSubscriptionManager,
175+ tokenProvider = deps.tokenProvider,
176+ tokenManager = deps.tokenManager,
177+ singleFlight = deps.singleFlight,
178+ serialQueue = deps.serialQueue,
179+ retryProcessor = deps.retryProcessor,
180+ scope = testScope,
181+ connectionIdHolder = deps.connectionIdHolder,
182+ socketFactory = deps.socketFactory,
183+ healthMonitor = deps.healthMonitor,
184+ batcher = deps.batcher,
185+ httpConfig = httpConfig,
186+ serializationConfig = serializationConfig,
187+ watchListener = watchListener,
188+ cidWatcher = watcher,
189+ logProvider = logProvider,
190+ networkMonitor = deps.networkMonitor,
191+ lifecycleMonitor = deps.lifecycleMonitor,
192+ connectionRecoveryEvaluator = deps.connectionRecoveryEvaluator,
193+ )
194+ }
195+
114196 private fun createClient (
115197 httpConfig : StreamHttpConfig ? = null
116198 ): Pair <StreamClient , Dependencies > {
117- val deps =
118- Dependencies (
119- apiKey = StreamApiKey .fromString(" key123" ),
120- user = StreamUser (id = StreamUserId .fromString(" user-123" )),
121- wsUrl = StreamWsUrl .fromString(" wss://test.stream/video" ),
122- clientInfo =
123- StreamHttpClientInfoHeader .create(
124- product = " android" ,
125- productVersion = " 1.0" ,
126- os = " android" ,
127- apiLevel = 33 ,
128- deviceModel = " Pixel" ,
129- app = " test-app" ,
130- appVersion = " 1.0.0" ,
131- ),
132- clientSubscriptionManager = mockk(relaxed = true ),
133- tokenProvider = mockk(relaxed = true ),
134- tokenManager = mockk(relaxed = true ),
135- singleFlight = mockk(relaxed = true ),
136- serialQueue = mockk(relaxed = true ),
137- retryProcessor = mockk(relaxed = true ),
138- connectionIdHolder = mockk(relaxed = true ),
139- socketFactory = mockk(relaxed = true ),
140- healthMonitor = mockk(relaxed = true ),
141- batcher = mockk(relaxed = true ),
142- lifecycleMonitor = mockk(relaxed = true ),
143- networkMonitor = mockk(relaxed = true ),
144- connectionRecoveryEvaluator = mockk(relaxed = true ),
145- )
146-
147- val client =
148- StreamClient (
149- context = mockk(relaxed = true ),
150- apiKey = deps.apiKey,
151- user = deps.user,
152- wsUrl = deps.wsUrl,
153- products = listOf (" feeds" ),
154- clientInfoHeader = deps.clientInfo,
155- clientSubscriptionManager = deps.clientSubscriptionManager,
156- tokenProvider = deps.tokenProvider,
157- tokenManager = deps.tokenManager,
158- singleFlight = deps.singleFlight,
159- serialQueue = deps.serialQueue,
160- retryProcessor = deps.retryProcessor,
161- scope = testScope,
162- connectionIdHolder = deps.connectionIdHolder,
163- socketFactory = deps.socketFactory,
164- healthMonitor = deps.healthMonitor,
165- batcher = deps.batcher,
166- httpConfig = httpConfig,
167- serializationConfig = serializationConfig,
168- logProvider = logProvider,
169- networkMonitor = deps.networkMonitor,
170- lifecycleMonitor = deps.lifecycleMonitor,
171- connectionRecoveryEvaluator = deps.connectionRecoveryEvaluator,
172- )
173-
199+ val deps = createDependencies()
200+ val client = buildClient(deps = deps, httpConfig = httpConfig)
174201 return client to deps
175202 }
176203
@@ -361,4 +388,27 @@ internal class StreamClientFactoryTest {
361388 manager.assertFieldEquals(" maxStrongSubscriptions" , 250 )
362389 manager.assertFieldEquals(" maxWeakSubscriptions" , 250 )
363390 }
391+
392+ @Test
393+ fun `StreamClient factory auto subscribes provided watch listener` () {
394+ val deps = createDependencies()
395+ val cidWatcher = mockk<StreamCidWatcher >(relaxed = true )
396+ val listener = StreamCidRewatchListener { _, _ -> }
397+ every { cidWatcher.subscribe(listener, any()) } returns
398+ Result .success(mockk<StreamSubscription >(relaxed = true ))
399+
400+ buildClient(deps = deps, watchListener = listener, cidWatcher = cidWatcher)
401+
402+ verify(exactly = 1 ) { cidWatcher.subscribe(listener, any()) }
403+ }
404+
405+ @Test
406+ fun `StreamClient factory skips watch listener subscription when absent` () {
407+ val deps = createDependencies()
408+ val cidWatcher = mockk<StreamCidWatcher >(relaxed = true )
409+
410+ buildClient(deps = deps, cidWatcher = cidWatcher)
411+
412+ verify(exactly = 0 ) { cidWatcher.subscribe(any(), any()) }
413+ }
364414}
0 commit comments