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