test:implement unit tests for fetching campaigns and fix DTO mocking logic

This commit is contained in:
Kota-Jagadeesh 2025-10-18 22:33:25 +05:30
parent c9014f3538
commit 3e6561cdbf

View file

@ -3,6 +3,10 @@ package fr.free.nrw.commons
import com.google.gson.Gson import com.google.gson.Gson
import com.nhaarman.mockitokotlin2.any import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.verify import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.times
import fr.free.nrw.commons.campaigns.CampaignResponseDTO
import fr.free.nrw.commons.campaigns.CampaignConfig
import fr.free.nrw.commons.campaigns.models.Campaign
import fr.free.nrw.commons.explore.depictions.DepictsClient import fr.free.nrw.commons.explore.depictions.DepictsClient
import fr.free.nrw.commons.location.LatLng import fr.free.nrw.commons.location.LatLng
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
@ -10,13 +14,22 @@ import fr.free.nrw.commons.nearby.model.NearbyQueryParams
import okhttp3.Call import okhttp3.Call
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import okhttp3.ResponseBody
import okhttp3.mockwebserver.MockResponse
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito import org.mockito.Mockito
import org.mockito.Mockito.times import org.mockito.Mockito.eq
import org.mockito.MockitoAnnotations import org.mockito.MockitoAnnotations
import java.io.BufferedReader
import java.io.InputStreamReader
import java.lang.Exception import java.lang.Exception
class OkHttpJsonApiClientTests { class OkHttpJsonApiClientTests {
@ -45,34 +58,43 @@ class OkHttpJsonApiClientTests {
@Mock @Mock
lateinit var response: Response lateinit var response: Response
@Mock
lateinit var responseBody: ResponseBody
private lateinit var mockWebServer: TestWebServer
@Before @Before
fun setUp() { fun setUp() {
MockitoAnnotations.openMocks(this) MockitoAnnotations.openMocks(this)
okHttpJsonApiClient = mockWebServer = TestWebServer()
OkHttpJsonApiClient( mockWebServer.setUp()
okhttpClient, okHttpJsonApiClient = OkHttpJsonApiClient(
depictsClient, okhttpClient,
wikiMediaToolforgeUrl, depictsClient,
sparqlQueryUrl, wikiMediaToolforgeUrl,
campaignsUrl, sparqlQueryUrl,
gson, mockWebServer.getUrl(), //use the mock server for the campaignsUrl
) gson
)
Mockito.`when`(okhttpClient.newCall(any())).thenReturn(call) Mockito.`when`(okhttpClient.newCall(any())).thenReturn(call)
Mockito.`when`(call.execute()).thenReturn(response) Mockito.`when`(call.execute()).thenReturn(response)
Mockito.`when`(response.isSuccessful).thenReturn(false)
Mockito.`when`(response.message).thenReturn("test")
Mockito.`when`(response.body).thenReturn(responseBody)
Mockito.`when`(responseBody.string()).thenReturn("{\"error\": \"test\"}")
} }
@Test @Test
fun testGetNearbyPlacesCustomQuery() { fun testGetNearbyPlacesCustomQuery() {
Mockito.`when`(response.message).thenReturn("test")
try { try {
okHttpJsonApiClient.getNearbyPlaces(latLng, "test", 10.0, "test") okHttpJsonApiClient.getNearbyPlaces(latLng, "test", 10.0, "test")
} catch (e: Exception) { } catch (e: Exception) {
assert(e.message.equals("test")) assertEquals("test", e.message)
} }
try { try {
okHttpJsonApiClient.getNearbyPlaces(NearbyQueryParams.Rectangular(latLng, latLng), "test", true, "test") okHttpJsonApiClient.getNearbyPlaces(NearbyQueryParams.Rectangular(latLng, latLng), "test", true, "test")
} catch (e: Exception) { } catch (e: Exception) {
assert(e.message.equals("test")) assertEquals("test", e.message)
} }
verify(okhttpClient, times(2)).newCall(any()) verify(okhttpClient, times(2)).newCall(any())
verify(call, times(2)).execute() verify(call, times(2)).execute()
@ -80,11 +102,10 @@ class OkHttpJsonApiClientTests {
@Test @Test
fun testGetNearbyPlaces() { fun testGetNearbyPlaces() {
Mockito.`when`(response.message).thenReturn("test")
try { try {
okHttpJsonApiClient.getNearbyPlaces(latLng, "test", 10.0, null) okHttpJsonApiClient.getNearbyPlaces(latLng, "test", 10.0, null)
} catch (e: Exception) { } catch (e: Exception) {
assert(e.message.equals("test")) assertEquals("test", e.message)
} }
try { try {
okHttpJsonApiClient.getNearbyPlaces( okHttpJsonApiClient.getNearbyPlaces(
@ -93,9 +114,8 @@ class OkHttpJsonApiClientTests {
true, true,
null null
) )
} catch (e: Exception) { } catch (e: Exception) {
assert(e.message.equals("test")) assertEquals("test", e.message)
} }
try { try {
okHttpJsonApiClient.getNearbyPlaces( okHttpJsonApiClient.getNearbyPlaces(
@ -105,7 +125,7 @@ class OkHttpJsonApiClientTests {
null null
) )
} catch (e: Exception) { } catch (e: Exception) {
assert(e.message.equals("test")) assertEquals("test", e.message)
} }
verify(okhttpClient, times(3)).newCall(any()) verify(okhttpClient, times(3)).newCall(any())
verify(call, times(3)).execute() verify(call, times(3)).execute()
@ -113,18 +133,121 @@ class OkHttpJsonApiClientTests {
@Test @Test
fun testGetNearbyItemCount() { fun testGetNearbyItemCount() {
Mockito.`when`(response.message).thenReturn("test")
try { try {
okHttpJsonApiClient.getNearbyItemCount(NearbyQueryParams.Radial(latLng, 10f)) okHttpJsonApiClient.getNearbyItemCount(NearbyQueryParams.Radial(latLng, 10f))
} catch (e: Exception) { } catch (e: Exception) {
assert(e.message.equals("test")) assertEquals("test", e.message)
} }
try { try {
okHttpJsonApiClient.getNearbyItemCount(NearbyQueryParams.Rectangular(latLng, latLng)) okHttpJsonApiClient.getNearbyItemCount(NearbyQueryParams.Rectangular(latLng, latLng))
} catch (e: Exception) { } catch (e: Exception) {
assert(e.message.equals("test")) assertEquals("test", e.message)
} }
verify(okhttpClient, times(2)).newCall(any()) verify(okhttpClient, times(2)).newCall(any())
verify(call, times(2)).execute() verify(call, times(2)).execute()
} }
@Test
fun testGetCampaignsWithData() {
//loads the json response from resources
val jsonResponse = loadJsonFromResource("campaigns_response_with_data.json")
//mocks the succesfull response chain
Mockito.`when`(response.isSuccessful).thenReturn(true)
Mockito.`when`(response.message).thenReturn("OK")
Mockito.`when`(response.body).thenReturn(responseBody)
Mockito.`when`(responseBody.string()).thenReturn(jsonResponse)
val campaignResponse = CampaignResponseDTO().apply {
campaignConfig = CampaignConfig().apply {
showOnlyLiveCampaigns = false
sortBy = "startDate"
}
campaigns = listOf(
Campaign().apply {
title = "Wiki Loves Monuments"
isWLMCampaign = true
},
Campaign().apply {
title = "Wiki Loves Nature"
isWLMCampaign = false
}
)
}
//any() for the string argument and eq() for the class argument.
Mockito.`when`(
gson.fromJson(
any<String>(),
eq(CampaignResponseDTO::class.java)
)
).thenReturn(campaignResponse)
//call the getCampaigns
val result: CampaignResponseDTO? = okHttpJsonApiClient.getCampaigns().blockingGet()
//verify the results
assertNotNull(result)
assertNotNull(result?.campaigns)
assertEquals(2, result?.campaigns!!.size)
assertEquals("Wiki Loves Monuments", result.campaigns!![0].title)
assertTrue(result.campaigns!![0].isWLMCampaign)
assertEquals("Wiki Loves Nature", result.campaigns!![1].title)
assertEquals(false, result.campaigns!![1].isWLMCampaign)
assertNotNull(result.campaignConfig)
assertFalse(result.campaignConfig!!.showOnlyLiveCampaigns)
assertEquals("startDate", result.campaignConfig!!.sortBy)
}
@Test
fun testGetCampaignsEmpty() {
//loads the empty json response
val jsonResponse = loadJsonFromResource("campaigns_response_empty.json")
//mocks the successful response chain
Mockito.`when`(response.isSuccessful).thenReturn(true)
Mockito.`when`(response.message).thenReturn("OK")
Mockito.`when`(response.body).thenReturn(responseBody)
Mockito.`when`(responseBody.string()).thenReturn(jsonResponse)
val campaignResponse = CampaignResponseDTO().apply {
campaignConfig = CampaignConfig().apply {
showOnlyLiveCampaigns = false
sortBy = "startDate"
}
campaigns = emptyList()
}
//use any() for the string argument and eq() for the class argument.
Mockito.`when`(
gson.fromJson(
any<String>(),
eq(CampaignResponseDTO::class.java)
)
).thenReturn(campaignResponse)
//calls getCampaigns
val result: CampaignResponseDTO? = okHttpJsonApiClient.getCampaigns().blockingGet()
//verify the results
assertNotNull(result)
assertNotNull(result?.campaigns)
assertTrue(result?.campaigns!!.isEmpty())
assertNotNull(result.campaignConfig)
assertFalse(result.campaignConfig!!.showOnlyLiveCampaigns)
assertEquals("startDate", result.campaignConfig!!.sortBy)
}
fun loadJsonFromResource(fileName: String): String {
val resourcePath = "raw/$fileName"
//use the classloader to find the resource in the test environment
val inputStream = javaClass.classLoader?.getResourceAsStream(resourcePath)
if (inputStream != null) {
//reads the entire stream content
return BufferedReader(InputStreamReader(inputStream)).use { it.readText() }
}
//throws an exception with the correct expected path
throw IllegalArgumentException("Resource $fileName not found. Please ensure the file is located in app/src/test/resources/raw/")
}
} }