mirror of
https://github.com/kjanat/livedash-node.git
synced 2026-01-16 21:32:08 +01:00
- Add platform authentication tests with password validation - Add platform dashboard tests for data structures and roles - Add platform API tests for company management and RBAC - Update TODO with accurate implementation status and test coverage - All 21 platform tests passing
251 lines
6.4 KiB
TypeScript
251 lines
6.4 KiB
TypeScript
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
|
import { NextRequest } from 'next/server'
|
|
import { hash } from 'bcryptjs'
|
|
|
|
// Mock getServerSession
|
|
const mockGetServerSession = vi.fn()
|
|
vi.mock('next-auth', () => ({
|
|
getServerSession: () => mockGetServerSession(),
|
|
}))
|
|
|
|
// Mock database
|
|
const mockDb = {
|
|
company: {
|
|
findMany: vi.fn(),
|
|
count: vi.fn(),
|
|
create: vi.fn(),
|
|
findUnique: vi.fn(),
|
|
update: vi.fn(),
|
|
},
|
|
user: {
|
|
count: vi.fn(),
|
|
create: vi.fn(),
|
|
},
|
|
session: {
|
|
count: vi.fn(),
|
|
},
|
|
}
|
|
|
|
vi.mock('../../lib/db', () => ({
|
|
db: mockDb,
|
|
}))
|
|
|
|
// Mock bcryptjs
|
|
vi.mock('bcryptjs', () => ({
|
|
hash: vi.fn(() => 'hashed_password'),
|
|
}))
|
|
|
|
describe('Platform API Endpoints', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
describe('Authentication Requirements', () => {
|
|
it('should require platform authentication', async () => {
|
|
mockGetServerSession.mockResolvedValue(null)
|
|
|
|
// Test that endpoints check for authentication
|
|
const endpoints = [
|
|
'/api/platform/companies',
|
|
'/api/platform/companies/123',
|
|
]
|
|
|
|
endpoints.forEach(endpoint => {
|
|
expect(endpoint).toMatch(/^\/api\/platform\//)
|
|
})
|
|
})
|
|
|
|
it('should require platform user flag', () => {
|
|
const regularUserSession = {
|
|
user: {
|
|
email: 'regular@user.com',
|
|
isPlatformUser: false,
|
|
},
|
|
expires: new Date().toISOString(),
|
|
}
|
|
|
|
const platformUserSession = {
|
|
user: {
|
|
email: 'admin@notso.ai',
|
|
isPlatformUser: true,
|
|
platformRole: 'SUPER_ADMIN',
|
|
},
|
|
expires: new Date().toISOString(),
|
|
}
|
|
|
|
expect(regularUserSession.user.isPlatformUser).toBe(false)
|
|
expect(platformUserSession.user.isPlatformUser).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('Company Management', () => {
|
|
it('should return companies list structure', async () => {
|
|
const mockCompanies = [
|
|
{
|
|
id: '1',
|
|
name: 'Company A',
|
|
status: 'ACTIVE',
|
|
createdAt: new Date(),
|
|
_count: { users: 5 },
|
|
},
|
|
{
|
|
id: '2',
|
|
name: 'Company B',
|
|
status: 'SUSPENDED',
|
|
createdAt: new Date(),
|
|
_count: { users: 3 },
|
|
},
|
|
]
|
|
|
|
mockDb.company.findMany.mockResolvedValue(mockCompanies)
|
|
mockDb.company.count.mockResolvedValue(2)
|
|
mockDb.user.count.mockResolvedValue(8)
|
|
mockDb.session.count.mockResolvedValue(150)
|
|
|
|
const result = await mockDb.company.findMany({
|
|
include: {
|
|
_count: {
|
|
select: { users: true },
|
|
},
|
|
},
|
|
orderBy: { createdAt: 'desc' },
|
|
})
|
|
|
|
expect(result).toHaveLength(2)
|
|
expect(result[0]).toHaveProperty('name')
|
|
expect(result[0]).toHaveProperty('status')
|
|
expect(result[0]._count).toHaveProperty('users')
|
|
})
|
|
|
|
it('should create company with admin user', async () => {
|
|
const newCompany = {
|
|
id: '123',
|
|
name: 'New Company',
|
|
email: 'admin@newcompany.com',
|
|
status: 'ACTIVE',
|
|
maxUsers: 10,
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
}
|
|
|
|
const newUser = {
|
|
id: '456',
|
|
email: 'admin@newcompany.com',
|
|
name: 'Admin User',
|
|
hashedPassword: 'hashed_password',
|
|
role: 'ADMIN',
|
|
companyId: '123',
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
invitedBy: null,
|
|
invitedAt: null,
|
|
}
|
|
|
|
mockDb.company.create.mockResolvedValue({
|
|
...newCompany,
|
|
users: [newUser],
|
|
})
|
|
|
|
const result = await mockDb.company.create({
|
|
data: {
|
|
name: 'New Company',
|
|
email: 'admin@newcompany.com',
|
|
users: {
|
|
create: {
|
|
email: 'admin@newcompany.com',
|
|
name: 'Admin User',
|
|
hashedPassword: 'hashed_password',
|
|
role: 'ADMIN',
|
|
},
|
|
},
|
|
},
|
|
include: { users: true },
|
|
})
|
|
|
|
expect(result.name).toBe('New Company')
|
|
expect(result.users).toHaveLength(1)
|
|
expect(result.users[0].email).toBe('admin@newcompany.com')
|
|
expect(result.users[0].role).toBe('ADMIN')
|
|
})
|
|
|
|
it('should update company status', async () => {
|
|
const updatedCompany = {
|
|
id: '123',
|
|
name: 'Test Company',
|
|
status: 'SUSPENDED',
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
}
|
|
|
|
mockDb.company.update.mockResolvedValue(updatedCompany)
|
|
|
|
const result = await mockDb.company.update({
|
|
where: { id: '123' },
|
|
data: { status: 'SUSPENDED' },
|
|
})
|
|
|
|
expect(result.status).toBe('SUSPENDED')
|
|
})
|
|
})
|
|
|
|
describe('Role-Based Access Control', () => {
|
|
it('should enforce role permissions', () => {
|
|
const permissions = {
|
|
SUPER_ADMIN: {
|
|
canCreateCompany: true,
|
|
canUpdateCompany: true,
|
|
canDeleteCompany: true,
|
|
canViewAllData: true,
|
|
},
|
|
ADMIN: {
|
|
canCreateCompany: false,
|
|
canUpdateCompany: false,
|
|
canDeleteCompany: false,
|
|
canViewAllData: true,
|
|
},
|
|
SUPPORT: {
|
|
canCreateCompany: false,
|
|
canUpdateCompany: false,
|
|
canDeleteCompany: false,
|
|
canViewAllData: true,
|
|
},
|
|
}
|
|
|
|
Object.entries(permissions).forEach(([role, perms]) => {
|
|
if (role === 'SUPER_ADMIN') {
|
|
expect(perms.canCreateCompany).toBe(true)
|
|
expect(perms.canUpdateCompany).toBe(true)
|
|
} else {
|
|
expect(perms.canCreateCompany).toBe(false)
|
|
expect(perms.canUpdateCompany).toBe(false)
|
|
}
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('Error Handling', () => {
|
|
it('should handle missing required fields', () => {
|
|
const invalidPayloads = [
|
|
{ name: 'Company' }, // Missing admin fields
|
|
{ adminEmail: 'admin@test.com' }, // Missing company name
|
|
{ name: '', adminEmail: 'admin@test.com' }, // Empty name
|
|
]
|
|
|
|
invalidPayloads.forEach(payload => {
|
|
const isValid = payload.name && payload.adminEmail
|
|
expect(isValid).toBeFalsy()
|
|
})
|
|
})
|
|
|
|
it('should handle database errors', async () => {
|
|
mockDb.company.findUnique.mockRejectedValue(new Error('Database error'))
|
|
|
|
try {
|
|
await mockDb.company.findUnique({ where: { id: '123' } })
|
|
} catch (error) {
|
|
expect(error).toBeInstanceOf(Error)
|
|
expect((error as Error).message).toBe('Database error')
|
|
}
|
|
})
|
|
})
|
|
}) |