3
import { makeAPICall, pruneDatabase } from "@/src/__tests__/test-utils";
4
import { prisma } from "@/src/server/db";
5
import { v4 as uuidv4 } from "uuid";
7
interface GetTracesAPIResponse {
10
[key: string]: unknown;
14
describe("/api/public/traces API Endpoint", () => {
15
beforeEach(async () => await pruneDatabase());
16
afterEach(async () => await pruneDatabase());
18
it("should create", async () => {
19
await pruneDatabase();
21
await makeAPICall("POST", "/api/public/traces", {
24
projectId: "7a88fb47-b4e2-43b8-a06c-a5ce950dc53a",
25
metadata: { key: "value" },
30
const dbTrace = await prisma.trace.findMany({
36
expect(dbTrace.length).toBeGreaterThan(0);
37
expect(dbTrace[0]?.name).toBe("trace-name");
38
expect(dbTrace[0]?.release).toBe("1.0.0");
39
expect(dbTrace[0]?.externalId).toBeNull();
40
expect(dbTrace[0]?.version).toBe("2.0.0");
41
expect(dbTrace[0]?.projectId).toBe("7a88fb47-b4e2-43b8-a06c-a5ce950dc53a");
44
it("should upsert second trace", async () => {
45
await pruneDatabase();
47
await makeAPICall("POST", "/api/public/traces", {
51
metadata: { key: "value" },
57
const dbTrace1 = await prisma.trace.findFirst({
63
expect(dbTrace1).not.toBeNull();
64
expect(dbTrace1).toMatchObject({
73
await makeAPICall("POST", "/api/public/traces", {
75
metadata: { key: "value" },
76
timestamp: "2021-01-01T00:00:00.000Z",
82
const dbTrace2 = await prisma.trace.findFirst({
88
expect(dbTrace2).not.toBeNull();
89
expect(dbTrace2).toMatchObject({
96
timestamp: new Date("2021-01-01T00:00:00.000Z"),
100
it("should use tags correctly on POST and GET", async () => {
101
await pruneDatabase();
103
await makeAPICall("POST", "/api/public/traces", {
105
tags: ["tag-1", "tag-2", "tag-3"],
108
await makeAPICall("POST", "/api/public/traces", {
113
await makeAPICall("POST", "/api/public/traces", {
115
tags: ["tag-2", "tag-3"],
119
const traces = await makeAPICall<GetTracesAPIResponse>(
121
"/api/public/traces?tags=tag-2&tags=tag-3",
123
const traceIds = traces.body.data.map((t) => t.id);
125
expect(traceIds).toEqual(["trace-3", "trace-1"]);
128
const traces2 = await makeAPICall<GetTracesAPIResponse>(
130
"/api/public/traces?tags=tag-1",
132
const traceIds2 = traces2.body.data.map((t) => t.id);
134
expect(traceIds2).toEqual(["trace-2", "trace-1"]);
137
const traces3 = await makeAPICall<GetTracesAPIResponse>(
139
"/api/public/traces?tags=tag-10",
141
const traceIds3 = traces3.body.data.map((t) => t.id);
143
expect(traceIds3).toEqual([]);
146
const traces4 = await makeAPICall<GetTracesAPIResponse>(
148
"/api/public/traces?tags=",
150
const traceIds4 = traces4.body.data.map((t) => t.id);
152
expect(traceIds4).toEqual(["trace-3", "trace-2", "trace-1"]);
155
it("should handle metrics correctly on GET traces and GET trace", async () => {
156
await pruneDatabase();
159
const traceId = uuidv4();
160
await makeAPICall("POST", "/api/public/traces", {
162
name: "trace-with-costs",
163
userId: "user-costs",
164
projectId: "project-costs",
165
metadata: { key: "value" },
169
console.log(traceId);
172
await makeAPICall("POST", "/api/public/generations", {
174
usage: { totalCost: 10.5 },
175
startTime: "2021-01-01T00:00:00.000Z",
176
endTime: "2021-01-01T00:10:00.000Z",
178
await makeAPICall("POST", "/api/public/generations", {
180
usage: { totalCost: 5.25 },
181
startTime: "2021-01-01T00:10:00.000Z",
182
endTime: "2021-01-01T00:20:00.000Z",
187
const traces = await makeAPICall<GetTracesAPIResponse>(
189
`/api/public/traces`,
191
const traceData = traces.body.data[0];
192
if (!traceData) throw new Error("traceData is undefined");
195
expect(traceData.totalCost).toBeCloseTo(15.75);
196
expect(traceData.latency).toBeCloseTo(1200);
197
expect(traceData.id).toBe(traceId);
198
expect(traceData.htmlPath).toContain(`/traces/${traceId}`);
199
expect(traceData.htmlPath).toContain(`/project/`);
203
const trace = await makeAPICall<{
207
}>("GET", `/api/public/traces/${traceId}`);
208
console.log(trace.body);
209
expect(trace.body.totalCost).toBeCloseTo(15.75);
210
expect(trace.body.id).toBe(traceId);
211
expect(trace.body.id).toBe(traceId);
212
expect(trace.body.htmlPath).toContain(`/traces/${traceId}`);
213
expect(trace.body.htmlPath).toContain(`/project/`);