- mid commit

This commit is contained in:
2023-08-28 21:13:43 +01:00
parent a614dfe543
commit 07d7e6cbe7
29 changed files with 1646 additions and 457 deletions

View File

@@ -0,0 +1,239 @@
package com.appttude.h_mal.farmr.viewmodel
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.appttude.h_mal.farmr.data.Repository
import com.appttude.h_mal.farmr.data.legacydb.ShiftObject
import com.appttude.h_mal.farmr.data.prefs.DATE_IN
import com.appttude.h_mal.farmr.data.prefs.DATE_OUT
import com.appttude.h_mal.farmr.data.prefs.DESCRIPTION
import com.appttude.h_mal.farmr.data.prefs.TYPE
import com.appttude.h_mal.farmr.model.ShiftType
import com.appttude.h_mal.farmr.model.ViewState
import com.appttude.h_mal.farmr.utils.getOrAwaitValue
import io.mockk.every
import io.mockk.mockk
import org.junit.Assert.assertThrows
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyList
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.ArgumentMatchers.anyString
import java.util.concurrent.TimeoutException
import kotlin.test.assertEquals
class MainViewModelTest {
@get:Rule
val rule = InstantTaskExecutorRule()
private lateinit var repository: Repository
private lateinit var viewModel: MainViewModel
@Before
fun setUp() {
repository = mockk()
every { repository.readShiftsFromDatabase() }.returns(null)
every { repository.retrieveFilteringDetailsInPrefs() }.returns(getFilter())
viewModel = MainViewModel(repository)
}
@Test
fun initViewModel_liveDataIsEmpty() {
// Assert
assertThrows(TimeoutException::class.java) { viewModel.uiState.getOrAwaitValue() }
}
@Test
fun getShiftsFromRepository_liveDataIsShown() {
// Arrange
val listOfShifts = anyList<ShiftObject>()
// Act
every { repository.readShiftsFromDatabase() }.returns(listOfShifts)
viewModel.refreshLiveData()
// Assert
assertEquals(retrieveCurrentData(), listOfShifts)
}
@Test
fun getShiftsFromRepository_liveDataIsShown_defaultFiltersAndSortsValid() {
// Arrange
val listOfShifts = getShifts()
// Act
every { repository.readShiftsFromDatabase() }.returns(listOfShifts)
viewModel.refreshLiveData()
val retrievedShifts = retrieveCurrentData()
val description = viewModel.getInformation()
// Assert
assertEquals(retrievedShifts, listOfShifts)
assertEquals(
description, "8 Shifts\n" +
" (4 Hourly/4 Piece Rate)\n" +
"Total Hours: 4.0\n" +
"Total Units: 4.0\n" +
"Total Pay: £70.00"
)
}
@Test
fun getShiftsFromRepository_applyFiltersThenClearFilters_descriptionIsValid() {
// Arrange
val listOfShifts = getShifts()
val filteredShifts = getShifts().filter { it.type == ShiftType.HOURLY.type }
// Act
every { repository.readShiftsFromDatabase() }.returns(listOfShifts)
every { repository.retrieveFilteringDetailsInPrefs() }.returns(getFilter(type = ShiftType.HOURLY.type))
viewModel.refreshLiveData()
val retrievedShifts = retrieveCurrentData()
val description = viewModel.getInformation()
every { repository.setFilteringDetailsInPrefs(null, null, null, null) }.returns(Unit)
every { repository.retrieveFilteringDetailsInPrefs() }.returns(getFilter())
viewModel.clearFilters()
val descriptionAfterClearedFilter = viewModel.getInformation()
// Assert
assertEquals(retrievedShifts, filteredShifts)
assertEquals(
description, "4 Shifts\n" +
"Total Hours: 4.0\n" +
"Total Pay: £30.00"
)
assertEquals(
descriptionAfterClearedFilter, "8 Shifts\n" +
" (4 Hourly/4 Piece Rate)\n" +
"Total Hours: 4.0\n" +
"Total Units: 4.0\n" +
"Total Pay: £70.00"
)
}
private fun retrieveCurrentData() =
(viewModel.uiState.getOrAwaitValue() as ViewState.HasData<*>).data
private fun getFilter(
description: String? = null,
type: String? = null,
dateIn: String? = null,
dateOut: String? = null
): Map<String, String?> =
mapOf(
Pair(DESCRIPTION, description),
Pair(DATE_IN, dateIn),
Pair(DATE_OUT, dateOut),
Pair(TYPE, type)
)
private fun getShifts() = listOf(
ShiftObject(
anyLong(),
ShiftType.HOURLY.type,
"Day one",
"2023-08-01",
"12:00",
"13:00",
1f,
anyInt(),
anyFloat(),
10f,
10f
),
ShiftObject(
anyLong(),
ShiftType.HOURLY.type,
"Day two",
"2023-08-02",
"12:00",
"13:00",
1f,
anyInt(),
anyFloat(),
10f,
10f
),
ShiftObject(
anyLong(),
ShiftType.HOURLY.type,
"Day three",
"2023-08-03",
"12:00",
"13:00",
1f,
30,
anyFloat(),
10f,
5f
),
ShiftObject(
anyLong(),
ShiftType.HOURLY.type,
"Day four",
"2023-08-04",
"12:00",
"13:00",
1f,
30,
anyFloat(),
10f,
5f
),
ShiftObject(
anyLong(),
ShiftType.PIECE.type,
"Day five",
"2023-08-05",
anyString(),
anyString(),
anyFloat(),
anyInt(),
1f,
10f,
10f
),
ShiftObject(
anyLong(),
ShiftType.PIECE.type,
"Day six",
"2023-08-06",
anyString(),
anyString(),
anyFloat(),
anyInt(),
1f,
10f,
10f
),
ShiftObject(
anyLong(),
ShiftType.PIECE.type,
"Day seven",
"2023-08-07",
anyString(),
anyString(),
anyFloat(),
anyInt(),
1f,
10f,
10f
),
ShiftObject(
anyLong(),
ShiftType.PIECE.type,
"Day eight",
"2023-08-08",
anyString(),
anyString(),
anyFloat(),
anyInt(),
1f,
10f,
10f
),
)
}

