@@ -4,11 +4,16 @@ import * as sinon from 'sinon';
4
4
5
5
import {
6
6
AbstractCursor ,
7
+ Collection ,
8
+ CommandFailedEvent ,
9
+ CommandSucceededEvent ,
7
10
type MongoClient ,
8
11
MongoError ,
12
+ MongoServerError ,
9
13
ObjectId ,
10
14
ReturnDocument
11
15
} from '../../mongodb' ;
16
+ import { type FailPoint } from '../../tools/utils' ;
12
17
import { assert as test } from '../shared' ;
13
18
14
19
// instanceof cannot be use reliably to detect the new models in js due to scoping and new
@@ -70,10 +75,72 @@ describe('CRUD API', function () {
70
75
await client . close ( ) ;
71
76
} ) ;
72
77
73
- it ( 'findOne calls cursor.close()' , async function ( ) {
74
- const spy = sinon . spy ( AbstractCursor . prototype , 'close' ) ;
75
- await client . db ( ) . collection ( 't' ) . findOne ( { } ) ;
76
- expect ( spy ) . to . be . calledOnce ;
78
+ describe ( 'findOne()' , ( ) => {
79
+ let client : MongoClient ;
80
+ let events ;
81
+ let collection : Collection < { _id : number } > ;
82
+
83
+ beforeEach ( async function ( ) {
84
+ client = this . configuration . newClient ( { monitorCommands : true } ) ;
85
+ events = [ ] ;
86
+ client . on ( 'commandSucceeded' , commandSucceeded =>
87
+ commandSucceeded . commandName === 'find' ? events . push ( commandSucceeded ) : null
88
+ ) ;
89
+ client . on ( 'commandFailed' , commandFailed =>
90
+ commandFailed . commandName === 'find' ? events . push ( commandFailed ) : null
91
+ ) ;
92
+
93
+ collection = client . db ( 'findOne' ) . collection ( 'findOne' ) ;
94
+ await collection . drop ( ) . catch ( ( ) => null ) ;
95
+ await collection . insertMany ( [ { _id : 1 } , { _id : 2 } ] ) ;
96
+ } ) ;
97
+
98
+ afterEach ( async ( ) => {
99
+ await collection . drop ( ) . catch ( ( ) => null ) ;
100
+ await client . close ( ) ;
101
+ } ) ;
102
+
103
+ describe ( 'when the operation succeeds' , ( ) => {
104
+ it ( 'the cursor for findOne is closed' , async function ( ) {
105
+ const spy = sinon . spy ( Collection . prototype , 'find' ) ;
106
+ const result = await collection . findOne ( { } ) ;
107
+ expect ( result ) . to . deep . equal ( { _id : 1 } ) ;
108
+ expect ( events . at ( 0 ) ) . to . be . instanceOf ( CommandSucceededEvent ) ;
109
+ expect ( spy . returnValues . at ( 0 ) ) . to . have . property ( 'closed' , true ) ;
110
+ } ) ;
111
+ } ) ;
112
+
113
+ describe ( 'when the find operation fails' , ( ) => {
114
+ beforeEach ( async ( ) => {
115
+ const failPoint : FailPoint = {
116
+ configureFailPoint : 'failCommand' ,
117
+ mode : 'alwaysOn' ,
118
+ data : {
119
+ failCommands : [ 'find' ] ,
120
+ // 1 == InternalError, but this value not important to the test
121
+ errorCode : 1
122
+ }
123
+ } ;
124
+ await client . db ( ) . admin ( ) . command ( failPoint ) ;
125
+ } ) ;
126
+
127
+ afterEach ( async ( ) => {
128
+ const failPoint : FailPoint = {
129
+ configureFailPoint : 'failCommand' ,
130
+ mode : 'off' ,
131
+ data : { failCommands : [ 'find' ] }
132
+ } ;
133
+ await client . db ( ) . admin ( ) . command ( failPoint ) ;
134
+ } ) ;
135
+
136
+ it ( 'the cursor for findOne is closed' , async function ( ) {
137
+ const spy = sinon . spy ( Collection . prototype , 'find' ) ;
138
+ const error = await collection . findOne ( { } ) . catch ( error => error ) ;
139
+ expect ( error ) . to . be . instanceOf ( MongoServerError ) ;
140
+ expect ( events . at ( 0 ) ) . to . be . instanceOf ( CommandFailedEvent ) ;
141
+ expect ( spy . returnValues . at ( 0 ) ) . to . have . property ( 'closed' , true ) ;
142
+ } ) ;
143
+ } ) ;
77
144
} ) ;
78
145
79
146
context ( 'when creating a cursor with find' , ( ) => {
0 commit comments