1
- 'use strict ';
1
+ import { expect } from 'chai ';
2
2
3
- const { expect } = require ( 'chai' ) ;
4
- const { Topology } = require ( '../../../src/sdam/topology' ) ;
5
- const { ClientSession } = require ( '../../../src/sessions' ) ;
6
- const { MongoNetworkError } = require ( '../../../src/error' ) ;
3
+ import { Collection , MongoClient , ServerSessionPool } from '../../../src' ;
4
+ import { MongoNetworkError } from '../../../src/error' ;
5
+ import { ClientSession } from '../../../src/sessions' ;
7
6
8
7
describe ( 'Transactions' , function ( ) {
9
8
describe ( 'withTransaction' , function ( ) {
10
- let session , sessionPool ;
11
- beforeEach ( ( ) => {
12
- const topology = new Topology ( 'localhost:27017' ) ;
9
+ let session : ClientSession ;
10
+ let sessionPool : ServerSessionPool ;
11
+ let client : MongoClient ;
12
+
13
+ beforeEach ( async function ( ) {
14
+ client = this . configuration . newClient ( ) ;
15
+ const topology = ( await client . connect ( ) ) . topology ;
13
16
sessionPool = topology . s . sessionPool ;
14
- session = new ClientSession ( topology , sessionPool ) ;
17
+ session = new ClientSession ( topology , sessionPool , { } ) ;
15
18
} ) ;
16
19
17
- afterEach ( ( ) => {
20
+ afterEach ( async ( ) => {
18
21
sessionPool . endAllPooledSessions ( ) ;
22
+ await client . close ( ) ;
19
23
} ) ;
20
24
21
25
it ( 'should provide a useful error if a Promise is not returned' , {
@@ -27,6 +31,7 @@ describe('Transactions', function () {
27
31
return false ;
28
32
}
29
33
34
+ // @ts -expect-error: Testing that a non promise returning function is handled correctly
30
35
expect ( ( ) => session . withTransaction ( fnThatDoesntReturnPromise ) ) . to . throw (
31
36
/ m u s t r e t u r n a P r o m i s e /
32
37
) ;
@@ -37,8 +42,7 @@ describe('Transactions', function () {
37
42
38
43
it ( 'should return readable error if promise rejected with no reason' , {
39
44
metadata : {
40
- requires : { topology : [ 'replicaset' , 'sharded' ] , mongodb : '>=4.0.2' } ,
41
- serverless : 'forbid'
45
+ requires : { topology : [ 'replicaset' , 'sharded' ] , mongodb : '>=4.2.0' , serverless : 'forbid' }
42
46
} ,
43
47
test : function ( done ) {
44
48
function fnThatReturnsBadPromise ( ) {
@@ -54,6 +58,73 @@ describe('Transactions', function () {
54
58
} ) ;
55
59
}
56
60
} ) ;
61
+
62
+ describe (
63
+ 'return value semantics' ,
64
+ { requires : { mongodb : '>=4.2.0' , topology : '!single' } } ,
65
+ ( ) => {
66
+ let client : MongoClient ;
67
+ let collection : Collection < { a : number } > ;
68
+
69
+ beforeEach ( async function ( ) {
70
+ client = this . configuration . newClient ( ) ;
71
+ await client . connect ( ) ;
72
+ collection = await client
73
+ . db ( 'withTransactionReturnType' )
74
+ . createCollection ( 'withTransactionReturnType' ) ;
75
+ } ) ;
76
+
77
+ afterEach ( async function ( ) {
78
+ await collection . drop ( ) ;
79
+ await client . close ( ) ;
80
+ } ) ;
81
+
82
+ it ( 'should return undefined when transaction is aborted explicitly' , async ( ) => {
83
+ const session = client . startSession ( ) ;
84
+
85
+ const withTransactionResult = await session
86
+ . withTransaction ( async session => {
87
+ await collection . insertOne ( { a : 1 } , { session } ) ;
88
+ await collection . findOne ( { a : 1 } , { session } ) ;
89
+ await session . abortTransaction ( ) ;
90
+ } )
91
+ . finally ( async ( ) => await session . endSession ( ) ) ;
92
+
93
+ expect ( withTransactionResult ) . to . be . undefined ;
94
+ } ) ;
95
+
96
+ it ( 'should return raw command when transaction is successfully committed' , async ( ) => {
97
+ const session = client . startSession ( ) ;
98
+
99
+ const withTransactionResult = await session
100
+ . withTransaction ( async session => {
101
+ await collection . insertOne ( { a : 1 } , { session } ) ;
102
+ await collection . findOne ( { a : 1 } , { session } ) ;
103
+ } )
104
+ . finally ( async ( ) => await session . endSession ( ) ) ;
105
+
106
+ expect ( withTransactionResult ) . to . exist ;
107
+ expect ( withTransactionResult ) . to . be . an ( 'object' ) ;
108
+ expect ( withTransactionResult ) . to . have . property ( 'ok' , 1 ) ;
109
+ } ) ;
110
+
111
+ it ( 'should throw when transaction is aborted due to an error' , async ( ) => {
112
+ const session = client . startSession ( ) ;
113
+
114
+ const withTransactionResult = await session
115
+ . withTransaction ( async session => {
116
+ await collection . insertOne ( { a : 1 } , { session } ) ;
117
+ await collection . findOne ( { a : 1 } , { session } ) ;
118
+ throw new Error ( "I don't wanna transact anymore!" ) ;
119
+ } )
120
+ . catch ( error => error )
121
+ . finally ( async ( ) => await session . endSession ( ) ) ;
122
+
123
+ expect ( withTransactionResult ) . to . be . instanceOf ( Error ) ;
124
+ expect ( withTransactionResult . message ) . to . equal ( "I don't wanna transact anymore!" ) ;
125
+ } ) ;
126
+ }
127
+ ) ;
57
128
} ) ;
58
129
59
130
describe ( 'startTransaction' , function ( ) {
@@ -137,7 +208,9 @@ describe('Transactions', function () {
137
208
138
209
coll . insertOne ( { b : 2 } , { session } , err => {
139
210
expect ( err ) . to . exist . and . to . be . an . instanceof ( MongoNetworkError ) ;
140
- expect ( err . hasErrorLabel ( 'TransientTransactionError' ) ) . to . be . true ;
211
+ if ( err instanceof MongoNetworkError ) {
212
+ expect ( err . hasErrorLabel ( 'TransientTransactionError' ) ) . to . be . true ;
213
+ }
141
214
142
215
session . abortTransaction ( ( ) => session . endSession ( ( ) => client . close ( done ) ) ) ;
143
216
} ) ;
0 commit comments