View File

@@ -0,0 +1,171 @@
package com.appttude.h_mal.farmr.viewmodel
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.appttude.h_mal.farmr.data.Repository
import com.appttude.h_mal.farmr.data.legacydb.ShiftObject
import com.appttude.h_mal.farmr.model.ShiftType
import com.appttude.h_mal.farmr.model.ViewState
import com.appttude.h_mal.farmr.utils.getOrAwaitValue
import io.mockk.MockKAnnotations
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.RelaxedMockK
import org.junit.Before
import org.junit.Rule
import org.mockito.ArgumentMatchers
open class ShiftViewModelTest<V : ShiftViewModel> {
@get:Rule
val rule = InstantTaskExecutorRule()
@RelaxedMockK
lateinit var repository: Repository
@InjectMockKs
lateinit var viewModel: V
@Before
fun setUp() {
MockKAnnotations.init(this)
}
fun retrieveCurrentData() =
(viewModel.uiState.getOrAwaitValue() as ViewState.HasData<*>).data
fun retrieveCurrentError() =
(viewModel.uiState.getOrAwaitValue() as ViewState.HasError<*>).error
fun getHourlyShift() = ShiftObject(
ArgumentMatchers.anyLong(),
ShiftType.HOURLY.type,
"Day one",
"2023-08-01",
"12:00",
"13:00",
1f,
ArgumentMatchers.anyInt(),
ArgumentMatchers.anyFloat(),
10f,
10f
)
fun getPieceRateShift() = ShiftObject(
ArgumentMatchers.anyLong(),
ShiftType.PIECE.type,
"Day five",
"2023-08-05",
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString(),
ArgumentMatchers.anyFloat(),
ArgumentMatchers.anyInt(),
1f,
10f,
10f
)
fun getShifts() = listOf(
ShiftObject(
ArgumentMatchers.anyLong(),
ShiftType.HOURLY.type,
"Day one",
"2023-08-01",
"12:00",
"13:00",
1f,
ArgumentMatchers.anyInt(),
ArgumentMatchers.anyFloat(),
10f,
10f
),
ShiftObject(
ArgumentMatchers.anyLong(),
ShiftType.HOURLY.type,
"Day two",
"2023-08-02",
"12:00",
"13:00",
1f,
ArgumentMatchers.anyInt(),
ArgumentMatchers.anyFloat(),
10f,
10f
),
ShiftObject(
ArgumentMatchers.anyLong(),
ShiftType.HOURLY.type,
"Day three",
"2023-08-03",
"12:00",
"13:00",
1f,
30,
ArgumentMatchers.anyFloat(),
10f,
5f
),
ShiftObject(
ArgumentMatchers.anyLong(),
ShiftType.HOURLY.type,
"Day four",
"2023-08-04",
"12:00",
"13:00",
1f,
30,
ArgumentMatchers.anyFloat(),
10f,
5f
),
ShiftObject(
ArgumentMatchers.anyLong(),
ShiftType.PIECE.type,
"Day five",
"2023-08-05",
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString(),
ArgumentMatchers.anyFloat(),
ArgumentMatchers.anyInt(),
1f,
10f,
10f
),
ShiftObject(
ArgumentMatchers.anyLong(),
ShiftType.PIECE.type,
"Day six",
"2023-08-06",
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString(),
ArgumentMatchers.anyFloat(),
ArgumentMatchers.anyInt(),
1f,
10f,
10f
),
ShiftObject(
ArgumentMatchers.anyLong(),
ShiftType.PIECE.type,
"Day seven",
"2023-08-07",
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString(),
ArgumentMatchers.anyFloat(),
ArgumentMatchers.anyInt(),
1f,
10f,
10f
),
ShiftObject(
ArgumentMatchers.anyLong(),
ShiftType.PIECE.type,
"Day eight",
"2023-08-08",
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString(),
ArgumentMatchers.anyFloat(),
ArgumentMatchers.anyInt(),
1f,
10f,
10f
),
)
}

