Skip to content

Commit

Permalink
Merge pull request #13167 from woocommerce/issue/12289-get-accoutn-se…
Browse files Browse the repository at this point in the history
…ttings

[Shipping labels]: Get account settings
  • Loading branch information
atorresveiga authored Dec 19, 2024
2 parents 972f0d3 + 29f51c9 commit c1f4e56
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.woocommerce.android.ui.orders.wooshippinglabels

import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.ui.orders.wooshippinglabels.models.StoreOptionsModel
import com.woocommerce.android.ui.orders.wooshippinglabels.networking.WooShippingLabelRepository
import javax.inject.Inject

class FetchAccountSettings @Inject constructor(
private val shippingRepository: WooShippingLabelRepository,
private val selectedSite: SelectedSite
) {
suspend operator fun invoke(): Result<StoreOptionsModel> {
return selectedSite.getOrNull()?.let {
val response = shippingRepository.fetchAccountSettings(it)
val result = response.model
when {
response.isError.not() && result != null && result != StoreOptionsModel.EMPTY -> {
Result.success(result)
}

else -> {
val message = response.error?.message ?: "Unknown error"
Result.failure(Exception(message))
}
}
} ?: Result.failure(Exception("No site selected"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,10 @@ class WooShippingLabelCreationViewModel @Inject constructor(
private val getShippableItems: GetShippableItems,
private val currencyFormatter: CurrencyFormatter,
private val observeOriginAddresses: ObserveOriginAddresses,
private val getShippingRates: GetShippingRates
private val getShippingRates: GetShippingRates,
private val fetchAccountSettings: FetchAccountSettings
) : ScopedViewModel(savedState) {
private val navArgs: WooShippingLabelCreationFragmentArgs by savedState.navArgs()
private val mockStoreOptions = StoreOptionsModel(
currencySymbol = "$",
dimensionUnit = "cm",
weightUnit = "kg",
originCountry = "US"
)

private val emptyOrder = Order.getEmptyOrder(Date(), Date())
private val order = MutableStateFlow<Order?>(emptyOrder)
Expand Down Expand Up @@ -103,7 +98,16 @@ class WooShippingLabelCreationViewModel @Inject constructor(
}

private fun getStoreOptions() {
storeOptions.value = mockStoreOptions
launch {
fetchAccountSettings().fold(
onSuccess = {
storeOptions.value = it
},
onFailure = {
storeOptions.value = null
}
)
}
}

@Suppress("ComplexCondition")
Expand Down Expand Up @@ -179,14 +183,18 @@ class WooShippingLabelCreationViewModel @Inject constructor(
}

private suspend fun observePackageChanges() {
packageSelected.combine(packageWeight) { packageSelected, packageWeight ->
combine(
packageSelected,
packageWeight,
storeOptions
) { packageSelected, packageWeight, storeOptions ->
if (packageSelected == null || packageWeight == null) {
NotSelected
} else {
DataAvailable(
selectedPackage = packageSelected,
defaultWeight = packageWeight.defaultWeight.toString(),
weightUnit = mockStoreOptions.weightUnit
weightUnit = storeOptions?.weightUnit ?: ""
)
}
}.collectLatest {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.woocommerce.android.ui.orders.wooshippinglabels.networking

import com.google.gson.annotations.SerializedName

data class AccountSettingsDTO(
val storeOptions: StoreOptionsDTO
)

data class StoreOptionsDTO(
@SerializedName("currency_symbol") val currencySymbol: String? = null,
@SerializedName("dimension_unit") val dimensionUnit: String? = null,
@SerializedName("weight_unit") val weightUnit: String? = null,
@SerializedName("origin_country") val originCountry: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import org.wordpress.android.fluxc.model.SiteModel
import javax.inject.Inject

class WooShippingLabelRepository @Inject constructor(
private val restClient: WooShippingLabelRestClient
private val restClient: WooShippingLabelRestClient,
private val mapper: WooShippingNetworkingMapper
) {
suspend fun fetchShippingLabelPrinting(
site: SiteModel,
Expand All @@ -15,4 +16,10 @@ class WooShippingLabelRepository @Inject constructor(
labelIds = labelIds,
paperSize = paperSize
).asWooResult()

suspend fun fetchAccountSettings(
site: SiteModel,
) = restClient.fetchAccountSettings(
site = site,
).asWooResult { mapper(it.storeOptions) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,18 @@ class WooShippingLabelRestClient @Inject constructor(
clazz = ShippingLabelPrintingResponse::class.java,
).toWooPayload()
}

suspend fun fetchAccountSettings(
site: SiteModel,
): WooPayload<AccountSettingsDTO> {
val url = "/wcshipping/v1/account/settings/"

val result = wooNetwork.executeGetGsonRequest(
site = site,
path = url,
clazz = AccountSettingsDTO::class.java,
)

return result.toWooPayload()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.woocommerce.android.ui.orders.wooshippinglabels.networking

import com.woocommerce.android.ui.orders.wooshippinglabels.models.StoreOptionsModel
import javax.inject.Inject

class WooShippingNetworkingMapper @Inject constructor() {
operator fun invoke(storeOptionsDTO: StoreOptionsDTO): StoreOptionsModel {
return StoreOptionsModel(
currencySymbol = storeOptionsDTO.currencySymbol.orEmpty(),
dimensionUnit = storeOptionsDTO.dimensionUnit.orEmpty(),
weightUnit = storeOptionsDTO.weightUnit.orEmpty(),
originCountry = storeOptionsDTO.originCountry.orEmpty()
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.woocommerce.android.ui.orders.wooshippinglabels

import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.ui.orders.wooshippinglabels.models.StoreOptionsModel
import com.woocommerce.android.ui.orders.wooshippinglabels.networking.WooShippingLabelRepository
import com.woocommerce.android.viewmodel.BaseUnitTest
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.BaseRequest
import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooError
import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooErrorType
import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooResult
import kotlin.test.Test

@OptIn(ExperimentalCoroutinesApi::class)
class FetchAccountSettingsTests : BaseUnitTest() {
private val shippingRepository: WooShippingLabelRepository = mock()
private val selectedSite: SelectedSite = mock {
on { getOrNull() } doReturn SiteModel().apply {
url = "https://example.com"
}
}

private val defaultStoreOptions = StoreOptionsModel(
weightUnit = "kg",
currencySymbol = "$",
dimensionUnit = "cm",
originCountry = "US"
)

val sut = FetchAccountSettings(
shippingRepository = shippingRepository,
selectedSite = selectedSite
)

@Test
fun `when selected site is null then return failure`() = testBlocking {
whenever(selectedSite.getOrNull()).doReturn(null)
val result = sut.invoke()
assert(result.isFailure)
}

@Test
fun `when fetch account settings fails then return failure`() = testBlocking {
whenever(shippingRepository.fetchAccountSettings(any())).doReturn(
WooResult(WooError(WooErrorType.GENERIC_ERROR, BaseRequest.GenericErrorType.UNKNOWN))
)

val result = sut.invoke()
assert(result.isFailure)
}

@Test
fun `when fetch account settings is empty then return failure`() = testBlocking {
whenever(shippingRepository.fetchAccountSettings(any())).doReturn(
WooResult(StoreOptionsModel.EMPTY)
)

val result = sut.invoke()
assert(result.isFailure)
}

@Test
fun `when fetch account settings succeed then return success`() = testBlocking {
whenever(shippingRepository.fetchAccountSettings(any())).doReturn(
WooResult(defaultStoreOptions)
)

val result = sut.invoke()
assert(result.isSuccess)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.woocommerce.android.ui.orders.wooshippinglabels.WooShippingLabelCreat
import com.woocommerce.android.ui.orders.wooshippinglabels.WooShippingLabelCreationViewModel.WooShippingViewState.DataState
import com.woocommerce.android.ui.orders.wooshippinglabels.models.OriginShippingAddress
import com.woocommerce.android.ui.orders.wooshippinglabels.models.ShippableItemModel
import com.woocommerce.android.ui.orders.wooshippinglabels.models.StoreOptionsModel
import com.woocommerce.android.ui.orders.wooshippinglabels.models.WooShippingCarrier
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.ui.PackageData
import com.woocommerce.android.ui.orders.wooshippinglabels.rates.datasource.WooShippingRateModel
Expand Down Expand Up @@ -86,6 +87,12 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
private val defaultShipToAddress = Address.EMPTY.copy(
address1 = "1278 24st Perito AVE"
)
private val defaultStoreOptions = StoreOptionsModel(
weightUnit = "kg",
currencySymbol = "$",
dimensionUnit = "cm",
originCountry = "US"
)

private val defaultPackageData = PackageData(
id = "1",
Expand Down Expand Up @@ -152,6 +159,7 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {

private val observeOriginAddresses: ObserveOriginAddresses = mock()
private val getShippingRates: GetShippingRates = mock()
private val fetchAccountSettings: FetchAccountSettings = mock()

private lateinit var sut: WooShippingLabelCreationViewModel

Expand All @@ -162,6 +170,7 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
currencyFormatter = currencyFormatter,
observeOriginAddresses = observeOriginAddresses,
getShippingRates = getShippingRates,
fetchAccountSettings = fetchAccountSettings,
savedState = savedState
)
}
Expand All @@ -178,6 +187,7 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
whenever(orderDetailRepository.getOrderById(any())) doReturn order
whenever(getShippableItems(any())) doReturn defaultShippableItems
whenever(observeOriginAddresses()) doReturn flowOf(defaultOriginAddresses)
whenever(fetchAccountSettings()) doReturn Result.success(defaultStoreOptions)

createViewModel()

Expand All @@ -201,6 +211,7 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
whenever(orderDetailRepository.getOrderById(any())) doReturn order
whenever(getShippableItems(any())) doReturn defaultShippableItems
whenever(observeOriginAddresses()) doReturn flowOf(defaultOriginAddresses)
whenever(fetchAccountSettings()) doReturn Result.success(defaultStoreOptions)

createViewModel()

Expand Down Expand Up @@ -251,6 +262,7 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
whenever(orderDetailRepository.getOrderById(any())) doReturn order
whenever(getShippableItems(any())) doReturn defaultShippableItems
whenever(observeOriginAddresses()) doReturn flowOf(defaultOriginAddresses)
whenever(fetchAccountSettings()) doReturn Result.success(defaultStoreOptions)

createViewModel()

Expand Down Expand Up @@ -279,6 +291,7 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
whenever(
getShippingRates(any(), any(), any(), any(), any(), any())
) doReturn Result.success(defaultShippingRates)
whenever(fetchAccountSettings()) doReturn Result.success(defaultStoreOptions)

createViewModel()

Expand Down Expand Up @@ -307,6 +320,7 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
whenever(
getShippingRates(any(), any(), any(), any(), any(), any())
) doReturn Result.failure(Exception("Random error"))
whenever(fetchAccountSettings()) doReturn Result.success(defaultStoreOptions)

createViewModel()
sut.onPackageSelected(defaultPackageData)
Expand All @@ -329,7 +343,6 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
)
)
whenever(orderDetailRepository.getOrderById(any())) doReturn order
whenever(getShippableItems(any())) doReturn defaultShippableItems
whenever(observeOriginAddresses()) doReturn flowOf(defaultOriginAddresses)
whenever(
getShippingRates(any(), any(), any(), any(), any(), any())
Expand Down Expand Up @@ -358,7 +371,6 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
)
)
whenever(orderDetailRepository.getOrderById(any())) doReturn order
whenever(getShippableItems(any())) doReturn defaultShippableItems
whenever(observeOriginAddresses()) doReturn flowOf(defaultOriginAddresses)
whenever(
getShippingRates(any(), any(), any(), any(), any(), any())
Expand Down Expand Up @@ -387,7 +399,6 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
)
)
whenever(orderDetailRepository.getOrderById(any())) doReturn order
whenever(getShippableItems(any())) doReturn defaultShippableItems
whenever(observeOriginAddresses()) doReturn flowOf(defaultOriginAddresses)
whenever(
getShippingRates(any(), any(), any(), any(), any(), any())
Expand Down Expand Up @@ -415,6 +426,7 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
whenever(orderDetailRepository.getOrderById(any())) doReturn order
whenever(getShippableItems(any())) doReturn defaultShippableItems
whenever(observeOriginAddresses()) doReturn flowOf(defaultOriginAddresses)
whenever(fetchAccountSettings()) doReturn Result.success(defaultStoreOptions)

createViewModel()

Expand Down Expand Up @@ -454,6 +466,7 @@ class WooShippingLabelCreationViewModelTest : BaseUnitTest() {
whenever(orderDetailRepository.getOrderById(any())) doReturn order
whenever(getShippableItems(any())) doReturn defaultShippableItems
whenever(observeOriginAddresses()) doReturn flowOf(defaultOriginAddresses)
whenever(fetchAccountSettings()) doReturn Result.success(defaultStoreOptions)

createViewModel()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.woocommerce.android.ui.orders.wooshippinglabels.networking

import com.woocommerce.android.ui.orders.wooshippinglabels.models.StoreOptionsModel
import com.woocommerce.android.viewmodel.BaseUnitTest
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlin.test.Test
import kotlin.test.assertEquals

@OptIn(ExperimentalCoroutinesApi::class)
class WooShippingNetworkingMapperTest : BaseUnitTest() {
val sut = WooShippingNetworkingMapper()

@Test
fun `when all field are null then return empty model`() {
val emptyDTO = StoreOptionsDTO(
weightUnit = null,
currencySymbol = null,
dimensionUnit = null,
originCountry = null
)

val result = sut.invoke(emptyDTO)

assert(result == StoreOptionsModel.EMPTY)
}

@Test
fun `when a dto is received then return the expected model`() {
val dto = StoreOptionsDTO(
weightUnit = "kg",
currencySymbol = "$",
dimensionUnit = "cm",
originCountry = "US"
)

val result = sut.invoke(dto)

assertEquals(result.currencySymbol, dto.currencySymbol)
assertEquals(result.weightUnit, dto.weightUnit)
assertEquals(result.dimensionUnit, dto.dimensionUnit)
assertEquals(result.originCountry, dto.originCountry)
}
}

0 comments on commit c1f4e56

Please sign in to comment.