Skip to content

Commit 4863540

Browse files
authored
Merge pull request #14712 from woocommerce/woomob-1433-woo-possurveys-show-current-push-notification-after-order
[WOOMOB-1433][Woo POS][Surveys] Schedule current user survey notification on app start
2 parents 45f4e1f + bdb2ea0 commit 4863540

File tree

5 files changed

+110
-32
lines changed

5 files changed

+110
-32
lines changed

WooCommerce/src/main/kotlin/com/woocommerce/android/AppInitializer.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import com.woocommerce.android.ui.jitm.JitmStoreInMemoryCache
4444
import com.woocommerce.android.ui.login.AccountRepository
4545
import com.woocommerce.android.ui.main.MainActivity
4646
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderOnboardingChecker
47+
import com.woocommerce.android.ui.woopos.common.util.WooPosSurveysNotificationScheduler
4748
import com.woocommerce.android.ui.woopos.localcatalog.WooPosLocalCatalogSyncScheduler
4849
import com.woocommerce.android.util.AppThemeUtils
4950
import com.woocommerce.android.util.ApplicationEdgeToEdgeEnabler
@@ -165,6 +166,8 @@ class AppInitializer @Inject constructor() : ApplicationLifecycleListener {
165166

166167
@Inject lateinit var posLocalCatalogScheduler: WooPosLocalCatalogSyncScheduler
167168

169+
@Inject lateinit var wooPosSurveysNotificationScheduler: Lazy<WooPosSurveysNotificationScheduler>
170+
168171
private var connectionReceiverRegistered = false
169172

170173
private lateinit var application: Application
@@ -322,6 +325,7 @@ class AppInitializer @Inject constructor() : ApplicationLifecycleListener {
322325

323326
add(async { jitmStoreInMemoryCache.init() })
324327
add(async { trackStoreSnapshot() })
328+
add(async { wooPosSurveysNotificationScheduler.get().scheduleCurrentUserSurveyNotification() })
325329
}.awaitAll()
326330
}
327331
}

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/creation/OrderCreateEditViewModel.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ import com.woocommerce.android.ui.products.inventory.FetchProductByIdentifier
145145
import com.woocommerce.android.ui.products.selector.ProductSelectorViewModel.SelectedItem
146146
import com.woocommerce.android.ui.products.selector.ProductSelectorViewModel.SelectedItem.Product
147147
import com.woocommerce.android.ui.products.selector.variationIds
148-
import com.woocommerce.android.ui.woopos.common.util.WooPosSurveysNotificationSchedular
148+
import com.woocommerce.android.ui.woopos.common.util.WooPosSurveysNotificationScheduler
149149
import com.woocommerce.android.util.CoroutineDispatchers
150150
import com.woocommerce.android.util.DateUtils
151151
import com.woocommerce.android.viewmodel.LiveDataDelegate
@@ -211,7 +211,7 @@ class OrderCreateEditViewModel @Inject constructor(
211211
private val totalsHelper: OrderCreateEditTotalsHelper,
212212
private val feedbackRepository: FeedbackRepository,
213213
private val fetchProductByIdentifier: FetchProductByIdentifier,
214-
private val wooPosSurveysNotificationSchedular: WooPosSurveysNotificationSchedular,
214+
private val wooPosSurveysNotificationScheduler: WooPosSurveysNotificationScheduler,
215215
dateUtils: DateUtils,
216216
autoSyncOrder: AutoSyncOrder,
217217
autoSyncPriceModifier: AutoSyncPriceModifier,
@@ -1383,7 +1383,7 @@ class OrderCreateEditViewModel @Inject constructor(
13831383
).fold(
13841384
onSuccess = {
13851385
trackOrderCreationSuccess()
1386-
wooPosSurveysNotificationSchedular.schedularPotentialUserSurveyNotification()
1386+
wooPosSurveysNotificationScheduler.schedulePotentialUserSurveyNotification()
13871387
onSuccess(it)
13881388
},
13891389
onFailure = {
Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import com.woocommerce.android.ui.woopos.util.datastore.WooPosPreferencesReposit
88
import com.woocommerce.android.util.FeatureFlag
99
import kotlinx.coroutines.flow.first
1010
import org.wordpress.android.fluxc.store.WooCommerceStore
11+
import java.util.concurrent.TimeUnit
1112
import javax.inject.Inject
1213

13-
class WooPosSurveysNotificationSchedular @Inject constructor(
14+
class WooPosSurveysNotificationScheduler @Inject constructor(
1415
private val localNotificationScheduler: LocalNotificationScheduler,
1516
private val appPrefs: AppPrefsWrapper,
1617
private val wooPosPreferencesRepository: WooPosPreferencesRepository,
@@ -19,10 +20,14 @@ class WooPosSurveysNotificationSchedular @Inject constructor(
1920
) {
2021
companion object {
2122
private val ALLOWED_COUNTRIES = setOf("us", "gb")
23+
private const val CURRENT_USER_NOTIFICATION_DELAY_MINUTES = 5L
2224
}
2325

24-
suspend fun schedularPotentialUserSurveyNotification() {
25-
if (!appPrefs.isWooPosSurveyNotificationPotentialUserShown && areNotificationsAllowed()) {
26+
suspend fun schedulePotentialUserSurveyNotification() {
27+
if (!appPrefs.isWooPosSurveyNotificationPotentialUserShown &&
28+
!wooPosPreferencesRepository.wasOpenedOnce.first() &&
29+
areNotificationsAllowed()
30+
) {
2631
localNotificationScheduler.scheduleNotification(
2732
LocalNotification.WooPosSurveyPotentialUserNotification(
2833
siteId = selectedSite.get().siteId
@@ -31,10 +36,22 @@ class WooPosSurveysNotificationSchedular @Inject constructor(
3136
}
3237
}
3338

39+
suspend fun scheduleCurrentUserSurveyNotification() {
40+
if (!appPrefs.isWooPosSurveyNotificationCurrentUserShown &&
41+
wooPosPreferencesRepository.wasOpenedOnce.first() &&
42+
areNotificationsAllowed()
43+
) {
44+
localNotificationScheduler.scheduleNotification(
45+
LocalNotification.WooPosSurveyCurrentUserNotification(
46+
delay = TimeUnit.MINUTES.toMillis(CURRENT_USER_NOTIFICATION_DELAY_MINUTES),
47+
siteId = selectedSite.get().siteId
48+
)
49+
)
50+
}
51+
}
52+
3453
private suspend fun areNotificationsAllowed(): Boolean =
35-
isAllowedCountry() &&
36-
!wooPosPreferencesRepository.wasOpenedOnce.first() &&
37-
FeatureFlag.WOO_POS_SURVEYS.isEnabled()
54+
isAllowedCountry() && FeatureFlag.WOO_POS_SURVEYS.isEnabled()
3855

3956
private suspend fun isAllowedCountry(): Boolean {
4057
val countryCode = wooCommerceStore.getSiteSettingsAsync(selectedSite.get())?.countryCode

WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/creation/UnifiedOrderEditViewModelTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import com.woocommerce.android.ui.products.ProductType
5050
import com.woocommerce.android.ui.products.inventory.FetchProductByIdentifier
5151
import com.woocommerce.android.ui.products.models.SiteParameters
5252
import com.woocommerce.android.ui.products.selector.ProductSelectorViewModel
53-
import com.woocommerce.android.ui.woopos.common.util.WooPosSurveysNotificationSchedular
53+
import com.woocommerce.android.ui.woopos.common.util.WooPosSurveysNotificationScheduler
5454
import com.woocommerce.android.util.captureValues
5555
import com.woocommerce.android.viewmodel.BaseUnitTest
5656
import com.woocommerce.android.viewmodel.ResourceProvider
@@ -107,7 +107,7 @@ abstract class UnifiedOrderEditViewModelTest : BaseUnitTest() {
107107
private lateinit var getShippingMethodsWithOtherValue: GetShippingMethodsWithOtherValue
108108
protected lateinit var feedbackRepository: FeedbackRepository
109109
protected lateinit var fetchProductByIdentifier: FetchProductByIdentifier
110-
private lateinit var wooPosSurveysNotificationSchedular: WooPosSurveysNotificationSchedular
110+
private lateinit var wooPosSurveysNotificationScheduler: WooPosSurveysNotificationScheduler
111111

112112
protected val defaultOrderValue = Order.getEmptyOrder(Date(), Date()).copy(id = 123)
113113

@@ -221,7 +221,7 @@ abstract class UnifiedOrderEditViewModelTest : BaseUnitTest() {
221221
)
222222
}
223223
fetchProductByIdentifier = mock()
224-
wooPosSurveysNotificationSchedular = mock()
224+
wooPosSurveysNotificationScheduler = mock()
225225
}
226226

227227
protected abstract val tracksFlow: String
@@ -2178,7 +2178,7 @@ abstract class UnifiedOrderEditViewModelTest : BaseUnitTest() {
21782178
getShippingMethodsWithOtherValue = getShippingMethodsWithOtherValue,
21792179
feedbackRepository = feedbackRepository,
21802180
fetchProductByIdentifier = fetchProductByIdentifier,
2181-
wooPosSurveysNotificationSchedular = wooPosSurveysNotificationSchedular,
2181+
wooPosSurveysNotificationScheduler = wooPosSurveysNotificationScheduler,
21822182
)
21832183
}
21842184

Lines changed: 76 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import org.wordpress.android.fluxc.store.WooCommerceStore
2323
import org.wordpress.android.fluxc.wc.settings.WCSettingsTestUtils
2424

2525
@ExperimentalCoroutinesApi
26-
class WooPosSurveysNotificationSchedularTest {
26+
class WooPosSurveysNotificationSchedulerTest {
2727
@Rule
2828
@JvmField
2929
val coroutinesTestRule = WooPosCoroutineTestRule()
@@ -33,7 +33,7 @@ class WooPosSurveysNotificationSchedularTest {
3333
private lateinit var wooPosPreferencesRepository: WooPosPreferencesRepository
3434
private lateinit var selectedSite: SelectedSite
3535
private lateinit var wooCommerceStore: WooCommerceStore
36-
private lateinit var schedular: WooPosSurveysNotificationSchedular
36+
private lateinit var scheduler: WooPosSurveysNotificationScheduler
3737
private lateinit var siteModel: SiteModel
3838

3939
@Before
@@ -49,7 +49,7 @@ class WooPosSurveysNotificationSchedularTest {
4949

5050
whenever(selectedSite.get()).thenReturn(siteModel)
5151

52-
schedular = WooPosSurveysNotificationSchedular(
52+
scheduler = WooPosSurveysNotificationScheduler(
5353
localNotificationScheduler = localNotificationScheduler,
5454
appPrefs = appPrefs,
5555
wooPosPreferencesRepository = wooPosPreferencesRepository,
@@ -59,110 +59,167 @@ class WooPosSurveysNotificationSchedularTest {
5959
}
6060

6161
@Test
62-
fun `given all conditions met, when schedularPotentialUserSurveyNotification called, then notification scheduled`() =
62+
fun `given all conditions met, when schedulePotentialUserSurveyNotification called, then notification scheduled`() =
6363
runTest {
6464
val siteSettings = WCSettingsTestUtils.generateSettings(LocalId(1)).copy(countryCode = "US")
6565
whenever(appPrefs.isWooPosSurveyNotificationPotentialUserShown).thenReturn(false)
6666
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(false))
6767
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(siteSettings)
6868

69-
schedular.schedularPotentialUserSurveyNotification()
69+
scheduler.schedulePotentialUserSurveyNotification()
7070

7171
verify(localNotificationScheduler).scheduleNotification(
7272
LocalNotification.WooPosSurveyPotentialUserNotification(siteId = 123L)
7373
)
7474
}
7575

7676
@Test
77-
fun `given notification already shown, when schedularPotentialUserSurveyNotification called, then notification not scheduled`() =
77+
fun `given notification already shown, when schedulePotentialUserSurveyNotification called, then notification not scheduled`() =
7878
runTest {
7979
val siteSettings = WCSettingsTestUtils.generateSettings(LocalId(1)).copy(countryCode = "US")
8080
whenever(appPrefs.isWooPosSurveyNotificationPotentialUserShown).thenReturn(true)
8181
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(false))
8282
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(siteSettings)
8383

84-
schedular.schedularPotentialUserSurveyNotification()
84+
scheduler.schedulePotentialUserSurveyNotification()
8585

8686
verify(localNotificationScheduler, never()).scheduleNotification(any())
8787
}
8888

8989
@Test
90-
fun `given country not allowed, when schedularPotentialUserSurveyNotification called, then notification not scheduled`() =
90+
fun `given country not allowed, when schedulePotentialUserSurveyNotification called, then notification not scheduled`() =
9191
runTest {
9292
val siteSettings = WCSettingsTestUtils.generateSettings(LocalId(1)).copy(countryCode = "FR")
9393
whenever(appPrefs.isWooPosSurveyNotificationPotentialUserShown).thenReturn(false)
9494
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(false))
9595
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(siteSettings)
9696

97-
schedular.schedularPotentialUserSurveyNotification()
97+
scheduler.schedulePotentialUserSurveyNotification()
9898

9999
verify(localNotificationScheduler, never()).scheduleNotification(any())
100100
}
101101

102102
@Test
103-
fun `given WooPOS opened before, when schedularPotentialUserSurveyNotification called, then notification not scheduled`() =
103+
fun `given WooPOS opened before, when schedulePotentialUserSurveyNotification called, then notification not scheduled`() =
104104
runTest {
105105
val siteSettings = WCSettingsTestUtils.generateSettings(LocalId(1)).copy(countryCode = "US")
106106
whenever(appPrefs.isWooPosSurveyNotificationPotentialUserShown).thenReturn(false)
107107
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(true))
108108
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(siteSettings)
109109

110-
schedular.schedularPotentialUserSurveyNotification()
110+
scheduler.schedulePotentialUserSurveyNotification()
111111

112112
verify(localNotificationScheduler, never()).scheduleNotification(any())
113113
}
114114

115115
@Test
116-
fun `given GB country code, when schedularPotentialUserSurveyNotification called, then notification scheduled`() =
116+
fun `given GB country code, when schedulePotentialUserSurveyNotification called, then notification scheduled`() =
117117
runTest {
118118
val siteSettings = WCSettingsTestUtils.generateSettings(LocalId(1)).copy(countryCode = "GB")
119119
whenever(appPrefs.isWooPosSurveyNotificationPotentialUserShown).thenReturn(false)
120120
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(false))
121121
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(siteSettings)
122122

123-
schedular.schedularPotentialUserSurveyNotification()
123+
scheduler.schedulePotentialUserSurveyNotification()
124124

125125
verify(localNotificationScheduler).scheduleNotification(
126126
LocalNotification.WooPosSurveyPotentialUserNotification(siteId = 123L)
127127
)
128128
}
129129

130130
@Test
131-
fun `given lowercase country code, when schedularPotentialUserSurveyNotification called, then notification scheduled`() =
131+
fun `given lowercase country code, when schedulePotentialUserSurveyNotification called, then notification scheduled`() =
132132
runTest {
133133
val siteSettings = WCSettingsTestUtils.generateSettings(LocalId(1)).copy(countryCode = "us")
134134
whenever(appPrefs.isWooPosSurveyNotificationPotentialUserShown).thenReturn(false)
135135
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(false))
136136
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(siteSettings)
137137

138-
schedular.schedularPotentialUserSurveyNotification()
138+
scheduler.schedulePotentialUserSurveyNotification()
139139

140140
verify(localNotificationScheduler).scheduleNotification(
141141
LocalNotification.WooPosSurveyPotentialUserNotification(siteId = 123L)
142142
)
143143
}
144144

145145
@Test
146-
fun `given null country code, when schedularPotentialUserSurveyNotification called, then notification not scheduled`() =
146+
fun `given null country code, when schedulePotentialUserSurveyNotification called, then notification not scheduled`() =
147147
runTest {
148148
val siteSettings = WCSettingsTestUtils.generateSettings(LocalId(1)).copy(countryCode = "")
149149
whenever(appPrefs.isWooPosSurveyNotificationPotentialUserShown).thenReturn(false)
150150
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(false))
151151
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(siteSettings)
152152

153-
schedular.schedularPotentialUserSurveyNotification()
153+
scheduler.schedulePotentialUserSurveyNotification()
154154

155155
verify(localNotificationScheduler, never()).scheduleNotification(any())
156156
}
157157

158158
@Test
159-
fun `given null site settings, when schedularPotentialUserSurveyNotification called, then notification not scheduled`() =
159+
fun `given null site settings, when schedulePotentialUserSurveyNotification called, then notification not scheduled`() =
160160
runTest {
161161
whenever(appPrefs.isWooPosSurveyNotificationPotentialUserShown).thenReturn(false)
162162
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(false))
163163
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(null)
164164

165-
schedular.schedularPotentialUserSurveyNotification()
165+
scheduler.schedulePotentialUserSurveyNotification()
166+
167+
verify(localNotificationScheduler, never()).scheduleNotification(any())
168+
}
169+
170+
@Test
171+
fun `given all conditions met, when scheduleCurrentUserSurveyNotification called, then notification scheduled with delay`() =
172+
runTest {
173+
val siteSettings = WCSettingsTestUtils.generateSettings(LocalId(1)).copy(countryCode = "US")
174+
whenever(appPrefs.isWooPosSurveyNotificationCurrentUserShown).thenReturn(false)
175+
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(true))
176+
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(siteSettings)
177+
178+
scheduler.scheduleCurrentUserSurveyNotification()
179+
180+
verify(localNotificationScheduler).scheduleNotification(
181+
LocalNotification.WooPosSurveyCurrentUserNotification(
182+
delay = 300000L,
183+
siteId = 123L
184+
)
185+
)
186+
}
187+
188+
@Test
189+
fun `given notification already shown, when scheduleCurrentUserSurveyNotification called, then notification not scheduled`() =
190+
runTest {
191+
val siteSettings = WCSettingsTestUtils.generateSettings(LocalId(1)).copy(countryCode = "US")
192+
whenever(appPrefs.isWooPosSurveyNotificationCurrentUserShown).thenReturn(true)
193+
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(true))
194+
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(siteSettings)
195+
196+
scheduler.scheduleCurrentUserSurveyNotification()
197+
198+
verify(localNotificationScheduler, never()).scheduleNotification(any())
199+
}
200+
201+
@Test
202+
fun `given WooPOS not opened before, when scheduleCurrentUserSurveyNotification called, then notification not scheduled`() =
203+
runTest {
204+
val siteSettings = WCSettingsTestUtils.generateSettings(LocalId(1)).copy(countryCode = "US")
205+
whenever(appPrefs.isWooPosSurveyNotificationCurrentUserShown).thenReturn(false)
206+
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(false))
207+
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(siteSettings)
208+
209+
scheduler.scheduleCurrentUserSurveyNotification()
210+
211+
verify(localNotificationScheduler, never()).scheduleNotification(any())
212+
}
213+
214+
@Test
215+
fun `given country not allowed, when scheduleCurrentUserSurveyNotification called, then notification not scheduled`() =
216+
runTest {
217+
val siteSettings = WCSettingsTestUtils.generateSettings(LocalId(1)).copy(countryCode = "FR")
218+
whenever(appPrefs.isWooPosSurveyNotificationCurrentUserShown).thenReturn(false)
219+
whenever(wooPosPreferencesRepository.wasOpenedOnce).thenReturn(flowOf(true))
220+
whenever(wooCommerceStore.getSiteSettingsAsync(siteModel)).thenReturn(siteSettings)
221+
222+
scheduler.scheduleCurrentUserSurveyNotification()
166223

167224
verify(localNotificationScheduler, never()).scheduleNotification(any())
168225
}

0 commit comments

Comments
 (0)