@objectql/driver-mongo 1.7.2 → 1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -220,4 +220,104 @@ describe('MongoDriver', () => {
220
220
  expect(results[0]).toEqual({ id: '456', name: 'Dave' });
221
221
  });
222
222
 
223
+ it('should handle nested filter groups', async () => {
224
+ const query = {
225
+ filters: [
226
+ [
227
+ ['status', '=', 'completed'],
228
+ 'and',
229
+ ['amount', '>', 100]
230
+ ],
231
+ 'or',
232
+ [
233
+ ['customer', '=', 'Alice'],
234
+ 'and',
235
+ ['status', '=', 'pending']
236
+ ]
237
+ ]
238
+ };
239
+ await driver.find('orders', query);
240
+
241
+ // Expected MongoDB query structure:
242
+ // { $or: [
243
+ // { $and: [{ status: { $eq: 'completed' } }, { amount: { $gt: 100 } }] },
244
+ // { $and: [{ customer: { $eq: 'Alice' } }, { status: { $eq: 'pending' } }] }
245
+ // ] }
246
+ expect(mockCollection.find).toHaveBeenCalledWith(
247
+ {
248
+ $or: [
249
+ { $and: [{ status: { $eq: 'completed' } }, { amount: { $gt: 100 } }] },
250
+ { $and: [{ customer: { $eq: 'Alice' } }, { status: { $eq: 'pending' } }] }
251
+ ]
252
+ },
253
+ expect.any(Object)
254
+ );
255
+ });
256
+
257
+ it('should handle deeply nested filter groups', async () => {
258
+ const query = {
259
+ filters: [
260
+ [
261
+ [
262
+ ['age', '>', 22],
263
+ 'and',
264
+ ['status', '=', 'active']
265
+ ],
266
+ 'or',
267
+ ['role', '=', 'admin']
268
+ ],
269
+ 'and',
270
+ ['name', '!=', 'Bob']
271
+ ]
272
+ };
273
+ await driver.find('users', query);
274
+
275
+ // Expected structure:
276
+ // { $and: [
277
+ // { $or: [
278
+ // { $and: [{ age: { $gt: 22 } }, { status: { $eq: 'active' } }] },
279
+ // { role: { $eq: 'admin' } }
280
+ // ] },
281
+ // { name: { $ne: 'Bob' } }
282
+ // ] }
283
+ expect(mockCollection.find).toHaveBeenCalledWith(
284
+ {
285
+ $and: [
286
+ {
287
+ $or: [
288
+ { $and: [{ age: { $gt: 22 } }, { status: { $eq: 'active' } }] },
289
+ { role: { $eq: 'admin' } }
290
+ ]
291
+ },
292
+ { name: { $ne: 'Bob' } }
293
+ ]
294
+ },
295
+ expect.any(Object)
296
+ );
297
+ });
298
+
299
+ it('should handle nested groups with implicit AND', async () => {
300
+ const query = {
301
+ filters: [
302
+ [
303
+ ['status', '=', 'active'],
304
+ ['role', '=', 'admin']
305
+ ],
306
+ ['age', '>', 25]
307
+ ]
308
+ };
309
+ await driver.find('users', query);
310
+
311
+ // Nested array without explicit 'and' should still be treated as AND
312
+ expect(mockCollection.find).toHaveBeenCalledWith(
313
+ {
314
+ $and: [
315
+ { $and: [{ status: { $eq: 'active' } }, { role: { $eq: 'admin' } }] },
316
+ { age: { $gt: 25 } }
317
+ ]
318
+ },
319
+ expect.any(Object)
320
+ );
321
+ });
322
+
223
323
  });
@@ -539,6 +539,68 @@ describe('MongoDriver Integration Tests', () => {
539
539
  expect(results.length).toBe(2);
540
540
  });
541
541
 
542
+ test('should handle nested filter groups', async () => {
543
+ // Create test data matching the SQL driver's advanced test
544
+ await driver.create('orders', { customer: 'Alice', product: 'Laptop', amount: 1200.00, quantity: 1, status: 'completed' });
545
+ await driver.create('orders', { customer: 'Bob', product: 'Mouse', amount: 25.50, quantity: 2, status: 'completed' });
546
+ await driver.create('orders', { customer: 'Alice', product: 'Keyboard', amount: 75.00, quantity: 1, status: 'pending' });
547
+ await driver.create('orders', { customer: 'Charlie', product: 'Monitor', amount: 350.00, quantity: 1, status: 'completed' });
548
+
549
+ // Nested filter: (status = 'completed' AND amount > 100) OR (customer = 'Alice' AND status = 'pending')
550
+ const results = await driver.find('orders', {
551
+ filters: [
552
+ [
553
+ ['status', '=', 'completed'],
554
+ 'and',
555
+ ['amount', '>', 100]
556
+ ],
557
+ 'or',
558
+ [
559
+ ['customer', '=', 'Alice'],
560
+ 'and',
561
+ ['status', '=', 'pending']
562
+ ]
563
+ ]
564
+ });
565
+
566
+ // Should match: Alice's Laptop (completed, 1200), Charlie's Monitor (completed, 350), Alice's Keyboard (pending)
567
+ expect(results.length).toBe(3);
568
+
569
+ const customers = results.map(r => r.customer).sort();
570
+ expect(customers).toEqual(['Alice', 'Alice', 'Charlie']);
571
+ });
572
+
573
+ test('should handle deeply nested filters', async () => {
574
+ await driver.create('users', { name: 'Alice', age: 25, status: 'active', role: 'admin' });
575
+ await driver.create('users', { name: 'Bob', age: 30, status: 'active', role: 'user' });
576
+ await driver.create('users', { name: 'Charlie', age: 20, status: 'inactive', role: 'user' });
577
+ await driver.create('users', { name: 'Dave', age: 35, status: 'active', role: 'admin' });
578
+
579
+ // Complex nested: ((age > 22 AND status = 'active') OR role = 'admin') AND name != 'Bob'
580
+ const results = await driver.find('users', {
581
+ filters: [
582
+ [
583
+ [
584
+ ['age', '>', 22],
585
+ 'and',
586
+ ['status', '=', 'active']
587
+ ],
588
+ 'or',
589
+ ['role', '=', 'admin']
590
+ ],
591
+ 'and',
592
+ ['name', '!=', 'Bob']
593
+ ]
594
+ });
595
+
596
+ // Should match: Alice (age>22 AND active), Dave (age>22 AND active AND admin)
597
+ // Should NOT match: Bob (excluded by name filter), Charlie (age<=22, inactive, not admin)
598
+ expect(results.length).toBe(2);
599
+ const names = results.map(r => r.name).sort();
600
+ expect(names).toEqual(['Alice', 'Dave']);
601
+ });
602
+
603
+
542
604
  test('should handle nin (not in) filter', async () => {
543
605
  await driver.create('users', { name: 'Alice', status: 'active' });
544
606
  await driver.create('users', { name: 'Bob', status: 'inactive' });