11import XCTest
2+ import Combine
23@testable import WooCommerce
4+ @testable import Yosemite
35
46class ReviewReplyViewModelTests : XCTestCase {
57
8+ private let sampleSiteID : Int64 = 12345
9+
10+ private let sampleReviewID : Int64 = 7
11+
12+ private var subscriptions : [ AnyCancellable ] = [ ]
13+
614 func test_send_button_is_disabled_when_reply_content_is_empty( ) {
715 // Given
8- let viewModel = ReviewReplyViewModel ( )
16+ let viewModel = ReviewReplyViewModel ( siteID : sampleSiteID , reviewID : sampleReviewID )
917
1018 // When
1119 let navigationItem = viewModel. navigationTrailingItem
@@ -16,12 +24,162 @@ class ReviewReplyViewModelTests: XCTestCase {
1624
1725 func test_send_button_is_enabled_when_reply_is_entered( ) {
1826 // Given
19- let viewModel = ReviewReplyViewModel ( )
27+ let viewModel = ReviewReplyViewModel ( siteID : sampleSiteID , reviewID : sampleReviewID )
2028
2129 // When
2230 viewModel. newReply = " New reply "
2331
2432 // Then
2533 assertEqual ( viewModel. navigationTrailingItem, . send( enabled: true ) )
2634 }
35+
36+ func test_loading_indicator_enabled_during_network_request( ) {
37+ // Given
38+ let stores = MockStoresManager ( sessionManager: . testingInstance)
39+ let viewModel = ReviewReplyViewModel ( siteID: sampleSiteID, reviewID: sampleReviewID, stores: stores)
40+ viewModel. newReply = " New reply "
41+
42+ // When
43+ let navigationItem : ReviewReplyNavigationItem = waitFor { promise in
44+ stores. whenReceivingAction ( ofType: CommentAction . self) { action in
45+ switch action {
46+ case . replyToComment:
47+ promise ( viewModel. navigationTrailingItem)
48+ default :
49+ XCTFail ( " Received unsupported action: \( action) " )
50+ }
51+ }
52+ viewModel. sendReply { _ in }
53+ }
54+
55+ // Then
56+ XCTAssertEqual ( navigationItem, . loading)
57+ }
58+
59+ func test_send_button_renabled_after_network_request_completes( ) {
60+ // Given
61+ let stores = MockStoresManager ( sessionManager: . testingInstance)
62+ let viewModel = ReviewReplyViewModel ( siteID: sampleSiteID, reviewID: sampleReviewID, stores: stores)
63+ stores. whenReceivingAction ( ofType: CommentAction . self) { action in
64+ switch action {
65+ case let . replyToComment( _, _, _, onCompletion) :
66+ onCompletion ( . failure( NSError ( domain: " " , code: 0 ) ) )
67+ default :
68+ XCTFail ( " Received unsupported action: \( action) " )
69+ }
70+ }
71+
72+ // When
73+ viewModel. newReply = " New reply "
74+ let navigationItem : ReviewReplyNavigationItem = waitFor { promise in
75+ viewModel. sendReply { _ in
76+ promise ( viewModel. navigationTrailingItem)
77+ }
78+ }
79+
80+ // Then
81+ XCTAssertEqual ( navigationItem, . send( enabled: true ) )
82+ }
83+
84+ func test_sendReply_completion_block_returns_true_after_successful_network_request( ) {
85+ // Given
86+ let stores = MockStoresManager ( sessionManager: . testingInstance)
87+ let viewModel = ReviewReplyViewModel ( siteID: sampleSiteID, reviewID: sampleReviewID, stores: stores)
88+ stores. whenReceivingAction ( ofType: CommentAction . self) { action in
89+ switch action {
90+ case let . replyToComment( _, _, _, onCompletion) :
91+ onCompletion ( . success( . approved) )
92+ default :
93+ XCTFail ( " Received unsupported action: \( action) " )
94+ }
95+ }
96+
97+ // When
98+ viewModel. newReply = " New reply "
99+ let successResponse : Bool = waitFor { promise in
100+ viewModel. sendReply { successResponse in
101+ promise ( successResponse)
102+ }
103+ }
104+
105+ // Then
106+ XCTAssertTrue ( successResponse)
107+ }
108+
109+ func test_sendReply_completion_block_returns_false_after_failed_network_request( ) {
110+ // Given
111+ let stores = MockStoresManager ( sessionManager: . testingInstance)
112+ let viewModel = ReviewReplyViewModel ( siteID: sampleSiteID, reviewID: sampleReviewID, stores: stores)
113+ stores. whenReceivingAction ( ofType: CommentAction . self) { action in
114+ switch action {
115+ case let . replyToComment( _, _, _, onCompletion) :
116+ onCompletion ( . failure( NSError ( domain: " " , code: 0 ) ) )
117+ default :
118+ XCTFail ( " Received unsupported action: \( action) " )
119+ }
120+ }
121+
122+ // When
123+ viewModel. newReply = " New reply "
124+ let successResponse : Bool = waitFor { promise in
125+ viewModel. sendReply { successResponse in
126+ promise ( successResponse)
127+ }
128+ }
129+
130+ // Then
131+ XCTAssertFalse ( successResponse)
132+ }
133+
134+ func test_view_model_triggers_success_notice_after_reply_is_sent_successfully( ) {
135+ // Given
136+ let stores = MockStoresManager ( sessionManager: . testingInstance)
137+ let viewModel = ReviewReplyViewModel ( siteID: sampleSiteID, reviewID: sampleReviewID, stores: stores)
138+ stores. whenReceivingAction ( ofType: CommentAction . self) { action in
139+ switch action {
140+ case let . replyToComment( _, _, _, onCompletion) :
141+ onCompletion ( . success( . approved) )
142+ default :
143+ XCTFail ( " Received unsupported action: \( action) " )
144+ }
145+ }
146+
147+ var noticeTypes : [ ReviewReplyNotice ] = [ ]
148+ viewModel. presentNoticeSubject. sink { notice in
149+ noticeTypes. append ( notice)
150+ } . store ( in: & subscriptions)
151+
152+ // When
153+ viewModel. newReply = " New reply "
154+ viewModel. sendReply { _ in }
155+
156+ // Then
157+ XCTAssertEqual ( noticeTypes, [ . success] )
158+ }
159+
160+ func test_view_model_triggers_error_notice_using_modal_notice_presenter_after_reply_fails( ) {
161+ // Given
162+ let stores = MockStoresManager ( sessionManager: . testingInstance)
163+ let viewModel = ReviewReplyViewModel ( siteID: sampleSiteID, reviewID: sampleReviewID, stores: stores)
164+ stores. whenReceivingAction ( ofType: CommentAction . self) { action in
165+ switch action {
166+ case let . replyToComment( _, _, _, onCompletion) :
167+ onCompletion ( . failure( NSError ( domain: " " , code: 0 ) ) )
168+ default :
169+ XCTFail ( " Received unsupported action: \( action) " )
170+ }
171+ }
172+
173+ var noticeTypes : [ ReviewReplyNotice ] = [ ]
174+ viewModel. presentNoticeSubject. sink { notice in
175+ noticeTypes. append ( notice)
176+ } . store ( in: & subscriptions)
177+
178+ // When
179+ viewModel. newReply = " New reply "
180+ viewModel. sendReply { _ in }
181+
182+ // Then
183+ XCTAssertEqual ( noticeTypes, [ . error] )
184+ }
27185}
0 commit comments