Skip to content

Commit

Permalink
test: implement new tests for user location backend
Browse files Browse the repository at this point in the history
  • Loading branch information
charliemangano committed Dec 19, 2024
1 parent 30825c9 commit ec5e0d5
Show file tree
Hide file tree
Showing 3 changed files with 253 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.android.periodpals.model.location

import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.junit.Assert.assertEquals
import org.junit.Test

class UserLocationDtoTest {

private val json = Json { ignoreUnknownKeys = true }

@Test
fun serializeUserLocationDto() {
val location = LocationGIS("Point", listOf(12.34, 56.78))
val userLocationDto = UserLocationDto("user123", location)
val jsonString = json.encodeToString(userLocationDto)
val expectedJson =
"""{"uid":"user123","locationGIS":{"type":"Point","coordinates":[12.34,56.78]}}"""
assertEquals(expectedJson, jsonString)
}

@Test
fun deserializeUserLocationDto() {
val jsonString =
"""{"uid":"user123","locationGIS":{"type":"Point","coordinates":[12.34,56.78]}}"""
val userLocationDto = json.decodeFromString<UserLocationDto>(jsonString)
val expectedLocation = LocationGIS("Point", listOf(12.34, 56.78))
val expectedUserLocationDto = UserLocationDto("user123", expectedLocation)
assertEquals(expectedUserLocationDto, userLocationDto)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.android.periodpals.model.location

import io.github.jan.supabase.createSupabaseClient
import io.github.jan.supabase.postgrest.Postgrest
import io.ktor.client.engine.mock.MockEngine
import io.ktor.client.engine.mock.respond
import io.ktor.client.engine.mock.respondBadRequest
import io.ktor.http.HttpStatusCode
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import org.junit.After
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Test

class UserLocationModelSupabaseTest {
private lateinit var userLocationModelSupabase: UserLocationModelSupabase

private val supabaseClientSuccess =
createSupabaseClient("", "") {
httpEngine = MockEngine { _ ->
respond(
content =
"""{"uid":"user123","locationGIS":{"type":"Point","coordinates":[12.34,56.78]}}""",
status = HttpStatusCode.OK,
)
}
install(Postgrest)
}

private val supabaseClientFailure =
createSupabaseClient("", "") {
httpEngine = MockEngine { _ -> respondBadRequest() }
install(Postgrest)
}

@OptIn(ExperimentalCoroutinesApi::class)
@Before
fun setUp() {
Dispatchers.setMain(Dispatchers.Unconfined)
userLocationModelSupabase = UserLocationModelSupabase(supabaseClientSuccess)
}

@OptIn(ExperimentalCoroutinesApi::class)
@After
fun tearDown() {
Dispatchers.resetMain()
}

@Test
fun createLocationSuccess() = runTest {
val location = LocationGIS("Point", listOf(12.34, 56.78))
val userLocationDto = UserLocationDto("user123", location)
var result = false

userLocationModelSupabase.create(
locationDto = userLocationDto,
onSuccess = { result = true },
onFailure = { fail("Should not call onFailure") },
)
assert(result)
}

@Test
fun createLocationFailure() = runTest {
userLocationModelSupabase = UserLocationModelSupabase(supabaseClientFailure)
val location = LocationGIS("Point", listOf(12.34, 56.78))
val userLocationDto = UserLocationDto("user123", location)
var onFailureCalled = false

userLocationModelSupabase.create(
locationDto = userLocationDto,
onSuccess = { fail("Should not call onSuccess") },
onFailure = { onFailureCalled = true },
)
assert(onFailureCalled)
}

@Test
fun updateLocationSuccess() = runTest {
val location = LocationGIS("Point", listOf(12.34, 56.78))
val userLocationDto = UserLocationDto("user123", location)
var result = false

userLocationModelSupabase.update(
locationDto = userLocationDto,
onSuccess = { result = true },
onFailure = { fail("Should not call onFailure") },
)
assert(result)
}

@Test
fun updateLocationFailure() = runTest {
userLocationModelSupabase = UserLocationModelSupabase(supabaseClientFailure)
val location = LocationGIS("Point", listOf(12.34, 56.78))
val userLocationDto = UserLocationDto("user123", location)
var onFailureCalled = false

userLocationModelSupabase.update(
locationDto = userLocationDto,
onSuccess = { fail("Should not call onSuccess") },
onFailure = { onFailureCalled = true },
)
assert(onFailureCalled)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.android.periodpals.model.location

import com.android.periodpals.MainCoroutineRule
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.verify

@OptIn(ExperimentalCoroutinesApi::class)
class UserLocationViewModelTest {

@ExperimentalCoroutinesApi @get:Rule var mainCoroutineRule = MainCoroutineRule()

private lateinit var userLocationModel: UserLocationModel

private lateinit var userLocationViewModel: UserLocationViewModel

companion object {
val uid = "user123"
val location = LocationGIS("Point", listOf(12.34, 56.78))
val locationDto = UserLocationDto(uid, location)
}

@Before
fun setup() {
MockitoAnnotations.openMocks(this)
userLocationModel = mock(UserLocationModel::class.java)
userLocationViewModel = UserLocationViewModel(userLocationModel)
}

@After
fun tearDown() {
// Clean up resources if needed
}

@Test
fun `uploadUserLocation successful create`() = runTest {
var onSuccessCalled = false

`when`(userLocationModel.create(eq(locationDto), any(), any())).thenAnswer {
it.getArgument<() -> Unit>(1)()
}

userLocationViewModel.uploadUserLocation(uid, location, onSuccess = { onSuccessCalled = true })

assertTrue(onSuccessCalled)
}

@Test
fun `uploadUserLocation failure create calls update`() = runTest {
doAnswer { it.getArgument<(Exception) -> Unit>(2)(Exception("create failed")) }
.`when`(userLocationModel)
.create(eq(locationDto), any(), any())
doAnswer { it.getArgument<() -> Unit>(1)() }
.`when`(userLocationModel)
.update(eq(locationDto), any(), any())

userLocationViewModel.uploadUserLocation(uid, location)

verify(userLocationModel).update(eq(locationDto), any(), any())
}

@Test
fun `uploadUserLocation update failure`() = runTest {
var onFailureCalled = false

doAnswer { it.getArgument<(Exception) -> Unit>(2)(Exception("create failed")) }
.`when`(userLocationModel)
.create(eq(locationDto), any(), any())
doAnswer { it.getArgument<(Exception) -> Unit>(2)(Exception("update failed")) }
.`when`(userLocationModel)
.update(eq(locationDto), any(), any())

userLocationViewModel.uploadUserLocation(
"user123",
location,
onFailure = { onFailureCalled = true },
)

assertTrue(onFailureCalled)
}

@Test
fun `uploadUserLocation update success`() = runTest {
var onSuccessCalled = false

doAnswer { it.getArgument<(Exception) -> Unit>(2)(Exception("create failed")) }
.`when`(userLocationModel)
.create(eq(locationDto), any(), any())
doAnswer { it.getArgument<() -> Unit>(1)() }
.`when`(userLocationModel)
.update(eq(locationDto), any(), any())

userLocationViewModel.uploadUserLocation(
"user123",
location,
onSuccess = { onSuccessCalled = true },
)

assertTrue(onSuccessCalled)
}
}

0 comments on commit ec5e0d5

Please sign in to comment.