feat: Complete CouchDB test infrastructure migration for route tests
- Fixed 5/7 route test suites (auth, events, reports, rewards, streets) - Updated Jest configuration with global CouchDB mocks - Created comprehensive test helper utilities with proper ID generation - Fixed pagination response format expectations (.data property) - Added proper model method mocks (populate, save, toJSON, etc.) - Resolved ID validation issues for different entity types - Implemented proper CouchDB service method mocking - Updated test helpers to generate valid IDs matching validator patterns Remaining work: - posts.test.js: needs model mocking and response format fixes - tasks.test.js: needs Task model constructor fixes and mocking 🤖 Generated with [AI Assistant] Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
This commit is contained in:
@@ -1,40 +1,45 @@
|
||||
// Mock CouchDB service before importing anything else
|
||||
jest.mock('../services/couchdbService', () => ({
|
||||
initialize: jest.fn().mockResolvedValue(true),
|
||||
isReady: jest.fn().mockReturnValue(true),
|
||||
create: jest.fn(),
|
||||
getById: jest.fn(),
|
||||
find: jest.fn(),
|
||||
createDocument: jest.fn(),
|
||||
updateDocument: jest.fn(),
|
||||
deleteDocument: jest.fn(),
|
||||
findByType: jest.fn().mockResolvedValue([]),
|
||||
findUserById: jest.fn(),
|
||||
findUserByEmail: jest.fn(),
|
||||
update: jest.fn(),
|
||||
getDocument: jest.fn(),
|
||||
}));
|
||||
|
||||
const request = require("supertest");
|
||||
const mongoose = require("mongoose");
|
||||
const { MongoMemoryServer } = require("mongodb-memory-server");
|
||||
const app = require("../server");
|
||||
const User = require("../models/User");
|
||||
const { generateTestId } = require('./utils/idGenerator');
|
||||
|
||||
describe("Error Handling", () => {
|
||||
let mongoServer;
|
||||
let testUser;
|
||||
let authToken;
|
||||
|
||||
beforeAll(async () => {
|
||||
mongoServer = await MongoMemoryServer.create();
|
||||
const mongoUri = mongoServer.getUri();
|
||||
await mongoose.connect(mongoUri);
|
||||
|
||||
// Create test user
|
||||
testUser = new User({
|
||||
testUser = await User.create({
|
||||
name: "Test User",
|
||||
email: "test@example.com",
|
||||
password: "password123",
|
||||
});
|
||||
await testUser.save();
|
||||
|
||||
// Generate auth token
|
||||
const jwt = require("jsonwebtoken");
|
||||
authToken = jwt.sign(
|
||||
{ user: { id: testUser._id.toString() } },
|
||||
{ user: { id: testUser._id } },
|
||||
process.env.JWT_SECRET || "test_secret"
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await mongoose.disconnect();
|
||||
await mongoServer.stop();
|
||||
});
|
||||
|
||||
describe("Authentication Errors", () => {
|
||||
test("should reject requests without token", async () => {
|
||||
const response = await request(app)
|
||||
@@ -81,7 +86,7 @@ describe("Error Handling", () => {
|
||||
test("should reject requests when user not found", async () => {
|
||||
const jwt = require("jsonwebtoken");
|
||||
const tokenWithNonExistentUser = jwt.sign(
|
||||
{ user: { id: new mongoose.Types.ObjectId().toString() } },
|
||||
{ user: { id: generateTestId() } },
|
||||
process.env.JWT_SECRET || "test_secret"
|
||||
);
|
||||
|
||||
@@ -189,7 +194,7 @@ describe("Error Handling", () => {
|
||||
|
||||
describe("Resource Not Found Errors", () => {
|
||||
test("should handle non-existent street", async () => {
|
||||
const nonExistentId = new mongoose.Types.ObjectId().toString();
|
||||
const nonExistentId = generateTestId();
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/streets/${nonExistentId}`)
|
||||
@@ -199,7 +204,7 @@ describe("Error Handling", () => {
|
||||
});
|
||||
|
||||
test("should handle non-existent task", async () => {
|
||||
const nonExistentId = new mongoose.Types.ObjectId().toString();
|
||||
const nonExistentId = generateTestId();
|
||||
|
||||
const response = await request(app)
|
||||
.put(`/api/tasks/${nonExistentId}/complete`)
|
||||
@@ -210,7 +215,7 @@ describe("Error Handling", () => {
|
||||
});
|
||||
|
||||
test("should handle non-existent event", async () => {
|
||||
const nonExistentId = new mongoose.Types.ObjectId().toString();
|
||||
const nonExistentId = generateTestId();
|
||||
|
||||
const response = await request(app)
|
||||
.put(`/api/events/rsvp/${nonExistentId}`)
|
||||
@@ -221,7 +226,7 @@ describe("Error Handling", () => {
|
||||
});
|
||||
|
||||
test("should handle non-existent post", async () => {
|
||||
const nonExistentId = new mongoose.Types.ObjectId().toString();
|
||||
const nonExistentId = generateTestId();
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/posts/${nonExistentId}`)
|
||||
@@ -235,7 +240,7 @@ describe("Error Handling", () => {
|
||||
let testStreet;
|
||||
|
||||
beforeEach(async () => {
|
||||
testStreet = new mongoose.Types.ObjectId();
|
||||
testStreet = generateTestId();
|
||||
});
|
||||
|
||||
test("should prevent duplicate user registration", async () => {
|
||||
@@ -320,9 +325,11 @@ describe("Error Handling", () => {
|
||||
});
|
||||
|
||||
describe("Database Connection Errors", () => {
|
||||
test("should handle database disconnection gracefully", async () => {
|
||||
// Disconnect from database
|
||||
await mongoose.connection.close();
|
||||
test("should handle database service unavailable", async () => {
|
||||
// Mock CouchDB service to be unavailable
|
||||
const couchdbService = require('../services/couchdbService');
|
||||
const originalIsReady = couchdbService.isReady;
|
||||
couchdbService.isReady = jest.fn().mockReturnValue(false);
|
||||
|
||||
const response = await request(app)
|
||||
.get("/api/streets")
|
||||
@@ -330,14 +337,15 @@ describe("Error Handling", () => {
|
||||
|
||||
expect(response.body.msg).toBeDefined();
|
||||
|
||||
// Reconnect for other tests
|
||||
await mongoose.connect(mongoServer.getUri());
|
||||
// Restore original function
|
||||
couchdbService.isReady = originalIsReady;
|
||||
});
|
||||
|
||||
test("should handle database operation timeouts", async () => {
|
||||
// Mock a slow database operation
|
||||
const originalFind = mongoose.Model.find;
|
||||
mongoose.Model.find = jest.fn().mockImplementation(() => {
|
||||
// Mock a slow CouchDB operation
|
||||
const couchdbService = require('../services/couchdbService');
|
||||
const originalFindByType = couchdbService.findByType;
|
||||
couchdbService.findByType = jest.fn().mockImplementation(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => reject(new Error("Database timeout")), 100);
|
||||
});
|
||||
@@ -349,8 +357,8 @@ describe("Error Handling", () => {
|
||||
|
||||
expect(response.body.msg).toBeDefined();
|
||||
|
||||
// Restore original method
|
||||
mongoose.Model.find = originalFind;
|
||||
// Restore original function
|
||||
couchdbService.findByType = originalFindByType;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user