Skip to content

Commit 7e3c259

Browse files
authored
Merge pull request #4 from isoguzay/task/test-case-implementation
task/test-case-implementation
2 parents 1a0e416 + f8923d2 commit 7e3c259

File tree

13 files changed

+504
-12
lines changed

13 files changed

+504
-12
lines changed

app/src/main/java/com/adyen/android/assignment/datasource/remote/PlacesRemoteData.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.adyen.android.assignment.datasource.remote
22

3-
import com.adyen.android.assignment.model.response.PlacesReponse
3+
import com.adyen.android.assignment.model.response.PlacesResponse
44
import com.adyen.android.assignment.model.request.LocationRequestModel
55
import com.adyen.android.assignment.network.querybuilder.VenueRecommendationsQueryBuilder
66
import com.adyen.android.assignment.network.service.PlacesService
@@ -9,7 +9,7 @@ import javax.inject.Inject
99

1010
class PlacesRemoteData @Inject constructor(private val remoteService: PlacesService) {
1111

12-
suspend fun getPlaces(requestModel: LocationRequestModel): NetworkResult<PlacesReponse> {
12+
suspend fun getPlaces(requestModel: LocationRequestModel): NetworkResult<PlacesResponse> {
1313
return remoteService.getVenueRecommendationPlaces(
1414
VenueRecommendationsQueryBuilder()
1515
.setLatitudeLongitude(
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package com.adyen.android.assignment.model.response
22

3-
data class PlacesReponse(
3+
data class PlacesResponse(
44
var results: List<Result>?
55
)

app/src/main/java/com/adyen/android/assignment/network/service/PlacesService.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.adyen.android.assignment.network.service
22

33
import com.adyen.android.assignment.BuildConfig
4-
import com.adyen.android.assignment.model.response.PlacesReponse
4+
import com.adyen.android.assignment.model.response.PlacesResponse
55
import com.adyen.android.assignment.network.util.NetworkResult
66
import retrofit2.Call
77
import retrofit2.Retrofit
@@ -18,7 +18,7 @@ interface PlacesService {
1818
*/
1919
@Headers("Authorization: ${BuildConfig.API_KEY}")
2020
@GET("places/nearby")
21-
fun getVenueRecommendations(@QueryMap query: Map<String, String>): Call<PlacesReponse>
21+
fun getVenueRecommendations(@QueryMap query: Map<String, String>): Call<PlacesResponse>
2222

2323
/**
2424
* Get venue recommendations.
@@ -27,7 +27,7 @@ interface PlacesService {
2727
*/
2828
@Headers("Authorization: ${BuildConfig.API_KEY}")
2929
@GET("places/nearby")
30-
suspend fun getVenueRecommendationPlaces(@QueryMap query: Map<String, String>): NetworkResult<PlacesReponse>
30+
suspend fun getVenueRecommendationPlaces(@QueryMap query: Map<String, String>): NetworkResult<PlacesResponse>
3131

3232
companion object {
3333
private val retrofit by lazy {

app/src/main/java/com/adyen/android/assignment/repository/remote/PlacesRepository.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
package com.adyen.android.assignment.repository.remote
22

33
import com.adyen.android.assignment.datasource.remote.PlacesRemoteData
4-
import com.adyen.android.assignment.model.response.PlacesReponse
4+
import com.adyen.android.assignment.model.response.PlacesResponse
55
import com.adyen.android.assignment.model.request.LocationRequestModel
6-
import com.adyen.android.assignment.model.response.Result
76
import com.adyen.android.assignment.network.util.NetworkResult
87
import javax.inject.Inject
98

109
class PlacesRepository @Inject constructor(private val remote: PlacesRemoteData) {
1110

12-
suspend fun getPlaces(requestModel: LocationRequestModel): NetworkResult<PlacesReponse> {
11+
suspend fun getPlaces(requestModel: LocationRequestModel): NetworkResult<PlacesResponse> {
1312
return remote.getPlaces(requestModel)
1413
}
1514

app/src/main/java/com/adyen/android/assignment/screens/home/viewmodel/HomeViewModel.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import androidx.lifecycle.MutableLiveData
88
import androidx.lifecycle.ViewModel
99
import androidx.lifecycle.viewModelScope
1010
import com.adyen.android.assignment.model.request.LocationRequestModel
11-
import com.adyen.android.assignment.model.response.PlacesReponse
1211
import com.adyen.android.assignment.model.response.Result
1312
import com.adyen.android.assignment.network.util.NetworkResult
1413
import com.adyen.android.assignment.repository.remote.PlacesRepository
@@ -82,5 +81,4 @@ class HomeViewModel @Inject constructor(private val placesRepository: PlacesRepo
8281
)
8382
}
8483

85-
8684
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.adyen.android.assignment.repository
2+
3+
import com.adyen.android.assignment.model.request.LocationRequestModel
4+
import com.adyen.android.assignment.model.response.PlacesResponse
5+
import com.adyen.android.assignment.network.util.NetworkResult
6+
import com.adyen.android.assignment.utils.FakeDataTest
7+
8+
class FakePlacesRepository {
9+
10+
private var isNetworkResultSuccess = false
11+
12+
fun setNetworkResultStatus(networkResult: Boolean) {
13+
isNetworkResultSuccess = networkResult
14+
}
15+
16+
fun getPlacesOnLocation(requestModel: LocationRequestModel): NetworkResult<PlacesResponse> {
17+
return if (isNetworkResultSuccess)
18+
FakeDataTest.getPlacesFromServiceFakeResponse(requestModel)
19+
else
20+
FakeDataTest.getFakeFailureExceptionResponse(requestModel)
21+
}
22+
23+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.adyen.android.assignment.repository
2+
3+
import com.adyen.android.assignment.model.response.PlacesResponse
4+
import com.adyen.android.assignment.network.util.NetworkResult
5+
import com.adyen.android.assignment.utils.FakeDataTest.getDummyLocationRequest
6+
import com.google.common.truth.Truth.assertThat
7+
import kotlinx.coroutines.runBlocking
8+
import org.junit.Before
9+
import org.junit.Test
10+
11+
class PlacesRepositoryTest {
12+
13+
private lateinit var fakePlacesRepository: FakePlacesRepository
14+
15+
@Before
16+
fun setUp() {
17+
fakePlacesRepository = FakePlacesRepository()
18+
}
19+
20+
@Test
21+
fun verify_api_service_result_should_be_not_null() {
22+
runBlocking {
23+
val result = fakePlacesRepository.getPlacesOnLocation(requestModel = getDummyLocationRequest())
24+
assertThat(result).isNotNull()
25+
}
26+
}
27+
28+
@Test
29+
fun verify_api_request_should_not_be_failure() {
30+
runBlocking {
31+
fakePlacesRepository.setNetworkResultStatus(true)
32+
val result = fakePlacesRepository.getPlacesOnLocation(requestModel = getDummyLocationRequest())
33+
assertThat(result).isNotInstanceOf(NetworkResult.Failure::class.java)
34+
}
35+
}
36+
37+
@Test
38+
fun verify_api_request_result_should_be_instance_of_network_result_success() {
39+
runBlocking {
40+
fakePlacesRepository.setNetworkResultStatus(true)
41+
val result = fakePlacesRepository.getPlacesOnLocation(requestModel = getDummyLocationRequest())
42+
assertThat(result).isInstanceOf(NetworkResult.Success::class.java)
43+
}
44+
}
45+
46+
@Test
47+
fun verify_api_request_result_data_should_not_be_null() {
48+
runBlocking {
49+
fakePlacesRepository.setNetworkResultStatus(true)
50+
val result = fakePlacesRepository.getPlacesOnLocation(requestModel = getDummyLocationRequest())
51+
as NetworkResult.Success<PlacesResponse>
52+
assertThat(result.data).isNotNull()
53+
}
54+
}
55+
56+
@Test
57+
fun verify_api_request_result_data_should_be_instance_of_places_response() {
58+
runBlocking {
59+
fakePlacesRepository.setNetworkResultStatus(true)
60+
val result = fakePlacesRepository.getPlacesOnLocation(requestModel = getDummyLocationRequest())
61+
as NetworkResult.Success<PlacesResponse>
62+
assertThat(result.data).isInstanceOf(PlacesResponse::class.java)
63+
}
64+
}
65+
66+
@Test
67+
fun verify_api_request_places_results_should_not_be_empty() {
68+
runBlocking {
69+
fakePlacesRepository.setNetworkResultStatus(true)
70+
val result = fakePlacesRepository.getPlacesOnLocation(requestModel = getDummyLocationRequest())
71+
as NetworkResult.Success<PlacesResponse>
72+
assertThat(result.data?.results).isNotEmpty()
73+
}
74+
}
75+
76+
@Test
77+
fun verify_api_request_return_failure_should_be_not_null() {
78+
runBlocking {
79+
fakePlacesRepository.setNetworkResultStatus(false)
80+
val result = fakePlacesRepository.getPlacesOnLocation(requestModel = getDummyLocationRequest())
81+
as NetworkResult.Failure<PlacesResponse>
82+
assertThat(result).isNotNull()
83+
}
84+
}
85+
86+
@Test
87+
fun verify_api_request_return_failure_should_be_instance_of_exception() {
88+
runBlocking {
89+
fakePlacesRepository.setNetworkResultStatus(false)
90+
val result = fakePlacesRepository.getPlacesOnLocation(requestModel = getDummyLocationRequest())
91+
as NetworkResult.Failure<PlacesResponse>
92+
assertThat(result.exception).isInstanceOf(Exception::class.java)
93+
}
94+
}
95+
96+
}

app/src/test/java/com/adyen/android/assignment/PlacesUnitTest.kt renamed to app/src/test/java/com/adyen/android/assignment/service/PlacesUnitTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.adyen.android.assignment
1+
package com.adyen.android.assignment.service
22

33
import com.adyen.android.assignment.network.querybuilder.VenueRecommendationsQueryBuilder
44
import com.adyen.android.assignment.network.service.PlacesService
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.adyen.android.assignment.utils
2+
3+
import kotlinx.coroutines.Dispatchers
4+
import kotlinx.coroutines.ExperimentalCoroutinesApi
5+
import kotlinx.coroutines.test.*
6+
import org.junit.rules.TestRule
7+
import org.junit.runner.Description
8+
import org.junit.runners.model.Statement
9+
10+
@ExperimentalCoroutinesApi
11+
12+
class CoroutinesTestRule : TestRule {
13+
14+
private val testCoroutineDispatcher = TestCoroutineDispatcher()
15+
private val testCoroutineScope = TestCoroutineScope(testCoroutineDispatcher)
16+
17+
override fun apply(base: Statement?, description: Description?) = object : Statement() {
18+
@Throws(Throwable::class)
19+
override fun evaluate() {
20+
Dispatchers.setMain(testCoroutineDispatcher)
21+
base?.evaluate()
22+
Dispatchers.resetMain()
23+
testCoroutineScope.cleanupTestCoroutines()
24+
}
25+
}
26+
27+
fun runBlockingTest(block: suspend TestCoroutineScope.() -> Unit) =
28+
testCoroutineScope.runBlockingTest { block() }
29+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package com.adyen.android.assignment.utils
2+
3+
import android.content.res.Resources
4+
import com.adyen.android.assignment.model.request.LocationRequestModel
5+
import com.adyen.android.assignment.model.response.*
6+
import com.adyen.android.assignment.network.util.NetworkResult
7+
import com.google.android.gms.maps.model.LatLng
8+
9+
object FakeDataTest {
10+
11+
private fun getFakePlacesList() = listOf(
12+
Result(
13+
categories = listOf(Category(icon = null, id = 0, name = "")),
14+
chains = null,
15+
distance = 5,
16+
geocodes = Geocodes(
17+
main = Main(latitude = 52.376513, longitude = 4.906092),
18+
roof = null
19+
),
20+
location = Location(
21+
address = "Simon Carmiggeltstraat 6",
22+
country = "NL",
23+
cross_street = null,
24+
formatted_address = "Simon Carmiggeltstraat 6",
25+
postcode = null,
26+
locality = null,
27+
neighborhood = null,
28+
region = null
29+
),
30+
name = "VodafoneZiggo Amsterdam (Oosterdokseiland)",
31+
related_places = null,
32+
timezone = "Europe/Amsterdam",
33+
fsq_id = "58a403d20593e16c4579149d"
34+
),
35+
Result(
36+
categories = listOf(Category(icon = null, id = 0, name = "")),
37+
chains = null,
38+
distance = 127,
39+
geocodes = Geocodes(
40+
main = Main(latitude = 52.375978, longitude = 4.907301),
41+
roof = null
42+
),
43+
location = Location(
44+
address = "Oosterdokskade 133",
45+
country = "NL",
46+
cross_street = null,
47+
formatted_address = "Oosterdokskade 133, 1011 DL Amsterdam",
48+
postcode = null,
49+
locality = null,
50+
neighborhood = null,
51+
region = null
52+
),
53+
name = "Mo-Jo Japanese Kitchen",
54+
related_places = null,
55+
timezone = "North Holland",
56+
fsq_id = "5650bd5e498e58a4af099b37"
57+
),
58+
Result(
59+
categories = listOf(Category(icon = null, id = 0, name = "")),
60+
chains = null,
61+
distance = 5,
62+
geocodes = Geocodes(
63+
main = Main(latitude = 52.376898, longitude = 4.904513),
64+
roof = null
65+
),
66+
location = Location(
67+
address = "Oosterdoksstraat 4",
68+
country = "NL",
69+
cross_street = null,
70+
formatted_address = "Oosterdoksstraat 4 (Double Tree by Hilton), 1001 RD Amsterdam",
71+
postcode = "1001 RD",
72+
locality = null,
73+
neighborhood = null,
74+
region = null
75+
),
76+
name = "Starbucks",
77+
related_places = null,
78+
timezone = "North Holland",
79+
fsq_id = "50056329e4b0c7e958812543"
80+
)
81+
)
82+
83+
fun getSelectedPlace() = Result(
84+
categories = listOf(Category(icon = null, id = 0, name = "")),
85+
chains = null,
86+
distance = 5,
87+
geocodes = Geocodes(
88+
main = Main(latitude = 52.376898, longitude = 4.904513),
89+
roof = null
90+
),
91+
location = Location(
92+
address = "Oosterdoksstraat 4",
93+
country = "NL",
94+
cross_street = null,
95+
formatted_address = "Oosterdoksstraat 4 (Double Tree by Hilton), 1001 RD Amsterdam",
96+
postcode = "1001 RD",
97+
locality = null,
98+
neighborhood = null,
99+
region = null
100+
),
101+
name = "Starbucks",
102+
related_places = null,
103+
timezone = "North Holland",
104+
fsq_id = "50056329e4b0c7e958812543"
105+
)
106+
107+
fun getPlacesFromServiceFakeResponse(requestModel: LocationRequestModel): NetworkResult<PlacesResponse> {
108+
return NetworkResult.Success(PlacesResponse(getFakePlacesList()))
109+
}
110+
111+
fun getFakeFailureExceptionResponse(requestModel: LocationRequestModel): NetworkResult<PlacesResponse> {
112+
return NetworkResult.Failure(
113+
404, Resources.NotFoundException()
114+
)
115+
}
116+
117+
fun getDummyAmsterdamLocation(): LatLng {
118+
return LatLng(Constant.DUMMY_LOCATION_LAT, Constant.DUMMY_LOCATION_LON)
119+
}
120+
121+
fun getDummyLocationRequest(): LocationRequestModel {
122+
return LocationRequestModel(
123+
latitude = Constant.DUMMY_LOCATION_LAT,
124+
longitude = Constant.DUMMY_LOCATION_LON
125+
)
126+
}
127+
128+
}
129+
130+

0 commit comments

Comments
 (0)