127 lines
4.1 KiB
TypeScript
127 lines
4.1 KiB
TypeScript
import { vi } from "vitest"
|
|
|
|
import type { Doc, Id } from "../../convex/_generated/dataModel"
|
|
|
|
type ReportsCtxOptions = {
|
|
tickets?: Doc<"tickets">[]
|
|
createdRangeTickets?: Doc<"tickets">[]
|
|
queues?: Doc<"queues">[]
|
|
companies?: Map<string, Doc<"companies">>
|
|
users?: Map<string, Doc<"users">>
|
|
ticketEventsByTicket?: Map<string, Array<{ type: string; payload?: unknown; createdAt: number }>>
|
|
ticketWorkSessionsByAgent?: Map<string, Array<{ agentId: Id<"users">; startedAt: number; stoppedAt?: number; durationMs?: number }>>
|
|
}
|
|
|
|
const noopFilterBuilder = {
|
|
lt: () => noopFilterBuilder,
|
|
field: () => "createdAt",
|
|
}
|
|
|
|
const noopIndexBuilder = {
|
|
eq: () => noopIndexBuilder,
|
|
gte: () => noopIndexBuilder,
|
|
}
|
|
|
|
function ticketsChain(collection: Doc<"tickets">[]) {
|
|
const chain = {
|
|
filter: vi.fn((cb?: (builder: typeof noopFilterBuilder) => unknown) => {
|
|
cb?.(noopFilterBuilder)
|
|
return chain
|
|
}),
|
|
order: vi.fn(() => chain),
|
|
collect: vi.fn(async () => collection),
|
|
}
|
|
return chain
|
|
}
|
|
|
|
export function createReportsCtx({
|
|
tickets = [],
|
|
createdRangeTickets = tickets,
|
|
queues = [],
|
|
companies = new Map<string, Doc<"companies">>(),
|
|
users = new Map<string, Doc<"users">>(),
|
|
ticketEventsByTicket = new Map<string, Array<{ type: string; payload?: unknown; createdAt: number }>>(),
|
|
ticketWorkSessionsByAgent = new Map<string, Array<{ agentId: Id<"users">; startedAt: number; stoppedAt?: number; durationMs?: number }>>(),
|
|
}: ReportsCtxOptions = {}) {
|
|
const db = {
|
|
get: vi.fn(async (id: Id<"companies"> | Id<"users">) => {
|
|
const company = companies.get(String(id))
|
|
if (company) return company
|
|
const user = users.get(String(id))
|
|
if (user) return user
|
|
return null
|
|
}),
|
|
query: vi.fn((table: string) => {
|
|
if (table === "tickets") {
|
|
return {
|
|
withIndex: vi.fn((indexName: string, cb?: (builder: typeof noopIndexBuilder) => unknown) => {
|
|
cb?.(noopIndexBuilder)
|
|
const collection =
|
|
indexName.includes("created") || indexName.includes("tenant_company_created")
|
|
? createdRangeTickets
|
|
: tickets
|
|
return ticketsChain(collection)
|
|
}),
|
|
collect: vi.fn(async () => tickets),
|
|
}
|
|
}
|
|
|
|
if (table === "queues") {
|
|
return {
|
|
withIndex: vi.fn((_indexName: string, cb?: (builder: typeof noopIndexBuilder) => unknown) => {
|
|
cb?.(noopIndexBuilder)
|
|
return {
|
|
collect: vi.fn(async () => queues),
|
|
}
|
|
}),
|
|
collect: vi.fn(async () => queues),
|
|
}
|
|
}
|
|
|
|
if (table === "ticketEvents") {
|
|
return {
|
|
withIndex: vi.fn((_indexName: string, cb?: (builder: { eq: (field: unknown, value: unknown) => unknown }) => unknown) => {
|
|
let ticketId: string | null = null
|
|
const builder = {
|
|
eq: (_field: unknown, value: unknown) => {
|
|
ticketId = String(value)
|
|
return builder
|
|
},
|
|
}
|
|
cb?.(builder as { eq: (field: unknown, value: unknown) => unknown })
|
|
return {
|
|
collect: vi.fn(async () => (ticketId ? ticketEventsByTicket.get(ticketId) ?? [] : [])),
|
|
}
|
|
}),
|
|
}
|
|
}
|
|
|
|
if (table === "ticketWorkSessions") {
|
|
return {
|
|
withIndex: vi.fn((_indexName: string, cb?: (builder: { eq: (field: unknown, value: unknown) => unknown }) => unknown) => {
|
|
let agentId: string | null = null
|
|
const builder = {
|
|
eq: (_field: unknown, value: unknown) => {
|
|
agentId = String(value)
|
|
return builder
|
|
},
|
|
}
|
|
cb?.(builder as { eq: (field: unknown, value: unknown) => unknown })
|
|
return {
|
|
collect: vi.fn(async () => (agentId ? ticketWorkSessionsByAgent.get(agentId) ?? [] : [])),
|
|
}
|
|
}),
|
|
}
|
|
}
|
|
|
|
return {
|
|
withIndex: vi.fn(() => ({
|
|
collect: vi.fn(async () => []),
|
|
})),
|
|
collect: vi.fn(async () => []),
|
|
}
|
|
}),
|
|
}
|
|
|
|
return { db } as unknown
|
|
}
|