This commit is contained in:
5 files changed
+258
-170
No files matched your search
+73
-35
@@ -5,6 +5,7 @@ import io.mockk.every
|
||||
import io.mockk.mockkObject
|
||||
import io.mockk.unmockkAll
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
@@ -32,50 +33,68 @@ class DashboardSessionTokenRefresherTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchExtractsInjectedDashboardToken() {
|
||||
fun fetchExtractsInjectedDashboardToken() =
|
||||
runBlocking {
|
||||
server.enqueue(
|
||||
MockResponse()
|
||||
.setResponseCode(200)
|
||||
.setBody("""<script>window.__HERMES_SESSION_TOKEN__ = "new-token";</script>"""),
|
||||
)
|
||||
|
||||
val token = DashboardSessionTokenRefresher.fetch(server.url("/").toString(), OkHttpClient())
|
||||
|
||||
assertEquals("new-token", token)
|
||||
assertEquals("/", server.takeRequest().path)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchReturnsNullWhenDashboardDoesNotInjectToken() =
|
||||
runBlocking {
|
||||
server.enqueue(MockResponse().setResponseCode(200).setBody("<html></html>"))
|
||||
|
||||
val token = DashboardSessionTokenRefresher.fetch(server.url("/").toString(), OkHttpClient())
|
||||
|
||||
assertNull(token)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchReturnsNullForFailedResponse() =
|
||||
runBlocking {
|
||||
server.enqueue(MockResponse().setResponseCode(500))
|
||||
|
||||
val token = DashboardSessionTokenRefresher.fetch(server.url("/").toString(), OkHttpClient())
|
||||
|
||||
assertNull(token)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchReturnsNullWhenTokenIsBlank() =
|
||||
runBlocking {
|
||||
server.enqueue(
|
||||
MockResponse()
|
||||
.setResponseCode(200)
|
||||
.setBody("""<script>window.__HERMES_SESSION_TOKEN__ = "";</script>"""),
|
||||
)
|
||||
|
||||
val token = DashboardSessionTokenRefresher.fetch(server.url("/").toString(), OkHttpClient())
|
||||
|
||||
assertNull(token)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchSyncExtractsInjectedDashboardToken() {
|
||||
server.enqueue(
|
||||
MockResponse()
|
||||
.setResponseCode(200)
|
||||
.setBody("""<script>window.__HERMES_SESSION_TOKEN__ = "new-token";</script>"""),
|
||||
.setBody("""<script>window.__HERMES_SESSION_TOKEN__ = "sync-token";</script>"""),
|
||||
)
|
||||
|
||||
val token = DashboardSessionTokenRefresher.fetch(server.url("/").toString(), OkHttpClient())
|
||||
val token = DashboardSessionTokenRefresher.fetchSync(server.url("/").toString(), OkHttpClient())
|
||||
|
||||
assertEquals("new-token", token)
|
||||
assertEquals("sync-token", token)
|
||||
assertEquals("/", server.takeRequest().path)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchReturnsNullWhenDashboardDoesNotInjectToken() {
|
||||
server.enqueue(MockResponse().setResponseCode(200).setBody("<html></html>"))
|
||||
|
||||
val token = DashboardSessionTokenRefresher.fetch(server.url("/").toString(), OkHttpClient())
|
||||
|
||||
assertNull(token)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchReturnsNullForFailedResponse() {
|
||||
server.enqueue(MockResponse().setResponseCode(500))
|
||||
|
||||
val token = DashboardSessionTokenRefresher.fetch(server.url("/").toString(), OkHttpClient())
|
||||
|
||||
assertNull(token)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchReturnsNullWhenTokenIsBlank() {
|
||||
server.enqueue(
|
||||
MockResponse()
|
||||
.setResponseCode(200)
|
||||
.setBody("""<script>window.__HERMES_SESSION_TOKEN__ = "";</script>"""),
|
||||
)
|
||||
|
||||
val token = DashboardSessionTokenRefresher.fetch(server.url("/").toString(), OkHttpClient())
|
||||
|
||||
assertNull(token)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun refreshUpdatesAuthManagerOnSuccess() {
|
||||
mockkObject(AuthManager)
|
||||
@@ -94,6 +113,25 @@ class DashboardSessionTokenRefresherTest {
|
||||
verify { AuthManager.setToken("mocked-token") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun refreshAsyncUpdatesAuthManagerOnSuccess() =
|
||||
runBlocking {
|
||||
mockkObject(AuthManager)
|
||||
every { AuthManager.baseUrl() } returns server.url("/").toString()
|
||||
every { AuthManager.setToken(any()) } returns Unit
|
||||
|
||||
server.enqueue(
|
||||
MockResponse()
|
||||
.setResponseCode(200)
|
||||
.setBody("""<script>window.__HERMES_SESSION_TOKEN__ = "async-token";</script>"""),
|
||||
)
|
||||
|
||||
val token = DashboardSessionTokenRefresher.refreshAsync()
|
||||
|
||||
assertEquals("async-token", token)
|
||||
verify { AuthManager.setToken("async-token") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun refreshReturnsNullOnException() {
|
||||
mockkObject(AuthManager)
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.m57.hermescontrol.data.remote.OkHttpProvider
|
||||
import com.m57.hermescontrol.data.remote.ServerEndpoint
|
||||
import com.m57.hermescontrol.data.remote.buildFakePersistentCookieJar
|
||||
import com.m57.hermescontrol.data.session.ActiveSessionHolder
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkObject
|
||||
@@ -84,6 +85,10 @@ class HermesWsClientTest {
|
||||
// the WS stack can build its OkHttp clients without app context.
|
||||
CookieManager.setJarForTest(buildFakePersistentCookieJar())
|
||||
|
||||
mockkObject(DashboardSessionTokenRefresher)
|
||||
coEvery { DashboardSessionTokenRefresher.refreshAsync() } returns null
|
||||
every { DashboardSessionTokenRefresher.refresh() } returns null
|
||||
|
||||
// Reset state
|
||||
val connectedField = HermesWsClient::class.java.getDeclaredField("connected")
|
||||
connectedField.isAccessible = true
|
||||
@@ -850,12 +855,11 @@ class HermesWsClientTest {
|
||||
@Test
|
||||
fun testDisconnectThenConnectSupersedesBlockedSocketOpen() =
|
||||
runBlocking {
|
||||
mockkObject(DashboardSessionTokenRefresher)
|
||||
every { AuthManager.baseUrl() } returns mockWebServer.url("/").toString()
|
||||
val refreshStarted = CountDownLatch(1)
|
||||
val releaseRefresh = CountDownLatch(1)
|
||||
val refreshCalls = AtomicInteger(0)
|
||||
every { DashboardSessionTokenRefresher.fetch(any(), any()) } answers {
|
||||
coEvery { DashboardSessionTokenRefresher.refreshAsync() } answers {
|
||||
if (refreshCalls.getAndIncrement() == 0) {
|
||||
refreshStarted.countDown()
|
||||
releaseRefresh.await(5, TimeUnit.SECONDS)
|
||||
@@ -1181,10 +1185,8 @@ class HermesWsClientTest {
|
||||
// 5-6s latch windows routinely overshoot under parallel load).
|
||||
HermesWsClient.setReconnectBackoffForTest(0L)
|
||||
// The reconnect path refreshes the WS token over the network before
|
||||
// opening the socket. Stub it so no real HTTP call sits inside the
|
||||
// opening the socket. Stubbed in setUp() so no real HTTP call sits inside the
|
||||
// test's timing window (CI network latency was the dominant flake).
|
||||
mockkObject(DashboardSessionTokenRefresher)
|
||||
every { DashboardSessionTokenRefresher.fetch(any(), any()) } returns null
|
||||
|
||||
var serverSocket1: WebSocket? = null
|
||||
var serverSocket2: WebSocket? = null
|
||||
@@ -1523,6 +1525,11 @@ class HermesWsClientTest {
|
||||
|
||||
HermesWsClient.connect()
|
||||
|
||||
runBlocking {
|
||||
withTimeout(5000) {
|
||||
HermesWsClient.connectionStatus.first { it == ConnectionStatus.DISCONNECTED }
|
||||
}
|
||||
}
|
||||
assertEquals(ConnectionStatus.DISCONNECTED, HermesWsClient.connectionStatus.value)
|
||||
ticketServer.shutdown()
|
||||
}
|
||||
@@ -1549,6 +1556,11 @@ class HermesWsClientTest {
|
||||
|
||||
HermesWsClient.connect()
|
||||
|
||||
runBlocking {
|
||||
withTimeout(5000) {
|
||||
HermesWsClient.connectionStatus.first { it == ConnectionStatus.RECONNECTING }
|
||||
}
|
||||
}
|
||||
assertEquals(ConnectionStatus.RECONNECTING, HermesWsClient.connectionStatus.value)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user