Skip to content

Commit ad20362

Browse files
test(notification): add error resilience tests
1 parent f0ea6e2 commit ad20362

1 file changed

Lines changed: 101 additions & 0 deletions

File tree

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import mongoose from 'mongoose';
2+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3+
4+
describe('Notification error resilience', () => {
5+
beforeEach(() => {
6+
vi.resetModules();
7+
vi.restoreAllMocks();
8+
});
9+
10+
afterEach(() => {
11+
vi.restoreAllMocks();
12+
});
13+
14+
it('should safely reuse existing Notification model during hydration', async () => {
15+
vi.resetModules();
16+
17+
const existingModel = { mocked: true };
18+
19+
mongoose.models.Notification = existingModel as never;
20+
21+
const { Notification } = await import('./Notification');
22+
23+
expect(Notification).toBe(existingModel);
24+
});
25+
26+
it('should recover cleanly when mongoose.model throws unexpectedly', async () => {
27+
vi.resetModules();
28+
29+
// Force recreation instead of reusing cached model
30+
delete mongoose.models.Notification;
31+
32+
vi.spyOn(mongoose, 'model').mockImplementation(() => {
33+
throw new Error('Database connectivity error');
34+
});
35+
36+
let caughtError: Error | null = null;
37+
38+
try {
39+
await import('./Notification');
40+
} catch (error) {
41+
caughtError = error as Error;
42+
}
43+
44+
expect(caughtError).toBeTruthy();
45+
expect(caughtError?.message).toContain('Database connectivity error');
46+
});
47+
48+
it('should expose safe default values for recovery stability', async () => {
49+
vi.resetModules();
50+
51+
delete mongoose.models.Notification;
52+
53+
const { Notification } = await import('./Notification');
54+
55+
const doc = new Notification({
56+
username: 'pari',
57+
email: 'pari@example.com',
58+
});
59+
60+
expect(doc.frequency).toBe('daily');
61+
expect(doc.notifyOnCommit).toBe(true);
62+
expect(doc.notifyOnStreak).toBe(true);
63+
expect(doc.notifyOnMilestone).toBe(true);
64+
expect(doc.isActive).toBe(true);
65+
});
66+
67+
it('should prevent invalid frequency values from crashing validation', async () => {
68+
vi.resetModules();
69+
70+
delete mongoose.models.Notification;
71+
72+
const { Notification } = await import('./Notification');
73+
74+
const doc = new Notification({
75+
username: 'pari',
76+
email: 'pari@example.com',
77+
frequency: 'invalid-value',
78+
});
79+
80+
const validationError = doc.validateSync();
81+
82+
expect(validationError).toBeTruthy();
83+
expect(validationError?.errors.frequency).toBeDefined();
84+
});
85+
86+
it('should keep required validation failures localized', async () => {
87+
vi.resetModules();
88+
89+
delete mongoose.models.Notification;
90+
91+
const { Notification } = await import('./Notification');
92+
93+
const doc = new Notification({});
94+
95+
const validationError = doc.validateSync();
96+
97+
expect(validationError).toBeTruthy();
98+
expect(validationError?.errors.username).toBeDefined();
99+
expect(validationError?.errors.email).toBeDefined();
100+
});
101+
});

0 commit comments

Comments
 (0)