File tree 3 files changed +82
-2
lines changed
3 files changed +82
-2
lines changed Original file line number Diff line number Diff line change @@ -809,8 +809,11 @@ function hasAtomicOperators(doc) {
809
809
return doc . reduce ( ( err , u ) => err || hasAtomicOperators ( u ) , null ) ;
810
810
}
811
811
812
- const keys = Object . keys ( doc ) ;
813
- return keys . length > 0 && keys [ 0 ] [ 0 ] === '$' ;
812
+ return (
813
+ Object . keys ( typeof doc . toBSON !== 'function' ? doc : doc . toBSON ( ) )
814
+ . map ( k => k [ 0 ] )
815
+ . indexOf ( '$' ) >= 0
816
+ ) ;
814
817
}
815
818
816
819
module . exports = {
Original file line number Diff line number Diff line change @@ -1662,4 +1662,67 @@ describe('Bulk', function() {
1662
1662
) ;
1663
1663
} ) ;
1664
1664
} ) ;
1665
+
1666
+ it ( 'should enforce no atomic operators' , function ( ) {
1667
+ const client = this . configuration . newClient ( ) ;
1668
+ return client
1669
+ . connect ( )
1670
+ . then ( ( ) => {
1671
+ const collection = client . db ( ) . collection ( 'noAtomicOp' ) ;
1672
+ return collection
1673
+ . drop ( )
1674
+ . catch ( ignoreNsNotFound )
1675
+ . then ( ( ) => collection ) ;
1676
+ } )
1677
+ . then ( collection => {
1678
+ return collection . insertMany ( [ { a : 1 } , { a : 1 } , { a : 1 } ] ) . then ( ( ) => collection ) ;
1679
+ } )
1680
+ . then ( collection => {
1681
+ try {
1682
+ return collection . replaceOne ( { a : 1 } , { $atomic : 1 } ) ;
1683
+ } catch ( err ) {
1684
+ expect ( err ) . to . be . instanceOf (
1685
+ TypeError ,
1686
+ 'Replacement document must not use atomic operators'
1687
+ ) ;
1688
+ }
1689
+ } )
1690
+ . finally ( ( ) => {
1691
+ return client . close ( ) ;
1692
+ } ) ;
1693
+ } ) ;
1694
+
1695
+ it ( 'should respect toBSON conversion when checking for atomic operators' , function ( ) {
1696
+ const client = this . configuration . newClient ( ) ;
1697
+ return client
1698
+ . connect ( )
1699
+ . then ( ( ) => {
1700
+ const collection = client . db ( ) . collection ( 'noAtomicOp' ) ;
1701
+ return collection
1702
+ . drop ( )
1703
+ . catch ( ignoreNsNotFound )
1704
+ . then ( ( ) => collection ) ;
1705
+ } )
1706
+ . then ( collection => {
1707
+ return collection . insertMany ( [ { a : 1 } , { a : 1 } , { a : 1 } ] ) . then ( ( ) => collection ) ;
1708
+ } )
1709
+ . then ( collection => {
1710
+ try {
1711
+ return collection . replaceOne (
1712
+ { a : 1 } ,
1713
+ {
1714
+ $atomic : 1 ,
1715
+ toBSON ( ) {
1716
+ return { atomic : this . $atomic } ;
1717
+ }
1718
+ }
1719
+ ) ;
1720
+ } catch ( err ) {
1721
+ expect . fail ( ) ; // shouldn't throw any error
1722
+ }
1723
+ } )
1724
+ . finally ( ( ) => {
1725
+ return client . close ( ) ;
1726
+ } ) ;
1727
+ } ) ;
1665
1728
} ) ;
Original file line number Diff line number Diff line change 2
2
const eachAsync = require ( '../../lib/core/utils' ) . eachAsync ;
3
3
const makeInterruptableAsyncInterval = require ( '../../lib/utils' ) . makeInterruptableAsyncInterval ;
4
4
const now = require ( '../../lib/utils' ) . now ;
5
+ const hasAtomicOperators = require ( '../../lib/utils' ) . hasAtomicOperators ;
5
6
const expect = require ( 'chai' ) . expect ;
6
7
const sinon = require ( 'sinon' ) ;
7
8
@@ -163,4 +164,17 @@ describe('utils', function() {
163
164
this . clock . tick ( 250 ) ;
164
165
} ) ;
165
166
} ) ;
167
+
168
+ it ( 'should assert hasAtomicOperators and respect toBSON conversion' , function ( ) {
169
+ expect ( hasAtomicOperators ( { $key : 2.3 } ) ) . to . be . true ;
170
+ expect ( hasAtomicOperators ( { nonAtomic : 1 , $key : 2.3 } ) ) . to . be . true ;
171
+ expect (
172
+ hasAtomicOperators ( {
173
+ $key : 2.3 ,
174
+ toBSON ( ) {
175
+ return { key : this . $key } ;
176
+ }
177
+ } )
178
+ ) . to . be . false ;
179
+ } ) ;
166
180
} ) ;
You can’t perform that action at this time.
0 commit comments