Thin MongoDB ODM built for Standard Schema
mongodb zod deno

connection health checks

knotbin.com aaebb767 9add0dd1

verified
+519
PRODUCTION_READINESS_ASSESSMENT.md
···
+
# Production Readiness Assessment: Nozzle vs Mongoose
+
+
## Executive Summary
+
+
**Current Status: Not Ready for Production** ⚠️
+
+
Nozzle is a promising lightweight ODM with excellent type safety, but it lacks several critical features required for production use compared to Mongoose. It's suitable for small projects or prototypes but needs significant enhancements before replacing Mongoose in production environments.
+
+
---
+
+
## ✅ Strengths
+
+
### 1. **Type Safety**
+
- Excellent TypeScript integration with `InferModel` and `Input` (uses Zod's native types)
+
- Type-safe operations throughout
+
- Better type inference than Mongoose in many cases
+
- Leverages Zod's built-in `z.input<T>` for input types (handles defaults automatically)
+
+
### 2. **Clean API**
+
- Simple, intuitive API design
+
- No decorators or magic - explicit and predictable
+
- Minimal abstraction layer
+
+
### 3. **Schema Validation**
+
- Uses Zod for schema validation
+
- Validation on insert and update operations
+
- Type-safe schema definitions
+
+
### 4. **Modern Stack**
+
- Built on MongoDB native driver v6+
+
- Deno-first (can work with Node.js)
+
- Lightweight dependencies
+
+
---
+
+
## ❌ Critical Missing Features for Production
+
+
### 1. **Transactions** 🔴 CRITICAL
+
**Status:** Not implemented
+
+
**Impact:** Cannot perform multi-document atomic operations
+
+
**Mongoose Equivalent:**
+
```javascript
+
const session = await mongoose.startSession();
+
session.startTransaction();
+
try {
+
await UserModel.updateOne({...}, {...}, { session });
+
await OrderModel.create([...], { session });
+
await session.commitTransaction();
+
} catch (error) {
+
await session.abortTransaction();
+
}
+
```
+
+
**Required for:**
+
- Financial operations
+
- Multi-collection updates
+
- Data consistency guarantees
+
- Rollback capabilities
+
+
---
+
+
### 2. **Connection Management** 🔴 CRITICAL
+
**Status:** ⚠️ **IMPROVED** - Connection pooling options exposed, but still missing advanced features
+
+
**Current Features:**
+
- ✅ Connection pooling configuration exposed via `MongoClientOptions`
+
- ✅ Users can configure `maxPoolSize`, `minPoolSize`, `maxIdleTimeMS`, etc.
+
- ✅ All MongoDB driver connection options available
+
- ✅ Leverages MongoDB driver's built-in pooling (no custom implementation)
+
+
**Remaining Issues:**
+
- ⚠️ No connection retry logic
+
- ⚠️ No health checks
+
- ⚠️ No connection event handling
+
- ⚠️ Cannot connect to multiple databases (singleton pattern)
+
- ⚠️ No connection string validation
+
- ⚠️ No automatic reconnection on connection loss
+
+
**Mongoose Provides:**
+
- Automatic reconnection
+
- Connection pool management (similar to what we expose)
+
- Connection events (connected, error, disconnected)
+
- Multiple database support
+
- Connection options (readPreference, etc.)
+
+
**Production Impact:**
+
- Application crashes on connection loss (no automatic recovery)
+
- No monitoring capabilities
+
- Cannot use multiple databases in same application
+
+
**Usage Example:**
+
```typescript
+
await connect("mongodb://localhost:27017", "mydb", {
+
clientOptions: {
+
maxPoolSize: 10,
+
minPoolSize: 2,
+
maxIdleTimeMS: 30000,
+
connectTimeoutMS: 10000,
+
}
+
});
+
```
+
+
---
+
+
### 3. **Middleware/Hooks** 🔴 CRITICAL
+
**Status:** Not implemented
+
+
**Missing:**
+
- Pre/post save hooks
+
- Pre/post remove hooks
+
- Pre/post update hooks
+
- Pre/post find hooks
+
- Document methods
+
- Static methods
+
+
**Use Cases:**
+
- Password hashing before save
+
- Timestamp updates
+
- Audit logging
+
- Data transformation
+
- Business logic encapsulation
+
+
**Example Needed:**
+
```typescript
+
// Pre-save hook for password hashing
+
UserModel.pre('save', async function() {
+
if (this.isModified('password')) {
+
this.password = await hashPassword(this.password);
+
}
+
});
+
```
+
+
---
+
+
### 4. **Index Management** 🟡 IMPORTANT
+
**Status:** ✅ **IMPLEMENTED** - Comprehensive index management API
+
+
**Current Features:**
+
- ✅ `createIndex()` - Create single index with options (unique, sparse, TTL, etc.)
+
- ✅ `createIndexes()` - Create multiple indexes at once
+
- ✅ `dropIndex()` - Drop a single index
+
- ✅ `dropIndexes()` - Drop all indexes (except _id)
+
- ✅ `listIndexes()` - List all indexes on collection
+
- ✅ `getIndex()` - Get index information by name
+
- ✅ `indexExists()` - Check if index exists
+
- ✅ `syncIndexes()` - Synchronize indexes (create missing, update changed)
+
- ✅ Support for compound indexes
+
- ✅ Support for unique indexes
+
- ✅ Support for text indexes (via MongoDB driver)
+
- ✅ Support for geospatial indexes (via MongoDB driver)
+
- ✅ Comprehensive test coverage (index_test.ts)
+
+
**Remaining Gaps:**
+
- ⚠️ No schema-level index definition (indexes defined programmatically, not in Zod schema)
+
- ⚠️ No automatic index creation on model initialization
+
- ⚠️ No index migration utilities (though `syncIndexes` helps)
+
+
**Usage Example:**
+
```typescript
+
// Create a unique index
+
await UserModel.createIndex({ email: 1 }, { unique: true });
+
+
// Create compound index
+
await UserModel.createIndex({ name: 1, age: -1 });
+
+
// Sync indexes (useful for migrations)
+
await UserModel.syncIndexes([
+
{ key: { email: 1 }, name: "email_idx", unique: true },
+
{ key: { name: 1, age: -1 }, name: "name_age_idx" },
+
]);
+
```
+
+
---
+
+
### 5. **Update Validation** 🟡 IMPORTANT
+
**Status:** ✅ **IMPLEMENTED** - Now validates updates using `parsePartial`
+
+
**Current Behavior:**
+
```typescript
+
// ✅ Now validates update data!
+
await UserModel.updateOne({...}, { email: "invalid-email" }); // Throws validation error
+
```
+
+
**Implementation:**
+
- `parsePartial` function validates partial update data (model.ts:33-57)
+
- Both `update` and `updateOne` methods validate updates (model.ts:95-109)
+
- Uses schema's `partial()` method if available (e.g., Zod)
+
- Comprehensive tests confirm update validation works (validation_test.ts)
+
+
**Remaining Gaps:**
+
- No `setDefaultsOnInsert` option for updates
+
- No `runValidators` toggle option
+
- Validation errors still generic (not structured)
+
+
---
+
+
### 6. **Error Handling** 🟡 IMPORTANT
+
**Status:** Basic error handling
+
+
**Issues:**
+
- Generic Error types
+
- No custom error classes
+
- Poor error messages
+
- No error recovery strategies
+
- Validation errors not structured
+
+
**Mongoose Provides:**
+
- `ValidationError`
+
- `CastError`
+
- `MongoError`
+
- Detailed error paths
+
- Error recovery utilities
+
+
---
+
+
### 7. **Default Values** 🟡 IMPORTANT
+
**Status:** Partial support
+
+
**Current Issues:**
+
- Default values only work on insert if schema supports it
+
- No `setDefaultsOnInsert` for updates
+
- No function-based defaults with context
+
- No conditional defaults
+
+
---
+
+
### 8. **Relationships/Population** 🟡 IMPORTANT
+
**Status:** Not implemented
+
+
**Missing:**
+
- Document references
+
- Population (join-like queries)
+
- Virtual populate
+
- Embedded documents management
+
+
**Impact:**
+
- Manual joins required
+
- N+1 query problems
+
- No relationship validation
+
- Complex manual relationship management
+
+
---
+
+
### 9. **Query Building** 🟢 NICE TO HAVE
+
**Status:** Basic MongoDB queries + pagination helper
+
+
**Current Features:**
+
- ✅ `findPaginated` method with skip, limit, and sort options (model.ts:138-149)
+
- Basic MongoDB queries
+
+
**Still Missing:**
+
- Query builder API (fluent interface)
+
- Query helpers
+
- Query middleware
+
- Query optimization hints
+
+
**Mongoose Provides:**
+
```javascript
+
UserModel.find()
+
.where('age').gte(18)
+
.where('name').equals('John')
+
.select('name email')
+
.limit(10)
+
.sort({ createdAt: -1 })
+
```
+
+
---
+
+
### 10. **Plugins** 🟢 NICE TO HAVE
+
**Status:** Not implemented
+
+
**Missing:**
+
- Plugin system
+
- Reusable functionality
+
- Ecosystem support
+
+
---
+
+
### 11. **Testing & Documentation** 🟡 IMPORTANT
+
**Status:** ✅ **IMPROVED** - More comprehensive tests added
+
+
**Current Coverage:**
+
- ✅ CRUD operations (crud_test.ts)
+
- ✅ Update validation (validation_test.ts)
+
- ✅ Default values (features_test.ts)
+
- ✅ Schema validation on insert
+
- ✅ Update validation with various scenarios
+
+
**Still Missing:**
+
- Performance tests
+
- Edge case testing (connection failures, concurrent operations)
+
- API documentation
+
- Migration guides
+
- Best practices guide
+
+
---
+
+
### 12. **Production Features** 🔴 CRITICAL
+
**Missing:**
+
- Connection retry logic
+
- Graceful shutdown
+
- Health check endpoints
+
- Monitoring hooks
+
- Performance metrics
+
- Query logging
+
- Slow query detection
+
+
---
+
+
## 🔍 Code Quality Issues
+
+
### 1. **Error Messages**
+
```typescript
+
// Current: Generic error
+
throw new Error(`Validation failed: ${JSON.stringify(result.issues)}`);
+
+
// Should be: Structured error with details
+
throw new ValidationError(result.issues, schema);
+
```
+
+
### 2. **Type Safety Gaps**
+
```typescript
+
// This cast is unsafe
+
validatedData as OptionalUnlessRequiredId<Infer<T>>
+
```
+
+
### 3. **No Input Sanitization**
+
- No protection against NoSQL injection
+
- No query sanitization
+
- Direct MongoDB query passthrough
+
+
### 4. **Connection State Management**
+
```typescript
+
// No way to check if connected
+
// No way to reconnect
+
// No connection state events
+
```
+
+
### 5. **Async Validation Not Supported**
+
```typescript
+
if (result instanceof Promise) {
+
throw new Error("Async validation not supported");
+
}
+
```
+
+
---
+
+
## 📊 Feature Comparison Matrix
+
+
| Feature | Nozzle | Mongoose | Production Critical |
+
|---------|--------|----------|-------------------|
+
| Basic CRUD | ✅ | ✅ | ✅ |
+
| Type Safety | ✅✅ | ✅ | ✅ |
+
| Schema Validation | ✅ | ✅✅ | ✅ |
+
| Transactions | ❌ | ✅ | 🔴 |
+
| Middleware/Hooks | ❌ | ✅ | 🔴 |
+
| Index Management | ✅ | ✅ | 🟡 |
+
| Update Validation | ✅ | ✅ | 🟡 |
+
| Relationships | ❌ | ✅ | 🟡 |
+
| Connection Management | ⚠️ | ✅ | 🔴 |
+
| Error Handling | ⚠️ | ✅ | 🟡 |
+
| Plugins | ❌ | ✅ | 🟢 |
+
| Query Builder | ⚠️ | ✅ | 🟢 |
+
| Pagination | ✅ | ✅ | 🟢 |
+
| Default Values | ⚠️ | ✅ | 🟡 |
+
| Virtual Fields | ❌ | ✅ | 🟢 |
+
| Methods/Statics | ❌ | ✅ | 🟡 |
+
+
**Legend:**
+
- ✅ = Fully implemented
+
- ✅✅ = Better than Mongoose
+
- ⚠️ = Partially implemented
+
- ❌ = Not implemented
+
- 🔴 = Critical for production
+
- 🟡 = Important for production
+
- 🟢 = Nice to have
+
+
---
+
+
## 🎯 Recommendations
+
+
### For Production Use
+
+
**Do NOT use Nozzle in production if you need:**
+
1. Transactions
+
2. Complex relationships
+
3. Robust connection management
+
4. Middleware/hooks
+
5. Enterprise-level features
+
+
**Consider Nozzle if:**
+
1. Building a simple CRUD API
+
2. Type safety is paramount
+
3. Minimal abstraction desired
+
4. Small to medium projects
+
5. Prototyping/MVP stage
+
+
### Migration Path
+
+
If you want to make Nozzle production-ready:
+
+
**Phase 1: Critical (Must Have)**
+
1. ❌ Implement transactions
+
2. ❌ Add connection retry logic
+
3. ❌ Improve error handling
+
4. ✅ **COMPLETED** - Add update validation
+
5. ❌ Connection health checks
+
+
**Phase 2: Important (Should Have)**
+
1. ❌ Middleware/hooks system
+
2. ✅ **COMPLETED** - Index management
+
3. ⚠️ Better default value handling (works via schema defaults)
+
4. ❌ Relationship support
+
5. ⚠️ Comprehensive testing (improved, but needs more edge cases)
+
+
**Phase 3: Enhancement (Nice to Have)**
+
1. ✅ Plugin system
+
2. ✅ Query builder
+
3. ✅ Virtual fields
+
4. ✅ Methods/statics
+
5. ✅ Performance optimizations
+
+
---
+
+
## 📈 Production Readiness Score
+
+
| Category | Score | Weight | Weighted Score |
+
|----------|-------|--------|----------------|
+
| Core Functionality | 8/10 | 20% | 1.6 |
+
| Type Safety | 9/10 | 15% | 1.35 |
+
| Error Handling | 4/10 | 15% | 0.6 |
+
| Connection Management | 3/10 | 15% | 0.45 |
+
| Advanced Features | 2/10 | 20% | 0.4 |
+
| Testing & Docs | 6/10 | 10% | 0.6 |
+
| Production Features | 2/10 | 5% | 0.1 |
+
+
**Overall Score: 5.1/10** (Not Production Ready)
+
+
**Mongoose Equivalent Score: ~8.5/10**
+
+
---
+
+
## 🚀 Conclusion
+
+
Nozzle is an excellent **proof of concept** and **development tool** with superior type safety, but it's **not ready to replace Mongoose in production** without significant development work.
+
+
**Estimated effort to reach production parity:** 3-6 months of full-time development
+
+
**Recommendation:** Use Mongoose for production, or invest heavily in Nozzle development before considering it as a replacement.
+
+
---
+
+
## 📝 Specific Code Issues Found
+
+
1. **model.ts:28** - Generic error messages, no structured error types
+
2. **model.ts:24-26** - Async validation explicitly unsupported (throws error)
+
3. **model.ts:71, 78, 118** - Unsafe type casting (`as OptionalUnlessRequiredId`)
+
4. ✅ **FIXED** - **model.ts:95-109** - Update operations now validate input via `parsePartial`
+
5. ✅ **FIXED** - All update methods (`update`, `updateOne`, `replaceOne`) now validate consistently
+
-6. **client.ts** - No connection options (pool size, timeouts, retry logic)
+
+6. ✅ **IMPROVED** - **client.ts** - Connection pooling options now exposed via `MongoClientOptions` (but still no retry logic)
+
7. **client.ts** - No way to reconnect if connection is lost
+
8. **client.ts** - Singleton pattern prevents multiple database connections
+
9. **No transaction support** - Critical for data consistency
+
10. **No query sanitization** - Direct MongoDB query passthrough (potential NoSQL injection)
+
11. ✅ **FIXED** - Removed `InsertType` in favor of Zod's native `z.input<T>` which handles defaults generically
+
12. **No error recovery** - Application will crash on connection loss
+
+
## 🆕 Recent Improvements
+
+
5. ✅ **Connection Pooling Exposed** (client.ts)
+
- Connection pooling options now available via `MongoClientOptions`
+
- Users can configure all MongoDB driver connection options
+
- Comprehensive test coverage (connection_test.ts)
+
+
1. ✅ **Update Validation Implemented** (model.ts:33-57, 95-109)
+
- `parsePartial` function validates partial update data
+
- Both `update` and `updateOne` methods now validate
+
- Comprehensive test coverage added
+
+
2. ✅ **Pagination Support Added** (model.ts:138-149)
+
- `findPaginated` method with skip, limit, and sort options
+
- Convenient helper for common pagination needs
+
+
3. ✅ **Index Management Implemented** (model.ts:147-250)
+
- Full index management API: createIndex, createIndexes, dropIndex, dropIndexes
+
- Index querying: listIndexes, getIndex, indexExists
+
- Index synchronization: syncIndexes for migrations
+
- Support for all MongoDB index types (unique, compound, text, geospatial)
+
- Comprehensive test coverage (index_test.ts)
+
+
4. ✅ **Enhanced Test Coverage**
+
- CRUD operations testing
+
- Update validation testing
+
- Default values testing
+
- Index management testing
+
+
---
+
+
*Assessment Date: 2024*
+
*Last Updated: 2024*
+
*Assessed by: AI Code Review*
+
*Version: 0.2.0*
+
+
## 📋 Changelog
+
+
### Version 0.2.0 (Latest)
+
- ✅ Update validation now implemented
+
- ✅ Pagination support added (`findPaginated`)
+
- ✅ Index management implemented
+
- ✅ Connection pooling options exposed
+
- ✅ Enhanced test coverage
+
- Updated scores and feature matrix
+
- Fixed incorrect code issue reports
+
+
### Version 0.1.0 (Initial)
+
- Initial production readiness assessment
+27
README.md
···
---
+
## 🗺️ Roadmap
+
+
### 🔴 Critical (Must Have)
+
- [ ] Transactions support
+
- [ ] Connection retry logic
+
- [ ] Improved error handling
+
- [x] Connection health checks
+
- [x] Connection pooling configuration
+
+
### 🟡 Important (Should Have)
+
- [x] Index management
+
- [ ] Middleware/hooks system
+
- [ ] Relationship/population support
+
- [ ] Better default value handling
+
- [ ] Comprehensive edge case testing
+
+
### 🟢 Nice to Have
+
- [x] Pagination support
+
- [ ] Plugin system
+
- [ ] Query builder API
+
- [ ] Virtual fields
+
- [ ] Document/static methods
+
+
For detailed production readiness assessment, see [PRODUCTION_READINESS_ASSESSMENT.md](./PRODUCTION_READINESS_ASSESSMENT.md).
+
+
---
+
## 📄 License
MIT — use it freely and contribute back if you'd like!
+79 -17
client.ts
···
let connection: Connection | null = null;
-
export interface ConnectOptions {
-
/**
-
* MongoDB connection options (pooling, timeouts, etc.)
-
* See: https://mongodb.github.io/node-mongodb-native/6.18/interfaces/MongoClientOptions.html
-
*/
-
clientOptions?: MongoClientOptions;
+
export interface ConnectOptions extends MongoClientOptions {};
+
+
/**
+
* Health check details of the MongoDB connection
+
*
+
* @property healthy - Overall health status of the connection
+
* @property connected - Whether a connection is established
+
* @property responseTimeMs - Response time in milliseconds (if connection is healthy)
+
* @property error - Error message if health check failed
+
* @property timestamp - Timestamp when health check was performed
+
*/
+
export interface HealthCheckResult {
+
healthy: boolean;
+
connected: boolean;
+
responseTimeMs?: number;
+
error?: string;
+
timestamp: Date;
}
/**
-
* Connect to MongoDB with connection pooling and other options
+
* Connect to MongoDB with options including connection pooling
*
-
* The MongoDB driver handles connection pooling automatically.
-
* Configure pooling via `clientOptions`:
+
* @param uri - MongoDB connection string
+
* @param dbName - Name of the database to connect to
+
* @param options - Connection options including connection pooling
*
* @example
* ```ts
* await connect("mongodb://localhost:27017", "mydb", {
-
* clientOptions: {
-
* maxPoolSize: 10, // Maximum connections in pool
-
* minPoolSize: 2, // Minimum connections in pool
-
* maxIdleTimeMS: 30000, // Close idle connections after 30s
-
* connectTimeoutMS: 10000, // Connection timeout
-
* socketTimeoutMS: 45000, // Socket timeout
-
* }
+
* maxPoolSize: 10,
+
* minPoolSize: 2,
+
* maxIdleTimeMS: 30000,
+
* connectTimeoutMS: 10000,
+
* socketTimeoutMS: 45000,
* });
* ```
*/
···
return connection;
}
-
const client = new MongoClient(uri, options?.clientOptions);
+
const client = new MongoClient(uri, options);
await client.connect();
const db = client.db(dbName);
···
}
return connection.db;
}
+
+
/**
+
* Check the health of the MongoDB connection
+
*
+
* Performs a ping operation to verify the database is responsive
+
* and returns detailed health information including response time.
+
*
+
* @example
+
* ```ts
+
* const health = await healthCheck();
+
* if (health.healthy) {
+
* console.log(`Database healthy (${health.responseTimeMs}ms)`);
+
* } else {
+
* console.error(`Database unhealthy: ${health.error}`);
+
* }
+
* ```
+
*/
+
export async function healthCheck(): Promise<HealthCheckResult> {
+
const timestamp = new Date();
+
+
// Check if connection exists
+
if (!connection) {
+
return {
+
healthy: false,
+
connected: false,
+
error: "No active connection. Call connect() first.",
+
timestamp,
+
};
+
}
+
+
try {
+
// Measure ping response time
+
const startTime = performance.now();
+
await connection.db.admin().ping();
+
const endTime = performance.now();
+
const responseTimeMs = Math.round(endTime - startTime);
+
+
return {
+
healthy: true,
+
connected: true,
+
responseTimeMs,
+
timestamp,
+
};
+
} catch (error) {
+
return {
+
healthy: false,
+
connected: true,
+
error: error instanceof Error ? error.message : String(error),
+
timestamp,
+
};
+
}
+
}
+1 -1
mod.ts
···
export { type InferModel, type Input } from "./schema.ts";
-
export { connect, disconnect, type ConnectOptions } from "./client.ts";
+
export { connect, disconnect, healthCheck, type ConnectOptions, type HealthCheckResult } from "./client.ts";
export { Model } from "./model.ts";
+105 -11
tests/connection_test.ts
···
-
import { assert, assertEquals } from "@std/assert";
-
import { connect, disconnect, type ConnectOptions } from "../mod.ts";
+
import { assert, assertEquals, assertExists } from "@std/assert";
+
import { connect, disconnect, healthCheck, type ConnectOptions } from "../mod.ts";
import { MongoMemoryServer } from "mongodb-memory-server-core";
let mongoServer: MongoMemoryServer | null = null;
···
async fn() {
const uri = await setupTestServer();
const options: ConnectOptions = {
-
clientOptions: {
-
maxPoolSize: 10,
-
minPoolSize: 2,
-
maxIdleTimeMS: 30000,
-
connectTimeoutMS: 5000,
-
},
+
maxPoolSize: 10,
+
minPoolSize: 2,
+
maxIdleTimeMS: 30000,
+
connectTimeoutMS: 5000,
};
const connection = await connect(uri, "test_db", options);
···
async fn() {
const uri = await setupTestServer();
const options: ConnectOptions = {
-
clientOptions: {
-
maxPoolSize: 5,
-
},
+
maxPoolSize: 5,
};
const connection = await connect(uri, "test_db", options);
···
sanitizeOps: false,
});
+
Deno.test({
+
name: "Health Check: should return unhealthy when not connected",
+
async fn() {
+
const result = await healthCheck();
+
+
assertEquals(result.healthy, false);
+
assertEquals(result.connected, false);
+
assertExists(result.error);
+
assert(result.error?.includes("No active connection"));
+
assertExists(result.timestamp);
+
assertEquals(result.responseTimeMs, undefined);
+
},
+
sanitizeResources: false,
+
sanitizeOps: false,
+
});
+
+
Deno.test({
+
name: "Health Check: should return healthy when connected",
+
async fn() {
+
const uri = await setupTestServer();
+
await connect(uri, "test_db");
+
+
const result = await healthCheck();
+
+
assertEquals(result.healthy, true);
+
assertEquals(result.connected, true);
+
assertExists(result.responseTimeMs);
+
assert(result.responseTimeMs! >= 0);
+
assertEquals(result.error, undefined);
+
assertExists(result.timestamp);
+
},
+
sanitizeResources: false,
+
sanitizeOps: false,
+
});
+
+
Deno.test({
+
name: "Health Check: should measure response time",
+
async fn() {
+
const uri = await setupTestServer();
+
await connect(uri, "test_db");
+
+
const result = await healthCheck();
+
+
assertEquals(result.healthy, true);
+
assertExists(result.responseTimeMs);
+
// Response time should be reasonable (less than 1 second for in-memory MongoDB)
+
assert(result.responseTimeMs! < 1000);
+
},
+
sanitizeResources: false,
+
sanitizeOps: false,
+
});
+
+
Deno.test({
+
name: "Health Check: should work multiple times consecutively",
+
async fn() {
+
const uri = await setupTestServer();
+
await connect(uri, "test_db");
+
+
// Run health check multiple times
+
const results = await Promise.all([
+
healthCheck(),
+
healthCheck(),
+
healthCheck(),
+
]);
+
+
// All should be healthy
+
for (const result of results) {
+
assertEquals(result.healthy, true);
+
assertEquals(result.connected, true);
+
assertExists(result.responseTimeMs);
+
}
+
},
+
sanitizeResources: false,
+
sanitizeOps: false,
+
});
+
+
Deno.test({
+
name: "Health Check: should detect disconnection",
+
async fn() {
+
const uri = await setupTestServer();
+
await connect(uri, "test_db");
+
+
// First check should be healthy
+
let result = await healthCheck();
+
assertEquals(result.healthy, true);
+
+
// Disconnect
+
await disconnect();
+
+
// Second check should be unhealthy
+
result = await healthCheck();
+
assertEquals(result.healthy, false);
+
assertEquals(result.connected, false);
+
},
+
sanitizeResources: false,
+
sanitizeOps: false,
+
});
+