feat(update): add aggregation pipeline updates and enforce immutable _id handling
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import * as smartdb from '../ts/index.js';
|
||||
import { MongoClient, Db, Collection } from 'mongodb';
|
||||
import { MongoClient, Db, Collection, ObjectId } from 'mongodb';
|
||||
|
||||
let server: smartdb.SmartdbServer;
|
||||
let client: MongoClient;
|
||||
@@ -252,6 +252,71 @@ tap.test('smartdb: update - upsert creates new document', async () => {
|
||||
expect(inserted!.email).toEqual('new@example.com');
|
||||
});
|
||||
|
||||
tap.test('smartdb: update - aggregation pipeline updateOne', async () => {
|
||||
const collection = db.collection('users');
|
||||
await collection.insertOne({ name: 'PipelineUser', source: 'alpha', legacy: true, visits: 2 });
|
||||
|
||||
const result = await collection.updateOne(
|
||||
{ name: 'PipelineUser' },
|
||||
[
|
||||
{ $set: { sourceCopy: '$source', pipelineStatus: 'updated' } },
|
||||
{ $unset: ['legacy'] },
|
||||
]
|
||||
);
|
||||
|
||||
expect(result.matchedCount).toEqual(1);
|
||||
expect(result.modifiedCount).toEqual(1);
|
||||
|
||||
const updated = await collection.findOne({ name: 'PipelineUser' });
|
||||
expect(updated).toBeTruthy();
|
||||
expect(updated!.sourceCopy).toEqual('alpha');
|
||||
expect(updated!.pipelineStatus).toEqual('updated');
|
||||
expect(updated!.legacy).toBeUndefined();
|
||||
});
|
||||
|
||||
tap.test('smartdb: update - aggregation pipeline upsert', async () => {
|
||||
const collection = db.collection('users');
|
||||
const result = await collection.updateOne(
|
||||
{ name: 'PipelineUpsert' },
|
||||
[
|
||||
{ $set: { email: 'pipeline@example.com', status: 'new', mirroredName: '$name' } },
|
||||
],
|
||||
{ upsert: true }
|
||||
);
|
||||
|
||||
expect(result.upsertedCount).toEqual(1);
|
||||
|
||||
const inserted = await collection.findOne({ name: 'PipelineUpsert' });
|
||||
expect(inserted).toBeTruthy();
|
||||
expect(inserted!.email).toEqual('pipeline@example.com');
|
||||
expect(inserted!.status).toEqual('new');
|
||||
expect(inserted!.mirroredName).toEqual('PipelineUpsert');
|
||||
});
|
||||
|
||||
tap.test('smartdb: update - cannot modify immutable _id through pipeline', async () => {
|
||||
const collection = db.collection('users');
|
||||
const inserted = await collection.insertOne({ name: 'ImmutableIdUser' });
|
||||
|
||||
let threw = false;
|
||||
try {
|
||||
await collection.updateOne(
|
||||
{ _id: inserted.insertedId },
|
||||
[
|
||||
{ $set: { _id: new ObjectId() } },
|
||||
]
|
||||
);
|
||||
} catch (err: any) {
|
||||
threw = true;
|
||||
expect(err.code).toEqual(66);
|
||||
}
|
||||
|
||||
expect(threw).toBeTrue();
|
||||
|
||||
const persisted = await collection.findOne({ _id: inserted.insertedId });
|
||||
expect(persisted).toBeTruthy();
|
||||
expect(persisted!.name).toEqual('ImmutableIdUser');
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Cursor Tests
|
||||
// ============================================================================
|
||||
@@ -306,6 +371,23 @@ tap.test('smartdb: findOneAndUpdate - returns updated document', async () => {
|
||||
expect(result!.status).toEqual('active');
|
||||
});
|
||||
|
||||
tap.test('smartdb: findOneAndUpdate - supports aggregation pipeline updates', async () => {
|
||||
const collection = db.collection('users');
|
||||
await collection.insertOne({ name: 'PipelineFindAndModify', sourceName: 'Finder' });
|
||||
|
||||
const result = await collection.findOneAndUpdate(
|
||||
{ name: 'PipelineFindAndModify' },
|
||||
[
|
||||
{ $set: { displayName: '$sourceName', mode: 'pipeline' } },
|
||||
],
|
||||
{ returnDocument: 'after' }
|
||||
);
|
||||
|
||||
expect(result).toBeTruthy();
|
||||
expect(result!.displayName).toEqual('Finder');
|
||||
expect(result!.mode).toEqual('pipeline');
|
||||
});
|
||||
|
||||
tap.test('smartdb: findOneAndDelete - returns deleted document', async () => {
|
||||
const collection = db.collection('users');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user