import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { formatServerResponse } from "./format-server-response.js";
// ============================================================================
// Helpers
// ============================================================================
/** Override process.stdout.columns for narrow/wide terminal simulation */
function setTerminalWidth(cols: number) {
Object.defineProperty(process.stdout, "columns", {
value: cols,
writable: true,
configurable: true,
});
}
// ============================================================================
// formatServerResponse — primitives & edge cases
// ============================================================================
describe("formatServerResponse", () => {
let originalColumns: number | undefined;
beforeEach(() => {
originalColumns = process.stdout.columns;
// Default to wide terminal for most tests
setTerminalWidth(120);
});
afterEach(() => {
if (originalColumns !== undefined) {
setTerminalWidth(originalColumns);
} else {
// Reset by deleting the property so it falls back to the real value
Object.defineProperty(process.stdout, "columns", {
value: originalColumns,
writable: true,
configurable: true,
});
}
});
// --------------------------------------------------------------------------
// String passthrough
// --------------------------------------------------------------------------
describe("string passthrough", () => {
it("returns strings unchanged", () => {
expect(formatServerResponse("hello world")).toBe("hello world");
});
it("returns empty string unchanged", () => {
expect(formatServerResponse("")).toBe("");
});
it("returns multi-line string unchanged", () => {
const multi = "line 1\nline 2\nline 3";
expect(formatServerResponse(multi)).toBe(multi);
});
});
// --------------------------------------------------------------------------
// Null / undefined
// --------------------------------------------------------------------------
describe("null and undefined handling", () => {
it("returns 'No data returned.' for null", () => {
expect(formatServerResponse(null)).toBe("No data returned.");
});
it("returns 'No data returned.' for undefined", () => {
expect(formatServerResponse(undefined)).toBe("No data returned.");
});
});
// --------------------------------------------------------------------------
// Empty array
// --------------------------------------------------------------------------
describe("empty array", () => {
it("returns 'No results found.' for empty array", () => {
expect(formatServerResponse([])).toBe("No results found.");
});
});
// --------------------------------------------------------------------------
// Array of flat objects → markdown table
// --------------------------------------------------------------------------
describe("array of objects → table", () => {
it("formats a simple array of objects into a markdown table", () => {
const data = [
{ name: "Widget A", quantity: 10 },
{ name: "Widget B", quantity: 25 },
];
const result = formatServerResponse(data);
// Should contain markdown table structure
expect(result).toContain("|");
expect(result).toContain("---");
expect(result).toContain("Widget A");
expect(result).toContain("Widget B");
expect(result).toContain("10");
expect(result).toContain("25");
});
it("includes a result count header", () => {
const data = [
{ name: "A" },
{ name: "B" },
{ name: "C" },
];
const result = formatServerResponse(data);
expect(result).toContain("(3 results)");
});
it("uses singular 'result' for single item", () => {
const data = [{ name: "Only One" }];
const result = formatServerResponse(data);
expect(result).toContain("(1 result)");
expect(result).not.toContain("(1 results)");
});
it("shows category label when tool name matches a known category", () => {
const data = [
{ name: "Blue Dream", sku: "BD-001", status: "published" },
];
const result = formatServerResponse(data, "products");
expect(result).toContain("**Products**");
});
it("uses 'Results' label when tool name does not match any category", () => {
const data = [
{ name: "Something", value: 42 },
];
const result = formatServerResponse(data, "unknown_tool");
expect(result).toContain("**Results**");
});
});
// --------------------------------------------------------------------------
// Single flat object → bold key-value pairs
// --------------------------------------------------------------------------
describe("single flat object → key-value pairs", () => {
it("formats a flat object as bold key-value pairs", () => {
const data = { name: "Test Product", status: "active", quantity: 50 };
const result = formatServerResponse(data);
expect(result).toContain("**Name**: Test Product");
expect(result).toContain("**Status**: active");
expect(result).toContain("**Quantity**: 50");
});
it("filters out low-priority keys", () => {
const data = {
name: "Visible",
id: "some-uuid",
store_id: "store-uuid",
created_at: "2025-01-01",
updated_at: "2025-01-02",
metadata: "meta",
};
const result = formatServerResponse(data);
expect(result).toContain("**Name**: Visible");
expect(result).not.toContain("**ID**");
expect(result).not.toContain("**Store ID**");
expect(result).not.toContain("**Created At**");
expect(result).not.toContain("**Updated At**");
expect(result).not.toContain("**Metadata**");
});
it("formats money keys with dollar sign", () => {
const data = { name: "Item", price: 29.99, cost: 15 };
const result = formatServerResponse(data);
expect(result).toContain("**Price**: $29.99");
expect(result).toContain("**Cost**: $15.00");
});
});
// --------------------------------------------------------------------------
// Nested wrapper objects (data/results/items/rows/records)
// --------------------------------------------------------------------------
describe("wrapper object with nested array", () => {
it("extracts data from 'data' wrapper key when object is not flat", () => {
// Wrapper extraction only triggers when isFlatObject returns false.
// Including a nested non-array object forces the non-flat path.
const data = {
total: 2,
meta: { page: 1 },
data: [
{ name: "A", quantity: 1 },
{ name: "B", quantity: 2 },
],
};
const result = formatServerResponse(data);
expect(result).toContain("**Total**: 2");
expect(result).toContain("A");
expect(result).toContain("B");
});
it("extracts data from 'results' wrapper key when object is not flat", () => {
const data = {
count: 1,
meta: { info: "x" },
results: [{ name: "Found" }],
};
const result = formatServerResponse(data);
expect(result).toContain("Found");
expect(result).toContain("**Count**: 1");
});
it("extracts data from 'items' wrapper key when object is not flat", () => {
const data = {
meta: { info: "x" },
items: [{ name: "Item 1" }, { name: "Item 2" }],
};
const result = formatServerResponse(data);
expect(result).toContain("Item 1");
expect(result).toContain("Item 2");
});
it("extracts data from 'rows' wrapper key when object is not flat", () => {
const data = {
meta: { info: "x" },
rows: [{ name: "Row 1" }],
};
const result = formatServerResponse(data);
expect(result).toContain("Row 1");
});
it("extracts data from 'records' wrapper key when object is not flat", () => {
const data = {
meta: { info: "x" },
records: [{ name: "Record A" }],
};
const result = formatServerResponse(data);
expect(result).toContain("Record A");
});
it("formats flat wrapper objects as key-value pairs (isFlatObject catches them first)", () => {
// When a wrapper object has only primitives + arrays, isFlatObject returns true,
// so it's formatted as key-value pairs rather than extracting the nested array.
// Note: "total" matches the money key regex, so it gets formatted with $.
const data = {
count: 2,
items: [{ name: "A" }, { name: "B" }],
};
const result = formatServerResponse(data);
expect(result).toContain("**Count**: 2");
expect(result).toContain("**Items**: [2 items]");
});
it("includes non-object summary fields from wrapper", () => {
const data = {
total: 100,
page: 1,
nested_config: { key: "ignored" },
data: [{ name: "X" }],
};
const result = formatServerResponse(data);
expect(result).toContain("**Total**: 100");
expect(result).toContain("**Page**: 1");
// nested_config should not appear in summary since it's an object
expect(result).not.toContain("**Nested Config**");
});
it("skips empty wrapper arrays", () => {
const data = {
total: 0,
data: [],
status: "ok",
};
// data is empty, so it won't match the "length > 0" condition;
// the object itself is flat so it'll be formatted as key-value
const result = formatServerResponse(data);
// Should not contain "No results found." because it's an object, not an array
expect(result).toContain("**Status**: ok");
});
});
// --------------------------------------------------------------------------
// JSON fallback
// --------------------------------------------------------------------------
describe("JSON fallback", () => {
it("falls back to JSON fence for deeply nested objects", () => {
const data = {
level1: {
level2: {
level3: "deep",
},
},
};
const result = formatServerResponse(data);
expect(result).toContain("```json");
expect(result).toContain("```");
expect(result).toContain('"level3": "deep"');
});
it("falls back to JSON for arrays of primitives", () => {
const data = [1, 2, 3, 4, 5];
const result = formatServerResponse(data);
expect(result).toContain("```json");
});
it("falls back to JSON for boolean primitives", () => {
const result = formatServerResponse(true);
expect(result).toContain("```json");
expect(result).toContain("true");
});
it("falls back to JSON for number primitives", () => {
const result = formatServerResponse(42);
expect(result).toContain("```json");
expect(result).toContain("42");
});
it("falls back to JSON for object with > 20 flat entries", () => {
const data: Record<string, string> = {};
for (let i = 0; i < 25; i++) {
data[`field_${i}`] = `value_${i}`;
}
const result = formatServerResponse(data);
expect(result).toContain("```json");
});
});
// --------------------------------------------------------------------------
// Value formatting
// --------------------------------------------------------------------------
describe("value formatting in tables", () => {
it("formats null/undefined as em dash", () => {
const data = [{ name: "Test", optional: null }];
const result = formatServerResponse(data);
// The em dash character
expect(result).toContain("\u2014");
});
it("formats booleans as check/cross marks", () => {
const data = [{ name: "Feature", enabled: true, deprecated: false }];
const result = formatServerResponse(data);
expect(result).toContain("\u2713"); // checkmark for true
expect(result).toContain("\u2715"); // cross for false
});
it("truncates UUIDs to 8 characters", () => {
const uuid = "550e8400-e29b-41d4-a716-446655440000";
const data = [{ name: "Item", ref: uuid }];
const result = formatServerResponse(data);
expect(result).toContain("550e8400");
expect(result).not.toContain("446655440000");
});
it("formats ISO dates to YYYY-MM-DD", () => {
const data = [{ name: "Event", date: "2025-06-15T14:30:00Z" }];
const result = formatServerResponse(data);
expect(result).toContain("2025-06-15");
expect(result).not.toContain("T14:30:00Z");
});
it("formats money-like strings with dollar sign", () => {
const data = { revenue: "1234.56" };
const result = formatServerResponse(data);
expect(result).toContain("$");
});
it("formats arrays as item count", () => {
const data = [{ name: "Group", members: ["a", "b", "c"] }];
const result = formatServerResponse(data);
expect(result).toContain("[3 items]");
});
it("formats nested objects as {...}", () => {
// This triggers in value formatting but nested objects are excluded from table columns
// Let's test it via key-value pair rendering
const data = { name: "Test", config: { nested: true } };
// This object is NOT flat (has nested object), so isFlatObject returns false
// Falls through to wrapper check, then JSON fallback
const result = formatServerResponse(data);
expect(result).toContain("```json");
});
it("truncates strings longer than 40 characters", () => {
const longStr = "A".repeat(50);
const data = [{ name: longStr }];
const result = formatServerResponse(data);
expect(result).toContain("...");
expect(result).not.toContain("A".repeat(50));
});
});
// --------------------------------------------------------------------------
// Money formatting
// --------------------------------------------------------------------------
describe("money key detection and formatting", () => {
it("detects price as money key", () => {
const data = [{ name: "Widget", price: 19.99 }];
const result = formatServerResponse(data);
expect(result).toContain("$19.99");
});
it("detects revenue as money key", () => {
const data = [{ name: "Q1", revenue: 50000 }];
const result = formatServerResponse(data);
expect(result).toContain("$50,000.00");
});
it("detects total as money key", () => {
const data = [{ name: "Order", total: 125.5 }];
const result = formatServerResponse(data);
expect(result).toContain("$125.50");
});
it("detects cost as money key", () => {
const data = { cost_price: 8.5 };
const result = formatServerResponse(data);
expect(result).toContain("$8.50");
});
it("detects subtotal as money key", () => {
const data = { subtotal: 99.99 };
const result = formatServerResponse(data);
expect(result).toContain("$99.99");
});
it("does not add dollar sign to non-money number keys", () => {
const data = { name: "Test", quantity: 42 };
const result = formatServerResponse(data);
expect(result).toContain("42");
// Quantity line should not have $
const quantityLine = result.split("\n").find(l => l.includes("Quantity"));
expect(quantityLine).toBeDefined();
expect(quantityLine).not.toContain("$");
});
});
// --------------------------------------------------------------------------
// Key prettification
// --------------------------------------------------------------------------
describe("key prettification", () => {
it("converts snake_case to Title Case", () => {
const data = { first_name: "John" };
const result = formatServerResponse(data);
expect(result).toContain("**First Name**: John");
});
it("capitalizes 'id' to 'ID'", () => {
// Note: id is filtered out by LOW_PRIORITY_KEYS, so use a compound key
const data = { customer_id_ref: "abc123" };
const result = formatServerResponse(data);
expect(result).toContain("Customer ID Ref");
});
it("handles single word keys", () => {
const data = { name: "Solo" };
const result = formatServerResponse(data);
expect(result).toContain("**Name**: Solo");
});
});
// --------------------------------------------------------------------------
// Column selection
// --------------------------------------------------------------------------
describe("column selection with tool name", () => {
it("prioritizes product columns for products tool", () => {
const data = [
{
name: "Blue Dream",
sku: "BD-001",
status: "published",
price: 35,
category: "Flower",
stock_quantity: 100,
id: "uuid-here",
store_id: "store-uuid",
created_at: "2025-01-01",
},
];
const result = formatServerResponse(data, "products");
// Priority columns should appear
expect(result).toContain("Name");
expect(result).toContain("Sku");
expect(result).toContain("Status");
// Low priority keys like id, store_id should be excluded
expect(result).not.toContain("Store ID");
});
it("prioritizes analytics columns for analytics tool", () => {
const data = [
{ name: "Q1", revenue: 10000, quantity: 500, count: 100, average: 100 },
];
const result = formatServerResponse(data, "analytics_summary");
expect(result).toContain("**Analytics**");
expect(result).toContain("Name");
expect(result).toContain("Revenue");
});
it("prioritizes customer columns for customers tool", () => {
const data = [
{
first_name: "John",
last_name: "Doe",
email: "john@example.com",
phone: "555-1234",
status: "active",
loyalty_tier: "Gold",
id: "uuid",
},
];
const result = formatServerResponse(data, "customers");
expect(result).toContain("**Customers**");
expect(result).toContain("John");
expect(result).toContain("Doe");
});
it("prioritizes order columns for orders tool", () => {
const data = [
{
order_number: "ORD-001",
status: "completed",
total: 150.00,
customer_name: "Jane",
created_at: "2025-03-01T10:00:00Z",
},
];
const result = formatServerResponse(data, "orders");
expect(result).toContain("**Orders**");
expect(result).toContain("ORD-001");
});
it("prioritizes inventory columns for inventory tool", () => {
const data = [
{ name: "Widget", product_name: "Widget Pro", quantity: 50, location: "Warehouse A", status: "in_stock" },
];
const result = formatServerResponse(data, "inventory_summary");
expect(result).toContain("**Inventory**");
});
it("prioritizes workflow columns for workflows tool", () => {
const data = [
{ name: "Welcome Flow", status: "active", trigger_type: "event" },
];
const result = formatServerResponse(data, "workflows_list");
expect(result).toContain("**Workflows**");
});
it("prioritizes email columns for email tool", () => {
const data = [
{ subject: "Hello", to: "user@test.com", status: "sent" },
];
const result = formatServerResponse(data, "email_send");
expect(result).toContain("**Email**");
});
it("prioritizes supply_chain columns for supply_chain tool", () => {
const data = [
{ name: "PO-001", status: "approved", quantity: 100, supplier: "Acme" },
];
const result = formatServerResponse(data, "supply_chain_po_list");
expect(result).toContain("**Supply Chain**");
});
});
// --------------------------------------------------------------------------
// Narrow vs wide terminal
// --------------------------------------------------------------------------
describe("narrow vs wide terminal", () => {
it("limits to 4 columns on narrow terminals (< 90 cols)", () => {
setTerminalWidth(80);
const data = [
{
name: "A",
sku: "S1",
status: "active",
price: 10,
category: "Cat",
stock_quantity: 5,
extra1: "x",
extra2: "y",
},
];
const result = formatServerResponse(data, "products");
// Count pipe-delimited columns in header row
const headerLine = result.split("\n").find(l => l.includes("Name"));
if (headerLine) {
// Count separators: N columns means N+1 pipe chars in "| col1 | col2 | ... | colN |"
const pipes = headerLine.split("|").length - 1;
const colCount = pipes / 2; // each col has a leading and trailing pipe
// Narrow = max 4 cols, but let's just check it's 4 or fewer
expect(colCount).toBeLessThanOrEqual(5); // 4 cols = 5 pipe pairs (roughly)
}
});
it("allows up to 6 columns on wide terminals (>= 90 cols)", () => {
setTerminalWidth(150);
const data = [
{
name: "A",
sku: "S1",
status: "active",
price: 10,
category: "Cat",
stock_quantity: 5,
extra1: "x",
extra2: "y",
},
];
const result = formatServerResponse(data, "products");
// Should have more columns than narrow
expect(result).toContain("Name");
expect(result).toContain("Sku");
});
});
// --------------------------------------------------------------------------
// Column selection edge cases
// --------------------------------------------------------------------------
describe("column selection edge cases", () => {
it("excludes nested object values from table columns", () => {
const data = [
{ name: "Test", config: { nested: true }, simple: "yes" },
];
const result = formatServerResponse(data);
// config is an object, should be excluded from columns
// The table should not have a Config column header
const lines = result.split("\n");
const headerLine = lines.find(l => l.includes("Name"));
expect(headerLine).toBeDefined();
// config should not be a column header
expect(headerLine).not.toContain("Config");
});
it("collects keys from first 5 rows", () => {
const data = [
{ name: "A" },
{ name: "B", extra: "x" },
{ name: "C", extra: "y", bonus: "z" },
];
const result = formatServerResponse(data);
// All keys from first few rows should be considered
expect(result).toContain("Name");
});
});
// --------------------------------------------------------------------------
// Table alignment
// --------------------------------------------------------------------------
describe("table alignment", () => {
it("right-aligns numeric values", () => {
const data = [
{ name: "Short", quantity: 5 },
{ name: "Longer Name", quantity: 12345 },
];
const result = formatServerResponse(data);
// Numbers should be right-aligned (padStart)
// The exact formatting depends on column widths, but the numbers should be present
expect(result).toContain("5");
expect(result).toContain("12,345");
});
it("right-aligns money values", () => {
const data = [
{ name: "Cheap", price: 5 },
{ name: "Expensive", price: 1000 },
];
const result = formatServerResponse(data);
expect(result).toContain("$5.00");
expect(result).toContain("$1,000.00");
});
it("produces valid markdown table structure", () => {
const data = [
{ name: "A", value: 1 },
{ name: "B", value: 2 },
];
const result = formatServerResponse(data);
const lines = result.split("\n");
// Find the table lines (after the header text)
const tableLines = lines.filter(l => l.startsWith("|"));
expect(tableLines.length).toBeGreaterThanOrEqual(3); // header + separator + at least 1 row
// Second table line should be the separator
expect(tableLines[1]).toMatch(/^\|[\s-|]+\|$/);
});
});
// --------------------------------------------------------------------------
// Tool category detection
// --------------------------------------------------------------------------
describe("tool category detection", () => {
it("detects analytics from tool name containing 'analytics'", () => {
const data = [{ name: "Q1", revenue: 100 }];
const result = formatServerResponse(data, "sales_analytics");
expect(result).toContain("**Analytics**");
});
it("detects products from tool name containing 'products'", () => {
const data = [{ name: "Item" }];
const result = formatServerResponse(data, "my_products_list");
expect(result).toContain("**Products**");
});
it("returns undefined category for no tool name", () => {
const data = [{ name: "Item" }];
const result = formatServerResponse(data);
expect(result).toContain("**Results**");
});
it("is case-insensitive for category matching", () => {
const data = [{ name: "Item" }];
const result = formatServerResponse(data, "PRODUCTS_FIND");
expect(result).toContain("**Products**");
});
});
// --------------------------------------------------------------------------
// isFlatObject behavior
// --------------------------------------------------------------------------
describe("flat vs non-flat object detection", () => {
it("treats object with only primitives and arrays as flat", () => {
const data = {
name: "Test",
count: 5,
active: true,
tags: ["a", "b"],
};
const result = formatServerResponse(data);
// Should be formatted as key-value pairs, not JSON
expect(result).toContain("**Name**: Test");
expect(result).toContain("**Count**: 5");
expect(result).not.toContain("```json");
});
it("treats object with nested objects as non-flat", () => {
const data = {
name: "Test",
config: { key: "value" },
};
const result = formatServerResponse(data);
// Not flat, so falls through to JSON
expect(result).toContain("```json");
});
it("treats arrays as not flat objects", () => {
const data = [1, 2, 3];
// Array of primitives falls through to JSON
const result = formatServerResponse(data);
expect(result).toContain("```json");
});
});
// --------------------------------------------------------------------------
// Edge case: object with all low-priority keys
// --------------------------------------------------------------------------
describe("objects with all low-priority keys", () => {
it("falls back to JSON when all keys are low priority", () => {
const data = {
id: "abc",
store_id: "def",
created_at: "2025-01-01",
updated_at: "2025-01-02",
};
const result = formatServerResponse(data);
// All keys filtered out → entries.length becomes 0 → falls through to JSON
expect(result).toContain("```json");
});
});
// --------------------------------------------------------------------------
// Large table formatting
// --------------------------------------------------------------------------
describe("large datasets", () => {
it("handles many rows without crashing", () => {
const data = Array.from({ length: 100 }, (_, i) => ({
name: `Item ${i}`,
quantity: i * 10,
status: i % 2 === 0 ? "active" : "inactive",
}));
const result = formatServerResponse(data);
expect(result).toContain("(100 results)");
expect(result).toContain("Item 0");
expect(result).toContain("Item 99");
});
it("caps individual column width at 30 characters", () => {
const longName = "A".repeat(50);
const data = [{ category: longName, qty: 1 }];
const result = formatServerResponse(data);
// The value in the table should be truncated to 37+3=40 by formatValue,
// then column width capped at 30
// The formatted string will contain "..." since it's > 40 chars
expect(result).toContain("...");
});
});
// --------------------------------------------------------------------------
// Number formatting with locale
// --------------------------------------------------------------------------
describe("number formatting", () => {
it("formats large numbers with locale separators", () => {
const data = [{ name: "Big", count: 1000000 }];
const result = formatServerResponse(data);
// toLocaleString should add commas (in en-US locale at least)
expect(result).toContain("1,000,000");
});
it("formats zero correctly", () => {
const data = { count: 0 };
const result = formatServerResponse(data);
expect(result).toContain("0");
});
it("formats negative numbers", () => {
const data = { balance: -500 };
const result = formatServerResponse(data);
expect(result).toContain("-500");
});
});
// --------------------------------------------------------------------------
// Real-world response shapes
// --------------------------------------------------------------------------
describe("real-world response shapes", () => {
it("formats an analytics summary response (flat object with array)", () => {
// This object is flat (all values are primitives or arrays), so isFlatObject
// returns true and it renders as key-value pairs.
const data = {
period: "last_30",
total_revenue: 45000,
total_orders: 320,
average_order_value: 140.63,
data: [
{ name: "Flower", revenue: 25000, quantity: 200, count: 180 },
{ name: "Edibles", revenue: 12000, quantity: 80, count: 90 },
{ name: "Vapes", revenue: 8000, quantity: 40, count: 50 },
],
};
const result = formatServerResponse(data, "analytics");
expect(result).toContain("**Period**: last_30");
expect(result).toContain("**Total Revenue**: $45,000.00");
expect(result).toContain("**Data**: [3 items]");
});
it("formats an analytics wrapper response with nested metadata", () => {
// Including a nested object forces non-flat path, allowing wrapper extraction.
const data = {
period: "last_30",
meta: { generated: "2025-01-01" },
data: [
{ name: "Flower", revenue: 25000, quantity: 200, count: 180 },
{ name: "Edibles", revenue: 12000, quantity: 80, count: 90 },
],
};
const result = formatServerResponse(data, "analytics");
expect(result).toContain("**Period**: last_30");
expect(result).toContain("Flower");
expect(result).toContain("Edibles");
});
it("formats an inventory summary response", () => {
const data = [
{ product_name: "Blue Dream", quantity: 50, location_name: "Main Store", status: "in_stock" },
{ product_name: "OG Kush", quantity: 0, location_name: "Main Store", status: "out_of_stock" },
];
const result = formatServerResponse(data, "inventory");
expect(result).toContain("**Inventory**");
expect(result).toContain("Blue Dream");
expect(result).toContain("OG Kush");
});
it("formats a customer find response", () => {
const data = [
{
first_name: "Alice",
last_name: "Smith",
email: "alice@example.com",
phone: "555-0001",
status: "active",
loyalty_tier: "Gold",
id: "550e8400-e29b-41d4-a716-446655440000",
store_id: "660e8400-e29b-41d4-a716-446655440000",
created_at: "2025-01-15T08:30:00Z",
},
];
const result = formatServerResponse(data, "customers");
expect(result).toContain("**Customers**");
expect(result).toContain("Alice");
expect(result).toContain("Smith");
expect(result).toContain("alice@example.com");
expect(result).toContain("Gold");
// UUID should be truncated in table
expect(result).not.toContain("446655440000");
});
it("formats an order detail response", () => {
const data = {
order_number: "ORD-2025-001",
status: "completed",
total: 250.00,
subtotal: 230.00,
tax: 20.00,
customer_name: "Bob Jones",
};
const result = formatServerResponse(data);
expect(result).toContain("**Order Number**: ORD-2025-001");
expect(result).toContain("**Status**: completed");
expect(result).toContain("$250.00");
expect(result).toContain("$230.00");
expect(result).toContain("$20.00");
});
});
// --------------------------------------------------------------------------
// Array of objects where first element is null or non-object
// --------------------------------------------------------------------------
describe("array edge cases", () => {
it("falls back to JSON for array starting with null", () => {
const data = [null, { name: "test" }];
const result = formatServerResponse(data);
expect(result).toContain("```json");
});
it("falls back to JSON for array of strings", () => {
const data = ["apple", "banana", "cherry"];
const result = formatServerResponse(data);
expect(result).toContain("```json");
});
it("falls back to JSON for array of numbers", () => {
const data = [1, 2, 3];
const result = formatServerResponse(data);
expect(result).toContain("```json");
});
it("falls back to JSON for array of booleans", () => {
const data = [true, false, true];
const result = formatServerResponse(data);
expect(result).toContain("```json");
});
});
});