Files
livedash-node/tests/integration/platform-api.test.ts
Kaj Kowalski cd05fc8648 fix: resolve Prettier markdown code block parsing errors
- Fix syntax errors in skills markdown files (.github/skills, .opencode/skills)
- Change typescript to tsx for code blocks with JSX
- Replace ellipsis (...) in array examples with valid syntax
- Separate CSS from TypeScript into distinct code blocks
- Convert JavaScript object examples to valid JSON in docs
- Fix enum definitions with proper comma separation
2026-01-20 21:09:29 +01:00

257 lines
6.6 KiB
TypeScript

import { describe, it, expect, beforeEach, vi } from "vitest";
// Mock neonAuth from lib/auth/server
const mockNeonAuth = vi.fn();
vi.mock("../../lib/auth/server", () => ({
neonAuth: () => mockNeonAuth(),
getAuthenticatedPlatformUser: () => mockNeonAuth(),
hasPlatformAccess: vi.fn(() => true),
isPlatformRole: vi.fn((role: string) =>
["PLATFORM_SUPER_ADMIN", "PLATFORM_ADMIN", "PLATFORM_SUPPORT"].includes(
role
)
),
}));
// 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 () => {
mockNeonAuth.mockResolvedValue({ user: 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 role", () => {
const regularUser = {
id: "1",
email: "regular@user.com",
role: "USER",
companyId: "company-123",
};
const platformUser = {
id: "2",
email: "admin@notso.ai",
role: "PLATFORM_SUPER_ADMIN",
companyId: null,
};
const isPlatformRole = (role: string) =>
["PLATFORM_SUPER_ADMIN", "PLATFORM_ADMIN", "PLATFORM_SUPPORT"].includes(
role
);
expect(isPlatformRole(regularUser.role)).toBe(false);
expect(isPlatformRole(platformUser.role)).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 placeholder", async () => {
const newCompany = {
id: "123",
name: "New Company",
status: "ACTIVE",
maxUsers: 10,
createdAt: new Date(),
updatedAt: new Date(),
};
const newUser = {
id: "456",
email: "admin@newcompany.com",
name: "Admin User",
role: "ADMIN",
companyId: "123",
createdAt: new Date(),
updatedAt: new Date(),
invitedBy: "platform@notso.ai",
invitedAt: new Date(),
};
mockDb.company.create.mockResolvedValue({
...newCompany,
users: [newUser],
});
const result = await mockDb.company.create({
data: {
name: "New Company",
users: {
create: {
email: "admin@newcompany.com",
name: "Admin User",
role: "ADMIN",
invitedBy: "platform@notso.ai",
invitedAt: new Date(),
},
},
},
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");
}
});
});
});