Skip to content

Commit dcc2c81

Browse files
authored
test(mongodb): verify User schema behaviors under connection state 3 (disconnecting) (JhaSourav07#1989)
## Description Fixes JhaSourav07#1426 ## Pillar - [ ] 🎨 Pillar 1 — New Theme Design - [ ] 📐 Pillar 2 — Geometric SVG Improvement - [ ] 🕐 Pillar 3 — Timezone Logic Optimization - [x] 🛠️ Other (Bug fix, refactoring, docs, testing) ## Visual Preview N/A — Test suite addition. No user interface or SVG layout modifications were made. ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [x] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). - [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): ...`). - [x] 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 8960fed + 81eb25b commit dcc2c81

2 files changed

Lines changed: 64 additions & 0 deletions

File tree

lib/mongodb.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,16 @@ describe('dbConnect', () => {
137137
expect(global.mongoose.conn).toBe(mockMongoose);
138138
expect(conn).toBe(mockMongoose);
139139
});
140+
141+
it('handles mongoose Connection State 3 (disconnecting) gracefully by throwing or clearing cache', async () => {
142+
process.env.MONGODB_URI = 'mongodb://localhost:27017/test';
143+
mockMongooseConnection.readyState = 3;
144+
145+
vi.mocked(mongoose.connect).mockRejectedValue(new Error('Database is disconnecting'));
146+
147+
await expect(dbConnect()).rejects.toThrow('Database is disconnecting');
148+
149+
// The promise should be cleared so it can try again
150+
expect(global.mongoose.promise).toBeNull();
151+
});
140152
});

models/User.test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,56 @@ describe('User Model', () => {
126126
findOneSpy.mockRestore();
127127
});
128128
});
129+
130+
describe('Database Connection State 3 (Disconnecting) Handling', () => {
131+
it('aborts/rolls back active transactions cleanly when connection is in state 3 (disconnecting)', async () => {
132+
const { vi } = await import('vitest');
133+
134+
// 1. Mock mongoose.connection.readyState to return 3 (disconnecting)
135+
const readyStateSpy = vi
136+
.spyOn(mongoose.connection, 'readyState', 'get')
137+
.mockReturnValue(3 as unknown as typeof mongoose.connection.readyState);
138+
139+
// 2. Mock a mongoose session with transaction support
140+
const mockSession = {
141+
startTransaction: vi.fn(),
142+
commitTransaction: vi.fn(),
143+
abortTransaction: vi.fn().mockResolvedValue(undefined),
144+
endSession: vi.fn().mockResolvedValue(undefined),
145+
} as unknown as mongoose.ClientSession;
146+
147+
const startSessionSpy = vi.spyOn(mongoose, 'startSession').mockResolvedValue(mockSession);
148+
149+
// 3. Simulate a database transaction workflow that checks connection state
150+
const runTransactionWithCheck = async (session: mongoose.ClientSession) => {
151+
session.startTransaction();
152+
try {
153+
if (mongoose.connection.readyState === 3) {
154+
await session.abortTransaction();
155+
return { status: 'aborted' };
156+
}
157+
await session.commitTransaction();
158+
return { status: 'committed' };
159+
} catch (error) {
160+
await session.abortTransaction();
161+
throw error;
162+
} finally {
163+
await session.endSession();
164+
}
165+
};
166+
167+
const session = await mongoose.startSession();
168+
const result = await runTransactionWithCheck(session);
169+
170+
// 4. Assertions
171+
expect(result.status).toBe('aborted');
172+
expect(mockSession.abortTransaction).toHaveBeenCalledTimes(1);
173+
expect(mockSession.endSession).toHaveBeenCalledTimes(1);
174+
expect(mockSession.commitTransaction).not.toHaveBeenCalled();
175+
176+
// Cleanup
177+
readyStateSpy.mockRestore();
178+
startSessionSpy.mockRestore();
179+
});
180+
});
129181
});

0 commit comments

Comments
 (0)