View File

@@ -0,0 +1,85 @@
package com.appttude.h_mal.farmr.viewmodel
import com.appttude.h_mal.farmr.model.Success
import io.mockk.every
import org.junit.Assert.assertEquals
import org.junit.Test
import kotlin.test.assertIs
class SubmissionViewModelTest : ShiftViewModelTest<SubmissionViewModel>() {
@Test
fun insertHourlyShifts_validParameters_successfulInsertions() {
// Arrange
val hourly = getHourlyShift()
// Act
every { repository.insertShiftIntoDatabase(hourly.copyToShift()) }.returns(true)
hourly.run {
viewModel.insertHourlyShift(description, date, rateOfPay, timeIn, timeOut, breakMins)
}
// Assert
assertIs<Success>(retrieveCurrentData())
assertEquals(
(retrieveCurrentData() as Success).successMessage,
"New shift successfully added"
)
}
@Test
fun insertPieceShifts_validParameters_successfulInsertions() {
// Arrange
val piece = getPieceRateShift()
// Act
every { repository.insertShiftIntoDatabase(piece.copyToShift()) }.returns(true)
piece.run {
viewModel.insertPieceRateShift(description, date, units, rateOfPay)
}
// Assert
assertIs<Success>(retrieveCurrentData())
assertEquals(
(retrieveCurrentData() as Success).successMessage,
"New shift successfully added"
)
}
@Test
fun insertHourlyShifts_validParameters_unsuccessfulInsertions() {
// Arrange
val hourly = getHourlyShift()
// Act
every { repository.insertShiftIntoDatabase(hourly.copyToShift()) }.returns(false)
hourly.run {
viewModel.insertHourlyShift(description, date, rateOfPay, timeIn, timeOut, breakMins)
}
// Assert
assertEquals(
retrieveCurrentError(),
"Cannot insert shift"
)
}
@Test
fun insertPieceShifts_validParameters_unsuccessfulInsertions() {
// Arrange
val piece = getPieceRateShift()
// Act
every { repository.insertShiftIntoDatabase(piece.copyToShift()) }.returns(false)
piece.run {
viewModel.insertPieceRateShift(description, date, units, rateOfPay)
}
// Assert
assertEquals(
retrieveCurrentError(),
"Cannot insert shift"
)
}
}