Skip to content

Commit c225db1

Browse files
authored
Merge pull request #14971 from woocommerce/woomob-1697-disable-cellular-data-toggle-in-local-catalog-settings-in
[Woo POS][Local Catalog] Disable "cellular data" toggle if device doesn't have data modem
2 parents 0680aa0 + be15797 commit c225db1

File tree

6 files changed

+163
-16
lines changed

6 files changed

+163
-16
lines changed

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
23.8
66
-----
7+
- [*] Optimized POS Local Catalog Settings screen [https://github.com/woocommerce/woocommerce-android/pull/14971]
78
- [Internal][Woo POS] Improve detection and handling of deleted products during checkout [https://github.com/woocommerce/woocommerce-android/pull/14981]
89
- [*][Woo POS] Fixed payment screen layout to properly position payment instructions text [https://github.com/woocommerce/woocommerce-android/pull/14991]
910
- [*][Woo POS] Automatically scroll to newly created orders when returning to the Orders screen [https://github.com/woocommerce/woocommerce-android/pull/14990]

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/settings/details/localcatalog/WooPosSettingsLocalCatalogScreen.kt

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,14 @@ private fun WooPosSettingsLocalCatalogScreen(
8484
catalogStatus = state.catalogStatus
8585
)
8686

87-
CellularDataSection(
88-
allowCellularDataUpdate = state.allowCellularDataUpdate,
89-
onToggleCellularData = onToggleCellularData,
90-
isLoading = state.catalogStatus is WooPosSettingsLocalCatalogState.CatalogStatus.Loading ||
91-
state.catalogStatus is WooPosSettingsLocalCatalogState.CatalogStatus.RefreshingCatalog
92-
)
87+
if (state.cellularCapability is WooPosSettingsLocalCatalogState.CellularCapability.Available) {
88+
CellularDataSection(
89+
allowCellularDataUpdate = state.cellularCapability.allowCellularDataUpdate,
90+
onToggleCellularData = onToggleCellularData,
91+
isLoading = state.catalogStatus is WooPosSettingsLocalCatalogState.CatalogStatus.Loading ||
92+
state.catalogStatus is WooPosSettingsLocalCatalogState.CatalogStatus.RefreshingCatalog
93+
)
94+
}
9395

9496
ManualUpdateSection(
9597
catalogStatus = state.catalogStatus,
@@ -391,7 +393,29 @@ fun WooPosSettingsLocalCatalogScreenPreview() {
391393
lastUpdate = "2 hours ago",
392394
lastFullUpdate = "Yesterday at 3:45 PM"
393395
),
394-
allowCellularDataUpdate = true
396+
cellularCapability = WooPosSettingsLocalCatalogState.CellularCapability.Available(
397+
allowCellularDataUpdate = true
398+
)
399+
),
400+
onToggleCellularData = {},
401+
onRefreshCatalog = {}
402+
)
403+
}
404+
}
405+
406+
@WooPosPreview
407+
@Composable
408+
fun WooPosSettingsLocalCatalogScreenNoCellularPreview() {
409+
WooPosTheme {
410+
WooPosSettingsLocalCatalogScreen(
411+
state = WooPosSettingsLocalCatalogState(
412+
catalogStatus = WooPosSettingsLocalCatalogState.CatalogStatus.Available(
413+
productCount = 1250,
414+
variationCount = 3420,
415+
lastUpdate = "2 hours ago",
416+
lastFullUpdate = "Yesterday at 3:45 PM"
417+
),
418+
cellularCapability = WooPosSettingsLocalCatalogState.CellularCapability.None
395419
),
396420
onToggleCellularData = {},
397421
onRefreshCatalog = {}
@@ -406,7 +430,9 @@ fun WooPosSettingsLocalCatalogScreenLoadingPreview() {
406430
WooPosSettingsLocalCatalogScreen(
407431
state = WooPosSettingsLocalCatalogState(
408432
catalogStatus = WooPosSettingsLocalCatalogState.CatalogStatus.Loading,
409-
allowCellularDataUpdate = true
433+
cellularCapability = WooPosSettingsLocalCatalogState.CellularCapability.Available(
434+
allowCellularDataUpdate = true
435+
)
410436
),
411437
onToggleCellularData = {},
412438
onRefreshCatalog = {}
@@ -421,7 +447,9 @@ fun WooPosSettingsLocalCatalogRefreshingPreview() {
421447
WooPosSettingsLocalCatalogScreen(
422448
state = WooPosSettingsLocalCatalogState(
423449
catalogStatus = WooPosSettingsLocalCatalogState.CatalogStatus.RefreshingCatalog,
424-
allowCellularDataUpdate = true
450+
cellularCapability = WooPosSettingsLocalCatalogState.CellularCapability.Available(
451+
allowCellularDataUpdate = true
452+
)
425453
),
426454
onToggleCellularData = {},
427455
onRefreshCatalog = {}

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/settings/details/localcatalog/WooPosSettingsLocalCatalogState.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package com.woocommerce.android.ui.woopos.settings.details.localcatalog
22

33
data class WooPosSettingsLocalCatalogState(
44
val catalogStatus: CatalogStatus = CatalogStatus.Loading,
5-
val allowCellularDataUpdate: Boolean = false,
5+
val cellularCapability: CellularCapability = CellularCapability.None,
66
) {
77
sealed class CatalogStatus {
88
data class Available(
@@ -15,4 +15,9 @@ data class WooPosSettingsLocalCatalogState(
1515
object Loading : CatalogStatus()
1616
object RefreshingCatalog : CatalogStatus()
1717
}
18+
19+
sealed class CellularCapability {
20+
object None : CellularCapability()
21+
data class Available(val allowCellularDataUpdate: Boolean) : CellularCapability()
22+
}
1823
}

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/settings/details/localcatalog/WooPosSettingsLocalCatalogViewModel.kt

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.woocommerce.android.ui.woopos.home.WooPosParentToChildrenEventReceive
1010
import com.woocommerce.android.ui.woopos.localcatalog.PosLocalCatalogSyncResult
1111
import com.woocommerce.android.ui.woopos.localcatalog.WooPosLocalCatalogSyncRepository
1212
import com.woocommerce.android.ui.woopos.localcatalog.WooPosLocalCatalogSyncScheduler
13+
import com.woocommerce.android.ui.woopos.util.WooPosCellularCapabilityDetector
1314
import com.woocommerce.android.ui.woopos.util.datastore.WooPosPreferencesRepository
1415
import com.woocommerce.android.ui.woopos.util.datastore.WooPosSyncTimestampManager
1516
import com.woocommerce.android.ui.woopos.util.format.WooPosDateFormatter
@@ -31,18 +32,30 @@ class WooPosSettingsLocalCatalogViewModel @Inject constructor(
3132
private val syncScheduler: WooPosLocalCatalogSyncScheduler,
3233
private val childToParentEventSender: WooPosChildrenToParentEventSender,
3334
private val parentToChildEventReceiver: WooPosParentToChildrenEventReceiver,
35+
private val cellularCapabilityDetector: WooPosCellularCapabilityDetector,
3436
) : ViewModel() {
3537
private val _state = MutableStateFlow(WooPosSettingsLocalCatalogState())
3638
val state: StateFlow<WooPosSettingsLocalCatalogState> = _state.asStateFlow()
3739

3840
init {
41+
checkCellularCapability()
42+
3943
loadCatalogStatus()
4044

4145
listenToCellularDataUpdateValue()
4246

4347
listenToParentEvents()
4448
}
4549

50+
private fun checkCellularCapability() {
51+
if (!cellularCapabilityDetector.hasCellularCapability()) {
52+
_state.update { it.copy(cellularCapability = WooPosSettingsLocalCatalogState.CellularCapability.None) }
53+
viewModelScope.launch {
54+
preferencesRepository.setAllowCellularDataUpdate(false)
55+
}
56+
}
57+
}
58+
4659
private fun listenToParentEvents() {
4760
viewModelScope.launch {
4861
parentToChildEventReceiver.events.collect { event ->
@@ -90,8 +103,18 @@ class WooPosSettingsLocalCatalogViewModel @Inject constructor(
90103
private fun listenToCellularDataUpdateValue() {
91104
viewModelScope.launch {
92105
preferencesRepository.allowCellularDataUpdate.collect { allowCellularDataUpdate ->
93-
_state.update {
94-
it.copy(allowCellularDataUpdate = allowCellularDataUpdate)
106+
_state.update { currentState ->
107+
if (cellularCapabilityDetector.hasCellularCapability()) {
108+
currentState.copy(
109+
cellularCapability = WooPosSettingsLocalCatalogState.CellularCapability.Available(
110+
allowCellularDataUpdate = allowCellularDataUpdate
111+
)
112+
)
113+
} else {
114+
currentState.copy(
115+
cellularCapability = WooPosSettingsLocalCatalogState.CellularCapability.None
116+
)
117+
}
95118
}
96119
}
97120
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.woocommerce.android.ui.woopos.util
2+
3+
import android.content.Context
4+
import android.content.pm.PackageManager
5+
import dagger.Reusable
6+
import dagger.hilt.android.qualifiers.ApplicationContext
7+
import javax.inject.Inject
8+
9+
@Reusable
10+
class WooPosCellularCapabilityDetector @Inject constructor(
11+
@ApplicationContext private val context: Context
12+
) {
13+
fun hasCellularCapability(): Boolean {
14+
return context.packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
15+
}
16+
}

WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/settings/details/localcatalog/WooPosSettingsLocalCatalogViewModelTest.kt

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import com.woocommerce.android.ui.woopos.home.WooPosParentToChildrenEventReceive
88
import com.woocommerce.android.ui.woopos.localcatalog.PosLocalCatalogSyncResult
99
import com.woocommerce.android.ui.woopos.localcatalog.WooPosLocalCatalogSyncRepository
1010
import com.woocommerce.android.ui.woopos.localcatalog.WooPosLocalCatalogSyncScheduler
11+
import com.woocommerce.android.ui.woopos.util.WooPosCellularCapabilityDetector
1112
import com.woocommerce.android.ui.woopos.util.WooPosCoroutineTestRule
1213
import com.woocommerce.android.ui.woopos.util.datastore.WooPosPreferencesRepository
1314
import com.woocommerce.android.ui.woopos.util.datastore.WooPosSyncTimestampManager
@@ -45,6 +46,7 @@ class WooPosSettingsLocalCatalogViewModelTest {
4546
private val syncScheduler: WooPosLocalCatalogSyncScheduler = mock()
4647
private val childToParentEventSender: WooPosChildrenToParentEventSender = mock()
4748
private val parentToChildEventReceiver: WooPosParentToChildrenEventReceiver = mock()
49+
private val cellularCapabilityDetector: WooPosCellularCapabilityDetector = mock()
4850

4951
private val mockSite: SiteModel = mock()
5052
private val allowCellularDataFlow = MutableStateFlow(false)
@@ -57,6 +59,7 @@ class WooPosSettingsLocalCatalogViewModelTest {
5759
whenever(selectedSite.get()).thenReturn(mockSite)
5860
whenever(preferencesRepository.allowCellularDataUpdate).thenReturn(allowCellularDataFlow)
5961
whenever(parentToChildEventReceiver.events).thenReturn(parentEventsFlow)
62+
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(true)
6063
whenever(localCatalogSyncRepository.syncLocalCatalogFull(any()))
6164
.thenReturn(
6265
PosLocalCatalogSyncResult.Success(
@@ -79,26 +82,34 @@ class WooPosSettingsLocalCatalogViewModelTest {
7982
fun `given cellular data is disabled, when init, then state reflects disabled preference`() = runTest {
8083
// GIVEN
8184
allowCellularDataFlow.value = false
85+
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(true)
8286

8387
// WHEN
8488
sut = createViewModel()
8589
advanceUntilIdle()
8690

8791
// THEN
88-
assertThat(sut.state.value.allowCellularDataUpdate).isFalse()
92+
val capability = sut.state.value.cellularCapability
93+
assertThat(capability).isInstanceOf(WooPosSettingsLocalCatalogState.CellularCapability.Available::class.java)
94+
assertThat((capability as WooPosSettingsLocalCatalogState.CellularCapability.Available).allowCellularDataUpdate)
95+
.isFalse()
8996
}
9097

9198
@Test
9299
fun `given cellular data is enabled, when init, then state reflects enabled preference`() = runTest {
93100
// GIVEN
94101
allowCellularDataFlow.value = true
102+
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(true)
95103

96104
// WHEN
97105
sut = createViewModel()
98106
advanceUntilIdle()
99107

100108
// THEN
101-
assertThat(sut.state.value.allowCellularDataUpdate).isTrue()
109+
val capability = sut.state.value.cellularCapability
110+
assertThat(capability).isInstanceOf(WooPosSettingsLocalCatalogState.CellularCapability.Available::class.java)
111+
assertThat((capability as WooPosSettingsLocalCatalogState.CellularCapability.Available).allowCellularDataUpdate)
112+
.isTrue()
102113
}
103114

104115
@Test
@@ -118,16 +129,24 @@ class WooPosSettingsLocalCatalogViewModelTest {
118129
@Test
119130
fun `when cellular data preference changes, then state is updated`() = runTest {
120131
// GIVEN
132+
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(true)
121133
sut = createViewModel()
122134
advanceUntilIdle()
123-
assertThat(sut.state.value.allowCellularDataUpdate).isFalse()
135+
136+
var capability = sut.state.value.cellularCapability
137+
assertThat(capability).isInstanceOf(WooPosSettingsLocalCatalogState.CellularCapability.Available::class.java)
138+
assertThat((capability as WooPosSettingsLocalCatalogState.CellularCapability.Available).allowCellularDataUpdate)
139+
.isFalse()
124140

125141
// WHEN
126142
allowCellularDataFlow.value = true
127143
advanceUntilIdle()
128144

129145
// THEN
130-
assertThat(sut.state.value.allowCellularDataUpdate).isTrue()
146+
capability = sut.state.value.cellularCapability
147+
assertThat(capability).isInstanceOf(WooPosSettingsLocalCatalogState.CellularCapability.Available::class.java)
148+
assertThat((capability as WooPosSettingsLocalCatalogState.CellularCapability.Available).allowCellularDataUpdate)
149+
.isTrue()
131150
}
132151

133152
@Test
@@ -295,6 +314,60 @@ class WooPosSettingsLocalCatalogViewModelTest {
295314
.isInstanceOf(WooPosSettingsLocalCatalogState.CatalogStatus.Available::class.java)
296315
}
297316

317+
@Test
318+
fun `given device has cellular capability, when init, then cellularCapability is Available`() = runTest {
319+
// GIVEN
320+
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(true)
321+
322+
// WHEN
323+
sut = createViewModel()
324+
advanceUntilIdle()
325+
326+
// THEN
327+
assertThat(sut.state.value.cellularCapability)
328+
.isInstanceOf(WooPosSettingsLocalCatalogState.CellularCapability.Available::class.java)
329+
}
330+
331+
@Test
332+
fun `given device has no cellular capability, when init, then cellularCapability is None`() = runTest {
333+
// GIVEN
334+
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(false)
335+
336+
// WHEN
337+
sut = createViewModel()
338+
advanceUntilIdle()
339+
340+
// THEN
341+
assertThat(sut.state.value.cellularCapability)
342+
.isEqualTo(WooPosSettingsLocalCatalogState.CellularCapability.None)
343+
}
344+
345+
@Test
346+
fun `given device has no cellular capability, when init, then allowCellularDataUpdate is set to false in preferences`() = runTest {
347+
// GIVEN
348+
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(false)
349+
350+
// WHEN
351+
sut = createViewModel()
352+
advanceUntilIdle()
353+
354+
// THEN
355+
verify(preferencesRepository).setAllowCellularDataUpdate(false)
356+
}
357+
358+
@Test
359+
fun `given device has cellular capability, when init, then allowCellularDataUpdate preference is not modified`() = runTest {
360+
// GIVEN
361+
whenever(cellularCapabilityDetector.hasCellularCapability()).thenReturn(true)
362+
363+
// WHEN
364+
sut = createViewModel()
365+
advanceUntilIdle()
366+
367+
// THEN
368+
verify(preferencesRepository, times(0)).setAllowCellularDataUpdate(false)
369+
}
370+
298371
private fun createViewModel() = WooPosSettingsLocalCatalogViewModel(
299372
syncTimestampManager = syncTimestampManager,
300373
localCatalogSyncRepository = localCatalogSyncRepository,
@@ -304,5 +377,6 @@ class WooPosSettingsLocalCatalogViewModelTest {
304377
syncScheduler = syncScheduler,
305378
childToParentEventSender = childToParentEventSender,
306379
parentToChildEventReceiver = parentToChildEventReceiver,
380+
cellularCapabilityDetector = cellularCapabilityDetector,
307381
)
308382
}

0 commit comments

Comments
 (0)