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:
269
backend/scripts/seedBadges.js
Normal file
269
backend/scripts/seedBadges.js
Normal file
@@ -0,0 +1,269 @@
|
||||
require("dotenv").config();
|
||||
const mongoose = require("mongoose");
|
||||
const Badge = require("../models/Badge");
|
||||
|
||||
/**
|
||||
* Initial badge definitions
|
||||
* These badges will be auto-awarded when users meet the criteria
|
||||
*/
|
||||
const badges = [
|
||||
// Street Adoption Badges
|
||||
{
|
||||
name: "First Adoption",
|
||||
description: "Adopted your first street",
|
||||
icon: "🏡",
|
||||
criteria: {
|
||||
type: "street_adoptions",
|
||||
threshold: 1,
|
||||
},
|
||||
rarity: "common",
|
||||
order: 1,
|
||||
},
|
||||
{
|
||||
name: "Street Adopter",
|
||||
description: "Adopted 5 streets",
|
||||
icon: "🏘️",
|
||||
criteria: {
|
||||
type: "street_adoptions",
|
||||
threshold: 5,
|
||||
},
|
||||
rarity: "rare",
|
||||
order: 2,
|
||||
},
|
||||
{
|
||||
name: "Neighborhood Champion",
|
||||
description: "Adopted 10 streets",
|
||||
icon: "🌆",
|
||||
criteria: {
|
||||
type: "street_adoptions",
|
||||
threshold: 10,
|
||||
},
|
||||
rarity: "epic",
|
||||
order: 3,
|
||||
},
|
||||
{
|
||||
name: "City Guardian",
|
||||
description: "Adopted 25 streets",
|
||||
icon: "🏙️",
|
||||
criteria: {
|
||||
type: "street_adoptions",
|
||||
threshold: 25,
|
||||
},
|
||||
rarity: "legendary",
|
||||
order: 4,
|
||||
},
|
||||
|
||||
// Task Completion Badges
|
||||
{
|
||||
name: "First Task",
|
||||
description: "Completed your first task",
|
||||
icon: "✅",
|
||||
criteria: {
|
||||
type: "task_completions",
|
||||
threshold: 1,
|
||||
},
|
||||
rarity: "common",
|
||||
order: 5,
|
||||
},
|
||||
{
|
||||
name: "Task Master",
|
||||
description: "Completed 10 tasks",
|
||||
icon: "🎯",
|
||||
criteria: {
|
||||
type: "task_completions",
|
||||
threshold: 10,
|
||||
},
|
||||
rarity: "rare",
|
||||
order: 6,
|
||||
},
|
||||
{
|
||||
name: "Dedicated Worker",
|
||||
description: "Completed 50 tasks",
|
||||
icon: "🛠️",
|
||||
criteria: {
|
||||
type: "task_completions",
|
||||
threshold: 50,
|
||||
},
|
||||
rarity: "epic",
|
||||
order: 7,
|
||||
},
|
||||
{
|
||||
name: "Maintenance Legend",
|
||||
description: "Completed 100 tasks",
|
||||
icon: "⚡",
|
||||
criteria: {
|
||||
type: "task_completions",
|
||||
threshold: 100,
|
||||
},
|
||||
rarity: "legendary",
|
||||
order: 8,
|
||||
},
|
||||
|
||||
// Post Creation Badges
|
||||
{
|
||||
name: "First Post",
|
||||
description: "Created your first post",
|
||||
icon: "📝",
|
||||
criteria: {
|
||||
type: "post_creations",
|
||||
threshold: 1,
|
||||
},
|
||||
rarity: "common",
|
||||
order: 9,
|
||||
},
|
||||
{
|
||||
name: "Social Butterfly",
|
||||
description: "Created 25 posts",
|
||||
icon: "🦋",
|
||||
criteria: {
|
||||
type: "post_creations",
|
||||
threshold: 25,
|
||||
},
|
||||
rarity: "rare",
|
||||
order: 10,
|
||||
},
|
||||
{
|
||||
name: "Community Voice",
|
||||
description: "Created 100 posts",
|
||||
icon: "📢",
|
||||
criteria: {
|
||||
type: "post_creations",
|
||||
threshold: 100,
|
||||
},
|
||||
rarity: "epic",
|
||||
order: 11,
|
||||
},
|
||||
{
|
||||
name: "Social Media Star",
|
||||
description: "Created 250 posts",
|
||||
icon: "⭐",
|
||||
criteria: {
|
||||
type: "post_creations",
|
||||
threshold: 250,
|
||||
},
|
||||
rarity: "legendary",
|
||||
order: 12,
|
||||
},
|
||||
|
||||
// Event Participation Badges
|
||||
{
|
||||
name: "Event Participant",
|
||||
description: "Participated in your first event",
|
||||
icon: "🎉",
|
||||
criteria: {
|
||||
type: "event_participations",
|
||||
threshold: 1,
|
||||
},
|
||||
rarity: "common",
|
||||
order: 13,
|
||||
},
|
||||
{
|
||||
name: "Community Leader",
|
||||
description: "Participated in 5 events",
|
||||
icon: "👥",
|
||||
criteria: {
|
||||
type: "event_participations",
|
||||
threshold: 5,
|
||||
},
|
||||
rarity: "rare",
|
||||
order: 14,
|
||||
},
|
||||
{
|
||||
name: "Event Enthusiast",
|
||||
description: "Participated in 15 events",
|
||||
icon: "🎊",
|
||||
criteria: {
|
||||
type: "event_participations",
|
||||
threshold: 15,
|
||||
},
|
||||
rarity: "epic",
|
||||
order: 15,
|
||||
},
|
||||
{
|
||||
name: "Community Pillar",
|
||||
description: "Participated in 30 events",
|
||||
icon: "🏛️",
|
||||
criteria: {
|
||||
type: "event_participations",
|
||||
threshold: 30,
|
||||
},
|
||||
rarity: "legendary",
|
||||
order: 16,
|
||||
},
|
||||
|
||||
// Points Badges
|
||||
{
|
||||
name: "Point Collector",
|
||||
description: "Earned 1,000 points",
|
||||
icon: "💰",
|
||||
criteria: {
|
||||
type: "points_earned",
|
||||
threshold: 1000,
|
||||
},
|
||||
rarity: "rare",
|
||||
order: 17,
|
||||
},
|
||||
{
|
||||
name: "Point Hoarder",
|
||||
description: "Earned 5,000 points",
|
||||
icon: "💎",
|
||||
criteria: {
|
||||
type: "points_earned",
|
||||
threshold: 5000,
|
||||
},
|
||||
rarity: "epic",
|
||||
order: 18,
|
||||
},
|
||||
{
|
||||
name: "Point Master",
|
||||
description: "Earned 10,000 points",
|
||||
icon: "👑",
|
||||
criteria: {
|
||||
type: "points_earned",
|
||||
threshold: 10000,
|
||||
},
|
||||
rarity: "legendary",
|
||||
order: 19,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Seed badges into the database
|
||||
*/
|
||||
async function seedBadges() {
|
||||
try {
|
||||
// Connect to MongoDB
|
||||
await mongoose.connect(process.env.MONGO_URI, {
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true,
|
||||
});
|
||||
|
||||
console.log("Connected to MongoDB");
|
||||
|
||||
// Clear existing badges (optional - remove if you want to preserve existing badges)
|
||||
await Badge.deleteMany({});
|
||||
console.log("Cleared existing badges");
|
||||
|
||||
// Insert new badges
|
||||
const createdBadges = await Badge.insertMany(badges);
|
||||
console.log(`Successfully seeded ${createdBadges.length} badges`);
|
||||
|
||||
// Display created badges
|
||||
createdBadges.forEach((badge) => {
|
||||
console.log(
|
||||
` ${badge.icon} ${badge.name} (${badge.rarity}) - ${badge.description}`
|
||||
);
|
||||
});
|
||||
|
||||
// Close connection
|
||||
await mongoose.connection.close();
|
||||
console.log("\nDatabase connection closed");
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
console.error("Error seeding badges:", error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Run the seeder
|
||||
seedBadges();
|
||||
Reference in New Issue
Block a user