Thin MongoDB ODM built for Standard Schema
mongodb
zod
deno
1import { assert, assertEquals, assertExists } from "@std/assert";
2import {
3 connect,
4 type ConnectOptions,
5 disconnect,
6 healthCheck,
7} from "../mod.ts";
8import { MongoMemoryServer } from "mongodb-memory-server-core";
9
10let mongoServer: MongoMemoryServer | null = null;
11
12async function setupTestServer() {
13 if (!mongoServer) {
14 mongoServer = await MongoMemoryServer.create();
15 }
16 return mongoServer.getUri();
17}
18
19Deno.test.afterEach(async () => {
20 await disconnect();
21});
22
23Deno.test.afterAll(async () => {
24 if (mongoServer) {
25 await mongoServer.stop();
26 mongoServer = null;
27 }
28});
29
30Deno.test({
31 name: "Connection: Basic - should connect without options",
32 async fn() {
33 const uri = await setupTestServer();
34 const connection = await connect(uri, "test_db");
35
36 assert(connection);
37 assert(connection.client);
38 assert(connection.db);
39 assertEquals(connection.db.databaseName, "test_db");
40 },
41 sanitizeResources: false,
42 sanitizeOps: false,
43});
44
45Deno.test({
46 name: "Connection: Options - should connect with pooling options",
47 async fn() {
48 const uri = await setupTestServer();
49 const options: ConnectOptions = {
50 maxPoolSize: 10,
51 minPoolSize: 2,
52 maxIdleTimeMS: 30000,
53 connectTimeoutMS: 5000,
54 };
55
56 const connection = await connect(uri, "test_db", options);
57
58 assert(connection);
59 assert(connection.client);
60 assert(connection.db);
61
62 // Verify connection is working
63 const adminDb = connection.db.admin();
64 const serverStatus = await adminDb.serverStatus();
65 assert(serverStatus);
66 },
67 sanitizeResources: false,
68 sanitizeOps: false,
69});
70
71Deno.test({
72 name: "Connection: Singleton - should reuse existing connection",
73 async fn() {
74 const uri = await setupTestServer();
75
76 const connection1 = await connect(uri, "test_db");
77 const connection2 = await connect(uri, "test_db");
78
79 // Should return the same connection instance
80 assertEquals(connection1, connection2);
81 assertEquals(connection1.client, connection2.client);
82 assertEquals(connection1.db, connection2.db);
83 },
84 sanitizeResources: false,
85 sanitizeOps: false,
86});
87
88Deno.test({
89 name: "Connection: Disconnect - should disconnect and allow reconnection",
90 async fn() {
91 const uri = await setupTestServer();
92
93 const connection1 = await connect(uri, "test_db");
94 assert(connection1);
95
96 await disconnect();
97
98 // Should be able to reconnect
99 const connection2 = await connect(uri, "test_db");
100 assert(connection2);
101
102 // Should be a new connection instance
103 assert(connection1 !== connection2);
104 },
105 sanitizeResources: false,
106 sanitizeOps: false,
107});
108
109Deno.test({
110 name: "Connection: Options - should apply maxPoolSize option",
111 async fn() {
112 const uri = await setupTestServer();
113 const options: ConnectOptions = {
114 maxPoolSize: 5,
115 };
116
117 const connection = await connect(uri, "test_db", options);
118
119 // Verify connection works with custom pool size
120 const collections = await connection.db.listCollections().toArray();
121 assert(Array.isArray(collections));
122 },
123 sanitizeResources: false,
124 sanitizeOps: false,
125});
126
127Deno.test({
128 name:
129 "Connection: Multiple Databases - should handle different database names",
130 async fn() {
131 const uri = await setupTestServer();
132
133 // Connect to first database
134 const connection1 = await connect(uri, "db1");
135 assertEquals(connection1.db.databaseName, "db1");
136
137 // Disconnect first
138 await disconnect();
139
140 // Connect to second database
141 const connection2 = await connect(uri, "db2");
142 assertEquals(connection2.db.databaseName, "db2");
143 },
144 sanitizeResources: false,
145 sanitizeOps: false,
146});
147
148Deno.test({
149 name: "Health Check: should return unhealthy when not connected",
150 async fn() {
151 const result = await healthCheck();
152
153 assertEquals(result.healthy, false);
154 assertEquals(result.connected, false);
155 assertExists(result.error);
156 assert(result.error?.includes("No active connection"));
157 assertExists(result.timestamp);
158 assertEquals(result.responseTimeMs, undefined);
159 },
160 sanitizeResources: false,
161 sanitizeOps: false,
162});
163
164Deno.test({
165 name: "Health Check: should return healthy when connected",
166 async fn() {
167 const uri = await setupTestServer();
168 await connect(uri, "test_db");
169
170 const result = await healthCheck();
171
172 assertEquals(result.healthy, true);
173 assertEquals(result.connected, true);
174 assertExists(result.responseTimeMs);
175 assert(result.responseTimeMs! >= 0);
176 assertEquals(result.error, undefined);
177 assertExists(result.timestamp);
178 },
179 sanitizeResources: false,
180 sanitizeOps: false,
181});
182
183Deno.test({
184 name: "Health Check: should measure response time",
185 async fn() {
186 const uri = await setupTestServer();
187 await connect(uri, "test_db");
188
189 const result = await healthCheck();
190
191 assertEquals(result.healthy, true);
192 assertExists(result.responseTimeMs);
193 // Response time should be reasonable (less than 1 second for in-memory MongoDB)
194 assert(result.responseTimeMs! < 1000);
195 },
196 sanitizeResources: false,
197 sanitizeOps: false,
198});
199
200Deno.test({
201 name: "Health Check: should work multiple times consecutively",
202 async fn() {
203 const uri = await setupTestServer();
204 await connect(uri, "test_db");
205
206 // Run health check multiple times
207 const results = await Promise.all([
208 healthCheck(),
209 healthCheck(),
210 healthCheck(),
211 ]);
212
213 // All should be healthy
214 for (const result of results) {
215 assertEquals(result.healthy, true);
216 assertEquals(result.connected, true);
217 assertExists(result.responseTimeMs);
218 }
219 },
220 sanitizeResources: false,
221 sanitizeOps: false,
222});
223
224Deno.test({
225 name: "Health Check: should detect disconnection",
226 async fn() {
227 const uri = await setupTestServer();
228 await connect(uri, "test_db");
229
230 // First check should be healthy
231 let result = await healthCheck();
232 assertEquals(result.healthy, true);
233
234 // Disconnect
235 await disconnect();
236
237 // Second check should be unhealthy
238 result = await healthCheck();
239 assertEquals(result.healthy, false);
240 assertEquals(result.connected, false);
241 },
242 sanitizeResources: false,
243 sanitizeOps: false,
244});
245
246Deno.test({
247 name: "Connection: Retry Options - should accept retry configuration",
248 async fn() {
249 const uri = await setupTestServer();
250 const options: ConnectOptions = {
251 retryReads: true,
252 retryWrites: true,
253 serverSelectionTimeoutMS: 5000,
254 connectTimeoutMS: 5000,
255 };
256
257 const connection = await connect(uri, "test_db", options);
258
259 assert(connection);
260 assert(connection.client);
261 assert(connection.db);
262
263 // Verify connection works with retry options
264 const collections = await connection.db.listCollections().toArray();
265 assert(Array.isArray(collections));
266 },
267 sanitizeResources: false,
268 sanitizeOps: false,
269});
270
271Deno.test({
272 name: "Connection: Resilience Options - should accept full production config",
273 async fn() {
274 const uri = await setupTestServer();
275 const options: ConnectOptions = {
276 // Pooling
277 maxPoolSize: 10,
278 minPoolSize: 2,
279
280 // Retry logic
281 retryReads: true,
282 retryWrites: true,
283
284 // Timeouts
285 connectTimeoutMS: 10000,
286 socketTimeoutMS: 45000,
287 serverSelectionTimeoutMS: 10000,
288
289 // Resilience
290 maxIdleTimeMS: 30000,
291 heartbeatFrequencyMS: 10000,
292 };
293
294 const connection = await connect(uri, "test_db", options);
295
296 assert(connection);
297
298 // Verify connection is working
299 const adminDb = connection.db.admin();
300 const serverStatus = await adminDb.serverStatus();
301 assert(serverStatus);
302 },
303 sanitizeResources: false,
304 sanitizeOps: false,
305});