test: improve test cleanup with selective deletion

- Replace deleteMany({}) with selective deletion by username/email/slug in:
  - events.test.js (target specific test users/events only)
  - matches.test.js (target specific test users/events only)
  - csrf.test.js (target csrftest user only)
- Replace delete() with deleteMany() for resilient cleanup:
  - matches.test.js (2 inline cleanups)
  - socket-webrtc.test.js (1 inline cleanup)
- Update TODO.md with test status and future UX/UI improvements

Test improvement: 189/223 passing (84.8%), up from 145/223 (65%)
This commit is contained in:
Radosław Gierwiało
2025-11-20 00:05:24 +01:00
parent d6f3eafeb2
commit fd0dcdf77f
5 changed files with 200 additions and 23 deletions

View File

@@ -6,11 +6,27 @@ const securityConfig = require('../config/security');
// Clean up database before and after tests
beforeAll(async () => {
await prisma.user.deleteMany({});
// Only delete test user, not all users
await prisma.user.deleteMany({
where: {
OR: [
{ username: 'csrftest' },
{ email: 'csrf@example.com' }
]
}
});
});
afterAll(async () => {
await prisma.user.deleteMany({});
// Only delete test user, not all users
await prisma.user.deleteMany({
where: {
OR: [
{ username: 'csrftest' },
{ email: 'csrf@example.com' }
]
}
});
await prisma.$disconnect();
});

View File

@@ -182,16 +182,62 @@ beforeAll(async () => {
}, 30000);
afterAll(async () => {
// Clean up
await prisma.eventUserHeat.deleteMany({});
await prisma.rating.deleteMany({});
await prisma.message.deleteMany({});
await prisma.match.deleteMany({});
await prisma.chatRoom.deleteMany({});
await prisma.eventCheckinToken.deleteMany({});
await prisma.eventParticipant.deleteMany({});
await prisma.event.deleteMany({});
await prisma.user.deleteMany({});
// Clean up - only delete test data, not all data
const testUsernames = ['john_dancer', 'sarah_swings', 'mike_blues'];
const testEmails = ['john@example.com', 'sarah@example.com', 'mike@example.com'];
const testEventSlugs = ['test-dance-festival-2025', 'test-another-event-2025'];
// Find test events
const testEvents = await prisma.event.findMany({
where: { slug: { in: testEventSlugs } },
select: { id: true }
});
const testEventIds = testEvents.map(e => e.id);
// Find test users
const testUsers = await prisma.user.findMany({
where: {
OR: [
{ username: { in: testUsernames } },
{ email: { in: testEmails } }
]
},
select: { id: true }
});
const testUserIds = testUsers.map(u => u.id);
// Delete related data for test users and events only
if (testUserIds.length > 0) {
await prisma.eventUserHeat.deleteMany({ where: { userId: { in: testUserIds } } });
await prisma.rating.deleteMany({ where: { raterId: { in: testUserIds } } });
await prisma.message.deleteMany({ where: { userId: { in: testUserIds } } });
await prisma.match.deleteMany({
where: {
OR: [
{ user1Id: { in: testUserIds } },
{ user2Id: { in: testUserIds } }
]
}
});
}
if (testEventIds.length > 0) {
await prisma.chatRoom.deleteMany({ where: { eventId: { in: testEventIds } } });
await prisma.eventCheckinToken.deleteMany({ where: { eventId: { in: testEventIds } } });
await prisma.eventParticipant.deleteMany({ where: { eventId: { in: testEventIds } } });
await prisma.event.deleteMany({ where: { id: { in: testEventIds } } });
}
// Delete test users
await prisma.user.deleteMany({
where: {
OR: [
{ username: { in: testUsernames } },
{ email: { in: testEmails } }
]
}
});
await prisma.$disconnect();
});

View File

