@@ -9,6 +9,16 @@ import struct Yosemite.JustInTimeMessage
99final class DashboardViewModelTests : XCTestCase {
1010 private let sampleSiteID : Int64 = 122
1111
12+ private var analytics : Analytics !
13+ private var analyticsProvider : MockAnalyticsProvider !
14+ private var stores : MockStoresManager !
15+
16+ override func setUp( ) {
17+ analyticsProvider = MockAnalyticsProvider ( )
18+ analytics = WooAnalytics ( analyticsProvider: analyticsProvider)
19+ stores = MockStoresManager ( sessionManager: . makeForTesting( ) )
20+ }
21+
1222 func test_default_statsVersion_is_v4( ) {
1323 // Given
1424 let viewModel = DashboardViewModel ( )
@@ -19,7 +29,6 @@ final class DashboardViewModelTests: XCTestCase {
1929
2030 func test_statsVersion_changes_from_v4_to_v3_when_store_stats_sync_returns_noRestRoute_error( ) {
2131 // Given
22- let stores = MockStoresManager ( sessionManager: . makeForTesting( ) )
2332 stores. whenReceivingAction ( ofType: StatsActionV4 . self) { action in
2433 if case let . retrieveStats( _, _, _, _, _, _, completion) = action {
2534 completion ( . failure( DotcomError . noRestRoute) )
@@ -37,7 +46,6 @@ final class DashboardViewModelTests: XCTestCase {
3746
3847 func test_statsVersion_remains_v4_when_non_store_stats_sync_returns_noRestRoute_error( ) {
3948 // Given
40- let stores = MockStoresManager ( sessionManager: . makeForTesting( ) )
4149 stores. whenReceivingAction ( ofType: StatsActionV4 . self) { action in
4250 if case let . retrieveStats( _, _, _, _, _, _, completion) = action {
4351 completion ( . failure( DotcomError . empty) )
@@ -61,7 +69,6 @@ final class DashboardViewModelTests: XCTestCase {
6169
6270 func test_statsVersion_changes_from_v3_to_v4_when_store_stats_sync_returns_success( ) {
6371 // Given
64- let stores = MockStoresManager ( sessionManager: . makeForTesting( ) )
6572 // `DotcomError.noRestRoute` error indicates the stats are unavailable.
6673 var storeStatsResult : Result < Void , Error > = . failure( DotcomError . noRestRoute)
6774 stores. whenReceivingAction ( ofType: StatsActionV4 . self) { action in
@@ -84,7 +91,6 @@ final class DashboardViewModelTests: XCTestCase {
8491 func test_products_onboarding_announcements_take_precedence( ) {
8592 // Given
8693 MockABTesting . setVariation ( . treatment( nil ) , for: . productsOnboardingBanner)
87- let stores = MockStoresManager ( sessionManager: . makeForTesting( ) )
8894 stores. whenReceivingAction ( ofType: ProductAction . self) { action in
8995 switch action {
9096 case let . checkProductsOnboardingEligibility( _, completion) :
@@ -96,7 +102,7 @@ final class DashboardViewModelTests: XCTestCase {
96102 stores. whenReceivingAction ( ofType: JustInTimeMessageAction . self) { action in
97103 switch action {
98104 case let . loadMessage( _, _, _, completion) :
99- completion ( . success( Yosemite . JustInTimeMessage. fake ( ) ) )
105+ completion ( . success( [ Yosemite . JustInTimeMessage. fake ( ) ] ) )
100106 default :
101107 XCTFail ( " Received unsupported action: \( action) " )
102108 }
@@ -112,7 +118,18 @@ final class DashboardViewModelTests: XCTestCase {
112118
113119 func test_view_model_syncs_just_in_time_messages_when_ineligible_for_products_onboarding( ) {
114120 // Given
115- let stores = MockStoresManager ( sessionManager: . makeForTesting( ) )
121+ let message = Yosemite . JustInTimeMessage. fake ( ) . copy ( title: " JITM Message " )
122+ prepareStoresToShowJustInTimeMessage ( . success( [ message] ) )
123+ let viewModel = DashboardViewModel ( stores: stores)
124+
125+ // When
126+ viewModel. syncAnnouncements ( for: sampleSiteID)
127+
128+ // Then
129+ XCTAssertEqual ( viewModel. announcementViewModel? . title, " JITM Message " )
130+ }
131+
132+ func prepareStoresToShowJustInTimeMessage( _ response: Result < [ Yosemite . JustInTimeMessage ] , Error > ) {
116133 stores. whenReceivingAction ( ofType: ProductAction . self) { action in
117134 switch action {
118135 case let . checkProductsOnboardingEligibility( _, completion) :
@@ -124,23 +141,15 @@ final class DashboardViewModelTests: XCTestCase {
124141 stores. whenReceivingAction ( ofType: JustInTimeMessageAction . self) { action in
125142 switch action {
126143 case let . loadMessage( _, _, _, completion) :
127- completion ( . success ( Yosemite . JustInTimeMessage . fake ( ) . copy ( title : " JITM Message " ) ) )
144+ completion ( response )
128145 default :
129146 XCTFail ( " Received unsupported action: \( action) " )
130147 }
131148 }
132- let viewModel = DashboardViewModel ( stores: stores)
133-
134- // When
135- viewModel. syncAnnouncements ( for: sampleSiteID)
136-
137- // Then
138- XCTAssertEqual ( viewModel. announcementViewModel? . title, " JITM Message " )
139149 }
140150
141151 func test_no_announcement_to_display_when_no_announcements_are_synced( ) {
142152 // Given
143- let stores = MockStoresManager ( sessionManager: . makeForTesting( ) )
144153 stores. whenReceivingAction ( ofType: ProductAction . self) { action in
145154 switch action {
146155 case let . checkProductsOnboardingEligibility( _, completion) :
@@ -152,7 +161,7 @@ final class DashboardViewModelTests: XCTestCase {
152161 stores. whenReceivingAction ( ofType: JustInTimeMessageAction . self) { action in
153162 switch action {
154163 case let . loadMessage( _, _, _, completion) :
155- completion ( . success( nil ) )
164+ completion ( . success( [ ] ) )
156165 default :
157166 XCTFail ( " Received unsupported action: \( action) " )
158167 }
@@ -165,4 +174,65 @@ final class DashboardViewModelTests: XCTestCase {
165174 // Then
166175 XCTAssertNil ( viewModel. announcementViewModel)
167176 }
177+
178+ func test_fetch_success_analytics_logged_when_just_in_time_messages_retrieved( ) {
179+ // Given
180+ let message = Yosemite . JustInTimeMessage. fake ( ) . copy ( messageID: " test-message-id " ,
181+ featureClass: " test-feature-class " )
182+
183+ let secondMessage = Yosemite . JustInTimeMessage. fake ( ) . copy ( messageID: " test-message-id-2 " ,
184+ featureClass: " test-feature-class-2 " )
185+ prepareStoresToShowJustInTimeMessage ( . success( [ message, secondMessage] ) )
186+ let viewModel = DashboardViewModel ( stores: stores, analytics: analytics)
187+
188+ // When
189+ viewModel. syncAnnouncements ( for: sampleSiteID)
190+
191+ // Then
192+ guard let eventIndex = analyticsProvider. receivedEvents. firstIndex ( of: " jitm_fetch_success " ) ,
193+ let properties = analyticsProvider. receivedProperties [ eventIndex] as? [ String : AnyHashable ]
194+ else {
195+ return XCTFail ( " Expected event was not logged " )
196+ }
197+
198+ assertEqual ( " my_store " , properties [ " source " ] as? String )
199+ assertEqual ( " test-message-id " , properties [ " jitm " ] as? String )
200+ assertEqual ( 2 , properties [ " count " ] as? Int64 )
201+ }
202+
203+ func test_when_two_messages_are_received_only_the_first_is_displayed( ) {
204+ // Given
205+ let message = Yosemite . JustInTimeMessage. fake ( ) . copy ( title: " Higher priority JITM " )
206+
207+ let secondMessage = Yosemite . JustInTimeMessage. fake ( ) . copy ( title: " Lower priority JITM " )
208+ prepareStoresToShowJustInTimeMessage ( . success( [ message, secondMessage] ) )
209+ let viewModel = DashboardViewModel ( stores: stores, analytics: analytics)
210+
211+ // When
212+ viewModel. syncAnnouncements ( for: sampleSiteID)
213+
214+ // Then
215+ XCTAssertEqual ( viewModel. announcementViewModel? . title, " Higher priority JITM " )
216+ }
217+
218+ func test_fetch_failure_analytics_logged_when_just_in_time_message_errors( ) {
219+ // Given
220+ let error = DotcomError . noRestRoute
221+ prepareStoresToShowJustInTimeMessage ( . failure( error) )
222+ let viewModel = DashboardViewModel ( stores: stores, analytics: analytics)
223+
224+ // When
225+ viewModel. syncAnnouncements ( for: sampleSiteID)
226+
227+ // Then
228+ guard let eventIndex = analyticsProvider. receivedEvents. firstIndex ( of: " jitm_fetch_failure " ) ,
229+ let properties = analyticsProvider. receivedProperties [ eventIndex] as? [ String : AnyHashable ]
230+ else {
231+ return XCTFail ( " Expected event was not logged " )
232+ }
233+
234+ assertEqual ( " my_store " , properties [ " source " ] as? String )
235+ assertEqual ( " Networking.DotcomError " , properties [ " error_domain " ] as? String )
236+ assertEqual ( " Dotcom Invalid REST Route " , properties [ " error_description " ] as? String )
237+ }
168238}
0 commit comments