Files
livedash-node/tests/api/dashboard-metrics.test.ts
Kaj Kowalski fa7e815a3b feat: complete tRPC integration and fix platform UI issues
- Implement comprehensive tRPC setup with type-safe API
- Create tRPC routers for dashboard, admin, and auth endpoints
- Migrate frontend components to use tRPC client
- Fix platform dashboard Settings button functionality
- Add platform settings page with profile and security management
- Create OpenAI API mocking infrastructure for cost-safe testing
- Update tests to work with new tRPC architecture
- Sync database schema to fix AIBatchRequest table errors
2025-07-12 00:27:57 +02:00

344 lines
10 KiB
TypeScript

import { describe, it, expect, beforeEach, vi } from "vitest";
import { NextRequest } from "next/server";
import { GET } from "../../app/api/dashboard/metrics/route";
// Mock NextAuth
vi.mock("next-auth", () => ({
getServerSession: vi.fn(),
}));
// Mock prisma
vi.mock("../../lib/prisma", () => ({
prisma: {
user: {
findUnique: vi.fn(),
},
company: {
findUnique: vi.fn(),
},
session: {
findMany: vi.fn(),
count: vi.fn(),
},
sessionQuestion: {
findMany: vi.fn(),
},
},
}));
describe("/api/dashboard/metrics", () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe("GET", () => {
it("should return 401 for unauthenticated users", async () => {
const { getServerSession } = await import("next-auth");
vi.mocked(getServerSession).mockResolvedValue(null);
const request = new NextRequest(
"http://localhost:3000/api/dashboard/metrics"
);
const response = await GET(request);
expect(response.status).toBe(401);
const data = await response.json();
expect(data.error).toBe("Unauthorized");
});
it("should return 404 when user not found", async () => {
const { getServerSession } = await import("next-auth");
const { prisma } = await import("../../lib/prisma");
vi.mocked(getServerSession).mockResolvedValue({
user: { email: "test@example.com" },
expires: "2024-12-31",
});
vi.mocked(prisma.user.findUnique).mockResolvedValue(null);
const request = new NextRequest(
"http://localhost:3000/api/dashboard/metrics"
);
const response = await GET(request);
expect(response.status).toBe(404);
const data = await response.json();
expect(data.error).toBe("User not found");
});
it("should return 404 when company not found", async () => {
const { getServerSession } = await import("next-auth");
const { prisma } = await import("../../lib/prisma");
vi.mocked(getServerSession).mockResolvedValue({
user: { email: "test@example.com" },
expires: "2024-12-31",
});
vi.mocked(prisma.user.findUnique).mockResolvedValue({
id: "user1",
name: "Test User",
email: "test@example.com",
companyId: "company1",
role: "ADMIN" as const,
password: "hashed",
resetToken: null,
resetTokenExpiry: null,
invitedAt: null,
invitedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
});
vi.mocked(prisma.company.findUnique).mockResolvedValue(null);
const request = new NextRequest(
"http://localhost:3000/api/dashboard/metrics"
);
const response = await GET(request);
expect(response.status).toBe(404);
const data = await response.json();
expect(data.error).toBe("Company not found");
});
it("should return dashboard metrics successfully for admin", async () => {
const { getServerSession } = await import("next-auth");
const { prisma } = await import("../../lib/prisma");
vi.mocked(getServerSession).mockResolvedValue({
user: { email: "admin@example.com" },
expires: "2024-12-31",
});
const mockUser = {
id: "user1",
name: "Test Admin",
email: "admin@example.com",
companyId: "company1",
role: "ADMIN" as const,
password: "hashed",
resetToken: null,
resetTokenExpiry: null,
invitedAt: null,
invitedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
};
const mockCompany = {
id: "company1",
name: "Test Company",
csvUrl: "http://example.com/data.csv",
csvUsername: null,
csvPassword: null,
dashboardOpts: {},
maxUsers: 10,
status: "ACTIVE" as const,
createdAt: new Date(),
updatedAt: new Date(),
};
const mockSessions = [
{
id: "session1",
companyId: "company1",
importId: "import1",
startTime: new Date("2024-01-01T10:00:00Z"),
endTime: new Date("2024-01-01T11:00:00Z"),
ipAddress: "192.168.1.1",
country: "US",
fullTranscriptUrl: null,
avgResponseTime: null,
initialMsg: null,
messagesSent: 5,
escalated: false,
forwardedHr: false,
sentiment: "POSITIVE" as const,
category: "SCHEDULE_HOURS" as const,
language: "en",
summary: "Test summary",
createdAt: new Date(),
updatedAt: new Date(),
},
];
vi.mocked(prisma.user.findUnique).mockResolvedValue(mockUser);
vi.mocked(prisma.company.findUnique).mockResolvedValue(mockCompany);
vi.mocked(prisma.session.findMany).mockResolvedValue(mockSessions);
vi.mocked(prisma.session.count).mockResolvedValue(1);
vi.mocked(prisma.sessionQuestion.findMany).mockResolvedValue([]);
const request = new NextRequest(
"http://localhost:3000/api/dashboard/metrics"
);
const response = await GET(request);
expect(response.status).toBe(200);
const data = await response.json();
expect(data).toHaveProperty("totalSessions");
expect(data).toHaveProperty("sentimentDistribution");
expect(data).toHaveProperty("countryCounts");
expect(data).toHaveProperty("topQuestions");
expect(data.totalSessions).toBe(1);
});
it("should return dashboard metrics successfully for regular user", async () => {
const { getServerSession } = await import("next-auth");
const { prisma } = await import("../../lib/prisma");
vi.mocked(getServerSession).mockResolvedValue({
user: { email: "user@example.com" },
expires: "2024-12-31",
});
const mockUser = {
id: "user1",
name: "Test User",
email: "user@example.com",
companyId: "company1",
role: "USER" as const,
password: "hashed",
resetToken: null,
resetTokenExpiry: null,
invitedAt: null,
invitedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
};
const mockCompany = {
id: "company1",
name: "Test Company",
csvUrl: "http://example.com/data.csv",
csvUsername: null,
csvPassword: null,
dashboardOpts: {},
maxUsers: 10,
status: "ACTIVE" as const,
createdAt: new Date(),
updatedAt: new Date(),
};
const mockSessions = [
{
id: "session1",
companyId: "company1",
importId: "import1",
startTime: new Date("2024-01-01T10:00:00Z"),
endTime: new Date("2024-01-01T11:00:00Z"),
ipAddress: "192.168.1.1",
country: "US",
fullTranscriptUrl: null,
avgResponseTime: null,
initialMsg: null,
messagesSent: 5,
escalated: false,
forwardedHr: false,
sentiment: "POSITIVE" as const,
category: "SCHEDULE_HOURS" as const,
language: "en",
summary: "Test summary",
createdAt: new Date(),
updatedAt: new Date(),
},
];
vi.mocked(prisma.user.findUnique).mockResolvedValue(mockUser);
vi.mocked(prisma.company.findUnique).mockResolvedValue(mockCompany);
vi.mocked(prisma.session.findMany).mockResolvedValue(mockSessions);
vi.mocked(prisma.session.count).mockResolvedValue(1);
vi.mocked(prisma.sessionQuestion.findMany).mockResolvedValue([]);
const request = new NextRequest(
"http://localhost:3000/api/dashboard/metrics"
);
const response = await GET(request);
expect(response.status).toBe(200);
const data = await response.json();
expect(data).toHaveProperty("totalSessions");
expect(data).toHaveProperty("sentimentDistribution");
expect(data).toHaveProperty("countryCounts");
expect(data).toHaveProperty("topQuestions");
});
it("should handle date range filters", async () => {
const { getServerSession } = await import("next-auth");
const { prisma } = await import("../../lib/prisma");
vi.mocked(getServerSession).mockResolvedValue({
user: { email: "user@example.com" },
expires: "2024-12-31",
});
const mockUser = {
id: "user1",
name: "Test User",
email: "user@example.com",
companyId: "company1",
role: "USER" as const,
password: "hashed",
resetToken: null,
resetTokenExpiry: null,
invitedAt: null,
invitedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
};
const mockCompany = {
id: "company1",
name: "Test Company",
csvUrl: "http://example.com/data.csv",
csvUsername: null,
csvPassword: null,
dashboardOpts: {},
maxUsers: 10,
status: "ACTIVE" as const,
createdAt: new Date(),
updatedAt: new Date(),
};
vi.mocked(prisma.user.findUnique).mockResolvedValue(mockUser);
vi.mocked(prisma.company.findUnique).mockResolvedValue(mockCompany);
vi.mocked(prisma.session.findMany).mockResolvedValue([]);
vi.mocked(prisma.session.count).mockResolvedValue(0);
vi.mocked(prisma.sessionQuestion.findMany).mockResolvedValue([]);
const request = new NextRequest(
"http://localhost:3000/api/dashboard/metrics?startDate=2024-01-01&endDate=2024-01-31"
);
const response = await GET(request);
expect(response.status).toBe(200);
const data = await response.json();
expect(data.totalSessions).toBe(0);
});
it("should handle database errors gracefully", async () => {
const { getServerSession } = await import("next-auth");
const { prisma } = await import("../../lib/prisma");
vi.mocked(getServerSession).mockResolvedValue({
user: { email: "user@example.com" },
expires: "2024-12-31",
});
vi.mocked(prisma.user.findUnique).mockRejectedValue(
new Error("Database connection failed")
);
const request = new NextRequest(
"http://localhost:3000/api/dashboard/metrics"
);
const response = await GET(request);
expect(response.status).toBe(500);
const data = await response.json();
expect(data.error).toBe("Internal server error");
});
});
});