@@ -11,7 +11,8 @@ import {
1111 type MongoClient ,
1212 MongoClientBulkWriteError ,
1313 MongoInvalidArgumentError ,
14- MongoServerError
14+ MongoServerError ,
15+ type PkFactory
1516} from '../../mongodb' ;
1617import { filterForCommands } from '../shared' ;
1718
@@ -1166,4 +1167,210 @@ describe('CRUD Prose Spec Tests', () => {
11661167 }
11671168 } ) ;
11681169 } ) ;
1170+
1171+ describe ( '16. Generated document identifiers are the first field in their document' , function ( ) {
1172+ // Test that the driver generates document identifiers as the first field in their document.
1173+ // use the command started event to check for first key of document
1174+ // repeat for insertOne, insertMany, updateOne, updateMany, replaceOne, legacy bulkWrite and client bulkWrite.
1175+
1176+ let client : MongoClient ;
1177+ const commands : CommandStartedEvent [ ] = [ ] ;
1178+ let collection : Collection < { _id ?: number ; name : string ; age ?: number } > ;
1179+
1180+ beforeEach ( async function ( ) {
1181+ client = this . configuration . newClient ( { } , { monitorCommands : true } ) ;
1182+ await client . connect ( ) ;
1183+
1184+ await client . db ( 'identifier-test' ) . dropDatabase ( ) ;
1185+ collection = await client . db ( 'identifier-test' ) . createCollection ( 'collection' , {
1186+ pkFactory : {
1187+ incrementingId : 1 ,
1188+ createPk ( ) {
1189+ return this . incrementingId ++ ;
1190+ }
1191+ } as PkFactory
1192+ } ) ;
1193+ commands . length = 0 ;
1194+
1195+ client . on ( 'commandStarted' , ( event : CommandStartedEvent ) => commands . push ( event ) ) ;
1196+ } ) ;
1197+
1198+ afterEach ( async function ( ) {
1199+ commands . length = 0 ;
1200+ await client . close ( ) ;
1201+ } ) ;
1202+
1203+ describe ( 'when the driver generates the _id' , function ( ) {
1204+ describe ( 'insertOne' , function ( ) {
1205+ it ( 'generates _id as the first field' , async function ( ) {
1206+ await collection . insertOne ( { name : 'john doe' } ) ;
1207+
1208+ const [ { command } ] = commands ;
1209+ expect ( command ) . to . have . nested . property ( 'documents[0]._id' ) ;
1210+ expect ( Object . keys ( command . documents [ 0 ] ) ) . to . have . property ( '0' , '_id' ) ;
1211+ } ) ;
1212+ } ) ;
1213+
1214+ describe ( 'insertMany' , function ( ) {
1215+ it ( 'generates _id as the first field' , async function ( ) {
1216+ await collection . insertMany ( [ { name : 'john doe' } , { name : 'jane doe' } ] ) ;
1217+
1218+ const [ { command } ] = commands ;
1219+ expect ( command ) . to . have . nested . property ( 'documents[0]._id' ) ;
1220+ expect ( Object . keys ( command . documents [ 0 ] ) ) . to . have . property ( '0' , '_id' ) ;
1221+ expect ( command ) . to . have . nested . property ( 'documents[1]._id' ) ;
1222+ expect ( Object . keys ( command . documents [ 1 ] ) ) . to . have . property ( '0' , '_id' ) ;
1223+ } ) ;
1224+ } ) ;
1225+
1226+ describe ( 'legacy bulkWrite' , function ( ) {
1227+ it ( 'generates _id as the first field in documents' , async function ( ) {
1228+ await collection . bulkWrite ( [
1229+ { insertOne : { document : { name : 'john doe' } } } ,
1230+ { insertOne : { document : { name : 'jane doe' } } }
1231+ ] ) ;
1232+
1233+ const [ { command } ] = commands ;
1234+ expect ( command ) . to . have . nested . property ( 'documents[0]._id' ) ;
1235+ expect ( Object . keys ( command . documents [ 0 ] ) ) . to . have . property ( '0' , '_id' ) ;
1236+ expect ( command ) . to . have . nested . property ( 'documents[1]._id' ) ;
1237+ expect ( Object . keys ( command . documents [ 1 ] ) ) . to . have . property ( '0' , '_id' ) ;
1238+ } ) ;
1239+ } ) ;
1240+
1241+ describe ( 'client bulkWrite' , function ( ) {
1242+ it ( 'generates _id as the first field in documents' , async function ( ) {
1243+ await client . bulkWrite < { 'identifier-test.collection' : { _id : number ; name : string } } > ( [
1244+ {
1245+ name : 'insertOne' ,
1246+ namespace : 'identifier-test.collection' ,
1247+ document : { name : 'john doe' }
1248+ } ,
1249+ {
1250+ name : 'insertOne' ,
1251+ namespace : 'identifier-test.collection' ,
1252+ document : { name : 'jane doe' }
1253+ }
1254+ ] ) ;
1255+
1256+ const [ { command } ] = commands ;
1257+ expect ( command ) . to . have . nested . property ( 'ops[0].document._id' ) ;
1258+ expect ( Object . keys ( command . ops [ 0 ] . document ) ) . to . have . property ( '0' , '_id' ) ;
1259+ expect ( command ) . to . have . nested . property ( 'ops[1].document._id' ) ;
1260+ expect ( Object . keys ( command . ops [ 1 ] . document ) ) . to . have . property ( '0' , '_id' ) ;
1261+ } ) ;
1262+ } ) ;
1263+ } ) ;
1264+
1265+ describe ( 'when the user provides the _id' , function ( ) {
1266+ describe ( 'insertOne' , function ( ) {
1267+ it ( 'keeps _id in its original position' , async function ( ) {
1268+ await collection . insertOne ( { name : 'john doe' , _id : 1 } ) ;
1269+
1270+ const [ { command } ] = commands ;
1271+ expect ( command ) . to . have . nested . property ( 'documents[0]._id' ) ;
1272+ expect ( Object . keys ( command . documents [ 0 ] ) ) . to . have . property ( '1' , '_id' ) ;
1273+ } ) ;
1274+ } ) ;
1275+
1276+ describe ( 'insertMany' , function ( ) {
1277+ it ( 'keeps _id in its original position' , async function ( ) {
1278+ await collection . insertMany ( [
1279+ { name : 'john doe' , _id : 1 } ,
1280+ { name : 'jane doe' , _id : 2 }
1281+ ] ) ;
1282+
1283+ const [ { command } ] = commands ;
1284+ expect ( command ) . to . have . nested . property ( 'documents[0]._id' ) ;
1285+ expect ( Object . keys ( command . documents [ 0 ] ) ) . to . have . property ( '1' , '_id' ) ;
1286+ expect ( command ) . to . have . nested . property ( 'documents[1]._id' ) ;
1287+ expect ( Object . keys ( command . documents [ 1 ] ) ) . to . have . property ( '1' , '_id' ) ;
1288+ } ) ;
1289+ } ) ;
1290+
1291+ describe ( 'updateOne' , function ( ) {
1292+ it ( 'keeps _id in its original position in upserted document' , async function ( ) {
1293+ await collection . updateOne ( { name : 'john doe' , _id : 1 } , { $set : { } } , { upsert : true } ) ;
1294+
1295+ const [ { command } ] = commands ;
1296+ expect ( command ) . to . have . nested . property ( 'updates[0].q._id' ) ;
1297+ expect ( Object . keys ( command . updates [ 0 ] . q ) ) . to . have . property ( '1' , '_id' ) ;
1298+ } ) ;
1299+ } ) ;
1300+
1301+ describe ( 'updateMany' , function ( ) {
1302+ it ( 'keeps _id in its original position in upserted documents' , async function ( ) {
1303+ await collection . updateMany ( { name : 'john doe' , _id : 1 } , { $set : { } } , { upsert : true } ) ;
1304+
1305+ const [ { command } ] = commands ;
1306+ expect ( command ) . to . have . nested . property ( 'updates[0].q._id' ) ;
1307+ expect ( Object . keys ( command . updates [ 0 ] . q ) ) . to . have . property ( '1' , '_id' ) ;
1308+ } ) ;
1309+ } ) ;
1310+
1311+ describe ( 'replaceOne' , function ( ) {
1312+ it ( 'keeps _id in its original position in filter document' , async function ( ) {
1313+ await collection . replaceOne (
1314+ { name : 'john doe' , _id : 1 } ,
1315+ { name : 'john doe' , age : 30 } ,
1316+ { upsert : true }
1317+ ) ;
1318+
1319+ const [ { command } ] = commands ;
1320+ expect ( command ) . to . have . nested . property ( 'updates[0].q._id' ) ;
1321+ expect ( Object . keys ( command . updates [ 0 ] . q ) ) . to . have . property ( '1' , '_id' ) ;
1322+ } ) ;
1323+
1324+ it ( 'keeps _id in its original position in replacement document' , async function ( ) {
1325+ await collection . replaceOne (
1326+ { name : 'john doe' } ,
1327+ { name : 'john doe' , age : 30 , _id : 1 } ,
1328+ { upsert : true }
1329+ ) ;
1330+
1331+ const [ { command } ] = commands ;
1332+ expect ( command ) . to . have . nested . property ( 'updates[0].u._id' ) ;
1333+ expect ( Object . keys ( command . updates [ 0 ] . u ) ) . to . have . property ( '2' , '_id' ) ;
1334+ } ) ;
1335+ } ) ;
1336+
1337+ describe ( 'legacy bulkWrite' , function ( ) {
1338+ it ( 'keeps _id in its original position in documents' , async function ( ) {
1339+ await collection . bulkWrite ( [
1340+ { insertOne : { document : { name : 'john doe' , _id : 1 } } } ,
1341+ { insertOne : { document : { name : 'jane doe' , _id : 2 } } }
1342+ ] ) ;
1343+
1344+ const [ { command } ] = commands ;
1345+ expect ( command ) . to . have . nested . property ( 'documents[0]._id' ) ;
1346+ expect ( Object . keys ( command . documents [ 0 ] ) ) . to . have . property ( '1' , '_id' ) ;
1347+ expect ( command ) . to . have . nested . property ( 'documents[1]._id' ) ;
1348+ expect ( Object . keys ( command . documents [ 1 ] ) ) . to . have . property ( '1' , '_id' ) ;
1349+ } ) ;
1350+ } ) ;
1351+
1352+ describe ( 'client bulkWrite' , function ( ) {
1353+ it ( 'keeps _id in its original position in documents' , async function ( ) {
1354+ await client . bulkWrite < { 'identifier-test.collection' : { _id : number ; name : string } } > ( [
1355+ {
1356+ name : 'insertOne' ,
1357+ namespace : 'identifier-test.collection' ,
1358+ document : { name : 'john doe' , _id : 1 }
1359+ } ,
1360+ {
1361+ name : 'insertOne' ,
1362+ namespace : 'identifier-test.collection' ,
1363+ document : { name : 'jane doe' , _id : 2 }
1364+ }
1365+ ] ) ;
1366+
1367+ const [ { command } ] = commands ;
1368+ expect ( command ) . to . have . nested . property ( 'ops[0].document._id' ) ;
1369+ expect ( Object . keys ( command . ops [ 0 ] . document ) ) . to . have . property ( '1' , '_id' ) ;
1370+ expect ( command ) . to . have . nested . property ( 'ops[1].document._id' ) ;
1371+ expect ( Object . keys ( command . ops [ 1 ] . document ) ) . to . have . property ( '1' , '_id' ) ;
1372+ } ) ;
1373+ } ) ;
1374+ } ) ;
1375+ } ) ;
11691376} ) ;
0 commit comments