@@ -1382,6 +1382,105 @@ public function testGetResumeTokenReturnsOriginalResumeTokenOnEmptyBatch()
1382
1382
$ this ->assertSame ($ resumeToken , $ changeStream ->getResumeToken ());
1383
1383
}
1384
1384
1385
+ /**
1386
+ * Prose test: "$changeStream stage for ChangeStream started with startAfter
1387
+ * against a server >=4.1.1 that has not received any results yet MUST
1388
+ * include a startAfter option and MUST NOT include a resumeAfter option
1389
+ * when resuming a change stream."
1390
+ */
1391
+ public function testResumingChangeStreamWithoutPreviousResultsIncludesStartAfterOption ()
1392
+ {
1393
+ if (version_compare ($ this ->getServerVersion (), '4.1.1 ' , '< ' )) {
1394
+ $ this ->markTestSkipped ('Testing resumeAfter and startAfter can only be tested on servers >= 4.1.1 ' );
1395
+ }
1396
+
1397
+ $ operation = new Watch ($ this ->manager , $ this ->getDatabaseName (), $ this ->getCollectionName (), [], $ this ->defaultOptions );
1398
+ $ changeStream = $ operation ->execute ($ this ->getPrimaryServer ());
1399
+
1400
+ $ this ->insertDocument (['x ' => 1 ]);
1401
+
1402
+ $ changeStream ->next ();
1403
+ $ this ->assertTrue ($ changeStream ->valid ());
1404
+ $ resumeToken = $ changeStream ->getResumeToken ();
1405
+
1406
+ $ options = ['startAfter ' => $ resumeToken ] + $ this ->defaultOptions ;
1407
+ $ operation = new Watch ($ this ->manager , $ this ->getDatabaseName (), $ this ->getCollectionName (), [], $ options );
1408
+ $ changeStream = $ operation ->execute ($ this ->getPrimaryServer ());
1409
+ $ changeStream ->rewind ();
1410
+ $ this ->killChangeStreamCursor ($ changeStream );
1411
+
1412
+ $ aggregateCommand = null ;
1413
+
1414
+ (new CommandObserver )->observe (
1415
+ function () use ($ changeStream ) {
1416
+ $ changeStream ->next ();
1417
+ },
1418
+ function (array $ event ) use (&$ aggregateCommand ) {
1419
+ if ($ event ['started ' ]->getCommandName () !== 'aggregate ' ) {
1420
+ return ;
1421
+ }
1422
+
1423
+ $ aggregateCommand = $ event ['started ' ]->getCommand ();
1424
+ }
1425
+ );
1426
+
1427
+ $ this ->assertNotNull ($ aggregateCommand );
1428
+ $ this ->assertObjectNotHasAttribute ('resumeAfter ' , $ aggregateCommand ->pipeline [0 ]->{'$changeStream ' });
1429
+ $ this ->assertObjectHasAttribute ('startAfter ' , $ aggregateCommand ->pipeline [0 ]->{'$changeStream ' });
1430
+ }
1431
+
1432
+ /**
1433
+ * Prose test: "$changeStream stage for ChangeStream started with startAfter
1434
+ * against a server >=4.1.1 that has received at least one result MUST
1435
+ * include a resumeAfter option and MUST NOT include a startAfter option
1436
+ * when resuming a change stream."
1437
+ */
1438
+ public function testResumingChangeStreamWithPreviousResultsIncludesResumeAfterOption ()
1439
+ {
1440
+ if (version_compare ($ this ->getServerVersion (), '4.1.1 ' , '< ' )) {
1441
+ $ this ->markTestSkipped ('Testing resumeAfter and startAfter can only be tested on servers >= 4.1.1 ' );
1442
+ }
1443
+
1444
+ $ operation = new Watch ($ this ->manager , $ this ->getDatabaseName (), $ this ->getCollectionName (), [], $ this ->defaultOptions );
1445
+ $ changeStream = $ operation ->execute ($ this ->getPrimaryServer ());
1446
+
1447
+ $ this ->insertDocument (['x ' => 1 ]);
1448
+
1449
+ $ changeStream ->next ();
1450
+ $ this ->assertTrue ($ changeStream ->valid ());
1451
+ $ resumeToken = $ changeStream ->getResumeToken ();
1452
+
1453
+ $ options = ['startAfter ' => $ resumeToken ] + $ this ->defaultOptions ;
1454
+ $ operation = new Watch ($ this ->manager , $ this ->getDatabaseName (), $ this ->getCollectionName (), [], $ options );
1455
+ $ changeStream = $ operation ->execute ($ this ->getPrimaryServer ());
1456
+ $ changeStream ->rewind ();
1457
+
1458
+ $ this ->insertDocument (['x ' => 2 ]);
1459
+ $ changeStream ->next ();
1460
+ $ this ->assertTrue ($ changeStream ->valid ());
1461
+
1462
+ $ this ->killChangeStreamCursor ($ changeStream );
1463
+
1464
+ $ aggregateCommand = null ;
1465
+
1466
+ (new CommandObserver )->observe (
1467
+ function () use ($ changeStream ) {
1468
+ $ changeStream ->next ();
1469
+ },
1470
+ function (array $ event ) use (&$ aggregateCommand ) {
1471
+ if ($ event ['started ' ]->getCommandName () !== 'aggregate ' ) {
1472
+ return ;
1473
+ }
1474
+
1475
+ $ aggregateCommand = $ event ['started ' ]->getCommand ();
1476
+ }
1477
+ );
1478
+
1479
+ $ this ->assertNotNull ($ aggregateCommand );
1480
+ $ this ->assertObjectNotHasAttribute ('startAfter ' , $ aggregateCommand ->pipeline [0 ]->{'$changeStream ' });
1481
+ $ this ->assertObjectHasAttribute ('resumeAfter ' , $ aggregateCommand ->pipeline [0 ]->{'$changeStream ' });
1482
+ }
1483
+
1385
1484
private function assertNoCommandExecuted (callable $ callable )
1386
1485
{
1387
1486
$ commands = [];
0 commit comments