@@ -25,8 +25,10 @@ import io.sentry.android.core.AppState
2525import io.sentry.android.core.BuildInfoProvider
2626import io.sentry.android.core.ContextUtils
2727import io.sentry.android.core.SystemEventsBreadcrumbsIntegration
28+ import io.sentry.test.DeferredExecutorService
2829import io.sentry.test.ImmediateExecutorService
2930import io.sentry.transport.ICurrentDateProvider
31+ import io.sentry.util.thread.IThreadChecker
3032import kotlin.test.AfterTest
3133import kotlin.test.BeforeTest
3234import kotlin.test.Test
@@ -38,6 +40,7 @@ import kotlin.test.assertTrue
3840import org.junit.runner.RunWith
3941import org.mockito.MockedStatic
4042import org.mockito.Mockito.mockStatic
43+ import org.mockito.Mockito.never
4144import org.mockito.kotlin.any
4245import org.mockito.kotlin.anyOrNull
4346import org.mockito.kotlin.argThat
@@ -205,6 +208,41 @@ class AndroidConnectionStatusProviderTest {
205208 providerWithNullConnectivity.close()
206209 }
207210
211+ @Test
212+ fun `When cache is updating, return UNKNOWN for connectionStatus on main thread` () {
213+ whenever(networkInfo.isConnected).thenReturn(true )
214+ // When we are on the main thread
215+ val mockThreadChecker = mock<IThreadChecker >()
216+ options.threadChecker = mockThreadChecker
217+ whenever(mockThreadChecker.isMainThread()).thenReturn(true )
218+
219+ // The update is done on the background
220+ val executorService = DeferredExecutorService ()
221+ options.executorService = executorService
222+
223+ // Advance time beyond TTL (2 minutes)
224+ currentTime + = 2 * 60 * 1000L
225+
226+ // Connection status is unknown while we update the cache
227+ assertEquals(
228+ IConnectionStatusProvider .ConnectionStatus .UNKNOWN ,
229+ connectionStatusProvider.connectionStatus,
230+ )
231+
232+ verify(connectivityManager, never()).activeNetworkInfo
233+ verify(connectivityManager, never()).activeNetwork
234+
235+ // When background cache update is done
236+ executorService.runAll()
237+
238+ // Connection status is updated
239+ verify(connectivityManager).activeNetwork
240+ assertEquals(
241+ IConnectionStatusProvider .ConnectionStatus .CONNECTED ,
242+ connectionStatusProvider.connectionStatus,
243+ )
244+ }
245+
208246 @Test
209247 fun `When there's no permission, return null for getConnectionType` () {
210248 whenever(contextMock.checkPermission(any(), any(), any())).thenReturn(PERMISSION_DENIED )
@@ -219,6 +257,35 @@ class AndroidConnectionStatusProviderTest {
219257 assertNull(connectionStatusProvider.connectionType)
220258 }
221259
260+ @Test
261+ fun `When cache is updating, return null for getConnectionType on main thread` () {
262+ whenever(networkInfo.isConnected).thenReturn(true )
263+ // When we are on the main thread
264+ val mockThreadChecker = mock<IThreadChecker >()
265+ options.threadChecker = mockThreadChecker
266+ whenever(mockThreadChecker.isMainThread()).thenReturn(true )
267+
268+ // The update is done on the background
269+ val executorService = DeferredExecutorService ()
270+ options.executorService = executorService
271+
272+ // Advance time beyond TTL (2 minutes)
273+ currentTime + = 2 * 60 * 1000L
274+
275+ // Connection type is null while we update the cache
276+ assertNull(connectionStatusProvider.connectionType)
277+
278+ verify(connectivityManager, never()).activeNetworkInfo
279+ verify(connectivityManager, never()).activeNetwork
280+
281+ // When background cache update is done
282+ executorService.runAll()
283+
284+ // Connection type is updated
285+ verify(connectivityManager).activeNetwork
286+ assertNotNull(connectionStatusProvider.connectionType)
287+ }
288+
222289 @Test
223290 fun `When network capabilities are not available, return null for getConnectionType` () {
224291 whenever(connectivityManager.getNetworkCapabilities(any())).thenReturn(null )
0 commit comments