Skip to content

Commit

Permalink
Rename HttpClient.getNumRetriesSoFar to getCurrentRetryCount, convert…
Browse files Browse the repository at this point in the history
… HttpClientUnitTest to Kotlin, and remove unused function and test class (#1242)
tdchow authored Dec 17, 2024
1 parent 8c181f1 commit a74fe2b
Showing 5 changed files with 176 additions and 227 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@ class HttpClient internal constructor(
}

if (url != null) {
val retryCount = getNumRetriesSoFar(url)
val retryCount = getCurrentRetryCount(url)
val shouldRetry = ((retryCount + 1) < MAX_RETRY_ATTEMPTS)
if (shouldRetry) {
scheduleRequest(request, retryStrategy, callback)
@@ -85,10 +85,7 @@ class HttpClient internal constructor(
}
}

private fun getNumRetriesSoFar(url: URL): Int {
val retryCount = retryCountMap[url] ?: return 0
return retryCount
}
private fun getCurrentRetryCount(url: URL) = retryCountMap[url] ?: 0

private fun resetRetryCount(request: HttpRequest) {
try {
Original file line number Diff line number Diff line change
@@ -27,20 +27,6 @@ public class TLSSocketFactory extends SSLSocketFactory {

private final SSLSocketFactory internalSSLSocketFactory;

static TLSSocketFactory newInstance() throws SSLException {
return new TLSSocketFactory();
}

TLSSocketFactory() throws SSLException {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null); // use system security providers
internalSSLSocketFactory = sslContext.getSocketFactory();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
throw new SSLException(e.getMessage());
}
}

/**
* @see <a href="http://developer.android.com/training/articles/security-ssl.html#UnknownCa">Android Documentation</a>
*/

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package com.braintreepayments.api.sharedutils

import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers
import org.mockito.Mockito

class HttpClientUnitTest {
private lateinit var syncHttpClient: SynchronousHttpClient
private lateinit var httpRequest: HttpRequest
private lateinit var threadScheduler: MockThreadScheduler

private lateinit var sut: HttpClient

@Before
fun beforeEach() {
syncHttpClient = Mockito.mock(SynchronousHttpClient::class.java)
threadScheduler = Mockito.spy(MockThreadScheduler())
httpRequest = HttpRequest().path("https://example.com")

sut = HttpClient(syncHttpClient, threadScheduler)
}

@Test
@Throws(Exception::class)
fun sendRequest_sendsRequestOnBackgroundThread() {
val callback = Mockito.mock(NetworkResponseCallback::class.java)
sut.sendRequest(httpRequest, callback, HttpClient.RetryStrategy.NO_RETRY)

Mockito.verifyNoInteractions(syncHttpClient)
threadScheduler.flushBackgroundThread()

Mockito.verify(syncHttpClient)?.request(httpRequest)
}

@Test
@Throws(Exception::class)
fun sendRequest_whenBaseHttpClientThrowsException_notifiesErrorViaCallbackOnMainThread() {
val exception = Exception("error")
Mockito.`when`(syncHttpClient.request(httpRequest)).thenThrow(exception)

val callback = Mockito.mock(NetworkResponseCallback::class.java)
sut.sendRequest(httpRequest, callback, HttpClient.RetryStrategy.NO_RETRY)

threadScheduler.flushBackgroundThread()
Mockito.verify(callback, Mockito.never()).onResult(null, exception)

threadScheduler.flushMainThread()
Mockito.verify(callback).onResult(null, exception)
}

@Test
@Throws(Exception::class)
fun sendRequest_onBaseHttpClientRequestSuccess_notifiesSuccessViaCallbackOnMainThread() {
val response = HttpResponse("response body", HttpResponseTiming(123, 456))

Mockito.`when`(syncHttpClient.request(httpRequest)).thenReturn(response)

val callback = Mockito.mock(NetworkResponseCallback::class.java)
sut.sendRequest(httpRequest, callback, HttpClient.RetryStrategy.NO_RETRY)

threadScheduler.flushBackgroundThread()
Mockito.verify(callback, Mockito.never()).onResult(response, null)

threadScheduler.flushMainThread()
Mockito.verify(callback).onResult(response, null)
}

@Test
@Throws(Exception::class)
fun sendRequest_whenCallbackIsNull_doesNotNotifySuccess() {
val response = HttpResponse("response body", HttpResponseTiming(123, 456))

Mockito.`when`(syncHttpClient.request(httpRequest)).thenReturn(response)
sut.sendRequest(httpRequest, null, HttpClient.RetryStrategy.NO_RETRY)

threadScheduler.flushBackgroundThread()
Mockito.verify(threadScheduler, Mockito.never())?.runOnMain(
ArgumentMatchers.any(Runnable::class.java)
)
}

@Test
@Throws(Exception::class)
fun sendRequest_whenCallbackIsNull_doesNotNotifyError() {
val exception = Exception("error")
Mockito.`when`(syncHttpClient.request(httpRequest)).thenThrow(exception)

sut.sendRequest(httpRequest, null, HttpClient.RetryStrategy.NO_RETRY)

threadScheduler.flushBackgroundThread()
Mockito.verify(threadScheduler, Mockito.never())?.runOnMain(
ArgumentMatchers.any(
Runnable::class.java
)
)
}

@Test
@Throws(Exception::class)
fun sendRequest_whenRetryMax3TimesEnabled_retriesRequest3Times() {
val exception = Exception("error")
Mockito.`when`(syncHttpClient.request(httpRequest)).thenThrow(exception)

val callback = Mockito.mock(NetworkResponseCallback::class.java)
sut.sendRequest(httpRequest, callback, HttpClient.RetryStrategy.RETRY_MAX_3_TIMES)

threadScheduler.flushBackgroundThread()
Mockito.verify(syncHttpClient, Mockito.times(3))?.request(httpRequest)
}

@Test
@Throws(Exception::class)
fun sendRequest_whenRetryMax3TimesEnabled_notifiesMaxRetriesLimitExceededOnForegroundThread() {
val exception = Exception("error")
Mockito.`when`(syncHttpClient.request(httpRequest)).thenThrow(exception)

val callback = Mockito.mock(NetworkResponseCallback::class.java)
sut.sendRequest(httpRequest, callback, HttpClient.RetryStrategy.RETRY_MAX_3_TIMES)

threadScheduler.flushBackgroundThread()
Mockito.verify(callback, Mockito.never()).onResult(
ArgumentMatchers.isNull(),
ArgumentMatchers.any(Exception::class.java)
)

threadScheduler.flushMainThread()

val captor = ArgumentCaptor.forClass(Exception::class.java)
Mockito.verify(callback).onResult(ArgumentMatchers.isNull(), captor.capture())

val httpClientException = captor.value as HttpClientException
val expectedMessage = "Retry limit has been exceeded. Try again later."
Assert.assertEquals(expectedMessage, httpClientException.message)
}

@Test
@Throws(Exception::class)
fun sendRequest_whenRetryMax3TimesEnabled_futureRequestsAreAllowed() {
val response = HttpResponse("response body", HttpResponseTiming(123, 456))

val exception = Exception("error")
Mockito.`when`(syncHttpClient.request(httpRequest)).thenThrow(exception)

val callback = Mockito.mock(NetworkResponseCallback::class.java)
sut.sendRequest(httpRequest, callback, HttpClient.RetryStrategy.RETRY_MAX_3_TIMES)

threadScheduler.flushBackgroundThread()

Mockito.reset(syncHttpClient)
Mockito.`when`(syncHttpClient.request(httpRequest))
.thenThrow(exception)
.thenReturn(response)
sut.sendRequest(httpRequest, callback, HttpClient.RetryStrategy.RETRY_MAX_3_TIMES)

threadScheduler.flushBackgroundThread()
threadScheduler.flushMainThread()

Mockito.verify(callback).onResult(response, null)
}

@Test
@Throws(Exception::class)
fun sendRequestSynchronous_sendsHttpRequest() {
val response = HttpResponse("response body", HttpResponseTiming(123, 456))

Mockito.`when`(syncHttpClient.request(httpRequest)).thenReturn(response)

val result = sut.sendRequest(httpRequest)
Assert.assertEquals("response body", result)
}
}

0 comments on commit a74fe2b

Please sign in to comment.