@@ -11,7 +11,8 @@ import {
11
11
type MongoClient ,
12
12
MongoClientBulkWriteError ,
13
13
MongoInvalidArgumentError ,
14
- MongoServerError
14
+ MongoServerError ,
15
+ type PkFactory
15
16
} from '../../mongodb' ;
16
17
import { filterForCommands } from '../shared' ;
17
18
@@ -1166,4 +1167,210 @@ describe('CRUD Prose Spec Tests', () => {
1166
1167
}
1167
1168
} ) ;
1168
1169
} ) ;
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
+ } ) ;
1169
1376
} ) ;
0 commit comments