22
22
#import " Core/FSTDatabaseInfo.h"
23
23
#import " FSTHelpers.h"
24
24
#import " FSTIntegrationTestCase.h"
25
+ #import " FSTTestDispatchQueue.h"
25
26
#import " Model/FSTDatabaseID.h"
26
27
#import " Remote/FSTDatastore.h"
27
28
#import " Util/FSTAssert.h"
28
- #import " Util/FSTDispatchQueue.h"
29
29
30
30
/* * Exposes otherwise private methods for testing. */
31
31
@interface FSTStream (Testing)
@@ -79,14 +79,14 @@ - (void)writeStreamDidCompleteHandshake {
79
79
_expectation = nil ;
80
80
}
81
81
82
- - (void )writeStreamDidClose : ( NSError *_Nullable )error {
83
- [_states addObject: @" writeStreamDidClose " ];
82
+ - (void )writeStreamWasInterruptedWithError : (nullable NSError *)error {
83
+ [_states addObject: @" writeStreamWasInterrupted " ];
84
84
[_expectation fulfill ];
85
85
_expectation = nil ;
86
86
}
87
87
88
- - (void )watchStreamDidClose : ( NSError *_Nullable )error {
89
- [_states addObject: @" watchStreamDidClose " ];
88
+ - (void )watchStreamWasInterruptedWithError : (nullable NSError *)error {
89
+ [_states addObject: @" watchStreamWasInterrupted " ];
90
90
[_expectation fulfill ];
91
91
_expectation = nil ;
92
92
}
@@ -126,10 +126,10 @@ @interface FSTStreamTests : XCTestCase
126
126
127
127
@implementation FSTStreamTests {
128
128
dispatch_queue_t _testQueue;
129
+ FSTTestDispatchQueue *_workerDispatchQueue;
129
130
FSTDatabaseInfo *_databaseInfo;
130
131
FSTEmptyCredentialsProvider *_credentials;
131
132
FSTStreamStatusDelegate *_delegate;
132
- FSTDispatchQueue *_workerDispatchQueue;
133
133
134
134
/* * Single mutation to send to the write stream. */
135
135
NSArray <FSTMutation *> *_mutations;
@@ -138,38 +138,37 @@ @implementation FSTStreamTests {
138
138
- (void )setUp {
139
139
[super setUp ];
140
140
141
- _mutations = @[ FSTTestSetMutation (@" foo/bar" , @{}) ];
142
-
143
141
FIRFirestoreSettings *settings = [FSTIntegrationTestCase settings ];
144
142
FSTDatabaseID *databaseID =
145
143
[FSTDatabaseID databaseIDWithProject: [FSTIntegrationTestCase projectID ]
146
144
database: kDefaultDatabaseID ];
147
145
146
+ _testQueue = dispatch_queue_create (" FSTStreamTestWorkerQueue" , DISPATCH_QUEUE_SERIAL);
147
+ _workerDispatchQueue = [[FSTTestDispatchQueue alloc ] initWithQueue: _testQueue];
148
+
148
149
_databaseInfo = [FSTDatabaseInfo databaseInfoWithDatabaseID: databaseID
149
150
persistenceKey: @" test-key"
150
151
host: settings.host
151
152
sslEnabled: settings.sslEnabled];
152
- _testQueue = dispatch_queue_create (" FSTStreamTestWorkerQueue" , DISPATCH_QUEUE_SERIAL);
153
- _workerDispatchQueue = [FSTDispatchQueue queueWith: _testQueue];
154
153
_credentials = [[FSTEmptyCredentialsProvider alloc ] init ];
154
+
155
+ _delegate = [[FSTStreamStatusDelegate alloc ] initWithTestCase: self queue: _workerDispatchQueue];
156
+
157
+ _mutations = @[ FSTTestSetMutation (@" foo/bar" , @{}) ];
155
158
}
156
159
157
160
- (FSTWriteStream *)setUpWriteStream {
158
161
FSTDatastore *datastore = [[FSTDatastore alloc ] initWithDatabaseInfo: _databaseInfo
159
162
workerDispatchQueue: _workerDispatchQueue
160
163
credentials: _credentials];
161
-
162
- _delegate = [[FSTStreamStatusDelegate alloc ] initWithTestCase: self queue: _workerDispatchQueue];
163
- return [datastore createWriteStreamWithDelegate: _delegate];
164
+ return [datastore createWriteStream ];
164
165
}
165
166
166
167
- (FSTWatchStream *)setUpWatchStream {
167
168
FSTDatastore *datastore = [[FSTDatastore alloc ] initWithDatabaseInfo: _databaseInfo
168
169
workerDispatchQueue: _workerDispatchQueue
169
170
credentials: _credentials];
170
-
171
- _delegate = [[FSTStreamStatusDelegate alloc ] initWithTestCase: self queue: _workerDispatchQueue];
172
- return [datastore createWatchStreamWithDelegate: _delegate];
171
+ return [datastore createWatchStream ];
173
172
}
174
173
175
174
/* *
@@ -190,7 +189,7 @@ - (void)testWatchStreamStopBeforeHandshake {
190
189
FSTWatchStream *watchStream = [self setUpWatchStream ];
191
190
192
191
[_delegate awaitNotificationFromBlock: ^{
193
- [watchStream start ];
192
+ [watchStream startWithDelegate: _delegate ];
194
193
}];
195
194
196
195
// Stop must not call watchStreamDidClose because the full implementation of the delegate could
@@ -210,7 +209,7 @@ - (void)testWriteStreamStopBeforeHandshake {
210
209
FSTWriteStream *writeStream = [self setUpWriteStream ];
211
210
212
211
[_delegate awaitNotificationFromBlock: ^{
213
- [writeStream start ];
212
+ [writeStream startWithDelegate: _delegate ];
214
213
}];
215
214
216
215
// Don't start the handshake.
@@ -231,7 +230,7 @@ - (void)testWriteStreamStopAfterHandshake {
231
230
FSTWriteStream *writeStream = [self setUpWriteStream ];
232
231
233
232
[_delegate awaitNotificationFromBlock: ^{
234
- [writeStream start ];
233
+ [writeStream startWithDelegate: _delegate ];
235
234
}];
236
235
237
236
// Writing before the handshake should throw
@@ -258,4 +257,55 @@ - (void)testWriteStreamStopAfterHandshake {
258
257
]];
259
258
}
260
259
260
+ - (void )testStreamClosesWhenIdle {
261
+ FSTWriteStream *writeStream = [self setUpWriteStream ];
262
+
263
+ [_delegate awaitNotificationFromBlock: ^{
264
+ [writeStream startWithDelegate: _delegate];
265
+ }];
266
+
267
+ [_delegate awaitNotificationFromBlock: ^{
268
+ [writeStream writeHandshake ];
269
+ }];
270
+
271
+ [_delegate awaitNotificationFromBlock: ^{
272
+ [writeStream markIdle ];
273
+ }];
274
+
275
+ dispatch_sync (_testQueue, ^{
276
+ XCTAssertFalse ([writeStream isOpen ]);
277
+ });
278
+
279
+ [self verifyDelegateObservedStates: @[
280
+ @" writeStreamDidOpen" , @" writeStreamDidCompleteHandshake" , @" writeStreamWasInterrupted"
281
+ ]];
282
+ }
283
+
284
+ - (void )testStreamCancelsIdleOnWrite {
285
+ FSTWriteStream *writeStream = [self setUpWriteStream ];
286
+
287
+ [_delegate awaitNotificationFromBlock: ^{
288
+ [writeStream startWithDelegate: _delegate];
289
+ }];
290
+
291
+ [_delegate awaitNotificationFromBlock: ^{
292
+ [writeStream writeHandshake ];
293
+ }];
294
+
295
+ // Mark the stream idle, but immediately cancel the idle timer by issuing another write.
296
+ [_delegate awaitNotificationFromBlock: ^{
297
+ [writeStream markIdle ];
298
+ [writeStream writeMutations: _mutations];
299
+ }];
300
+
301
+ dispatch_sync (_testQueue, ^{
302
+ XCTAssertTrue ([writeStream isOpen ]);
303
+ });
304
+
305
+ [self verifyDelegateObservedStates: @[
306
+ @" writeStreamDidOpen" , @" writeStreamDidCompleteHandshake" ,
307
+ @" writeStreamDidReceiveResponseWithVersion"
308
+ ]];
309
+ }
310
+
261
311
@end
0 commit comments