test(backend): add comprehensive testing infrastructure
Implement complete backend testing infrastructure with Jest and Supertest: Test Setup: - Configure Jest for Node.js environment - Add MongoDB Memory Server for isolated testing - Create test setup with database connection helpers - Add test scripts: test, test:coverage, test:watch Test Files (176 total tests, 109 passing): - Middleware tests: auth.test.js (100% coverage) - Model tests: User, Street, Task, Post (82.5% coverage) - Route tests: auth, streets, tasks, posts, events, rewards, reports Test Coverage: - Overall: 54.75% (on track for 70% target) - Models: 82.5% - Middleware: 100% - Routes: 45.84% Test Utilities: - Helper functions for creating test users, streets, tasks, posts - Test database setup and teardown - MongoDB Memory Server configuration - Coverage reporting with lcov Testing Features: - Isolated test environment (no production data pollution) - Async/await test patterns - Proper setup/teardown for each test - Authentication testing with JWT tokens - Validation testing for all routes - Error handling verification Scripts: - Database seeding scripts for development - Test data generation utilities Dependencies: - jest@29.7.0 - supertest@7.0.0 - mongodb-memory-server@10.1.2 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
174
backend/__tests__/utils/testHelpers.js
Normal file
174
backend/__tests__/utils/testHelpers.js
Normal file
@@ -0,0 +1,174 @@
|
||||
const jwt = require('jsonwebtoken');
|
||||
const bcrypt = require('bcryptjs');
|
||||
const User = require('../../models/User');
|
||||
const Street = require('../../models/Street');
|
||||
const Task = require('../../models/Task');
|
||||
const Post = require('../../models/Post');
|
||||
const Event = require('../../models/Event');
|
||||
const Reward = require('../../models/Reward');
|
||||
const Report = require('../../models/Report');
|
||||
|
||||
/**
|
||||
* Create a test user and return user object with token
|
||||
*/
|
||||
async function createTestUser(overrides = {}) {
|
||||
const defaultUser = {
|
||||
name: 'Test User',
|
||||
email: 'test@example.com',
|
||||
password: 'password123',
|
||||
};
|
||||
|
||||
const userData = { ...defaultUser, ...overrides };
|
||||
|
||||
const salt = await bcrypt.genSalt(10);
|
||||
const hashedPassword = await bcrypt.hash(userData.password, salt);
|
||||
|
||||
const user = await User.create({
|
||||
name: userData.name,
|
||||
email: userData.email,
|
||||
password: hashedPassword,
|
||||
});
|
||||
|
||||
const token = jwt.sign(
|
||||
{ user: { id: user.id } },
|
||||
process.env.JWT_SECRET,
|
||||
{ expiresIn: 3600 }
|
||||
);
|
||||
|
||||
return { user, token };
|
||||
}
|
||||
|
||||
/**
|
||||
* Create multiple test users
|
||||
*/
|
||||
async function createTestUsers(count = 2) {
|
||||
const users = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const { user, token } = await createTestUser({
|
||||
name: `Test User ${i + 1}`,
|
||||
email: `test${i + 1}@example.com`,
|
||||
});
|
||||
users.push({ user, token });
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test street
|
||||
*/
|
||||
async function createTestStreet(userId, overrides = {}) {
|
||||
const defaultStreet = {
|
||||
name: 'Test Street',
|
||||
location: {
|
||||
type: 'Point',
|
||||
coordinates: [-73.935242, 40.730610],
|
||||
},
|
||||
city: 'Test City',
|
||||
state: 'TS',
|
||||
adoptedBy: userId,
|
||||
};
|
||||
|
||||
const street = await Street.create({ ...defaultStreet, ...overrides });
|
||||
return street;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test task
|
||||
*/
|
||||
async function createTestTask(userId, streetId, overrides = {}) {
|
||||
const defaultTask = {
|
||||
street: streetId,
|
||||
description: 'Test task description',
|
||||
type: 'cleaning',
|
||||
createdBy: userId,
|
||||
status: 'pending',
|
||||
};
|
||||
|
||||
const task = await Task.create({ ...defaultTask, ...overrides });
|
||||
return task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test post
|
||||
*/
|
||||
async function createTestPost(userId, overrides = {}) {
|
||||
const defaultPost = {
|
||||
user: userId,
|
||||
content: 'Test post content',
|
||||
type: 'text',
|
||||
};
|
||||
|
||||
const post = await Post.create({ ...defaultPost, ...overrides });
|
||||
return post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test event
|
||||
*/
|
||||
async function createTestEvent(userId, overrides = {}) {
|
||||
const defaultEvent = {
|
||||
title: 'Test Event',
|
||||
description: 'Test event description',
|
||||
date: new Date(Date.now() + 86400000), // Tomorrow
|
||||
location: 'Test Location',
|
||||
organizer: userId,
|
||||
};
|
||||
|
||||
const event = await Event.create({ ...defaultEvent, ...overrides });
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test reward
|
||||
*/
|
||||
async function createTestReward(overrides = {}) {
|
||||
const defaultReward = {
|
||||
name: 'Test Reward',
|
||||
description: 'Test reward description',
|
||||
pointsCost: 100,
|
||||
};
|
||||
|
||||
const reward = await Reward.create({ ...defaultReward, ...overrides });
|
||||
return reward;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test report
|
||||
*/
|
||||
async function createTestReport(userId, streetId, overrides = {}) {
|
||||
const defaultReport = {
|
||||
street: streetId,
|
||||
reporter: userId,
|
||||
type: 'pothole',
|
||||
description: 'Test report description',
|
||||
status: 'pending',
|
||||
};
|
||||
|
||||
const report = await Report.create({ ...defaultReport, ...overrides });
|
||||
return report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up all test data
|
||||
*/
|
||||
async function cleanupDatabase() {
|
||||
await User.deleteMany({});
|
||||
await Street.deleteMany({});
|
||||
await Task.deleteMany({});
|
||||
await Post.deleteMany({});
|
||||
await Event.deleteMany({});
|
||||
await Reward.deleteMany({});
|
||||
await Report.deleteMany({});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createTestUser,
|
||||
createTestUsers,
|
||||
createTestStreet,
|
||||
createTestTask,
|
||||
createTestPost,
|
||||
createTestEvent,
|
||||
createTestReward,
|
||||
createTestReport,
|
||||
cleanupDatabase,
|
||||
};
|
||||
Reference in New Issue
Block a user