fix: update all tests and MCP catalog tool for manufacturerId schema migration
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { beforeEach, describe, expect, it } from "bun:test";
|
||||
import { Hono } from "hono";
|
||||
import { globalItems, setups } from "../../src/db/schema.ts";
|
||||
import { globalItems, manufacturers, setups } from "../../src/db/schema.ts";
|
||||
import { discoveryRoutes } from "../../src/server/routes/discovery.ts";
|
||||
import { createTestDb } from "../helpers/db.ts";
|
||||
|
||||
@@ -20,17 +20,28 @@ async function createTestApp() {
|
||||
return { app, db, userId };
|
||||
}
|
||||
|
||||
async function insertManufacturer(db: TestDb["db"], name: string) {
|
||||
const slug = name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
|
||||
const [row] = await db
|
||||
.insert(manufacturers)
|
||||
.values({ name, slug, website: `https://${slug}.com` })
|
||||
.onConflictDoUpdate({ target: manufacturers.slug, set: { name } })
|
||||
.returning();
|
||||
return row!;
|
||||
}
|
||||
|
||||
async function insertGlobalItem(
|
||||
db: TestDb["db"],
|
||||
brand: string,
|
||||
model: string,
|
||||
category?: string,
|
||||
) {
|
||||
const m = await insertManufacturer(db, brand);
|
||||
const [row] = await db
|
||||
.insert(globalItems)
|
||||
.values({ brand, model, category: category ?? "bags" })
|
||||
.values({ manufacturerId: m.id, model, category: category ?? "bags" })
|
||||
.returning();
|
||||
return row;
|
||||
return row!;
|
||||
}
|
||||
|
||||
async function insertPublicSetup(
|
||||
@@ -142,14 +153,16 @@ describe("Discovery Routes", () => {
|
||||
const olderTime = new Date("2024-01-01T00:00:00Z");
|
||||
const newerTime = new Date("2024-06-01T00:00:00Z");
|
||||
|
||||
const mA = await insertManufacturer(db, "Brand A");
|
||||
const mB = await insertManufacturer(db, "Brand B");
|
||||
await db.insert(globalItems).values({
|
||||
brand: "Brand A",
|
||||
manufacturerId: mA.id,
|
||||
model: "Model A",
|
||||
category: "bags",
|
||||
createdAt: olderTime,
|
||||
});
|
||||
await db.insert(globalItems).values({
|
||||
brand: "Brand B",
|
||||
manufacturerId: mB.id,
|
||||
model: "Model B",
|
||||
category: "bags",
|
||||
createdAt: newerTime,
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
globalItems,
|
||||
globalItemTags,
|
||||
items,
|
||||
manufacturers,
|
||||
tags,
|
||||
} from "../../src/db/schema.ts";
|
||||
import { globalItemRoutes } from "../../src/server/routes/global-items.ts";
|
||||
@@ -25,16 +26,27 @@ async function createTestApp() {
|
||||
return { app, db, userId };
|
||||
}
|
||||
|
||||
async function insertManufacturer(db: TestDb["db"], name: string) {
|
||||
const slug = name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
|
||||
const [row] = await db
|
||||
.insert(manufacturers)
|
||||
.values({ name, slug, website: `https://${slug}.com` })
|
||||
.onConflictDoUpdate({ target: manufacturers.slug, set: { name } })
|
||||
.returning();
|
||||
return row!;
|
||||
}
|
||||
|
||||
async function insertGlobalItem(
|
||||
db: TestDb["db"],
|
||||
brand: string,
|
||||
model: string,
|
||||
) {
|
||||
const m = await insertManufacturer(db, brand);
|
||||
const [row] = await db
|
||||
.insert(globalItems)
|
||||
.values({ brand, model, category: "bags" })
|
||||
.values({ manufacturerId: m.id, model, category: "bags" })
|
||||
.returning();
|
||||
return row;
|
||||
return row!;
|
||||
}
|
||||
|
||||
async function insertItem(
|
||||
@@ -113,18 +125,18 @@ describe("Global Item Routes", () => {
|
||||
|
||||
describe("POST /api/global-items", () => {
|
||||
it("returns 200 with item and created=true on new item", async () => {
|
||||
await insertManufacturer(db, "Revelate Designs");
|
||||
const res = await app.request("/api/global-items", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
brand: "Revelate Designs",
|
||||
manufacturerSlug: "revelate-designs",
|
||||
model: "Terrapin System",
|
||||
}),
|
||||
});
|
||||
expect(res.status).toBe(200);
|
||||
|
||||
const body = await res.json();
|
||||
expect(body.item.brand).toBe("Revelate Designs");
|
||||
expect(body.item.model).toBe("Terrapin System");
|
||||
expect(body.created).toBe(true);
|
||||
});
|
||||
@@ -136,7 +148,7 @@ describe("Global Item Routes", () => {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
brand: "Revelate Designs",
|
||||
manufacturerSlug: "revelate-designs",
|
||||
model: "Terrapin System",
|
||||
description: "Updated description",
|
||||
}),
|
||||
@@ -148,7 +160,7 @@ describe("Global Item Routes", () => {
|
||||
expect(body.item.description).toBe("Updated description");
|
||||
});
|
||||
|
||||
it("returns 400 when brand is missing", async () => {
|
||||
it("returns 400 when manufacturerSlug is missing", async () => {
|
||||
const res = await app.request("/api/global-items", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -161,7 +173,7 @@ describe("Global Item Routes", () => {
|
||||
const res = await app.request("/api/global-items", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ brand: "Revelate Designs" }),
|
||||
body: JSON.stringify({ manufacturerSlug: "revelate-designs" }),
|
||||
});
|
||||
expect(res.status).toBe(400);
|
||||
});
|
||||
@@ -169,13 +181,15 @@ describe("Global Item Routes", () => {
|
||||
|
||||
describe("POST /api/global-items/bulk", () => {
|
||||
it("returns 200 with created/updated counts", async () => {
|
||||
await insertManufacturer(db, "Revelate Designs");
|
||||
await insertManufacturer(db, "Apidura");
|
||||
const res = await app.request("/api/global-items/bulk", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
items: [
|
||||
{ brand: "Revelate Designs", model: "Terrapin System" },
|
||||
{ brand: "Apidura", model: "Handlebar Pack" },
|
||||
{ manufacturerSlug: "revelate-designs", model: "Terrapin System" },
|
||||
{ manufacturerSlug: "apidura", model: "Handlebar Pack" },
|
||||
],
|
||||
}),
|
||||
});
|
||||
@@ -189,14 +203,15 @@ describe("Global Item Routes", () => {
|
||||
|
||||
it("returns correct counts for mix of new and existing items", async () => {
|
||||
await insertGlobalItem(db, "Revelate Designs", "Terrapin System");
|
||||
await insertManufacturer(db, "Apidura");
|
||||
|
||||
const res = await app.request("/api/global-items/bulk", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
items: [
|
||||
{ brand: "Revelate Designs", model: "Terrapin System" },
|
||||
{ brand: "Apidura", model: "Handlebar Pack" },
|
||||
{ manufacturerSlug: "revelate-designs", model: "Terrapin System" },
|
||||
{ manufacturerSlug: "apidura", model: "Handlebar Pack" },
|
||||
],
|
||||
}),
|
||||
});
|
||||
@@ -218,7 +233,7 @@ describe("Global Item Routes", () => {
|
||||
|
||||
it("returns 400 when items array exceeds 100", async () => {
|
||||
const items = Array.from({ length: 101 }, (_, i) => ({
|
||||
brand: `Brand${i}`,
|
||||
manufacturerSlug: `brand${i}`,
|
||||
model: `Model${i}`,
|
||||
}));
|
||||
const res = await app.request("/api/global-items/bulk", {
|
||||
@@ -229,14 +244,14 @@ describe("Global Item Routes", () => {
|
||||
expect(res.status).toBe(400);
|
||||
});
|
||||
|
||||
it("returns 400 for invalid item in array (missing brand)", async () => {
|
||||
it("returns 400 for invalid item in array (missing manufacturerSlug)", async () => {
|
||||
const res = await app.request("/api/global-items/bulk", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
items: [
|
||||
{ brand: "Revelate Designs", model: "Terrapin System" },
|
||||
{ model: "Invalid Item without brand" },
|
||||
{ manufacturerSlug: "revelate-designs", model: "Terrapin System" },
|
||||
{ model: "Invalid Item without manufacturerSlug" },
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user