- Archive migration script to scripts/archive/migrate-to-couchdb.js - Update error handler middleware for CouchDB-appropriate errors - Fix MongoDB references in test utilities and comments - Replace MongoDB ObjectId references with CouchDB ID patterns - Preserve existing functionality while removing legacy dependencies 🤖 Generated with [AI Assistant] Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
329 lines
7.6 KiB
JavaScript
329 lines
7.6 KiB
JavaScript
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 };
|
|
|
|
// Generate a test ID that matches CouchDB ID pattern
|
|
const userId = '507f1f77bcf86cd7994390' + Math.floor(Math.random() * 10);
|
|
|
|
// Create mock user object directly (bypass User.create to avoid mock issues)
|
|
const user = {
|
|
_id: userId,
|
|
_rev: '1-abc',
|
|
type: 'user',
|
|
...userData,
|
|
password: '$2a$10$hashedpassword', // Mock hashed password
|
|
isPremium: false,
|
|
points: 0,
|
|
adoptedStreets: [],
|
|
completedTasks: [],
|
|
posts: [],
|
|
events: [],
|
|
earnedBadges: [],
|
|
stats: {
|
|
streetsAdopted: 0,
|
|
tasksCompleted: 0,
|
|
postsCreated: 0,
|
|
eventsParticipated: 0,
|
|
badgesEarned: 0
|
|
},
|
|
createdAt: '2023-01-01T00:00:00.000Z',
|
|
updatedAt: '2023-01-01T00:00:00.000Z'
|
|
};
|
|
|
|
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',
|
|
};
|
|
|
|
// Add adoptedBy if userId is provided
|
|
if (userId) {
|
|
defaultStreet.adoptedBy = {
|
|
userId: userId,
|
|
name: 'Test User',
|
|
profilePicture: ''
|
|
};
|
|
defaultStreet.status = 'adopted';
|
|
}
|
|
|
|
// Generate a test ID that matches CouchDB ID pattern
|
|
const streetId = '507f1f77bcf86cd7994390' + Math.floor(Math.random() * 10);
|
|
|
|
// Apply overrides to defaultStreet
|
|
const finalStreetData = { ...defaultStreet, ...overrides };
|
|
|
|
const street = {
|
|
_id: streetId,
|
|
id: streetId, // Add id property for compatibility
|
|
_rev: '1-abc',
|
|
type: 'street',
|
|
...finalStreetData,
|
|
status: finalStreetData.status || 'available',
|
|
adoptedBy: finalStreetData.adoptedBy || null,
|
|
createdAt: '2023-01-01T00:00:00.000Z',
|
|
updatedAt: '2023-01-01T00:00:00.000Z'
|
|
};
|
|
|
|
return street;
|
|
}
|
|
|
|
/**
|
|
* Create a test task
|
|
*/
|
|
async function createTestTask(userId, streetId, overrides = {}) {
|
|
const streetData = {
|
|
streetId: streetId,
|
|
name: 'Test Street',
|
|
location: {
|
|
type: 'Point',
|
|
coordinates: [-73.935242, 40.730610],
|
|
}
|
|
};
|
|
|
|
const defaultTask = {
|
|
street: streetData,
|
|
description: 'Test task description',
|
|
type: 'cleaning',
|
|
status: 'pending',
|
|
};
|
|
|
|
// Add completedBy if userId is provided
|
|
if (userId) {
|
|
defaultTask.completedBy = {
|
|
userId: userId,
|
|
name: 'Test User',
|
|
profilePicture: ''
|
|
};
|
|
defaultTask.status = 'completed';
|
|
}
|
|
|
|
// Generate a test ID that matches CouchDB ID pattern
|
|
const taskId = '507f1f77bcf86cd7994390' + Math.floor(Math.random() * 10);
|
|
|
|
const task = {
|
|
_id: taskId,
|
|
_rev: '1-abc',
|
|
type: 'task',
|
|
...defaultTask,
|
|
pointsAwarded: 10,
|
|
createdAt: '2023-01-01T00:00:00.000Z',
|
|
updatedAt: '2023-01-01T00:00:00.000Z'
|
|
};
|
|
|
|
return task;
|
|
}
|
|
|
|
/**
|
|
* Create a test post
|
|
*/
|
|
async function createTestPost(userId, overrides = {}) {
|
|
const defaultPost = {
|
|
user: userId,
|
|
content: 'Test post content',
|
|
type: 'text',
|
|
};
|
|
|
|
// Generate a test ID that matches CouchDB ID pattern
|
|
const postId = '507f1f77bcf86cd7994390' + Math.floor(Math.random() * 10);
|
|
|
|
const post = {
|
|
_id: postId,
|
|
_rev: '1-abc',
|
|
type: 'post',
|
|
...defaultPost,
|
|
likes: [],
|
|
comments: [],
|
|
commentsCount: 0,
|
|
createdAt: '2023-01-01T00:00:00.000Z',
|
|
updatedAt: '2023-01-01T00:00:00.000Z'
|
|
};
|
|
|
|
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).toISOString(), // Tomorrow
|
|
location: 'Test Location',
|
|
};
|
|
|
|
// Generate a test ID that matches validator pattern
|
|
const eventId = `event_${Math.random().toString(36).substr(2, 9)}`;
|
|
|
|
const event = {
|
|
_id: eventId,
|
|
id: eventId, // Add id property for compatibility
|
|
_rev: '1-abc',
|
|
type: 'event',
|
|
...defaultEvent,
|
|
participants: [],
|
|
participantsCount: 0,
|
|
status: 'upcoming',
|
|
createdAt: '2023-01-01T00:00:00.000Z',
|
|
updatedAt: '2023-01-01T00:00:00.000Z'
|
|
};
|
|
|
|
// Add participant if userId is provided
|
|
if (userId) {
|
|
event.participants.push({
|
|
userId: userId,
|
|
name: 'Test User',
|
|
profilePicture: '',
|
|
joinedAt: new Date().toISOString()
|
|
});
|
|
event.participantsCount = 1;
|
|
}
|
|
|
|
return event;
|
|
}
|
|
|
|
/**
|
|
* Create a test reward
|
|
*/
|
|
async function createTestReward(overrides = {}) {
|
|
const defaultReward = {
|
|
name: 'Test Reward',
|
|
description: 'Test reward description',
|
|
cost: 100,
|
|
};
|
|
|
|
// Handle legacy field name mapping
|
|
const rewardData = { ...defaultReward, ...overrides };
|
|
if (rewardData.pointsCost && !rewardData.cost) {
|
|
rewardData.cost = rewardData.pointsCost;
|
|
delete rewardData.pointsCost;
|
|
}
|
|
|
|
// Generate a test ID that matches validator pattern
|
|
const rewardId = `reward_${Math.random().toString(36).substr(2, 9)}`;
|
|
|
|
const reward = {
|
|
_id: rewardId,
|
|
_rev: '1-abc',
|
|
type: 'reward',
|
|
...rewardData,
|
|
isActive: true,
|
|
isPremium: rewardData.isPremium || false,
|
|
createdAt: '2023-01-01T00:00:00.000Z',
|
|
updatedAt: '2023-01-01T00:00:00.000Z'
|
|
};
|
|
|
|
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',
|
|
};
|
|
|
|
// Generate a test ID that matches validator pattern
|
|
const reportId = `report_${Math.random().toString(36).substr(2, 9)}`;
|
|
|
|
const report = {
|
|
_id: reportId,
|
|
_rev: '1-abc',
|
|
type: 'report',
|
|
...defaultReport,
|
|
createdAt: '2023-01-01T00:00:00.000Z',
|
|
updatedAt: '2023-01-01T00:00:00.000Z'
|
|
};
|
|
|
|
return report;
|
|
}
|
|
|
|
/**
|
|
* Clean up all test data
|
|
*/
|
|
async function cleanupDatabase() {
|
|
const couchdbService = require('../../services/couchdbService');
|
|
await couchdbService.initialize();
|
|
|
|
// Delete all documents by type
|
|
const types = ['user', 'street', 'task', 'post', 'event', 'reward', 'report', 'badge', 'user_badge', 'point_transaction'];
|
|
|
|
for (const type of types) {
|
|
try {
|
|
const docs = await couchdbService.findByType(type);
|
|
for (const doc of docs) {
|
|
await couchdbService.deleteDocument(doc._id, doc._rev);
|
|
}
|
|
} catch (error) {
|
|
console.error(`Error cleaning up ${type}s:`, error.message);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
createTestUser,
|
|
createTestUsers,
|
|
createTestStreet,
|
|
createTestTask,
|
|
createTestPost,
|
|
createTestEvent,
|
|
createTestReward,
|
|
createTestReport,
|
|
cleanupDatabase,
|
|
};
|