Update Prisma and harden tests

This commit is contained in:
Esdras Renan 2025-11-08 00:28:52 -03:00
parent a2f9d4bd1a
commit d8eb38fe52
17 changed files with 171 additions and 119 deletions

View file

@ -11,7 +11,7 @@
"@hookform/resolvers": "^3.10.0",
"@noble/hashes": "^1.5.0",
"@paper-design/shaders-react": "^0.0.55",
"@prisma/client": "^6.16.2",
"@prisma/client": "^6.19.0",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.3",
@ -83,7 +83,7 @@
"eslint-plugin-react-hooks": "^5.0.0",
"jsdom": "^27.0.1",
"playwright": "^1.56.1",
"prisma": "^6.16.2",
"prisma": "^6.19.0",
"tailwindcss": "^4",
"tsconfig-paths": "^4.2.0",
"tw-animate-css": "^1.3.8",
@ -421,19 +421,19 @@
"@popperjs/core": ["@popperjs/core@2.11.8", "", {}, "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="],
"@prisma/client": ["@prisma/client@6.16.3", "", { "optionalDependencies": { "prisma": "6.16.3", "typescript": "5.9.3" } }, "sha512-JfNfAtXG+/lIopsvoZlZiH2k5yNx87mcTS4t9/S5oufM1nKdXYxOvpDC1XoTCFBa5cQh7uXnbMPsmZrwZY80xw=="],
"@prisma/client": ["@prisma/client@6.19.0", "", { "peerDependencies": { "prisma": "*", "typescript": ">=5.1.0" }, "optionalPeers": ["prisma", "typescript"] }, "sha512-QXFT+N/bva/QI2qoXmjBzL7D6aliPffIwP+81AdTGq0FXDoLxLkWivGMawG8iM5B9BKfxLIXxfWWAF6wbuJU6g=="],
"@prisma/config": ["@prisma/config@6.16.3", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.16.12", "empathic": "2.0.0" } }, "sha512-VlsLnG4oOuKGGMToEeVaRhoTBZu5H3q51jTQXb/diRags3WV0+BQK5MolJTtP6G7COlzoXmWeS11rNBtvg+qFQ=="],
"@prisma/config": ["@prisma/config@6.19.0", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.18.4", "empathic": "2.0.0" } }, "sha512-zwCayme+NzI/WfrvFEtkFhhOaZb/hI+X8TTjzjJ252VbPxAl2hWHK5NMczmnG9sXck2lsXrxIZuK524E25UNmg=="],
"@prisma/debug": ["@prisma/debug@6.16.3", "", {}, "sha512-89DdqWtdKd7qoc9/qJCKLTazj3W3zPEiz0hc7HfZdpjzm21c7orOUB5oHWJsG+4KbV4cWU5pefq3CuDVYF9vgA=="],
"@prisma/debug": ["@prisma/debug@6.19.0", "", {}, "sha512-8hAdGG7JmxrzFcTzXZajlQCidX0XNkMJkpqtfbLV54wC6LSSX6Vni25W/G+nAANwLnZ2TmwkfIuWetA7jJxJFA=="],
"@prisma/engines": ["@prisma/engines@6.16.3", "", { "dependencies": { "@prisma/debug": "6.16.3", "@prisma/engines-version": "6.16.1-1.bb420e667c1820a8c05a38023385f6cc7ef8e83a", "@prisma/fetch-engine": "6.16.3", "@prisma/get-platform": "6.16.3" } }, "sha512-b+Rl4nzQDcoqe6RIpSHv8f5lLnwdDGvXhHjGDiokObguAAv/O1KaX1Oc69mBW/GFWKQpCkOraobLjU6s1h8HGg=="],
"@prisma/engines": ["@prisma/engines@6.19.0", "", { "dependencies": { "@prisma/debug": "6.19.0", "@prisma/engines-version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", "@prisma/fetch-engine": "6.19.0", "@prisma/get-platform": "6.19.0" } }, "sha512-pMRJ+1S6NVdXoB8QJAPIGpKZevFjxhKt0paCkRDTZiczKb7F4yTgRP8M4JdVkpQwmaD4EoJf6qA+p61godDokw=="],
"@prisma/engines-version": ["@prisma/engines-version@6.16.1-1.bb420e667c1820a8c05a38023385f6cc7ef8e83a", "", {}, "sha512-fftRmosBex48Ph1v2ll1FrPpirwtPZpNkE5CDCY1Lw2SD2ctyrLlVlHiuxDAAlALwWBOkPbAll4+EaqdGuMhJw=="],
"@prisma/engines-version": ["@prisma/engines-version@6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", "", {}, "sha512-gV7uOBQfAFlWDvPJdQxMT1aSRur3a0EkU/6cfbAC5isV67tKDWUrPauyaHNpB+wN1ebM4A9jn/f4gH+3iHSYSQ=="],
"@prisma/fetch-engine": ["@prisma/fetch-engine@6.16.3", "", { "dependencies": { "@prisma/debug": "6.16.3", "@prisma/engines-version": "6.16.1-1.bb420e667c1820a8c05a38023385f6cc7ef8e83a", "@prisma/get-platform": "6.16.3" } }, "sha512-bUoRIkVaI+CCaVGrSfcKev0/Mk4ateubqWqGZvQ9uCqFv2ENwWIR3OeNuGin96nZn5+SkebcD7RGgKr/+mJelw=="],
"@prisma/fetch-engine": ["@prisma/fetch-engine@6.19.0", "", { "dependencies": { "@prisma/debug": "6.19.0", "@prisma/engines-version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", "@prisma/get-platform": "6.19.0" } }, "sha512-OOx2Lda0DGrZ1rodADT06ZGqHzr7HY7LNMaFE2Vp8dp146uJld58sRuasdX0OiwpHgl8SqDTUKHNUyzEq7pDdQ=="],
"@prisma/get-platform": ["@prisma/get-platform@6.16.3", "", { "dependencies": { "@prisma/debug": "6.16.3" } }, "sha512-X1LxiFXinJ4iQehrodGp0f66Dv6cDL0GbRlcCoLtSu6f4Wi+hgo7eND/afIs5029GQLgNWKZ46vn8hjyXTsHLA=="],
"@prisma/get-platform": ["@prisma/get-platform@6.19.0", "", { "dependencies": { "@prisma/debug": "6.19.0" } }, "sha512-ym85WDO2yDhC3fIXHWYpG3kVMBA49cL1XD2GCsCF8xbwoy2OkDQY44gEbAt2X46IQ4Apq9H6g0Ex1iFfPqEkHA=="],
"@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="],
@ -1121,7 +1121,7 @@
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "1.0.2", "es-errors": "1.3.0", "gopd": "1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
"effect": ["effect@3.16.12", "", { "dependencies": { "@standard-schema/spec": "1.0.0", "fast-check": "3.23.2" } }, "sha512-N39iBk0K71F9nb442TLbTkjl24FLUzuvx2i1I2RsEAQsdAdUTuUoW0vlfUXgkMTUOnYqKnWcFfqw4hK4Pw27hg=="],
"effect": ["effect@3.18.4", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA=="],
"electron-to-chromium": ["electron-to-chromium@1.5.234", "", {}, "sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg=="],
@ -1617,7 +1617,7 @@
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
"prisma": ["prisma@6.16.3", "", { "dependencies": { "@prisma/config": "6.16.3", "@prisma/engines": "6.16.3" }, "optionalDependencies": { "typescript": "5.9.3" }, "bin": { "prisma": "build/index.js" } }, "sha512-4tJq3KB9WRshH5+QmzOLV54YMkNlKOtLKaSdvraI5kC/axF47HuOw6zDM8xrxJ6s9o2WodY654On4XKkrobQdQ=="],
"prisma": ["prisma@6.19.0", "", { "dependencies": { "@prisma/config": "6.19.0", "@prisma/engines": "6.19.0" }, "peerDependencies": { "typescript": ">=5.1.0" }, "optionalPeers": ["typescript"], "bin": { "prisma": "build/index.js" } }, "sha512-F3eX7K+tWpkbhl3l4+VkFtrwJlLXbAM+f9jolgoUZbFcm1DgHZ4cq9AgVEgUym2au5Ad/TDLN8lg83D+M10ycw=="],
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "1.4.0", "object-assign": "4.1.1", "react-is": "16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],

View file

@ -11,6 +11,7 @@ const eslintConfig = [
"build/**",
"apps/desktop/dist/**",
"apps/desktop/src-tauri/target/**",
"nova-calendar-main/**",
"next-env.d.ts",
"convex/_generated/**",
],

View file

@ -32,7 +32,7 @@
"@hookform/resolvers": "^3.10.0",
"@noble/hashes": "^1.5.0",
"@paper-design/shaders-react": "^0.0.55",
"@prisma/client": "^6.16.2",
"@prisma/client": "^6.19.0",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.3",
@ -104,7 +104,7 @@
"eslint-plugin-react-hooks": "^5.0.0",
"jsdom": "^27.0.1",
"playwright": "^1.56.1",
"prisma": "^6.16.2",
"prisma": "^6.19.0",
"tailwindcss": "^4",
"tsconfig-paths": "^4.2.0",
"tw-animate-css": "^1.3.8",

View file

@ -18,7 +18,7 @@ vi.mock("@/server/convex-client", () => {
})
const mockCookieStore = {
get: vi.fn<() => unknown, []>(),
get: vi.fn<() => unknown>(),
}
vi.mock("next/headers", () => ({

View file

@ -92,20 +92,25 @@ export const { signIn, signOut, useSession } = authClient
export function AuthProvider({ children }: { children: React.ReactNode }) {
const devBypass = process.env.NODE_ENV !== "production" && process.env.NEXT_PUBLIC_DEV_BYPASS_AUTH === "1"
const { data: baseSession, isPending } = useSession()
const session: AppSession | null = baseSession ?? (devBypass
? {
session: { id: "dev-session", expiresAt: Date.now() + 1000 * 60 * 60 },
user: {
id: "dev-user",
name: "Dev Admin",
email: "admin@sistema.dev",
role: "admin",
tenantId: "tenant-atlas",
avatarUrl: null,
machinePersona: null,
},
}
: null)
const session = useMemo<AppSession | null>(
() =>
baseSession ??
(devBypass
? {
session: { id: "dev-session", expiresAt: Date.now() + 1000 * 60 * 60 },
user: {
id: "dev-user",
name: "Dev Admin",
email: "admin@sistema.dev",
role: "admin",
tenantId: "tenant-atlas",
avatarUrl: null,
machinePersona: null,
},
}
: null),
[baseSession, devBypass]
)
const ensureUser = useMutation(api.users.ensureUser)
const [convexUserId, setConvexUserId] = useState<string | null>(null)
const [machineContext, setMachineContext] = useState<MachineContext | null>(null)

View file

@ -64,6 +64,5 @@ if (process.env.NODE_ENV !== "production") {
if (process.env.NODE_ENV !== "production") {
// Helps detect mismatched DB path during dev server bootstrap
// eslint-disable-next-line no-console
console.log("[prisma] Using database:", resolvedDatabaseUrl)
}

View file

@ -4,7 +4,8 @@ import { toast } from "sonner"
const METHODS = ["success", "error", "info", "warning", "message", "loading"] as const
const TRAILING_PUNCTUATION_REGEX = /[\s!?.,;:]+$/u
const toastAny = toast as unknown as Record<string, (...args: any[]) => unknown> & { __punctuationPatched?: boolean }
const toastAny = toast as typeof toast & { __punctuationPatched?: boolean }
type ToastMethodKey = (typeof METHODS)[number]
function stripTrailingPunctuation(value: string): string {
const trimmed = value.trimEnd()
@ -19,49 +20,50 @@ function sanitizeContent<T>(value: T): T {
return value
}
function sanitizeOptions(options: unknown): unknown {
function sanitizeOptions<T>(options: T): T {
if (!options || typeof options !== "object") return options
if ("description" in options && typeof (options as { description?: unknown }).description === "string") {
return {
...(options as Record<string, unknown>),
description: stripTrailingPunctuation((options as { description: string }).description),
}
} as T
}
return options
}
function wrapSimpleMethod(method: (typeof METHODS)[number]) {
const original = toastAny[method]
function wrapSimpleMethod<K extends ToastMethodKey>(method: K) {
const original = toastAny[method] as typeof toast[K]
if (typeof original !== "function") return
toastAny[method] = (message: unknown, options?: unknown, ...rest: unknown[]) => {
return original(sanitizeContent(message), sanitizeOptions(options), ...rest)
}
const patched = ((...args: Parameters<typeof toast[K]>) => {
const nextArgs = args.slice() as Parameters<typeof toast[K]>
if (nextArgs.length > 0) {
nextArgs[0] = sanitizeContent(nextArgs[0])
}
if (nextArgs.length > 1) {
nextArgs[1] = sanitizeOptions(nextArgs[1])
}
return original.apply(null, nextArgs as Parameters<typeof toast[K]>)
}) as typeof toast[K]
toastAny[method] = patched
}
function wrapPromise() {
const originalPromise = toastAny.promise
if (typeof originalPromise !== "function") return
toastAny.promise = (promise: Promise<unknown>, messages: Record<string, unknown>, options?: unknown) => {
const wrapMessage = (value: unknown) => {
if (typeof value === "function") {
return (...args: unknown[]) => sanitizeContent((value as (...args: unknown[]) => unknown)(...args))
}
return sanitizeContent(value)
}
toastAny.promise = ((promise, messages) => {
const normalizedMessages =
messages && typeof messages === "object"
? {
? ({
...messages,
loading: wrapMessage(messages.loading),
success: wrapMessage(messages.success),
error: wrapMessage(messages.error),
finally: wrapMessage((messages as { finally?: unknown }).finally),
}
loading: sanitizeContent(messages.loading),
success: sanitizeContent(messages.success),
error: sanitizeContent(messages.error),
description: sanitizeContent(messages.description),
} satisfies typeof messages)
: messages
return originalPromise(promise, normalizedMessages, sanitizeOptions(options))
}
return originalPromise(promise, normalizedMessages)
}) as typeof toast.promise
}
if (!toastAny.__punctuationPatched) {

View file

@ -185,7 +185,7 @@ describe("convex.machines.listTicketsHistory", () => {
})
expect(result.page).toHaveLength(1)
expect(result.page[0].id).toBe("ticket_match")
expect(result.page[0].id).toBe("ticket_match" as Id<"tickets">)
expect(result.isDone).toBe(true)
})
})

View file

@ -177,7 +177,7 @@ describe("convex.reports.backlogOverview", () => {
})
expect(result.rangeDays).toBe(7)
expect(result.statusCounts).toEqual({
expect(result.statusCounts).toMatchObject({
PENDING: 1,
PAUSED: 1,
RESOLVED: 1,

View file

@ -173,7 +173,7 @@ describe("convex.reports.csatOverview", () => {
expect(result.averageScore).toBe(4)
expect(result.distribution.find((entry) => entry.score === 5)?.total).toBe(1)
expect(result.distribution.find((entry) => entry.score === 3)?.total).toBe(1)
expect(result.recent[0]?.ticketId).toBe("ticket_a")
expect(result.recent[0]?.ticketId).toBe("ticket_a" as Id<"tickets">)
})
})

View file

@ -10,14 +10,14 @@ process.env.BETTER_AUTH_URL ??= process.env.NEXT_PUBLIC_APP_URL
const OriginalDate = Date
let fixedTimestamp: number | null = null
type MutableVi = typeof vi & {
mocked?: <T>(item: T) => T
setSystemTime?: (value: number | Date) => void
useFakeTimers?: (...args: Array<unknown>) => void
useRealTimers?: (...args: Array<unknown>) => void
type ExtendedVi = typeof vi & {
mocked?: typeof vi.mocked
setSystemTime?: typeof vi.setSystemTime
useFakeTimers?: typeof vi.useFakeTimers
useRealTimers?: typeof vi.useRealTimers
}
const viExtended = vi as MutableVi
const viExtended = vi as ExtendedVi
if (typeof window === "undefined" || typeof document === "undefined") {
const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>", {
@ -57,40 +57,48 @@ const applyFixedDate = () => {
}
if (!viExtended.mocked) {
viExtended.mocked = <T>(item: T) => item
viExtended.mocked = ((item: unknown) => item) as typeof vi.mocked
}
if (!viExtended.setSystemTime) {
viExtended.setSystemTime = (value: number | Date) => {
fixedTimestamp = typeof value === "number" ? value : value.getTime()
viExtended.setSystemTime = ((value: string | number | Date) => {
if (typeof value === "string") {
const parsed = Date.parse(value)
fixedTimestamp = Number.isFinite(parsed) ? parsed : Date.now()
} else {
fixedTimestamp = value instanceof Date ? value.getTime() : value
}
applyFixedDate()
}
return viExtended
}) as typeof vi.setSystemTime
}
if (!viExtended.useFakeTimers) {
viExtended.useFakeTimers = () => {
// Bun's fake timers are not required for our current tests. This is a noop
// placeholder to keep compatibility with the previous Vitest API.
}
viExtended.useFakeTimers = ((..._args: Parameters<typeof vi.useFakeTimers>) => {
return viExtended
}) as typeof vi.useFakeTimers
} else {
const originalUseFakeTimers = viExtended.useFakeTimers.bind(vi)
viExtended.useFakeTimers = (...args: Array<unknown>) => {
originalUseFakeTimers(...args)
}
viExtended.useFakeTimers = ((...args: Parameters<typeof vi.useFakeTimers>) => {
const result = originalUseFakeTimers(...args)
return result ?? viExtended
}) as typeof vi.useFakeTimers
}
if (!viExtended.useRealTimers) {
viExtended.useRealTimers = () => {
viExtended.useRealTimers = ((..._args: Parameters<typeof vi.useRealTimers>) => {
fixedTimestamp = null
applyFixedDate()
}
return viExtended
}) as typeof vi.useRealTimers
} else {
const originalUseRealTimers = viExtended.useRealTimers.bind(vi)
viExtended.useRealTimers = (...args: Array<unknown>) => {
originalUseRealTimers(...args)
viExtended.useRealTimers = ((...args: Parameters<typeof vi.useRealTimers>) => {
const result = originalUseRealTimers(...args)
fixedTimestamp = null
applyFixedDate()
}
return result ?? viExtended
}) as typeof vi.useRealTimers
}
applyFixedDate()

View file

@ -1,10 +1,10 @@
import { describe, expect, it, vi } from "bun:test"
import { buildCommentAuthorSummary } from "../convex/tickets"
import type { Doc, Id } from "../convex/_generated/dataModel"
import type { Doc, Id, TableNames } from "../convex/_generated/dataModel"
function makeId<TableName extends string>(value: string) {
return value as unknown as Id<TableName>
function makeId<TableName extends TableNames>(value: string) {
return value as Id<TableName>
}
function makeComment(overrides: Partial<Doc<"ticketComments">> = {}) {

View file

@ -2,6 +2,7 @@ import { describe, expect, it } from "bun:test"
import { normalizeCustomFieldInputs } from "../src/lib/ticket-form-helpers"
import type { TicketFormFieldDefinition } from "../src/lib/ticket-form-types"
import type { Id } from "../convex/_generated/dataModel"
describe("ticket form helpers", () => {
const baseFields: TicketFormFieldDefinition[] = [
@ -56,9 +57,9 @@ describe("ticket form helpers", () => {
expect(result.ok).toBe(true)
if (result.ok) {
expect(result.payload).toEqual([
{ fieldId: "field-nome", value: "Ana Silva" },
{ fieldId: "field-numero", value: 123 },
{ fieldId: "field-select", value: "nova" },
{ fieldId: "field-nome" as Id<"ticketFields">, value: "Ana Silva" },
{ fieldId: "field-numero" as Id<"ticketFields">, value: 123 },
{ fieldId: "field-select" as Id<"ticketFields">, value: "nova" },
])
}
})

View file

@ -41,29 +41,28 @@ function buildTicket(overrides: Partial<TicketDoc> = {}): MockedTicket {
tenantId: "tenant-1",
reference: 41_000,
subject: "Computador não liga",
summary: null,
summary: undefined,
status: "AWAITING_ATTENDANCE",
priority: "MEDIUM",
channel: "EMAIL",
queueId: null,
queueSnapshot: null,
queueId: undefined,
requesterId: "user_requester" as Id<"users">,
requesterSnapshot: { name: "Cliente", email: "cliente@example.com" },
assigneeId: "user_agent" as Id<"users">,
assigneeSnapshot: { name: "Agente", email: "agente@example.com" },
companyId: null,
companySnapshot: null,
machineId: null,
machineSnapshot: null,
slaPolicyId: null,
dueAt: null,
firstResponseAt: null,
resolvedAt: null,
companyId: undefined,
companySnapshot: undefined,
machineId: undefined,
machineSnapshot: undefined,
slaPolicyId: undefined,
dueAt: undefined,
firstResponseAt: undefined,
resolvedAt: undefined,
createdAt: NOW - 50_000,
updatedAt: NOW - 1_000,
tags: [],
customFields: [],
activeSessionId: null,
activeSessionId: undefined,
totalWorkedMs: 0,
internalWorkedMs: 0,
externalWorkedMs: 0,
@ -74,15 +73,12 @@ function buildTicket(overrides: Partial<TicketDoc> = {}): MockedTicket {
csatRatedBy: undefined,
csatAssigneeId: undefined,
csatAssigneeSnapshot: undefined,
workSummary: undefined,
reopenDeadline: undefined,
reopenedAt: undefined,
formTemplate: undefined,
chatEnabled: true,
relatedTicketIds: undefined,
resolvedWithTicketId: undefined,
reopenWindowDays: undefined,
reopenedBy: undefined,
}
return { ...(base as TicketDoc), ...overrides }
}
@ -149,8 +145,12 @@ describe("convex.tickets.resolveTicketHandler", () => {
mockedRequireStaff.mockResolvedValue({
user: {
_id: "user_agent" as Id<"users">,
_creationTime: NOW - 5_000,
tenantId: "tenant-1",
name: "Agente",
email: "agente@example.com",
role: "ADMIN",
teams: [],
},
role: "ADMIN",
})
@ -214,8 +214,13 @@ describe("convex.tickets.reopenTicketHandler", () => {
mockedRequireUser.mockResolvedValue({
user: {
_id: ticket.requesterId,
_creationTime: NOW - 20_000,
tenantId: "tenant-1",
email: "cliente@example.com",
companyId: null,
name: "Cliente",
role: "COLLABORATOR",
companyId: undefined,
teams: [],
},
role: "COLLABORATOR",
})
@ -247,8 +252,13 @@ describe("convex.tickets.reopenTicketHandler", () => {
mockedRequireUser.mockResolvedValue({
user: {
_id: ticket.requesterId,
_creationTime: NOW - 25_000,
tenantId: "tenant-1",
email: "cliente@example.com",
companyId: null,
name: "Cliente",
role: "COLLABORATOR",
companyId: undefined,
teams: [],
},
role: "COLLABORATOR",
})

View file

@ -23,29 +23,28 @@ function makeTicket(overrides: Partial<Doc<"tickets">> = {}): Doc<"tickets"> {
tenantId: "tenant-1",
reference: 42_100,
subject: "Computador não liga",
summary: null,
summary: undefined,
status: "RESOLVED",
priority: "MEDIUM",
channel: "EMAIL",
queueId: null,
queueSnapshot: null,
queueId: undefined,
requesterId: "user_requester" as Id<"users">,
requesterSnapshot: { name: "Cliente", email: "cliente@example.com" },
assigneeId: null,
assigneeSnapshot: null,
companyId: null,
companySnapshot: null,
machineId: null,
machineSnapshot: null,
slaPolicyId: null,
dueAt: null,
firstResponseAt: null,
assigneeId: undefined,
assigneeSnapshot: undefined,
companyId: undefined,
companySnapshot: undefined,
machineId: undefined,
machineSnapshot: undefined,
slaPolicyId: undefined,
dueAt: undefined,
firstResponseAt: undefined,
resolvedAt: FIXED_NOW - 1000,
createdAt: FIXED_NOW - 20_000,
updatedAt: FIXED_NOW - 100,
tags: [],
customFields: [],
activeSessionId: null,
activeSessionId: undefined,
totalWorkedMs: 0,
internalWorkedMs: 0,
externalWorkedMs: 0,
@ -103,8 +102,13 @@ describe("convex.tickets.submitCsat", () => {
mockedRequireUser.mockResolvedValue({
user: {
_id: "user_requester" as Id<"users">,
_creationTime: FIXED_NOW - 30_000,
tenantId: "tenant-1",
name: "Cliente",
email: "cliente@example.com",
companyId: null,
role: "COLLABORATOR",
companyId: undefined,
teams: [],
},
role: "COLLABORATOR",
})
@ -145,8 +149,13 @@ describe("convex.tickets.submitCsat", () => {
mockedRequireUser.mockResolvedValue({
user: {
_id: "user_requester" as Id<"users">,
_creationTime: FIXED_NOW - 30_000,
tenantId: "tenant-1",
name: "Cliente",
email: "cliente@example.com",
companyId: null,
role: "COLLABORATOR",
companyId: undefined,
teams: [],
},
role: "COLLABORATOR",
})
@ -174,8 +183,13 @@ describe("convex.tickets.submitCsat", () => {
mockedRequireUser.mockResolvedValue({
user: {
_id: "user_requester" as Id<"users">,
_creationTime: FIXED_NOW - 30_000,
tenantId: "tenant-1",
name: "Cliente",
email: "cliente@example.com",
companyId: null,
role: "COLLABORATOR",
companyId: undefined,
teams: [],
},
role: "COLLABORATOR",
})
@ -199,8 +213,13 @@ describe("convex.tickets.submitCsat", () => {
mockedRequireUser.mockResolvedValue({
user: {
_id: "user_admin" as Id<"users">,
_creationTime: FIXED_NOW - 40_000,
tenantId: "tenant-1",
name: "Administrador",
email: "admin@example.com",
companyId: null,
role: "ADMIN",
companyId: undefined,
teams: [],
},
role: "ADMIN",
})

View file

@ -35,11 +35,13 @@
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
"**/*.d.ts",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules",
"apps/desktop/**"
"apps/desktop/**",
"nova-calendar-main/**"
]
}

5
types/bun-test-vi.d.ts vendored Normal file
View file

@ -0,0 +1,5 @@
type VitestVi = typeof import("vitest")["vi"]
declare module "bun:test" {
export const vi: VitestVi
}