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("users_validation");
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 const invalidUser = {
32 name: "Invalid User",
33 email: "not-an-email", // Invalid email
34 age: -5, // Negative age
35 };
36
37 // This should throw an error due to schema validation
38 await assertRejects(
39 async () => {
40 await UserModel.insertOne(invalidUser as UserInsert);
41 },
42 Error,
43 );
44 },
45 sanitizeResources: false,
46 sanitizeOps: false,
47});
48
49Deno.test({
50 name: "Validation: Update - should reject invalid email in update",
51 async fn() {
52 // Insert a user for this test
53 const newUser: UserInsert = {
54 name: "Validation Test User",
55 email: "valid@example.com",
56 age: 25,
57 };
58 const insertResult = await UserModel.insertOne(newUser);
59 assertExists(insertResult.insertedId);
60
61 // Try to update with invalid email - should throw error
62 await assertRejects(
63 async () => {
64 await UserModel.update(
65 { _id: new ObjectId(insertResult.insertedId) },
66 { email: "not-an-email" },
67 );
68 },
69 Error,
70 "Validation failed on update",
71 );
72 },
73 sanitizeResources: false,
74 sanitizeOps: false,
75});
76
77Deno.test({
78 name: "Validation: Update - should reject negative age in update",
79 async fn() {
80 // Insert a user for this test
81 const newUser: UserInsert = {
82 name: "Age Validation Test User",
83 email: "age@example.com",
84 age: 25,
85 };
86 const insertResult = await UserModel.insertOne(newUser);
87 assertExists(insertResult.insertedId);
88
89 // Try to update with negative age - should throw error
90 await assertRejects(
91 async () => {
92 await UserModel.updateOne(
93 { _id: new ObjectId(insertResult.insertedId) },
94 { age: -5 },
95 );
96 },
97 Error,
98 "Validation failed on update",
99 );
100 },
101 sanitizeResources: false,
102 sanitizeOps: false,
103});
104
105Deno.test({
106 name: "Validation: Update - should reject invalid name type in update",
107 async fn() {
108 // Insert a user for this test
109 const newUser: UserInsert = {
110 name: "Type Validation Test User",
111 email: "type@example.com",
112 age: 25,
113 };
114 const insertResult = await UserModel.insertOne(newUser);
115 assertExists(insertResult.insertedId);
116
117 // Try to update with invalid name type (number instead of string) - should throw error
118 await assertRejects(
119 async () => {
120 await UserModel.updateOne(
121 { _id: new ObjectId(insertResult.insertedId) },
122 { name: 123 as unknown as string },
123 );
124 },
125 Error,
126 "Validation failed on update",
127 );
128 },
129 sanitizeResources: false,
130 sanitizeOps: false,
131});
132
133Deno.test({
134 name: "Validation: Update - should accept valid partial updates",
135 async fn() {
136 // Insert a user for this test
137 const newUser: UserInsert = {
138 name: "Valid Update Test User",
139 email: "validupdate@example.com",
140 age: 25,
141 };
142 const insertResult = await UserModel.insertOne(newUser);
143 assertExists(insertResult.insertedId);
144
145 // Update with valid data - should succeed
146 const updateResult = await UserModel.updateOne(
147 { _id: new ObjectId(insertResult.insertedId) },
148 { age: 30, email: "newemail@example.com" },
149 );
150
151 assertEquals(updateResult.modifiedCount, 1);
152
153 // Verify the update
154 const updatedUser = await UserModel.findOne({
155 _id: new ObjectId(insertResult.insertedId),
156 });
157
158 assertExists(updatedUser);
159 assertEquals(updatedUser.age, 30);
160 assertEquals(updatedUser.email, "newemail@example.com");
161 assertEquals(updatedUser.name, "Valid Update Test User"); // Should remain unchanged
162 },
163 sanitizeResources: false,
164 sanitizeOps: false,
165});