From fc5c801d88935656f9508675d747d404a812aa12 Mon Sep 17 00:00:00 2001
From: Neal Beeken <neal.beeken@mongodb.com>
Date: Mon, 28 Oct 2024 13:55:07 -0400
Subject: [PATCH] perf(NODE-6466): make _id appear first in document

---
 test/integration/crud/crud.prose.test.ts | 209 ++++++++++++++++++++++-
 1 file changed, 208 insertions(+), 1 deletion(-)

diff --git a/test/integration/crud/crud.prose.test.ts b/test/integration/crud/crud.prose.test.ts
index 8665d69a1f3..86379cf112c 100644
--- a/test/integration/crud/crud.prose.test.ts
+++ b/test/integration/crud/crud.prose.test.ts
@@ -11,7 +11,8 @@ import {
   type MongoClient,
   MongoClientBulkWriteError,
   MongoInvalidArgumentError,
-  MongoServerError
+  MongoServerError,
+  type PkFactory
 } from '../../mongodb';
 import { filterForCommands } from '../shared';
 
@@ -1166,4 +1167,210 @@ describe('CRUD Prose Spec Tests', () => {
       }
     });
   });
+
+  describe('16. Generated document identifiers are the first field in their document', function () {
+    // Test that the driver generates document identifiers as the first field in their document.
+    // use the command started event to check for first key of document
+    // repeat for insertOne, insertMany, updateOne, updateMany, replaceOne, legacy bulkWrite and client bulkWrite.
+
+    let client: MongoClient;
+    const commands: CommandStartedEvent[] = [];
+    let collection: Collection<{ _id?: number; name: string; age?: number }>;
+
+    beforeEach(async function () {
+      client = this.configuration.newClient({}, { monitorCommands: true });
+      await client.connect();
+
+      await client.db('identifier-test').dropDatabase();
+      collection = await client.db('identifier-test').createCollection('collection', {
+        pkFactory: {
+          incrementingId: 1,
+          createPk() {
+            return this.incrementingId++;
+          }
+        } as PkFactory
+      });
+      commands.length = 0;
+
+      client.on('commandStarted', (event: CommandStartedEvent) => commands.push(event));
+    });
+
+    afterEach(async function () {
+      commands.length = 0;
+      await client.close();
+    });
+
+    describe('when the driver generates the _id', function () {
+      describe('insertOne', function () {
+        it('generates _id as the first field', async function () {
+          await collection.insertOne({ name: 'john doe' });
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('documents[0]._id');
+          expect(Object.keys(command.documents[0])).to.have.property('0', '_id');
+        });
+      });
+
+      describe('insertMany', function () {
+        it('generates _id as the first field', async function () {
+          await collection.insertMany([{ name: 'john doe' }, { name: 'jane doe' }]);
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('documents[0]._id');
+          expect(Object.keys(command.documents[0])).to.have.property('0', '_id');
+          expect(command).to.have.nested.property('documents[1]._id');
+          expect(Object.keys(command.documents[1])).to.have.property('0', '_id');
+        });
+      });
+
+      describe('legacy bulkWrite', function () {
+        it('generates _id as the first field in documents', async function () {
+          await collection.bulkWrite([
+            { insertOne: { document: { name: 'john doe' } } },
+            { insertOne: { document: { name: 'jane doe' } } }
+          ]);
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('documents[0]._id');
+          expect(Object.keys(command.documents[0])).to.have.property('0', '_id');
+          expect(command).to.have.nested.property('documents[1]._id');
+          expect(Object.keys(command.documents[1])).to.have.property('0', '_id');
+        });
+      });
+
+      describe('client bulkWrite', function () {
+        it('generates _id as the first field in documents', async function () {
+          await client.bulkWrite<{ 'identifier-test.collection': { _id: number; name: string } }>([
+            {
+              name: 'insertOne',
+              namespace: 'identifier-test.collection',
+              document: { name: 'john doe' }
+            },
+            {
+              name: 'insertOne',
+              namespace: 'identifier-test.collection',
+              document: { name: 'jane doe' }
+            }
+          ]);
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('ops[0].document._id');
+          expect(Object.keys(command.ops[0].document)).to.have.property('0', '_id');
+          expect(command).to.have.nested.property('ops[1].document._id');
+          expect(Object.keys(command.ops[1].document)).to.have.property('0', '_id');
+        });
+      });
+    });
+
+    describe('when the user provides the _id', function () {
+      describe('insertOne', function () {
+        it('keeps _id in its original position', async function () {
+          await collection.insertOne({ name: 'john doe', _id: 1 });
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('documents[0]._id');
+          expect(Object.keys(command.documents[0])).to.have.property('1', '_id');
+        });
+      });
+
+      describe('insertMany', function () {
+        it('keeps _id in its original position', async function () {
+          await collection.insertMany([
+            { name: 'john doe', _id: 1 },
+            { name: 'jane doe', _id: 2 }
+          ]);
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('documents[0]._id');
+          expect(Object.keys(command.documents[0])).to.have.property('1', '_id');
+          expect(command).to.have.nested.property('documents[1]._id');
+          expect(Object.keys(command.documents[1])).to.have.property('1', '_id');
+        });
+      });
+
+      describe('updateOne', function () {
+        it('keeps _id in its original position in upserted document', async function () {
+          await collection.updateOne({ name: 'john doe', _id: 1 }, { $set: {} }, { upsert: true });
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('updates[0].q._id');
+          expect(Object.keys(command.updates[0].q)).to.have.property('1', '_id');
+        });
+      });
+
+      describe('updateMany', function () {
+        it('keeps _id in its original position in upserted documents', async function () {
+          await collection.updateMany({ name: 'john doe', _id: 1 }, { $set: {} }, { upsert: true });
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('updates[0].q._id');
+          expect(Object.keys(command.updates[0].q)).to.have.property('1', '_id');
+        });
+      });
+
+      describe('replaceOne', function () {
+        it('keeps _id in its original position in filter document', async function () {
+          await collection.replaceOne(
+            { name: 'john doe', _id: 1 },
+            { name: 'john doe', age: 30 },
+            { upsert: true }
+          );
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('updates[0].q._id');
+          expect(Object.keys(command.updates[0].q)).to.have.property('1', '_id');
+        });
+
+        it('keeps _id in its original position in replacement document', async function () {
+          await collection.replaceOne(
+            { name: 'john doe' },
+            { name: 'john doe', age: 30, _id: 1 },
+            { upsert: true }
+          );
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('updates[0].u._id');
+          expect(Object.keys(command.updates[0].u)).to.have.property('2', '_id');
+        });
+      });
+
+      describe('legacy bulkWrite', function () {
+        it('keeps _id in its original position in documents', async function () {
+          await collection.bulkWrite([
+            { insertOne: { document: { name: 'john doe', _id: 1 } } },
+            { insertOne: { document: { name: 'jane doe', _id: 2 } } }
+          ]);
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('documents[0]._id');
+          expect(Object.keys(command.documents[0])).to.have.property('1', '_id');
+          expect(command).to.have.nested.property('documents[1]._id');
+          expect(Object.keys(command.documents[1])).to.have.property('1', '_id');
+        });
+      });
+
+      describe('client bulkWrite', function () {
+        it('keeps _id in its original position in documents', async function () {
+          await client.bulkWrite<{ 'identifier-test.collection': { _id: number; name: string } }>([
+            {
+              name: 'insertOne',
+              namespace: 'identifier-test.collection',
+              document: { name: 'john doe', _id: 1 }
+            },
+            {
+              name: 'insertOne',
+              namespace: 'identifier-test.collection',
+              document: { name: 'jane doe', _id: 2 }
+            }
+          ]);
+
+          const [{ command }] = commands;
+          expect(command).to.have.nested.property('ops[0].document._id');
+          expect(Object.keys(command.ops[0].document)).to.have.property('1', '_id');
+          expect(command).to.have.nested.property('ops[1].document._id');
+          expect(Object.keys(command.ops[1].document)).to.have.property('1', '_id');
+        });
+      });
+    });
+  });
 });