Thin MongoDB ODM built for Standard Schema
mongodb
zod
deno
1import { assertEquals, assertExists, assertRejects } from "@std/assert";
2import { ObjectId } from "mongodb";
3import {
4 cleanupCollection,
5 createUserModel,
6 setupTestDb,
7 teardownTestDb,
8 type UserInsert,
9 type userSchema,
10} from "./utils.ts";
11import type { Model } from "../mod.ts";
12
13let UserModel: Model<typeof userSchema>;
14
15Deno.test.beforeAll(async () => {
16 await setupTestDb();
17 UserModel = createUserModel();
18});
19
20Deno.test.beforeEach(async () => {
21 await cleanupCollection(UserModel);
22});
23
24Deno.test.afterAll(async () => {
25 await teardownTestDb();
26});
27
28Deno.test({
29 name: "Validation: Schema - should validate user data on insert",
30 async fn() {
31
32 const invalidUser = {
33 name: "Invalid User",
34 email: "not-an-email", // Invalid email
35 age: -5, // Negative age
36 };
37
38 // This should throw an error due to schema validation
39 await assertRejects(
40 async () => {
41 await UserModel.insertOne(invalidUser as UserInsert);
42 },
43 Error,
44 );
45 },
46 sanitizeResources: false,
47 sanitizeOps: false,
48});
49
50Deno.test({
51 name: "Validation: Update - should reject invalid email in update",
52 async fn() {
53
54 // Insert a user for this test
55 const newUser: UserInsert = {
56 name: "Validation Test User",
57 email: "valid@example.com",
58 age: 25,
59 };
60 const insertResult = await UserModel.insertOne(newUser);
61 assertExists(insertResult.insertedId);
62
63 // Try to update with invalid email - should throw error
64 await assertRejects(
65 async () => {
66 await UserModel.update(
67 { _id: new ObjectId(insertResult.insertedId) },
68 { email: "not-an-email" },
69 );
70 },
71 Error,
72 "Update validation failed",
73 );
74 },
75 sanitizeResources: false,
76 sanitizeOps: false,
77});
78
79Deno.test({
80 name: "Validation: Update - should reject negative age in update",
81 async fn() {
82
83 // Insert a user for this test
84 const newUser: UserInsert = {
85 name: "Age Validation Test User",
86 email: "age@example.com",
87 age: 25,
88 };
89 const insertResult = await UserModel.insertOne(newUser);
90 assertExists(insertResult.insertedId);
91
92 // Try to update with negative age - should throw error
93 await assertRejects(
94 async () => {
95 await UserModel.updateOne(
96 { _id: new ObjectId(insertResult.insertedId) },
97 { age: -5 },
98 );
99 },
100 Error,
101 "Update validation failed",
102 );
103 },
104 sanitizeResources: false,
105 sanitizeOps: false,
106});
107
108Deno.test({
109 name: "Validation: Update - should reject invalid name type in update",
110 async fn() {
111
112 // Insert a user for this test
113 const newUser: UserInsert = {
114 name: "Type Validation Test User",
115 email: "type@example.com",
116 age: 25,
117 };
118 const insertResult = await UserModel.insertOne(newUser);
119 assertExists(insertResult.insertedId);
120
121 // Try to update with invalid name type (number instead of string) - should throw error
122 await assertRejects(
123 async () => {
124 await UserModel.updateOne(
125 { _id: new ObjectId(insertResult.insertedId) },
126 { name: 123 as unknown as string },
127 );
128 },
129 Error,
130 "Update validation failed",
131 );
132 },
133 sanitizeResources: false,
134 sanitizeOps: false,
135});
136
137Deno.test({
138 name: "Validation: Update - should accept valid partial updates",
139 async fn() {
140
141 // Insert a user for this test
142 const newUser: UserInsert = {
143 name: "Valid Update Test User",
144 email: "validupdate@example.com",
145 age: 25,
146 };
147 const insertResult = await UserModel.insertOne(newUser);
148 assertExists(insertResult.insertedId);
149
150 // Update with valid data - should succeed
151 const updateResult = await UserModel.updateOne(
152 { _id: new ObjectId(insertResult.insertedId) },
153 { age: 30, email: "newemail@example.com" },
154 );
155
156 assertEquals(updateResult.modifiedCount, 1);
157
158 // Verify the update
159 const updatedUser = await UserModel.findOne({
160 _id: new ObjectId(insertResult.insertedId),
161 });
162
163 assertExists(updatedUser);
164 assertEquals(updatedUser.age, 30);
165 assertEquals(updatedUser.email, "newemail@example.com");
166 assertEquals(updatedUser.name, "Valid Update Test User"); // Should remain unchanged
167 },
168 sanitizeResources: false,
169 sanitizeOps: false,
170});
171
172