test: enhance ai_generate_plan test for structured data validation and normalization
This commit is contained in:
@@ -45,46 +45,54 @@ async function getAuthedClient(): Promise<
|
|||||||
return { client, accessToken };
|
return { client, accessToken };
|
||||||
}
|
}
|
||||||
|
|
||||||
Deno.test("ai-generate-plan (JSON body)", async () => {
|
Deno.test("ai_generate_plan creates plan and returns structured data", async () => {
|
||||||
const { client, accessToken } = await getAuthedClient();
|
const { client, accessToken } = await getAuthedClient();
|
||||||
|
|
||||||
// Get any carrera
|
|
||||||
const { data: carrera, error: carreraError } = await client
|
const { data: carrera, error: carreraError } = await client
|
||||||
.from("carreras")
|
.from("carreras")
|
||||||
.select("id").limit(1).single();
|
.select("id")
|
||||||
if (carreraError) {
|
.limit(1)
|
||||||
throw new Error("Failed to fetch carrera: " + carreraError.message);
|
.single();
|
||||||
}
|
if (carreraError) throw new Error("Failed to fetch carrera: " + carreraError.message);
|
||||||
if (!carrera) throw new Error("No carrera found");
|
if (!carrera) throw new Error("No carrera found");
|
||||||
// datosBasicos (nombrePlan,carreraId,nivel,tipoCiclo,numCiclos)
|
|
||||||
const datosBasicos = {
|
const datosBasicos = {
|
||||||
nombrePlan: "Plan de estudios de Ingeniería en Sistemas Computacionales",
|
nombrePlan: "Plan de estudios de Ingeniería en Sistemas Computacionales",
|
||||||
carreraId: carrera.id,
|
carreraId: carrera.id,
|
||||||
nivel: "Licenciatura",
|
nivel: "Licenciatura",
|
||||||
tipoCiclo: "Semestral",
|
tipoCiclo: "Semestre", // important: normalizes to "Semestre"
|
||||||
numCiclos: 8,
|
numCiclos: 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data, error } = await client.functions.invoke("ai_generate_plan", {
|
const { data, error } = await client.functions.invoke("ai_generate_plan", {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${accessToken}`, // 👈 clave para que tu función pase el authHeader check
|
Authorization: `Bearer ${accessToken}`,
|
||||||
},
|
|
||||||
body: {
|
|
||||||
datosBasicos,
|
|
||||||
},
|
},
|
||||||
|
body: { datosBasicos },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error) throw new Error("Invoke failed: " + error.message);
|
if (error) throw new Error("Invoke failed: " + error.message);
|
||||||
assert(data, "Expected data from function");
|
assert(data, "Expected data from function");
|
||||||
|
|
||||||
// tu función responde { ok, output, outputText, ... }
|
// Top-level result
|
||||||
assertEquals(data.ok, true);
|
assertEquals(data.ok, true);
|
||||||
assert(data.plan);
|
|
||||||
assertEquals(data.output.ideas.length, 3);
|
// `plan` (DB record)
|
||||||
for (const it of data.output.ideas) {
|
assert(typeof data.plan?.id === "string");
|
||||||
assert(typeof it.titulo === "string");
|
assertEquals(data.plan.nombre, datosBasicos.nombrePlan);
|
||||||
assert(typeof it.descripcion === "string");
|
assertEquals(data.plan.nivel, "Licenciatura");
|
||||||
}
|
assertEquals(data.plan.tipo_ciclo, "Semestre");
|
||||||
|
assertEquals(data.plan.numero_ciclos, datosBasicos.numCiclos);
|
||||||
|
|
||||||
|
// `plan_datos` (normalized structured payload)
|
||||||
|
assert(typeof data.plan_datos === "object");
|
||||||
|
assertEquals(data.plan_datos.nombre, datosBasicos.nombrePlan);
|
||||||
|
assertEquals(data.plan_datos.nivel, "Licenciatura");
|
||||||
|
assertEquals(
|
||||||
|
data.plan_datos.total_de_ciclos_del_plan_de_estudios,
|
||||||
|
String(datosBasicos.numCiclos),
|
||||||
|
);
|
||||||
|
assertEquals(data.plan_datos.duracion_del_ciclo_escolar, "16"); // Semestre -> 16
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
Deno.test("ai-structured (multipart + file)", async () => {
|
Deno.test("ai-structured (multipart + file)", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user