1
1
import { strict as assert } from 'assert' ;
2
2
import { expect } from 'chai' ;
3
3
import * as crypto from 'crypto' ;
4
+ import { once } from 'events' ;
4
5
import * as sinon from 'sinon' ;
5
6
import { PassThrough , Transform } from 'stream' ;
6
7
7
8
import {
8
9
ChangeStream ,
9
10
ChangeStreamOptions ,
10
11
Collection ,
12
+ Db ,
11
13
Long ,
12
14
MongoClient ,
13
15
MongoNetworkError ,
@@ -22,7 +24,7 @@ import {
22
24
TestBuilder ,
23
25
UnifiedTestSuiteBuilder
24
26
} from '../../tools/utils' ;
25
- import { delay , setupDatabase , withClient , withCursor } from '../shared' ;
27
+ import { delay , filterForCommands , setupDatabase , withClient , withCursor } from '../shared' ;
26
28
27
29
function withChangeStream (
28
30
callback : ( collection : Collection , changeStream : ChangeStream , done : Mocha . Done ) => void
@@ -1990,4 +1992,123 @@ describe('Change Streams', function () {
1990
1992
. toJSON ( )
1991
1993
)
1992
1994
. run ( ) ;
1995
+
1996
+ describe ( 'BSON Options' , function ( ) {
1997
+ let client : MongoClient ;
1998
+ let db : Db ;
1999
+ let collection : Collection ;
2000
+ let cs : ChangeStream ;
2001
+ beforeEach ( async function ( ) {
2002
+ client = await this . configuration . newClient ( { monitorCommands : true } ) . connect ( ) ;
2003
+ db = client . db ( 'db' ) ;
2004
+ collection = await db . createCollection ( 'collection' ) ;
2005
+ } ) ;
2006
+ afterEach ( async function ( ) {
2007
+ await db . dropCollection ( 'collection' ) ;
2008
+ await cs . close ( ) ;
2009
+ await client . close ( ) ;
2010
+ client = undefined ;
2011
+ db = undefined ;
2012
+ collection = undefined ;
2013
+ } ) ;
2014
+
2015
+ context ( 'promoteLongs' , ( ) => {
2016
+ context ( 'when set to true' , ( ) => {
2017
+ it ( 'does not convert Longs to numbers' , {
2018
+ metadata : { requires : { topology : '!single' } } ,
2019
+ test : async function ( ) {
2020
+ cs = collection . watch ( [ ] , { promoteLongs : true } ) ;
2021
+
2022
+ const willBeChange = once ( cs , 'change' ) . then ( args => args [ 0 ] ) ;
2023
+ await once ( cs . cursor , 'init' ) ;
2024
+
2025
+ const result = await collection . insertOne ( { a : Long . fromNumber ( 0 ) } ) ;
2026
+ expect ( result ) . to . exist ;
2027
+
2028
+ const change = await willBeChange ;
2029
+
2030
+ expect ( typeof change . fullDocument . a ) . to . equal ( 'number' ) ;
2031
+ }
2032
+ } ) ;
2033
+ } ) ;
2034
+
2035
+ context ( 'when set to false' , ( ) => {
2036
+ it ( 'converts Long values to native numbers' , {
2037
+ metadata : { requires : { topology : '!single' } } ,
2038
+ test : async function ( ) {
2039
+ cs = collection . watch ( [ ] , { promoteLongs : false } ) ;
2040
+
2041
+ const willBeChange = once ( cs , 'change' ) . then ( args => args [ 0 ] ) ;
2042
+ await once ( cs . cursor , 'init' ) ;
2043
+
2044
+ const result = await collection . insertOne ( { a : Long . fromNumber ( 0 ) } ) ;
2045
+ expect ( result ) . to . exist ;
2046
+
2047
+ const change = await willBeChange ;
2048
+ expect ( change ) . to . have . nested . property ( 'fullDocument.a' ) . that . is . instanceOf ( Long ) ;
2049
+ }
2050
+ } ) ;
2051
+ } ) ;
2052
+
2053
+ context ( 'when omitted' , ( ) => {
2054
+ it ( 'defaults to true' , {
2055
+ metadata : { requires : { topology : '!single' } } ,
2056
+ test : async function ( ) {
2057
+ cs = collection . watch ( [ ] ) ;
2058
+
2059
+ const willBeChange = once ( cs , 'change' ) . then ( args => args [ 0 ] ) ;
2060
+ await once ( cs . cursor , 'init' ) ;
2061
+
2062
+ const result = await collection . insertOne ( { a : Long . fromNumber ( 0 ) } ) ;
2063
+ expect ( result ) . to . exist ;
2064
+
2065
+ const change = await willBeChange ;
2066
+ expect ( typeof change . fullDocument . a ) . to . equal ( 'number' ) ;
2067
+ }
2068
+ } ) ;
2069
+ } ) ;
2070
+ } ) ;
2071
+
2072
+ context ( 'invalid options' , function ( ) {
2073
+ it ( 'does not send invalid options on the aggregate command' , {
2074
+ metadata : { requires : { topology : '!single' } } ,
2075
+ test : async function ( ) {
2076
+ const started = [ ] ;
2077
+
2078
+ client . on ( 'commandStarted' , filterForCommands ( [ 'aggregate' ] , started ) ) ;
2079
+ const doc = { invalidBSONOption : true } ;
2080
+ cs = collection . watch ( [ ] , doc ) ;
2081
+
2082
+ const willBeChange = once ( cs , 'change' ) . then ( args => args [ 0 ] ) ;
2083
+ await once ( cs . cursor , 'init' ) ;
2084
+
2085
+ const result = await collection . insertOne ( { a : Long . fromNumber ( 0 ) } ) ;
2086
+ expect ( result ) . to . exist ;
2087
+
2088
+ await willBeChange ;
2089
+ expect ( started [ 0 ] . command ) . not . to . haveOwnProperty ( 'invalidBSONOption' ) ;
2090
+ }
2091
+ } ) ;
2092
+
2093
+ it ( 'does not send invalid options on the getMore command' , {
2094
+ metadata : { requires : { topology : '!single' } } ,
2095
+ test : async function ( ) {
2096
+ const started = [ ] ;
2097
+
2098
+ client . on ( 'commandStarted' , filterForCommands ( [ 'aggregate' ] , started ) ) ;
2099
+ const doc = { invalidBSONOption : true } ;
2100
+ cs = collection . watch ( [ ] , doc ) ;
2101
+
2102
+ const willBeChange = once ( cs , 'change' ) . then ( args => args [ 0 ] ) ;
2103
+ await once ( cs . cursor , 'init' ) ;
2104
+
2105
+ const result = await collection . insertOne ( { a : Long . fromNumber ( 0 ) } ) ;
2106
+ expect ( result ) . to . exist ;
2107
+
2108
+ await willBeChange ;
2109
+ expect ( started [ 0 ] . command ) . not . to . haveOwnProperty ( 'invalidBSONOption' ) ;
2110
+ }
2111
+ } ) ;
2112
+ } ) ;
2113
+ } ) ;
1993
2114
} ) ;
0 commit comments