Hello from MCP server
import { ClientResponseError } from "pocketbase";
import { check, getApi, getPb, wait, waitMs, users } from "./common.js";
import {
benderMenus,
benderTiers,
spaceship,
scruffyTiers,
} from "./spaceshipBook.js";
export async function futuramaTests(api) {
await check(async () => {
await api.register(users.bender);
const r = await api.createOrg(users.bender);
users.bender.orgId = r.id;
await api.chooseCurrency(
users.bender,
users.bender.orgId,
users.bender.orgCurrency,
);
}, "Bender can register and choose a currency for his organization");
await check(async () => {
const tiersBook = await api.createBook(
users.bender,
users.bender.orgId,
"Bender's Tiers",
"tiersBook",
null,
null,
);
await api.publishChanges(
users.bender,
users.bender.orgId,
tiersBook.id,
benderTiers,
);
const costsBook = await api.createBook(
users.bender,
users.bender.orgId,
"Spaceship Repair Costs",
"spaceshipCosts",
null,
null,
);
await api.publishChanges(
users.bender,
users.bender.orgId,
costsBook.id,
spaceship,
);
const menusBook = await api.createBook(
users.bender,
users.bender.orgId,
"Spaceship Repair Book",
"spaceshipBook",
null,
[tiersBook.id, costsBook.id],
);
await api.publishChanges(
users.bender,
users.bender.orgId,
menusBook.id,
benderMenus,
);
users.bender.bookId = menusBook.id;
users.bender.tiersId = tiersBook.id;
users.bender.costsId = costsBook.id;
}, "Bender can author a pricebook while factoring out re-usable data into base books");
await check(async () => {
await api.register(users.scruffy);
const r = await api.createOrg(users.scruffy);
users.scruffy.orgId = r.id;
await api.chooseCurrency(
users.scruffy,
users.scruffy.orgId,
users.scruffy.orgCurrency,
);
}, "Scruffy can register and choose a currency for his organization");
await check(async () => {
await api.register(users.zoidberg);
const r = await api.createOrg(users.zoidberg);
users.zoidberg.orgId = r.id;
await api.chooseCurrency(
users.zoidberg,
users.zoidberg.orgId,
users.zoidberg.orgCurrency,
);
}, "Zoidberg can register and choose a currency for his organization");
await check(async () => {
await api.addSubscriber(
users.bender,
users.bender.costsId,
users.scruffy.orgId,
);
await api.addSubscriber(
users.bender,
users.bender.tiersId,
users.scruffy.orgId,
);
await api.addSubscriber(
users.bender,
users.bender.bookId,
users.scruffy.orgId,
);
}, "Bender can add Scruffy as a subscriber to his pricebook");
await check(async () => {
const books = await api.listBooks(users.bender);
const book = await api.viewBook(users.bender, users.bender.bookId);
if (book.id != users.bender.bookId) {
throw new Error("Can't see Bender's book");
}
}, "Bender can see his books");
// TODO: If "books.subscribers" is marked as a hidden field, then it breaks the API rule
// but at some point we need custom logic on the backend to strip "subscribers" from
// the API response for security, so we're not handing out unnecessary info about
// other people's organizations
await check(async () => {
const books = await api.listBooks(users.scruffy);
const found = books.find((e) => e.id == users.bender.bookId);
if (!found) {
throw new Error("Should be able to see Bender's book in the list");
}
const book = await api.viewBook(users.scruffy, users.bender.bookId);
if (book.id != users.bender.bookId) {
throw new Error("Can't see Bender's book");
}
}, "Scruffy can see Bender's Spaceship Repair book");
await check(async () => {
await api.publishChanges(
users.bender,
users.bender.orgId,
users.bender.bookId,
[
{
collection: "costsTime",
operation: "update",
data: {
name: "calibrateTimeBest",
refId: "calibrateTimeBest",
hours: 9,
},
},
],
);
}, "Bender can update a pricebook");
await check(async () => {
try {
const book = await api.viewBook(users.zoidberg, users.bender.bookId);
if (book.id == users.bender.bookId) {
throw new Error("Zoidberg shouldn't see Bender's book");
}
} catch (e) {
if (e instanceof ClientResponseError) {
return "Failed as expected";
} else {
throw e;
}
}
}, "Zoidberg can NOT see Bender's Spaceship Repair book");
await check(async () => {
const changes = await api.listChanges(users.scruffy);
const found = changes.find((e) => e.book == users.bender.bookId);
if (!found) {
throw new Error("Should be able to see Bender's changesets in the list");
}
if (!changes.find((e) => e.book == users.bender.tiersId)) {
throw new Error("Should be able to see Bender's changesets in the list");
}
}, "Scruffy can list the changesets for Bender's pricebook");
await check(async () => {
await api.register(users.amy);
await api.joinOrg(users.amy, users.scruffy.orgId);
}, "Amy can join Scruffy's org");
await check(async () => {
await api.assignRole(users.scruffy, users.amy, "support");
const updated = await api.getOrgProfile(users.scruffy, users.amy);
const roleNames = updated.expand.roles.map((e) => e.name);
if (!roleNames.includes("support")) {
throw new Error("Amy should have the support role");
}
}, "Scruffy can assign the support role to Amy");
await check(async () => {
await api.register(users.leela);
await api.joinOrg(users.leela, users.scruffy.orgId);
}, "Leela can join Scruffy's org");
await check(async () => {
await api.assignRole(users.scruffy, users.leela, "tech");
const updated = await api.getOrgProfile(users.scruffy, users.leela);
const roleNames = updated.expand.roles.map((e) => e.name);
if (!roleNames.includes("tech")) {
throw new Error("Leela should have the tech role");
}
}, "Scruffy can assign the tech role to Leela");
await check(async () => {
try {
const currencies = await api.listCurrencies(users.leela);
console.log(currencies);
} catch (e) {
console.log(e);
throw new Error("Everyone should be able to list currencies");
}
}, "Leela can list currencies");
await check(async () => {
const books = await api.listBooks(users.leela);
const found = books.find((e) => e.id == users.bender.bookId);
if (!found) {
throw new Error("Should be able to see Bender's book in the list");
}
const book = await api.viewBook(users.leela, users.bender.bookId);
if (book.id != users.bender.bookId) {
throw new Error("Can't see Bender's book");
}
const changes = await api.listChanges(users.leela);
const found2 = changes.find((e) => e.book == users.bender.bookId);
console.log(found2);
if (!found2) {
throw new Error("Should be able to see Bender's changesets in the list");
}
}, "Leela can see Bender's Spaceship Repair book");
await check(async () => {
try {
const book = await api.viewBook(users.zoidberg, users.bender.bookId);
if (book.id == users.bender.bookId) {
throw new Error("omy shouldn't see Bender's book");
}
const changes = await api.listChanges(users.amy);
const found = changes.find((e) => e.book == users.bender.bookId);
if (found) {
throw new Error("Amy shouldn't see Bender's book");
}
} catch (e) {
if (e instanceof ClientResponseError) {
return "Failed as expected";
} else {
throw e;
}
}
}, "Amy can NOT list the changesets for Bender's pricebook");
await check(async () => {
const book = await api.createBook(
users.scruffy,
users.scruffy.orgId,
"Spaceship Repair Book",
"spaceshipBookScruffy",
users.bender.bookId,
);
users.scruffy.bookId = book.id;
await api.publishChanges(
users.scruffy,
users.scruffy.orgId,
users.scruffy.bookId,
[
{
collection: "costsTime",
operation: "update",
data: {
name: "calibrateTimeBest",
refId: "calibrateTimeBest",
hours: 12,
},
},
],
);
}, "Scruffy can override data from Bender's pricebook");
await check(async () => {
await api.publishChanges(
users.scruffy,
users.scruffy.orgId,
users.scruffy.bookId,
scruffyTiers,
);
}, "Scruffy can override tiers with custom names");
}