feat(housekeeping): deliver economy vertical
This commit is contained in:
1 parent
1ec05cda39
commit
9c4b973faf
62 files changed
+6306
-1285
No files matched your search
@@ -0,0 +1,114 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { PERMS } from "@/lib/permission-slugs";
|
||||
import type { HousekeepingCapabilityContext } from "../../../foundation/contracts";
|
||||
import { ECONOMY_ROUTE_IDS } from "../routes";
|
||||
import { createEconomyQuery, type EconomyQueryData } from "./catalog";
|
||||
import { serializeEconomyAmount } from "./commerce";
|
||||
import { serializeEconomyValue } from "./value";
|
||||
|
||||
function context(granted: readonly string[]): HousekeepingCapabilityContext {
|
||||
const permissions = new Set(granted);
|
||||
return {
|
||||
actor: { id: 42, username: "operator", rank: 7 },
|
||||
isSuperAdmin: false,
|
||||
has: (slug) => permissions.has(slug),
|
||||
hasAny: (...slugs) => slugs.some((slug) => permissions.has(slug)),
|
||||
hasAll: (...slugs) => slugs.every((slug) => permissions.has(slug)),
|
||||
};
|
||||
}
|
||||
|
||||
describe("Economy query adapters", () => {
|
||||
it("fails closed before invoking an unauthorized adapter", async () => {
|
||||
const load = vi.fn();
|
||||
const query = createEconomyQuery({ load });
|
||||
const result = await query.run(context([]), {
|
||||
routeId: "economy.catalog.overview",
|
||||
});
|
||||
expect(result).toMatchObject({
|
||||
ok: false,
|
||||
error: { code: "FORBIDDEN" },
|
||||
});
|
||||
expect(load).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("normalizes stable pagination and preserves BIGINT identifiers", async () => {
|
||||
const load = vi.fn(
|
||||
async (): Promise<EconomyQueryData> => ({
|
||||
kind: "history",
|
||||
items: [
|
||||
{
|
||||
id: "18446744073709551615",
|
||||
title: "Completed order",
|
||||
amount: "EUR 12.50",
|
||||
href: "/ase/economy/history/transactions",
|
||||
},
|
||||
],
|
||||
total: 501,
|
||||
partialDependencies: [],
|
||||
}),
|
||||
);
|
||||
const query = createEconomyQuery({ load });
|
||||
const result = await query.run(context([PERMS.SHOP_VIEW]), {
|
||||
routeId: "economy.history.transactions",
|
||||
list: { search: " paid ", pageSize: 999, offset: 999_999 },
|
||||
});
|
||||
expect(load).toHaveBeenCalledWith({
|
||||
routeId: "economy.history.transactions",
|
||||
params: {},
|
||||
list: { search: "paid", pageSize: 100, offset: 100_000 },
|
||||
});
|
||||
expect(result).toMatchObject({
|
||||
ok: true,
|
||||
data: { items: [{ id: "18446744073709551615" }], total: 501 },
|
||||
});
|
||||
});
|
||||
|
||||
it("serializes money and rare values without locale-dependent rounding", () => {
|
||||
expect(serializeEconomyAmount(12.5, "eur")).toBe("EUR 12.50");
|
||||
expect(serializeEconomyAmount("9007199254740993", "usd")).toBe(
|
||||
"USD 9007199254740993",
|
||||
);
|
||||
expect(serializeEconomyValue("1250.50", "diamonds")).toEqual({
|
||||
value: "1250.50",
|
||||
currency: "diamonds",
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects fabricated partial dependencies and unsafe hrefs", async () => {
|
||||
const query = createEconomyQuery({
|
||||
load: async () => ({
|
||||
kind: "catalog",
|
||||
items: [
|
||||
{ id: "1", title: "Unsafe", href: "/ase/economy/%2e%2e/system" },
|
||||
],
|
||||
total: 1,
|
||||
partialDependencies: ["imaginary"],
|
||||
}),
|
||||
});
|
||||
expect(
|
||||
await query.run(context([PERMS.CATALOG_VIEW]), {
|
||||
routeId: "economy.catalog.overview",
|
||||
}),
|
||||
).toMatchObject({
|
||||
ok: false,
|
||||
error: { code: "DEPENDENCY_UNAVAILABLE" },
|
||||
});
|
||||
});
|
||||
|
||||
it("has an authorized adapter path for every Economy route", async () => {
|
||||
const load = vi.fn(async (input) => ({
|
||||
kind: input.routeId.split(".")[1] as EconomyQueryData["kind"],
|
||||
items: [],
|
||||
total: 0,
|
||||
partialDependencies: [],
|
||||
}));
|
||||
const query = createEconomyQuery({ load });
|
||||
for (const routeId of ECONOMY_ROUTE_IDS) {
|
||||
const result = await query.run(context(Object.values(PERMS)), {
|
||||
routeId,
|
||||
});
|
||||
expect(result.ok, routeId).toBe(true);
|
||||
}
|
||||
expect(load).toHaveBeenCalledTimes(ECONOMY_ROUTE_IDS.length);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user