@@ -379,20 +379,67 @@ public function testNoChangeAfterResumeBeforeInsert()
379
379
$ this ->assertMatchesDocument ($ expectedResult , $ changeStream ->current ());
380
380
}
381
381
382
- public function testResumeTokenIsUpdatedAfterResuming ()
382
+ public function testResumeMultipleTimesInSuccession ()
383
383
{
384
- $ this ->insertDocument (['_id ' => 1 ]);
384
+ $ operation = new CreateCollection ($ this ->getDatabaseName (), $ this ->getCollectionName ());
385
+ $ operation ->execute ($ this ->getPrimaryServer ());
385
386
386
387
$ operation = new Watch ($ this ->manager , $ this ->getDatabaseName (), $ this ->getCollectionName (), [], $ this ->defaultOptions );
387
388
$ changeStream = $ operation ->execute ($ this ->getPrimaryServer ());
388
389
390
+ /* Killing the cursor when there are no results will tests that neither
391
+ * the initial rewind() nor its resume attempt incremented the key. */
392
+ $ this ->killChangeStreamCursor ($ changeStream );
393
+
389
394
$ changeStream ->rewind ();
395
+ $ this ->assertFalse ($ changeStream ->valid ());
396
+ $ this ->assertNull ($ changeStream ->key ());
390
397
$ this ->assertNull ($ changeStream ->current ());
391
398
399
+ $ this ->insertDocument (['_id ' => 1 ]);
400
+
401
+ /* Killing the cursor a second time when there is a result will test
402
+ * that the resume attempt picks up the latest change. */
403
+ $ this ->killChangeStreamCursor ($ changeStream );
404
+
405
+ $ changeStream ->rewind ();
406
+ $ this ->assertTrue ($ changeStream ->valid ());
407
+ $ this ->assertSame (0 , $ changeStream ->key ());
408
+
409
+ $ expectedResult = [
410
+ '_id ' => $ changeStream ->current ()->_id ,
411
+ 'operationType ' => 'insert ' ,
412
+ 'fullDocument ' => ['_id ' => 1 ],
413
+ 'ns ' => ['db ' => $ this ->getDatabaseName (), 'coll ' => $ this ->getCollectionName ()],
414
+ 'documentKey ' => ['_id ' => 1 ],
415
+ ];
416
+
417
+ $ this ->assertMatchesDocument ($ expectedResult , $ changeStream ->current ());
418
+
419
+ /* Killing the cursor a second time will not trigger a resume until
420
+ * ChangeStream::next() is called. A successive call to rewind() should
421
+ * not change the iterator's state and preserve the current result. */
422
+ $ this ->killChangeStreamCursor ($ changeStream );
423
+
424
+ $ changeStream ->rewind ();
425
+ $ this ->assertTrue ($ changeStream ->valid ());
426
+ $ this ->assertSame (0 , $ changeStream ->key ());
427
+
428
+ $ expectedResult = [
429
+ '_id ' => $ changeStream ->current ()->_id ,
430
+ 'operationType ' => 'insert ' ,
431
+ 'fullDocument ' => ['_id ' => 1 ],
432
+ 'ns ' => ['db ' => $ this ->getDatabaseName (), 'coll ' => $ this ->getCollectionName ()],
433
+ 'documentKey ' => ['_id ' => 1 ],
434
+ ];
435
+
436
+ $ this ->assertMatchesDocument ($ expectedResult , $ changeStream ->current ());
437
+
392
438
$ this ->insertDocument (['_id ' => 2 ]);
393
439
394
440
$ changeStream ->next ();
395
441
$ this ->assertTrue ($ changeStream ->valid ());
442
+ $ this ->assertSame (1 , $ changeStream ->key ());
396
443
397
444
$ expectedResult = [
398
445
'_id ' => $ changeStream ->current ()->_id ,
@@ -410,6 +457,7 @@ public function testResumeTokenIsUpdatedAfterResuming()
410
457
411
458
$ changeStream ->next ();
412
459
$ this ->assertTrue ($ changeStream ->valid ());
460
+ $ this ->assertSame (2 , $ changeStream ->key ());
413
461
414
462
$ expectedResult = [
415
463
'_id ' => $ changeStream ->current ()->_id ,
@@ -431,6 +479,7 @@ public function testResumeTokenIsUpdatedAfterResuming()
431
479
432
480
$ changeStream ->next ();
433
481
$ this ->assertTrue ($ changeStream ->valid ());
482
+ $ this ->assertSame (3 , $ changeStream ->key ());
434
483
435
484
$ expectedResult = [
436
485
'_id ' => $ changeStream ->current ()->_id ,
0 commit comments