@@ -3,8 +3,11 @@ import * as sinon from 'sinon';
3
3
4
4
import {
5
5
BSON ,
6
+ BSONError ,
7
+ Collection ,
6
8
type MongoClient ,
7
9
MongoDBResponse ,
10
+ MongoError ,
8
11
MongoServerError ,
9
12
OpMsgResponse
10
13
} from '../../../mongodb' ;
@@ -153,3 +156,156 @@ describe('class MongoDBResponse', () => {
153
156
}
154
157
) ;
155
158
} ) ;
159
+
160
+ describe ( 'utf8 validation with cursors' , function ( ) {
161
+ let client : MongoClient ;
162
+ let collection : Collection ;
163
+
164
+ beforeEach ( async function ( ) {
165
+ client = this . configuration . newClient ( ) ;
166
+ await client . connect ( ) ;
167
+ const db = client . db ( "test" ) ;
168
+ collection = db . collection ( "invalidutf8" ) ;
169
+ } ) ;
170
+
171
+ afterEach ( async function ( ) {
172
+ await client . close ( ) ;
173
+ } ) ;
174
+
175
+ context ( 'when utf-8 validation is explicitly disabled' , function ( ) {
176
+ it ( 'documents can be read using a for-await loop without errors' , async function ( ) {
177
+ for await ( const doc of collection . find ( { } , { enableUtf8Validation : false } ) ) ;
178
+ } ) ;
179
+ it ( 'documents can be read using next() without errors' , async function ( ) {
180
+ const cursor = collection . find ( { } , { enableUtf8Validation : false } ) ;
181
+
182
+ while ( await cursor . hasNext ( ) ) {
183
+ await cursor . next ( ) ;
184
+ }
185
+ } ) ;
186
+
187
+ it ( 'documents can be read using toArray() without errors' , async function ( ) {
188
+ const cursor = collection . find ( { } , { enableUtf8Validation : false } ) ;
189
+ await cursor . toArray ( ) ;
190
+ } ) ;
191
+
192
+ it ( 'documents can be read using .stream() without errors' , async function ( ) {
193
+ const cursor = collection . find ( { } , { enableUtf8Validation : false } ) ;
194
+ await cursor . stream ( ) . toArray ( ) ;
195
+ } ) ;
196
+
197
+ it ( 'documents can be read with tryNext() without error' , async function ( ) {
198
+ const cursor = collection . find ( { } , { enableUtf8Validation : false } ) ;
199
+
200
+ while ( await cursor . hasNext ( ) ) {
201
+ await cursor . tryNext ( ) ;
202
+ }
203
+ } )
204
+ } )
205
+
206
+ async function expectReject ( fn : ( ) => Promise < void > , options ?: { regex ?: RegExp , errorClass } ) {
207
+ const regex = options ?. regex ?? / .* / ;
208
+ const errorClass = options ?. errorClass ?? MongoError ;
209
+ try {
210
+ await fn ( ) ;
211
+ expect . fail ( 'expected the provided callback function to reject, but it did not.' ) ;
212
+ } catch ( error ) {
213
+ expect ( error ) . to . match ( regex ) ;
214
+ expect ( error ) . to . be . instanceOf ( errorClass ) ;
215
+ }
216
+ }
217
+
218
+ context ( 'when utf-8 validation is explicitly enabled' , function ( ) {
219
+ it ( 'a for-await loop throw a BSON error' , async function ( ) {
220
+ await expectReject ( async ( ) => {
221
+ for await ( const doc of collection . find ( { } , { enableUtf8Validation : true } ) ) ;
222
+ } , { errorClass : BSONError , regex : / I n v a l i d U T F - 8 s t r i n g i n B S O N d o c u m e n t / } )
223
+ } ) ;
224
+ it ( 'next() throws a BSON error' , async function ( ) {
225
+ await expectReject ( async ( ) => {
226
+ const cursor = collection . find ( { } , { enableUtf8Validation : true } ) ;
227
+
228
+ while ( await cursor . hasNext ( ) ) {
229
+ await cursor . next ( ) ;
230
+ }
231
+ } , { errorClass : BSONError , regex : / I n v a l i d U T F - 8 s t r i n g i n B S O N d o c u m e n t / }
232
+ ) ;
233
+ } ) ;
234
+
235
+ it ( 'toArray() throws a BSON error' , async function ( ) {
236
+ await expectReject ( async ( ) => {
237
+ const cursor = collection . find ( { } , { enableUtf8Validation : true } ) ;
238
+ await cursor . toArray ( ) ;
239
+ } , { errorClass : BSONError , regex : / I n v a l i d U T F - 8 s t r i n g i n B S O N d o c u m e n t / }
240
+ ) ;
241
+
242
+ } ) ;
243
+
244
+ it ( '.stream() throws a BSONError' , async function ( ) {
245
+ await expectReject ( async ( ) => {
246
+ const cursor = collection . find ( { } , { enableUtf8Validation : true } ) ;
247
+ await cursor . stream ( ) . toArray ( ) ;
248
+ } , { errorClass : BSONError , regex : / I n v a l i d U T F - 8 s t r i n g i n B S O N d o c u m e n t / }
249
+ ) ;
250
+ } ) ;
251
+
252
+ it ( 'tryNext() throws a BSONError' , async function ( ) {
253
+ await expectReject ( async ( ) => {
254
+ const cursor = collection . find ( { } , { enableUtf8Validation : true } ) ;
255
+
256
+ while ( await cursor . hasNext ( ) ) {
257
+ await cursor . tryNext ( ) ;
258
+ }
259
+ } , { errorClass : BSONError , regex : / I n v a l i d U T F - 8 s t r i n g i n B S O N d o c u m e n t / }
260
+ ) ;
261
+
262
+ } )
263
+ } )
264
+
265
+ context ( 'utf-8 validation defaults to enabled' , function ( ) {
266
+ it ( 'a for-await loop throw a BSON error' , async function ( ) {
267
+ await expectReject ( async ( ) => {
268
+ for await ( const doc of collection . find ( { } ) ) ;
269
+ } , { errorClass : BSONError , regex : / I n v a l i d U T F - 8 s t r i n g i n B S O N d o c u m e n t / } )
270
+ } ) ;
271
+ it ( 'next() throws a BSON error' , async function ( ) {
272
+ await expectReject ( async ( ) => {
273
+ const cursor = collection . find ( { } ) ;
274
+
275
+ while ( await cursor . hasNext ( ) ) {
276
+ await cursor . next ( ) ;
277
+ }
278
+ } , { errorClass : BSONError , regex : / I n v a l i d U T F - 8 s t r i n g i n B S O N d o c u m e n t / }
279
+ ) ;
280
+ } ) ;
281
+
282
+ it ( 'toArray() throws a BSON error' , async function ( ) {
283
+ await expectReject ( async ( ) => {
284
+ const cursor = collection . find ( { } ) ;
285
+ await cursor . toArray ( ) ;
286
+ } , { errorClass : BSONError , regex : / I n v a l i d U T F - 8 s t r i n g i n B S O N d o c u m e n t / }
287
+ ) ;
288
+
289
+ } ) ;
290
+
291
+ it ( '.stream() throws a BSONError' , async function ( ) {
292
+ await expectReject ( async ( ) => {
293
+ const cursor = collection . find ( { } ) ;
294
+ await cursor . stream ( ) . toArray ( ) ;
295
+ } , { errorClass : BSONError , regex : / I n v a l i d U T F - 8 s t r i n g i n B S O N d o c u m e n t / }
296
+ ) ;
297
+ } ) ;
298
+
299
+ it ( 'tryNext() throws a BSONError' , async function ( ) {
300
+ await expectReject ( async ( ) => {
301
+ const cursor = collection . find ( { } ) ;
302
+
303
+ while ( await cursor . hasNext ( ) ) {
304
+ await cursor . tryNext ( ) ;
305
+ }
306
+ } , { errorClass : BSONError , regex : / I n v a l i d U T F - 8 s t r i n g i n B S O N d o c u m e n t / }
307
+ ) ;
308
+
309
+ } )
310
+ } )
311
+ } )
0 commit comments