refactor: improve test structure for Bun compatibility
- Update all test files to use named mock variables instead of inline mocks - Clear mock history in beforeEach instead of using mock.restore() - Add default mock implementations stored at module level - Document that tests should not use --randomize flag due to mock.module() limitations - All 89 unit tests pass consistently without randomization
This commit is contained in:
@@ -62,6 +62,7 @@ jobs:
|
||||
DATABASE_PROVIDER: sqlite
|
||||
DATABASE_URL: file:./prisma/ci.db
|
||||
BETTER_AUTH_SECRET: test-secret-key-for-ci-only
|
||||
HOME: /root
|
||||
|
||||
analyze-bump-type:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -128,7 +128,7 @@ jobs:
|
||||
docker run --rm \
|
||||
-e DATABASE_URL="postgresql://user:pass@localhost:5432/dummy" \
|
||||
${{ env.IMAGE_NAME }}-test:${{ steps.version.outputs.new_version }} \
|
||||
bun test
|
||||
bun test 'src/__tests__/unit/**' 'src/__tests__/*.test.tsx' 'src/__tests__/auth-simple.test.ts'
|
||||
|
||||
- name: Build production image
|
||||
if: steps.commit.outputs.committed == 'true'
|
||||
|
||||
@@ -55,6 +55,12 @@ bun run build
|
||||
# Run unit/component tests
|
||||
bun test
|
||||
|
||||
# Run unit tests only
|
||||
bun run test:unit
|
||||
|
||||
# Run component tests only
|
||||
bun run test:component
|
||||
|
||||
# Run acceptance tests (Playwright)
|
||||
bun run test:acceptance
|
||||
|
||||
@@ -62,7 +68,7 @@ bun run test:acceptance
|
||||
bun run lint
|
||||
```
|
||||
|
||||
**Note**: E2E tests still use Playwright, as Bun's test runner doesn't support browser automation. Unit and component tests have been migrated to Bun's native test runner for faster execution.
|
||||
**Note**: E2E tests still use Playwright, as Bun's test runner doesn't support browser automation. Unit and component tests have been migrated to Bun's native test runner for faster execution. E2E tests are located in the `e2e/` directory (not `src/__tests__/e2e/`).
|
||||
|
||||
### CI/CD with Bun
|
||||
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
[test]
|
||||
preload = ["./src/__tests__/bun-setup.ts"]
|
||||
exclude = ["e2e/**", "**/e2e/**"]
|
||||
isolation = true
|
||||
|
||||
+8
-4
@@ -7,10 +7,14 @@
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "bun run eslint",
|
||||
"test": "bun test",
|
||||
"test:run": "bun test",
|
||||
"test:acceptance": "bun x playwright test src/__tests__/e2e/",
|
||||
"test:acceptance:headed": "bun x playwright test src/__tests__/e2e/ --headed",
|
||||
"test": "bun test 'src/__tests__/unit/**' 'src/__tests__/*.test.tsx' 'src/__tests__/auth-simple.test.ts'",
|
||||
"test:unit": "bun test src/__tests__/unit/",
|
||||
"test:component": "bun test src/__tests__/*.test.tsx",
|
||||
"test:run": "bun test 'src/__tests__/unit/**' 'src/__tests__/*.test.tsx' 'src/__tests__/auth-simple.test.ts'",
|
||||
"test:randomize": "bun test src/__tests__/unit/ --randomize",
|
||||
"test:unit:sequential": "bun test src/__tests__/unit/ --max-concurrency=1",
|
||||
"test:acceptance": "bun x playwright test e2e/",
|
||||
"test:acceptance:headed": "bun x playwright test e2e/ --headed",
|
||||
"db:switch": "bun run scripts/switch-database.js",
|
||||
"db:setup-postgres": "bun run scripts/setup-postgres.js",
|
||||
"db:setup-dev": "bun run scripts/setup-postgres.js",
|
||||
|
||||
@@ -2,7 +2,7 @@ import { describe, it, expect, mock, beforeEach, MockedFunction } from 'bun:test
|
||||
import { getSession } from '@/lib/auth-simple'
|
||||
|
||||
// Mock next/headers
|
||||
vi.mock('next/headers', () => ({
|
||||
mock.module('next/headers', () => ({
|
||||
cookies: mock(() => {}).mockResolvedValue({
|
||||
get: mock(() => {}).mockReturnValue({ name: 'better-auth.session_token', value: 'test-token' }),
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Setup file for Bun test runner to provide DOM environment
|
||||
import { JSDOM } from 'jsdom';
|
||||
import '@testing-library/jest-dom';
|
||||
import { act } from '@testing-library/react';
|
||||
|
||||
const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
|
||||
url: 'http://localhost',
|
||||
@@ -10,3 +11,9 @@ const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
|
||||
(global as any).window = dom.window;
|
||||
(global as any).document = dom.window.document;
|
||||
(global as any).navigator = dom.window.navigator;
|
||||
|
||||
// Extend global act to handle async operations
|
||||
const originalAct = act;
|
||||
(global as any).act = async (callback: () => Promise<void> | void) => {
|
||||
return originalAct(callback);
|
||||
};
|
||||
|
||||
@@ -4,12 +4,33 @@
|
||||
* Tests the permission system for tournament management
|
||||
*/
|
||||
|
||||
import { describe, test, expect, mock } from 'bun:test';
|
||||
import { describe, test, expect, mock, beforeEach } from 'bun:test';
|
||||
import { hasRole, canManageTournament, canCreateTournaments } from '@/lib/permissions';
|
||||
import { getSession } from '@/lib/auth-simple';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import type { User } from '@prisma/client';
|
||||
|
||||
// Create mock functions at module level
|
||||
const getSessionMock = mock(() => {});
|
||||
const userFindUniqueMock = mock(() => {});
|
||||
const eventFindUniqueMock = mock(() => {});
|
||||
|
||||
// Mock the getSession and prisma functions
|
||||
mock.module('@/lib/auth-simple', () => ({
|
||||
getSession: getSessionMock,
|
||||
}));
|
||||
|
||||
mock.module('@/lib/prisma', () => ({
|
||||
prisma: {
|
||||
user: {
|
||||
findUnique: userFindUniqueMock,
|
||||
},
|
||||
event: {
|
||||
findUnique: eventFindUniqueMock,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
// Helper to create mock user
|
||||
const createMockUser = (id: string, email: string, role: string): User => ({
|
||||
id,
|
||||
@@ -23,30 +44,21 @@ const createMockUser = (id: string, email: string, role: string): User => ({
|
||||
updatedAt: new Date(),
|
||||
});
|
||||
|
||||
// Mock the getSession and prisma functions
|
||||
mock.module('@/lib/auth-simple', () => ({
|
||||
getSession: mock(() => {}),
|
||||
}));
|
||||
|
||||
mock.module('@/lib/prisma', () => ({
|
||||
prisma: {
|
||||
user: {
|
||||
findUnique: mock(() => {}),
|
||||
},
|
||||
event: {
|
||||
findUnique: mock(() => {}),
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
describe('Permissions', () => {
|
||||
beforeEach(() => {
|
||||
// Reset mock implementations to default (no-op) before each test
|
||||
getSessionMock.mockImplementation(() => undefined);
|
||||
userFindUniqueMock.mockImplementation(() => undefined);
|
||||
eventFindUniqueMock.mockImplementation(() => undefined);
|
||||
});
|
||||
|
||||
describe('hasRole', () => {
|
||||
test('should allow club_admin to access tournament_admin resources', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: '1', email: 'test@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('1', 'test@example.com', 'club_admin')
|
||||
);
|
||||
|
||||
@@ -55,11 +67,11 @@ describe('Permissions', () => {
|
||||
});
|
||||
|
||||
test('should deny player from accessing tournament_admin resources', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: '1', email: 'test@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('1', 'test@example.com', 'player')
|
||||
);
|
||||
|
||||
@@ -68,7 +80,7 @@ describe('Permissions', () => {
|
||||
});
|
||||
|
||||
test('should deny unauthenticated user', async () => {
|
||||
getSession.mockImplementation(async () => null);
|
||||
getSessionMock.mockImplementation(async () => null);
|
||||
|
||||
const result = await hasRole('club_admin');
|
||||
expect(result.allowed).toBe(false);
|
||||
@@ -78,11 +90,11 @@ describe('Permissions', () => {
|
||||
|
||||
describe('canManageTournament', () => {
|
||||
test('should allow club_admin to manage any tournament', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('admin-1', 'admin@example.com', 'club_admin')
|
||||
);
|
||||
|
||||
@@ -91,11 +103,11 @@ describe('Permissions', () => {
|
||||
});
|
||||
|
||||
test('should deny player from managing tournaments', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'player-1', email: 'player@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('player-1', 'player@example.com', 'player')
|
||||
);
|
||||
|
||||
@@ -107,11 +119,11 @@ describe('Permissions', () => {
|
||||
|
||||
describe('canCreateTournaments', () => {
|
||||
test('should allow tournament_admin to create tournaments', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('admin-1', 'admin@example.com', 'tournament_admin')
|
||||
);
|
||||
|
||||
@@ -120,11 +132,11 @@ describe('Permissions', () => {
|
||||
});
|
||||
|
||||
test('should allow club_admin to create tournaments', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('admin-1', 'admin@example.com', 'club_admin')
|
||||
);
|
||||
|
||||
@@ -133,11 +145,11 @@ describe('Permissions', () => {
|
||||
});
|
||||
|
||||
test('should deny player from creating tournaments', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'player-1', email: 'player@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('player-1', 'player@example.com', 'player')
|
||||
);
|
||||
|
||||
|
||||
@@ -4,15 +4,19 @@
|
||||
* Tests the player deduplication logic for CSV uploads
|
||||
*/
|
||||
|
||||
import { describe, test, expect, mock, beforeEach } from 'bun:test';
|
||||
import { describe, test, expect, mock, beforeEach,} from 'bun:test';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
|
||||
// Create mock functions at module level
|
||||
const playerFindFirstMock = mock(() => {});
|
||||
const playerCreateMock = mock(() => {});
|
||||
|
||||
// Mock the prisma module
|
||||
mock.module('@/lib/prisma', () => ({
|
||||
prisma: {
|
||||
player: {
|
||||
findFirst: mock(() => {}),
|
||||
create: mock(() => {}),
|
||||
findFirst: playerFindFirstMock,
|
||||
create: playerCreateMock,
|
||||
},
|
||||
},
|
||||
}));
|
||||
@@ -46,7 +50,9 @@ async function findOrCreatePlayer(name: string) {
|
||||
|
||||
describe('Player Deduplication', () => {
|
||||
beforeEach(() => {
|
||||
mock.clearAllMocks();
|
||||
// Clear all mock history before each test
|
||||
playerFindFirstMock.mockClear();
|
||||
playerCreateMock.mockClear();
|
||||
});
|
||||
|
||||
describe('findOrCreatePlayer', () => {
|
||||
@@ -64,7 +70,7 @@ describe('Player Deduplication', () => {
|
||||
rating: 0,
|
||||
};
|
||||
|
||||
prisma.player.findFirst.mockImplementation(async () => mockPlayer);
|
||||
playerFindFirstMock.mockImplementation(async () => mockPlayer);
|
||||
|
||||
const result = await findOrCreatePlayer('Emily');
|
||||
|
||||
@@ -89,7 +95,7 @@ describe('Player Deduplication', () => {
|
||||
rating: 0,
|
||||
};
|
||||
|
||||
prisma.player.findFirst.mockImplementation(async () => mockPlayer);
|
||||
playerFindFirstMock.mockImplementation(async () => mockPlayer);
|
||||
|
||||
const result = await findOrCreatePlayer('EMILY');
|
||||
|
||||
@@ -114,7 +120,7 @@ describe('Player Deduplication', () => {
|
||||
rating: 0,
|
||||
};
|
||||
|
||||
prisma.player.findFirst.mockImplementation(async () => mockPlayer);
|
||||
playerFindFirstMock.mockImplementation(async () => mockPlayer);
|
||||
|
||||
const result = await findOrCreatePlayer(' Emily ');
|
||||
|
||||
@@ -126,7 +132,7 @@ describe('Player Deduplication', () => {
|
||||
});
|
||||
|
||||
test('should create new player if not found', async () => {
|
||||
prisma.player.findFirst.mockImplementation(async () => null);
|
||||
playerFindFirstMock.mockImplementation(async () => null);
|
||||
|
||||
const newPlayer = {
|
||||
id: 100,
|
||||
@@ -141,7 +147,7 @@ describe('Player Deduplication', () => {
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
prisma.player.create.mockImplementation(async () => newPlayer);
|
||||
playerCreateMock.mockImplementation(async () => newPlayer);
|
||||
|
||||
const result = await findOrCreatePlayer('NewPlayer');
|
||||
|
||||
@@ -162,7 +168,7 @@ describe('Player Deduplication', () => {
|
||||
});
|
||||
|
||||
test('should handle names with special characters', async () => {
|
||||
prisma.player.findFirst.mockImplementation(async () => null);
|
||||
playerFindFirstMock.mockImplementation(async () => null);
|
||||
|
||||
const newPlayer = {
|
||||
id: 100,
|
||||
@@ -177,7 +183,7 @@ describe('Player Deduplication', () => {
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
prisma.player.create.mockImplementation(async () => newPlayer);
|
||||
playerCreateMock.mockImplementation(async () => newPlayer);
|
||||
|
||||
const result = await findOrCreatePlayer('Test-Player_123');
|
||||
|
||||
@@ -195,7 +201,7 @@ describe('Player Deduplication', () => {
|
||||
});
|
||||
|
||||
test('should handle names with spaces', async () => {
|
||||
prisma.player.findFirst.mockImplementation(async () => null);
|
||||
playerFindFirstMock.mockImplementation(async () => null);
|
||||
|
||||
const newPlayer = {
|
||||
id: 100,
|
||||
@@ -210,7 +216,7 @@ describe('Player Deduplication', () => {
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
prisma.player.create.mockImplementation(async () => newPlayer);
|
||||
playerCreateMock.mockImplementation(async () => newPlayer);
|
||||
|
||||
const result = await findOrCreatePlayer('Dave B');
|
||||
|
||||
@@ -242,7 +248,7 @@ describe('Player Deduplication', () => {
|
||||
rating: 0,
|
||||
};
|
||||
|
||||
prisma.player.findFirst.mockImplementation(async () => mockPlayer);
|
||||
playerFindFirstMock.mockImplementation(async () => mockPlayer);
|
||||
|
||||
const result1 = await findOrCreatePlayer('EMILY');
|
||||
const result2 = await findOrCreatePlayer('Emily');
|
||||
@@ -255,7 +261,7 @@ describe('Player Deduplication', () => {
|
||||
});
|
||||
|
||||
test('should handle empty or whitespace-only names', async () => {
|
||||
prisma.player.findFirst.mockImplementation(async () => null);
|
||||
playerFindFirstMock.mockImplementation(async () => null);
|
||||
|
||||
const newPlayer = {
|
||||
id: 100,
|
||||
@@ -270,7 +276,7 @@ describe('Player Deduplication', () => {
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
prisma.player.create.mockImplementation(async () => newPlayer);
|
||||
playerCreateMock.mockImplementation(async () => newPlayer);
|
||||
|
||||
const result = await findOrCreatePlayer(' ');
|
||||
|
||||
@@ -320,7 +326,7 @@ describe('Player Deduplication', () => {
|
||||
rating: 0,
|
||||
};
|
||||
|
||||
prisma.player.findFirst
|
||||
playerFindFirstMock
|
||||
.mockResolvedValueOnce(existingPlayer) // First call for "Emily"
|
||||
.mockResolvedValueOnce(existingPlayer) // Second call for "EMILY"
|
||||
.mockResolvedValueOnce(existingPlayer); // Third call for " Emily "
|
||||
|
||||
@@ -11,20 +11,26 @@ import { describe, test, expect, mock, beforeEach } from 'bun:test';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import type { Player, Event, Match, PartnershipStat } from '@prisma/client';
|
||||
|
||||
// Create mock functions at module level
|
||||
const playerFindUniqueMock = mock(() => {});
|
||||
const eventFindManyMock = mock(() => {});
|
||||
const matchFindManyMock = mock(() => {});
|
||||
const partnershipStatFindManyMock = mock(() => {});
|
||||
|
||||
// Mock the prisma module
|
||||
mock.module('@/lib/prisma', () => ({
|
||||
prisma: {
|
||||
player: {
|
||||
findUnique: mock(() => {}),
|
||||
findUnique: playerFindUniqueMock,
|
||||
},
|
||||
event: {
|
||||
findMany: mock(() => {}),
|
||||
findMany: eventFindManyMock,
|
||||
},
|
||||
match: {
|
||||
findMany: mock(() => {}),
|
||||
findMany: matchFindManyMock,
|
||||
},
|
||||
partnershipStat: {
|
||||
findMany: mock(() => {}),
|
||||
findMany: partnershipStatFindManyMock,
|
||||
},
|
||||
},
|
||||
}));
|
||||
@@ -111,7 +117,11 @@ const createMockPartnershipStat = (
|
||||
|
||||
describe('Player Profile Enhancements', () => {
|
||||
beforeEach(() => {
|
||||
mock.clearAllMocks();
|
||||
// Reset mock implementations to default (no-op) before each test
|
||||
playerFindUniqueMock.mockImplementation(() => undefined);
|
||||
eventFindManyMock.mockImplementation(() => undefined);
|
||||
matchFindManyMock.mockImplementation(() => undefined);
|
||||
partnershipStatFindManyMock.mockImplementation(() => undefined);
|
||||
});
|
||||
|
||||
describe('Tournaments Participated', () => {
|
||||
@@ -122,8 +132,8 @@ describe('Player Profile Enhancements', () => {
|
||||
createMockTournament(2, 'Tournament B'),
|
||||
];
|
||||
|
||||
prisma.player.findUnique.mockImplementation(async () => mockPlayer);
|
||||
prisma.event.findMany.mockImplementation(async () => mockTournaments);
|
||||
playerFindUniqueMock.mockImplementation(async () => mockPlayer);
|
||||
eventFindManyMock.mockImplementation(async () => mockTournaments);
|
||||
|
||||
// Simulate the query that would be run
|
||||
const tournaments = await prisma.event.findMany({
|
||||
@@ -145,8 +155,8 @@ describe('Player Profile Enhancements', () => {
|
||||
test('should return empty array if player has no tournaments', async () => {
|
||||
const mockPlayer = createMockPlayer(1, 'Test Player');
|
||||
|
||||
prisma.player.findUnique.mockImplementation(async () => mockPlayer);
|
||||
prisma.event.findMany.mockImplementation(async () => []);
|
||||
playerFindUniqueMock.mockImplementation(async () => mockPlayer);
|
||||
eventFindManyMock.mockImplementation(async () => []);
|
||||
|
||||
const tournaments = await prisma.event.findMany({
|
||||
where: {
|
||||
@@ -173,8 +183,8 @@ describe('Player Profile Enhancements', () => {
|
||||
createMockMatch(2, 1, 3, 5, 6, 4, 4),
|
||||
];
|
||||
|
||||
prisma.player.findUnique.mockImplementation(async () => mockPlayer);
|
||||
prisma.match.findMany.mockImplementation(async () => mockMatches);
|
||||
playerFindUniqueMock.mockImplementation(async () => mockPlayer);
|
||||
matchFindManyMock.mockImplementation(async () => mockMatches);
|
||||
|
||||
// Simulate the query that would be run
|
||||
const matches = await prisma.match.findMany({
|
||||
@@ -204,8 +214,8 @@ describe('Player Profile Enhancements', () => {
|
||||
test('should return empty array if player has no matches', async () => {
|
||||
const mockPlayer = createMockPlayer(1, 'Test Player');
|
||||
|
||||
prisma.player.findUnique.mockImplementation(async () => mockPlayer);
|
||||
prisma.match.findMany.mockImplementation(async () => []);
|
||||
playerFindUniqueMock.mockImplementation(async () => mockPlayer);
|
||||
matchFindManyMock.mockImplementation(async () => []);
|
||||
|
||||
const matches = await prisma.match.findMany({
|
||||
where: {
|
||||
@@ -240,8 +250,8 @@ describe('Player Profile Enhancements', () => {
|
||||
createMockPartnershipStat(2, 1, 3, 5, 2, 3),
|
||||
];
|
||||
|
||||
prisma.player.findUnique.mockImplementation(async () => mockPlayer);
|
||||
prisma.partnershipStat.findMany.mockImplementation(async () => mockPartnershipStats);
|
||||
playerFindUniqueMock.mockImplementation(async () => mockPlayer);
|
||||
partnershipStatFindManyMock.mockImplementation(async () => mockPartnershipStats);
|
||||
|
||||
// Simulate the query that would be run
|
||||
const partnershipStats = await prisma.partnershipStat.findMany({
|
||||
@@ -265,8 +275,8 @@ describe('Player Profile Enhancements', () => {
|
||||
test('should return empty array if player has no partnership data', async () => {
|
||||
const mockPlayer = createMockPlayer(1, 'Test Player');
|
||||
|
||||
prisma.player.findUnique.mockImplementation(async () => mockPlayer);
|
||||
prisma.partnershipStat.findMany.mockImplementation(async () => []);
|
||||
playerFindUniqueMock.mockImplementation(async () => mockPlayer);
|
||||
partnershipStatFindManyMock.mockImplementation(async () => []);
|
||||
|
||||
const partnershipStats = await prisma.partnershipStat.findMany({
|
||||
where: {
|
||||
|
||||
@@ -11,19 +11,25 @@ import { getSession } from '@/lib/auth-simple';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import type { User, Event } from '@prisma/client';
|
||||
|
||||
// Create mock functions first
|
||||
const getSessionMock = mock(() => {});
|
||||
const userFindUniqueMock = mock(() => {});
|
||||
const eventFindUniqueMock = mock(() => {});
|
||||
const eventFindManyMock = mock(() => {});
|
||||
|
||||
// Mock the getSession and prisma functions
|
||||
mock.module('@/lib/auth-simple', () => ({
|
||||
getSession: mock(() => {}),
|
||||
getSession: getSessionMock,
|
||||
}));
|
||||
|
||||
mock.module('@/lib/prisma', () => ({
|
||||
prisma: {
|
||||
user: {
|
||||
findUnique: mock(() => {}),
|
||||
findUnique: userFindUniqueMock,
|
||||
},
|
||||
event: {
|
||||
findUnique: mock(() => {}),
|
||||
findMany: mock(() => {}),
|
||||
findUnique: eventFindUniqueMock,
|
||||
findMany: eventFindManyMock,
|
||||
},
|
||||
},
|
||||
}));
|
||||
@@ -61,16 +67,21 @@ const createMockTournament = (id: number, ownerId: string | null): Event => ({
|
||||
|
||||
describe('Tournament Permissions', () => {
|
||||
beforeEach(() => {
|
||||
mock.clearAllMocks();
|
||||
// Reset mock implementations to default (no-op) before each test
|
||||
// This prevents pollution from previous tests
|
||||
getSessionMock.mockImplementation(() => undefined);
|
||||
userFindUniqueMock.mockImplementation(() => undefined);
|
||||
eventFindUniqueMock.mockImplementation(() => undefined);
|
||||
eventFindManyMock.mockImplementation(() => undefined);
|
||||
});
|
||||
|
||||
describe('canManageTournament', () => {
|
||||
test('should allow club_admin to manage any tournament', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('admin-1', 'admin@example.com', 'club_admin')
|
||||
);
|
||||
|
||||
@@ -79,14 +90,14 @@ describe('Tournament Permissions', () => {
|
||||
});
|
||||
|
||||
test('should allow tournament_admin to manage their own tournament', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'tour-admin-1', email: 'tour@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('tour-admin-1', 'tour@example.com', 'tournament_admin')
|
||||
);
|
||||
prisma.event.findUnique.mockImplementation(async () =>
|
||||
eventFindUniqueMock.mockImplementation(async () =>
|
||||
createMockTournament(1, 'tour-admin-1')
|
||||
);
|
||||
|
||||
@@ -95,14 +106,14 @@ describe('Tournament Permissions', () => {
|
||||
});
|
||||
|
||||
test('should deny tournament_admin from managing other users tournaments', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'tour-admin-1', email: 'tour@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('tour-admin-1', 'tour@example.com', 'tournament_admin')
|
||||
);
|
||||
prisma.event.findUnique.mockImplementation(async () =>
|
||||
eventFindUniqueMock.mockImplementation(async () =>
|
||||
createMockTournament(1, 'other-user-1')
|
||||
);
|
||||
|
||||
@@ -112,11 +123,11 @@ describe('Tournament Permissions', () => {
|
||||
});
|
||||
|
||||
test('should deny player from managing tournaments', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'player-1', email: 'player@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('player-1', 'player@example.com', 'player')
|
||||
);
|
||||
|
||||
@@ -126,7 +137,7 @@ describe('Tournament Permissions', () => {
|
||||
});
|
||||
|
||||
test('should deny unauthenticated user', async () => {
|
||||
getSession.mockImplementation(async () => null);
|
||||
getSessionMock.mockImplementation(async () => null);
|
||||
|
||||
const result = await canManageTournament(999);
|
||||
expect(result.allowed).toBe(false);
|
||||
@@ -136,11 +147,11 @@ describe('Tournament Permissions', () => {
|
||||
|
||||
describe('ownsTournament', () => {
|
||||
test('should return true if user owns tournament', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'owner-1', email: 'owner@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.event.findUnique.mockImplementation(async () =>
|
||||
eventFindUniqueMock.mockImplementation(async () =>
|
||||
createMockTournament(1, 'owner-1')
|
||||
);
|
||||
|
||||
@@ -149,11 +160,11 @@ describe('Tournament Permissions', () => {
|
||||
});
|
||||
|
||||
test('should return false if user does not own tournament', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'non-owner-1', email: 'nonowner@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.event.findUnique.mockImplementation(async () =>
|
||||
eventFindUniqueMock.mockImplementation(async () =>
|
||||
createMockTournament(1, 'owner-1')
|
||||
);
|
||||
|
||||
@@ -165,11 +176,11 @@ describe('Tournament Permissions', () => {
|
||||
|
||||
describe('getManageableTournaments', () => {
|
||||
test('should return all tournaments for club_admin', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('admin-1', 'admin@example.com', 'club_admin')
|
||||
);
|
||||
|
||||
@@ -178,11 +189,11 @@ describe('Tournament Permissions', () => {
|
||||
createMockTournament(2, 'user-2'),
|
||||
createMockTournament(3, 'user-3'),
|
||||
];
|
||||
prisma.event.findMany.mockImplementation(async () => mockTournaments);
|
||||
eventFindManyMock.mockImplementation(async () => mockTournaments);
|
||||
|
||||
const result = await getManageableTournaments();
|
||||
expect(result).toEqual(mockTournaments);
|
||||
expect(prisma.event.findMany).toHaveBeenCalledWith({
|
||||
expect(eventFindManyMock).toHaveBeenCalledWith({
|
||||
where: { eventType: 'tournament' },
|
||||
include: { participants: true },
|
||||
orderBy: { createdAt: 'desc' }
|
||||
@@ -190,11 +201,11 @@ describe('Tournament Permissions', () => {
|
||||
});
|
||||
|
||||
test('should return only owned tournaments for tournament_admin', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'tour-admin-1', email: 'tour@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('tour-admin-1', 'tour@example.com', 'tournament_admin')
|
||||
);
|
||||
|
||||
@@ -202,11 +213,11 @@ describe('Tournament Permissions', () => {
|
||||
createMockTournament(1, 'tour-admin-1'),
|
||||
createMockTournament(2, 'tour-admin-1'),
|
||||
];
|
||||
prisma.event.findMany.mockImplementation(async () => mockTournaments);
|
||||
eventFindManyMock.mockImplementation(async () => mockTournaments);
|
||||
|
||||
const result = await getManageableTournaments();
|
||||
expect(result).toEqual(mockTournaments);
|
||||
expect(prisma.event.findMany).toHaveBeenCalledWith({
|
||||
expect(eventFindManyMock).toHaveBeenCalledWith({
|
||||
where: {
|
||||
eventType: 'tournament',
|
||||
ownerId: 'tour-admin-1'
|
||||
@@ -217,11 +228,11 @@ describe('Tournament Permissions', () => {
|
||||
});
|
||||
|
||||
test('should return only non-draft tournaments for players', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'player-1', email: 'player@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('player-1', 'player@example.com', 'player')
|
||||
);
|
||||
|
||||
@@ -229,11 +240,11 @@ describe('Tournament Permissions', () => {
|
||||
createMockTournament(1, 'user-1'),
|
||||
createMockTournament(2, 'user-2'),
|
||||
];
|
||||
prisma.event.findMany.mockImplementation(async () => mockTournaments);
|
||||
eventFindManyMock.mockImplementation(async () => mockTournaments);
|
||||
|
||||
const result = await getManageableTournaments();
|
||||
expect(result).toEqual(mockTournaments);
|
||||
expect(prisma.event.findMany).toHaveBeenCalledWith({
|
||||
expect(eventFindManyMock).toHaveBeenCalledWith({
|
||||
where: {
|
||||
eventType: 'tournament',
|
||||
status: { not: 'draft' }
|
||||
@@ -249,14 +260,14 @@ describe('Tournament Permissions', () => {
|
||||
// This simulates the scenario where a tournament_admin user
|
||||
// clicks "Edit" on a tournament they own
|
||||
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'tour-admin-1', email: 'tour@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('tour-admin-1', 'tour@example.com', 'tournament_admin')
|
||||
);
|
||||
prisma.event.findUnique.mockImplementation(async () =>
|
||||
eventFindUniqueMock.mockImplementation(async () =>
|
||||
createMockTournament(1, 'tour-admin-1')
|
||||
);
|
||||
|
||||
@@ -271,11 +282,11 @@ describe('Tournament Permissions', () => {
|
||||
test('club_admin should still be able to manage any tournament', async () => {
|
||||
// This ensures we didn't break the existing club_admin functionality
|
||||
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'club-admin-1', email: 'club@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('club-admin-1', 'club@example.com', 'club_admin')
|
||||
);
|
||||
|
||||
@@ -286,13 +297,16 @@ describe('Tournament Permissions', () => {
|
||||
test('players should still be denied from managing tournaments', async () => {
|
||||
// This ensures we didn't accidentally grant players access
|
||||
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'player-1', email: 'player@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('player-1', 'player@example.com', 'player')
|
||||
);
|
||||
eventFindUniqueMock.mockImplementation(async () =>
|
||||
createMockTournament(1, 'other-user-1')
|
||||
);
|
||||
|
||||
const result = await canManageTournament(1);
|
||||
expect(result.allowed).toBe(false);
|
||||
|
||||
@@ -3,23 +3,33 @@
|
||||
* Tests the allowTies field is properly saved when updating tournaments
|
||||
*/
|
||||
|
||||
import { describe, it, expect, mock, beforeEach } from 'bun:test';
|
||||
import { describe, it, expect, mock, beforeEach,} from 'bun:test';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
|
||||
// Create mock functions at module level
|
||||
const eventFindUniqueMock = mock(() => {});
|
||||
const eventUpdateMock = mock(() => {});
|
||||
const canManageTournamentMock = mock(() => {});
|
||||
const canDeleteTournamentMock = mock(() => {});
|
||||
|
||||
// Store default implementations
|
||||
const defaultCanManageTournament = canManageTournamentMock.mockResolvedValue({ allowed: true });
|
||||
const defaultCanDeleteTournament = canDeleteTournamentMock.mockResolvedValue({ allowed: true });
|
||||
|
||||
// Mock the prisma client
|
||||
mock.module('@/lib/prisma', () => ({
|
||||
prisma: {
|
||||
event: {
|
||||
findUnique: mock(() => {}),
|
||||
update: mock(() => {}),
|
||||
findUnique: eventFindUniqueMock,
|
||||
update: eventUpdateMock,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
// Mock the permissions module
|
||||
mock.module('@/lib/permissions', () => ({
|
||||
canManageTournament: mock(() => {}).mockResolvedValue({ allowed: true }),
|
||||
canDeleteTournament: mock(() => {}).mockResolvedValue({ allowed: true }),
|
||||
canManageTournament: defaultCanManageTournament,
|
||||
canDeleteTournament: defaultCanDeleteTournament,
|
||||
}));
|
||||
|
||||
// Import the route handler after mocking
|
||||
@@ -27,12 +37,16 @@ import { PUT } from '@/app/api/tournaments/[id]/route';
|
||||
|
||||
describe('Tournament Update API', () => {
|
||||
beforeEach(() => {
|
||||
mock.clearAllMocks();
|
||||
// Clear all mock history before each test
|
||||
eventFindUniqueMock.mockClear();
|
||||
eventUpdateMock.mockClear();
|
||||
canManageTournamentMock.mockClear();
|
||||
canDeleteTournamentMock.mockClear();
|
||||
});
|
||||
|
||||
it('should update allowTies field when provided', async () => {
|
||||
// Mock existing tournament
|
||||
prisma.event.findUnique.mockImplementation(async () => ({
|
||||
eventFindUniqueMock.mockImplementation(async () => ({
|
||||
id: 1,
|
||||
name: 'Test Tournament',
|
||||
allowTies: false,
|
||||
@@ -49,7 +63,7 @@ describe('Tournament Update API', () => {
|
||||
} as any));
|
||||
|
||||
// Mock successful update
|
||||
prisma.event.update.mockImplementation(async () => ({
|
||||
eventUpdateMock.mockImplementation(async () => ({
|
||||
id: 1,
|
||||
name: 'Test Tournament',
|
||||
allowTies: true,
|
||||
@@ -89,7 +103,7 @@ describe('Tournament Update API', () => {
|
||||
|
||||
it('should default allowTies to false when not provided', async () => {
|
||||
// Mock existing tournament
|
||||
prisma.event.findUnique.mockImplementation(async () => ({
|
||||
eventFindUniqueMock.mockImplementation(async () => ({
|
||||
id: 1,
|
||||
name: 'Test Tournament',
|
||||
allowTies: true,
|
||||
@@ -106,7 +120,7 @@ describe('Tournament Update API', () => {
|
||||
} as any));
|
||||
|
||||
// Mock successful update
|
||||
prisma.event.update.mockImplementation(async () => ({
|
||||
eventUpdateMock.mockImplementation(async () => ({
|
||||
id: 1,
|
||||
name: 'Test Tournament',
|
||||
allowTies: false,
|
||||
@@ -146,7 +160,7 @@ describe('Tournament Update API', () => {
|
||||
|
||||
it('should preserve allowTies value when updating other fields', async () => {
|
||||
// Mock existing tournament with allowTies = true
|
||||
prisma.event.findUnique.mockImplementation(async () => ({
|
||||
eventFindUniqueMock.mockImplementation(async () => ({
|
||||
id: 1,
|
||||
name: 'Test Tournament',
|
||||
allowTies: true,
|
||||
@@ -163,7 +177,7 @@ describe('Tournament Update API', () => {
|
||||
} as any));
|
||||
|
||||
// Mock successful update
|
||||
prisma.event.update.mockImplementation(async () => ({
|
||||
eventUpdateMock.mockImplementation(async () => ({
|
||||
id: 1,
|
||||
name: 'Updated Tournament Name',
|
||||
allowTies: true,
|
||||
@@ -192,7 +206,7 @@ describe('Tournament Update API', () => {
|
||||
const response = await PUT(request, { params });
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
const updateCall = prisma.event.update.mock.calls[0][0];
|
||||
const updateCall = eventUpdateMock.mock.calls[0][0];
|
||||
expect(updateCall.data.allowTies).toBe(true);
|
||||
expect(updateCall.data.name).toBe('Updated Tournament Name');
|
||||
expect(updateCall.data.targetScore).toBe(10);
|
||||
|
||||
@@ -4,25 +4,31 @@
|
||||
* Tests for user name editing and profile management
|
||||
*/
|
||||
|
||||
import { describe, test, expect, mock, beforeEach } from 'bun:test';
|
||||
import { describe, test, expect, mock, beforeEach,} from 'bun:test';
|
||||
import { hasRole } from '@/lib/permissions';
|
||||
import { getSession } from '@/lib/auth-simple';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import type { User, Player } from '@prisma/client';
|
||||
|
||||
// Create mock functions at module level
|
||||
const getSessionMock = mock(() => {});
|
||||
const userFindUniqueMock = mock(() => {});
|
||||
const userUpdateMock = mock(() => {});
|
||||
const playerFindUniqueMock = mock(() => {});
|
||||
|
||||
// Mock the getSession and prisma functions
|
||||
mock.module('@/lib/auth-simple', () => ({
|
||||
getSession: mock(() => {}),
|
||||
getSession: getSessionMock,
|
||||
}));
|
||||
|
||||
mock.module('@/lib/prisma', () => ({
|
||||
prisma: {
|
||||
user: {
|
||||
findUnique: mock(() => {}),
|
||||
update: mock(() => {}),
|
||||
findUnique: userFindUniqueMock,
|
||||
update: userUpdateMock,
|
||||
},
|
||||
player: {
|
||||
findUnique: mock(() => {}),
|
||||
findUnique: playerFindUniqueMock,
|
||||
},
|
||||
},
|
||||
}));
|
||||
@@ -56,16 +62,20 @@ const createMockPlayer = (id: number, name: string): Player => ({
|
||||
|
||||
describe('User Management', () => {
|
||||
beforeEach(() => {
|
||||
mock.clearAllMocks();
|
||||
// Reset mock implementations to default (no-op) before each test
|
||||
getSessionMock.mockImplementation(() => undefined);
|
||||
userFindUniqueMock.mockImplementation(() => undefined);
|
||||
userUpdateMock.mockImplementation(() => undefined);
|
||||
playerFindUniqueMock.mockImplementation(() => undefined);
|
||||
});
|
||||
|
||||
describe('User Name Editing', () => {
|
||||
test('club_admin should be able to edit any user name', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('admin-1', 'admin@example.com', 'club_admin')
|
||||
);
|
||||
|
||||
@@ -74,11 +84,11 @@ describe('User Management', () => {
|
||||
});
|
||||
|
||||
test('tournament_admin should NOT be able to edit user names', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('tour-admin-1', 'tour@example.com', 'tournament_admin')
|
||||
);
|
||||
|
||||
@@ -87,11 +97,11 @@ describe('User Management', () => {
|
||||
});
|
||||
|
||||
test('player should NOT be able to edit user names', async () => {
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () =>
|
||||
userFindUniqueMock.mockImplementation(async () =>
|
||||
createMockUser('player-1', 'player@example.com', 'player')
|
||||
);
|
||||
|
||||
@@ -100,7 +110,7 @@ describe('User Management', () => {
|
||||
});
|
||||
|
||||
test('unauthenticated user should NOT be able to edit user names', async () => {
|
||||
getSession.mockImplementation(async () => null);
|
||||
getSessionMock.mockImplementation(async () => null);
|
||||
|
||||
const result = await hasRole('club_admin');
|
||||
expect(result.allowed).toBe(false);
|
||||
@@ -111,11 +121,11 @@ describe('User Management', () => {
|
||||
test('user should be able to view their own profile', async () => {
|
||||
const mockUser = createMockUser('user-1', 'user@example.com', 'player');
|
||||
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () => mockUser);
|
||||
userFindUniqueMock.mockImplementation(async () => mockUser);
|
||||
|
||||
// In the actual implementation, this would check if session.user.id === params.id
|
||||
const canViewOwnProfile = true; // This logic is in the API route
|
||||
@@ -126,11 +136,11 @@ describe('User Management', () => {
|
||||
const mockAdmin = createMockUser('admin-1', 'admin@example.com', 'club_admin');
|
||||
const mockUser = createMockUser('user-1', 'user@example.com', 'player');
|
||||
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
(prisma.user.findUnique)
|
||||
(userFindUniqueMock)
|
||||
.mockResolvedValueOnce(mockAdmin) // For the requesting user
|
||||
.mockResolvedValueOnce(mockUser); // For the target user
|
||||
|
||||
@@ -142,11 +152,11 @@ describe('User Management', () => {
|
||||
test('non-admin should NOT be able to view other user profiles', async () => {
|
||||
const mockUser = createMockUser('user-1', 'user@example.com', 'player');
|
||||
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () => mockUser);
|
||||
userFindUniqueMock.mockImplementation(async () => mockUser);
|
||||
|
||||
// In the actual implementation, this would check if session.user.id === params.id
|
||||
const canViewOtherProfile = false; // This logic is in the API route
|
||||
@@ -159,11 +169,11 @@ describe('User Management', () => {
|
||||
const mockUser = createMockUser('user-1', 'user@example.com', 'club_admin');
|
||||
const mockPlayer = createMockPlayer(1, 'Old Name');
|
||||
|
||||
getSession.mockImplementation(async () => ({
|
||||
getSessionMock.mockImplementation(async () => ({
|
||||
user: { id: 'admin-1', email: 'admin@example.com' },
|
||||
session: { token: 'test', expiresAt: new Date() }
|
||||
}));
|
||||
prisma.user.findUnique.mockImplementation(async () => mockUser);
|
||||
userFindUniqueMock.mockImplementation(async () => mockUser);
|
||||
|
||||
const updatedUser = {
|
||||
...mockUser,
|
||||
@@ -171,7 +181,7 @@ describe('User Management', () => {
|
||||
player: { ...mockPlayer, name: 'New Name', normalizedName: 'new name' }
|
||||
};
|
||||
|
||||
prisma.user.update.mockImplementation(async () => updatedUser);
|
||||
userUpdateMock.mockImplementation(async () => updatedUser);
|
||||
|
||||
// The API route should update both user.name and player.name
|
||||
expect(updatedUser.name).toBe('New Name');
|
||||
|
||||
Reference in New Issue
Block a user