Skip to content

Commit 3178ef7

Browse files
authored
test(models): add edge case and validation tests for Notification schema (JhaSourav07#3616)
## Description Fixes JhaSourav07#2893 ### What Changed * **Model Validation Tests (`models/Notification.empty-fallback.test.ts`):** Added a new Vitest suite specifically targeting backend schema validation, edge cases, and missing inputs for the Notification model. * **Required Field Enforcement:** Verified that Mongoose correctly blocks instantiation when strictly required fields (like `username` and `email`) are omitted or contain only whitespace (utilizing the schema's `trim` property). * **Default Fallback Resilience:** Asserted that unconfigured optional fields safely default to their intended schema values (e.g., `frequency` defaulting to `'daily'` and boolean flags defaulting to `true`) when instantiated with empty configurations. * **Type & Enum Safety:** Added strict runtime tests to ensure the model safely catches and rejects invalid enum strings (like `'hourly'`) and prevents hydration crashes by throwing standard `CastError` exceptions for invalid data types. * **Database-Free Testing:** Utilized Mongoose's `.validateSync()` method to perform lightning-fast, synchronous schema validation without requiring an active MongoDB connection. ## Pillar - [ ] 🎨 Pillar 1 — New Theme Design - [ ] 📐 Pillar 2 — Geometric SVG Improvement - [ ] 🕐 Pillar 3 — Timezone Logic Optimization - [x] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview *N/A — Backend model testing only.* ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [x] I have tested these changes locally (`vitest`). - [x] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). - [x] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). - [ ] I have updated `README.md` if I added a new theme or URL parameter. - [x] I have starred the repo. - [x] I have made sure that I have only one commit to merge in this PR. - [x] The SVG output matches the CommitPulse "premium quality" aesthetic standard (no raw elements, smooth animations, correct fonts). - [x] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support.
2 parents 43af4a9 + 090fb4d commit 3178ef7

1 file changed

Lines changed: 86 additions & 0 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { describe, it, expect } from 'vitest';
2+
import { Notification } from './Notification';
3+
4+
describe('Notification Model - Edge Cases & Empty/Missing Inputs Verification', () => {
5+
// 1. Missing required fields (Empty Object)
6+
it('throws validation errors when instantiated with completely empty parameters', () => {
7+
const notification = new Notification({});
8+
9+
// validateSync() allows us to check schema rules without needing a real MongoDB connection
10+
const err = notification.validateSync();
11+
12+
expect(err).toBeDefined();
13+
expect(err?.errors.username).toBeDefined();
14+
expect(err?.errors.username.message).toContain('Path `username` is required');
15+
16+
expect(err?.errors.email).toBeDefined();
17+
expect(err?.errors.email.message).toContain('Path `email` is required');
18+
});
19+
20+
// 2. Missing optional fields (Verify Default Fallbacks)
21+
it('applies default fallback configuration values when optional fields are completely missing', () => {
22+
const notification = new Notification({
23+
username: 'testuser',
24+
email: 'test@example.com',
25+
});
26+
27+
const err = notification.validateSync();
28+
29+
// Should have no validation errors since required fields are present
30+
expect(err).toBeUndefined();
31+
32+
// Verify all the unconfigured object fields safely fell back to schema defaults
33+
expect(notification.frequency).toBe('daily');
34+
expect(notification.notifyOnCommit).toBe(true);
35+
expect(notification.notifyOnStreak).toBe(true);
36+
expect(notification.notifyOnMilestone).toBe(true);
37+
expect(notification.isActive).toBe(true);
38+
expect(notification.createdAt).toBeDefined();
39+
expect(notification.updatedAt).toBeDefined();
40+
});
41+
42+
// 3. Empty string/whitespace handling
43+
it('fails validation safely if required strings contain only empty spaces', () => {
44+
const notification = new Notification({
45+
username: ' ', // Schema has `trim: true`, so this reduces to an empty string
46+
email: ' ',
47+
});
48+
49+
const err = notification.validateSync();
50+
51+
expect(err).toBeDefined();
52+
// Mongoose recognizes the trimmed empty string as a missing required field
53+
expect(err?.errors.username).toBeDefined();
54+
expect(err?.errors.email).toBeDefined();
55+
});
56+
57+
// 4. Invalid Enum Inputs (Missing standard layout state)
58+
it('rejects invalid inputs for enumerated fields and prevents database corruption', () => {
59+
const notification = new Notification({
60+
username: 'testuser',
61+
email: 'test@example.com',
62+
frequency: 'hourly', // Invalid! Valid options are: realtime, daily, weekly
63+
});
64+
65+
const err = notification.validateSync();
66+
67+
expect(err).toBeDefined();
68+
expect(err?.errors.frequency).toBeDefined();
69+
expect(err?.errors.frequency.message).toContain('is not a valid enum value');
70+
});
71+
72+
// 5. Type Casting Failures (Hydration/Runtime Error Resilience)
73+
it('gracefully handles invalid types by throwing standard cast errors instead of crashing', () => {
74+
const notification = new Notification({
75+
username: 'testuser',
76+
email: 'test@example.com',
77+
notifyOnCommit: 'not-a-boolean-value', // Injecting a raw string into a boolean field
78+
});
79+
80+
const err = notification.validateSync();
81+
82+
expect(err).toBeDefined();
83+
expect(err?.errors.notifyOnCommit).toBeDefined();
84+
expect(err?.errors.notifyOnCommit.name).toBe('CastError');
85+
});
86+
});

0 commit comments

Comments
 (0)