docs(ops): stop the compose header contradicting itself, and name the four variables step 2 dropped (#204) #210

Merged
bermudalamb merged 2 commits from feature/204-ops-doc-accuracy into main 2026-08-28 14:01:30 -05:00
3 changed files with 66 additions and 10 deletions
Showing only changes of commit 410aaa6d87 - Show all commits
+27 -1
View File
@@ -38,7 +38,16 @@ const COLUMNS = [
dataIndex: 'status',
render: (v: string) => <Tag color={STATUS_COLORS[v]}>{v}</Tag>
},
{ title: 'Processor', dataIndex: 'processor' },
{
title: 'Processor',
dataIndex: 'processor',
// `demo` used to render as a raw column value, which is not an explanation:
// a customer has no reason to read it as "this did not happen", and the row
// was otherwise identical to a real one — real price, `completed` status,
// same neutral tag. The cart says it is a demo (#195, #203) for about three
// seconds; this is the record they come back to. See #205.
render: (v: string) => (v === 'demo' ? <Tag color="warning">Demo (not charged)</Tag> : v)
},
{ title: 'Date', dataIndex: 'created_at', render: (v: string) => new Date(v).toLocaleDateString() }
];
@@ -69,6 +78,12 @@ function OrdersBody({ loading, error, orders, onRetry }: BodyProps) {
);
}
// Shown only when there is one to explain. The per-row tag says which order,
// this says what it means — a tag reading "Demo" still assumes the reader
// knows what a demo order is, and the thing they actually want to know is
// whether to expect a parcel.
const hasDemoOrder = orders.some(o => o.processor === 'demo');
if (orders.length === 0) {
return (
<Space direction="vertical" align="center" style={{ width: '100%', marginTop: 24 }}>
@@ -79,6 +94,16 @@ function OrdersBody({ loading, error, orders, onRetry }: BodyProps) {
}
return (
<>
{hasDemoOrder && (
<Alert
type="warning"
showIcon
style={{ marginBottom: 16 }}
message="Some of these are demo orders"
description="A demo order is a pretend one: nothing was charged, and nothing will be shipped."
/>
)}
<Table
rowKey="id"
dataSource={orders}
@@ -88,6 +113,7 @@ function OrdersBody({ loading, error, orders, onRetry }: BodyProps) {
scroll={{ x: 'max-content' }}
columns={COLUMNS}
/>
</>
);
}
+26
View File
@@ -61,6 +61,32 @@ test.describe('Demo mode says so to the customer', () => {
await expect(cart.demoNotice).toBeVisible({ timeout: 20000 });
});
// The toast is three seconds; this is the record the customer comes back to
// when they wonder where their item is. It showed `demo` as a raw value under
// a "Processor" heading, beside a real price and a neutral `completed` tag —
// nothing a customer would read as "this did not happen". See #205.
test('order history marks the demo order rather than showing it as a real one', async ({
page,
customer,
cart,
orders
}) => {
const name = `Demo h${uniqueSuffix()}`;
const item = await createItem(page.request, { name, price: '80' });
expect((await page.request.post(`/api/cart/items/${item.id}`)).status()).toBe(201);
expect((await page.request.post('/api/customers/me/addresses', { data: ADDRESS })).ok()).toBe(true);
await cart.goto();
await expect(cart.checkoutButton).toBeVisible({ timeout: 20000 });
await cart.checkoutButton.click();
await expect(page.getByText(/nothing was charged/i)).toBeVisible({ timeout: 20000 });
await orders.goto();
await expect(orders.demoOrderMarker).toBeVisible({ timeout: 20000 });
await expect(orders.demoNotice).toBeVisible();
});
test('the confirmation says nothing was charged', async ({ page, customer, cart }) => {
const name = `Demo p${uniqueSuffix()}`;
const item = await createItem(page.request, { name, price: '80' });
+4
View File
@@ -14,6 +14,8 @@ export class OrdersPage {
readonly continueShoppingButton: Locator;
readonly backToShopButton: Locator;
readonly anyDialog: Locator;
readonly demoNotice: Locator;
readonly demoOrderMarker: Locator;
constructor(private readonly page: Page) {
this.heading = page.getByRole('heading', { name: 'Order History' });
@@ -21,6 +23,8 @@ export class OrdersPage {
this.continueShoppingButton = page.getByRole('button', { name: 'Continue Shopping' });
this.backToShopButton = page.getByRole('button', { name: 'Back to Shop' });
this.anyDialog = page.getByRole('dialog');
this.demoNotice = page.getByText('Some of these are demo orders');
this.demoOrderMarker = page.getByText('Demo (not charged)');
}
async goto(): Promise<void> {