@@ -126,14 +126,60 @@ beforeAll(async () => {
});
afterAll(async () => {
// Clean up
await prisma.rating.deleteMany({});
await prisma.message.deleteMany({});
await prisma.match.deleteMany({});
await prisma.chatRoom.deleteMany({});
await prisma.eventParticipant.deleteMany({});
await prisma.event.deleteMany({});
await prisma.user.deleteMany({});
// Clean up - only delete test data, not all data
const testUsernames = ['john_dancer', 'sarah_swings', 'mike_moves', 'outsider'];
const testEmails = ['john@example.com', 'sarah@example.com', 'mike@example.com', 'outsider@example.com'];
const testEventSlugs = ['test-dance-festival'];
// Find test users
const testUsers = await prisma.user.findMany({
where: {
OR: [
{ username: { in: testUsernames } },
{ email: { in: testEmails } }
]
},
select: { id: true }
});
const testUserIds = testUsers.map(u => u.id);
// Find test events
const testEvents = await prisma.event.findMany({
where: { slug: { in: testEventSlugs } },
select: { id: true }
});
const testEventIds = testEvents.map(e => e.id);
// Delete related data for test users and events only
if (testUserIds.length > 0) {
await prisma.rating.deleteMany({ where: { raterId: { in: testUserIds } } });
await prisma.message.deleteMany({ where: { userId: { in: testUserIds } } });
await prisma.match.deleteMany({
where: {
OR: [
{ user1Id: { in: testUserIds } },
{ user2Id: { in: testUserIds } }
]
}
});
}
if (testEventIds.length > 0) {
await prisma.chatRoom.deleteMany({ where: { eventId: { in: testEventIds } } });
await prisma.eventParticipant.deleteMany({ where: { eventId: { in: testEventIds } } });
await prisma.event.deleteMany({ where: { id: { in: testEventIds } } });
}
// Delete test users
await prisma.user.deleteMany({
where: {
OR: [
{ username: { in: testUsernames } },
{ email: { in: testEmails } }
]
}
});
await prisma.$disconnect();
});
@@ -290,7 +336,7 @@ describe('Matches API Tests', () => {
expect(response.body).toHaveProperty('success', false);
// Clean up
await prisma.user.delete({ where: { id: testUser3.id } });
await prisma.user.deleteMany({ where: { id: testUser3.id } });
});
it('should return 404 for non-existent match slug', async () => {
@@ -351,7 +397,7 @@ describe('Matches API Tests', () => {
expect(response.body).toHaveProperty('success', false);
// Clean up
await prisma.match.delete({ where: { slug: newMatch.slug } });
await prisma.match.deleteMany({ where: { slug: newMatch.slug } });
});
});

View File

@@ -229,7 +229,7 @@ describe('Socket.IO WebRTC Signaling', () => {
expect(error.message).toContain('authorized');
// Cleanup
await prisma.match.delete({ where: { id: unauthorizedMatch.id } });
await prisma.match.deleteMany({ where: { id: unauthorizedMatch.id } });
});
});

View File

@@ -11,6 +11,75 @@
**Also Completed:** 1.6 (Competition Heats System - Backend & Frontend) - ✅ COMPLETED
**Progress:** ~72% complete
### 🔧 CURRENT STATUS - Backend Tests (2025-11-20)
**Test Status:** 189/223 passing (84.8%) - ✅ Significant improvement!
- **Before:** 145/223 (65%)
- **After fixes:** 189/223 (84.8%)
- **Improvement:** +44 tests (+19.8%)
**✅ Fixed:**
1. Test cleanup - replaced `deleteMany({})` with selective deletion:
- `backend/src/__tests__/events.test.js` - selective deletion by username/email/slug
- `backend/src/__tests__/matches.test.js` - selective deletion by username/email/slug
- `backend/src/__tests__/csrf.test.js` - selective deletion by username/email
2. Cleanup resilience - replaced `delete()` with `deleteMany()`:
- `backend/src/__tests__/socket.test.js` - all afterAll + inline cleanup
- `backend/src/__tests__/matches.test.js` - inline cleanup (2 locations)
- `backend/src/__tests__/socket-webrtc.test.js` - inline cleanup
3. Socket tests fixes:
- Changed `eventId``slug` in socket event handlers
- Added `EventParticipant` creation before join_event_room
- Added safety checks before creating FK relationships
4. Auth tests fixes:
- `app.test.js` - CORS origin localhost:8080
- `security.js` - added localhost:3000 to allowed origins (dev)
- `auth-phase1.5.test.js` - fixed error message expectations
**❌ Remaining issues (34 failing tests in 3 test suites):**
- `users.test.js` - ??? (unknown errors, needs analysis)
- `events.test.js` - ??? (unknown errors, despite cleanup fixes)
- `matches.test.js` - PASS individually, FAIL in suite (race conditions?)
**⏳ TODO:**
1. Check detailed errors in `users.test.js`
2. Check detailed errors in `events.test.js`
3. Investigate race conditions in `matches.test.js`
4. Potentially add test isolation (beforeEach cleanup)
5. Consider using transactions in tests
**Commits made:**
- `test: fix socket.test.js cleanup and event room parameters`
- `test: improve test cleanup - selective deletion instead of wiping tables`
### 📋 FUTURE UX/UI IMPROVEMENTS
**Dashboard Page (Post-Login):**
- [ ] Create `/dashboard` route as default landing page after login
- [ ] Show current user information (profile summary, stats)
- [ ] Quick access buttons to active chats (event rooms, match chats)
- [ ] Display ongoing discussions/conversations
- [ ] Show upcoming events user is registered for
- [ ] Recent activity feed (new matches, messages, ratings)
- [ ] Navigation shortcuts to key features
**Event Chat Sidebar Enhancements:**
- [ ] Add competitor number display for each user in sidebar
- [ ] Show user nationality (flag + country code)
- [ ] Expand user info cards in sidebar:
- Competition heats (already implemented)
- Competitor number
- Country/nationality
- User role/level
- Years of experience (if available in profile)
- Average rating (if rated)
- [ ] Consider expandable user cards (click to see more details)
- [ ] Add filtering options:
- By nationality
- By division/level
- By competitor number range
- [ ] Improve mobile responsiveness for extended sidebar info
### ✅ Completed
- Phase 0: Frontend mockup with all views
- Phase 1: Backend Foundation