@mohasinac/appkit 4.41.11 → 4.41.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -117,12 +117,12 @@ export const authored = {
117
117
  startPage: "/admin/orders",
118
118
  steps: [
119
119
  "Sign in as admin@letitrip.in / TempPass123!.",
120
- "Open /admin/orders and open the row drawer for order-1-20260721-11joon.",
120
+ "Open /admin/orders and open the row drawer for order-1-20251107-11joon.",
121
121
  "Write down the item titles, the shipping address, the payment method and the status.",
122
122
  "Close the drawer and use that row's Open full page action.",
123
123
  "Read the same four things on the full page.",
124
124
  ],
125
- inputs: { orderId: "order-1-20260721-11joon" },
125
+ inputs: { orderId: "order-1-20251107-11joon" },
126
126
  expectedBehaviour: "The drawer and the full page are two renderings of one record, so they must agree. Where they differ, one of them is reading a field the other is not — and the full page is the bookmarkable one an admin will send to somebody else.",
127
127
  expectedUiState: "Item titles, address, payment method and status are identical in both, and the full page is at a real bookmarkable URL rather than a modal over the list.",
128
128
  expectedData: { drawerAndPageAgree: true },
@@ -42,12 +42,12 @@ export const authored = {
42
42
  startPage: "/user/orders",
43
43
  steps: [
44
44
  "Sign in as karthik.new@gmail.com / TempPass123!, a seeded buyer who owns no seeded orders.",
45
- "Navigate directly to /api/user/orders/order-1-20260721-11joon/invoice — a seeded order belonging to a different persona.",
45
+ "Navigate directly to /api/user/orders/order-1-20251107-11joon/invoice — a seeded order belonging to a different persona.",
46
46
  "Read the response.",
47
- "Now navigate to /user/orders/order-1-20260721-11joon.",
47
+ "Now navigate to /user/orders/order-1-20251107-11joon.",
48
48
  "Read that page.",
49
49
  ],
50
- inputs: { foreignOrderId: "order-1-20260721-11joon" },
50
+ inputs: { foreignOrderId: "order-1-20251107-11joon" },
51
51
  expectedBehaviour: "An order id is short and guessable, so ownership is checked on every hit rather than relied upon to be secret. Answering 403 instead of 404 would confirm that an order with that id exists, which is a membership oracle over the id space.",
52
52
  expectedUiState: "Neither the invoice nor the order page shows any of that order's contents. No item titles, no address, no amounts.",
53
53
  expectedData: { foreignInvoiceServed: false },
@@ -74,14 +74,14 @@ export const authored = {
74
74
  startPage: "/user/orders",
75
75
  steps: [
76
76
  "Sign in as vivaan.kapoor@gmail.com / TempPass123! — this persona owns the seeded DELIVERED orders, and a return can only be requested on one.",
77
- "Open /user/orders and open order-1-20260721-11joon, which is delivered.",
77
+ "Open /user/orders and open order-1-20251107-11joon, which is delivered.",
78
78
  "Use the Return action.",
79
79
  "Give the reason: item not as described.",
80
80
  "Submit the request.",
81
81
  "Reload the order.",
82
82
  "Open /user/returns and look for it.",
83
83
  ],
84
- inputs: { orderId: "order-1-20260721-11joon", reason: "item not as described" },
84
+ inputs: { orderId: "order-1-20251107-11joon", reason: "item not as described" },
85
85
  expectedBehaviour: "A return request moves the order into Return Requested and appears on the returns surface. That status is deliberately an ACTIVE one — it is the seller's next action item, not a closed state — so the order must not disappear from the active list.",
86
86
  expectedUiState: "The order's status reads Return Requested, and the same order is listed under /user/returns.",
87
87
  expectedData: { statusAfterReturn: "return_requested" },
@@ -92,12 +92,12 @@ export const authored = {
92
92
  startPage: "/user/orders",
93
93
  steps: [
94
94
  "Sign in as rehan.sheikh@gmail.com / TempPass123! — this persona owns the seeded SHIPPED order.",
95
- "Open /user/orders and open order-1-20260718-aevnlw.",
95
+ "Open /user/orders and open order-1-20251104-aevnlw.",
96
96
  "Use the Track action.",
97
97
  "Read every step on the timeline and note which carry a date and which do not.",
98
98
  "Compare the dates shown against the order's own placed and shipped dates.",
99
99
  ],
100
- inputs: { orderId: "order-1-20260718-aevnlw" },
100
+ inputs: { orderId: "order-1-20251104-aevnlw" },
101
101
  expectedBehaviour: "Each timeline step shows the date actually recorded for it. A step with no recorded date renders an em-dash rather than a guess — an invented or estimated date is worse than a blank, because it cannot be told apart from a real one.",
102
102
  expectedUiState: "The placed and shipped steps carry dates matching the order. Steps the order has not reached show no date rather than today's.",
103
103
  expectedData: { fabricatedDatesShown: false },
@@ -108,14 +108,14 @@ export const authored = {
108
108
  startPage: "/user/orders",
109
109
  steps: [
110
110
  "Sign in as karthik.new@gmail.com / TempPass123!, a seeded buyer who owns no seeded orders.",
111
- "Navigate to /user/orders/order-1-20260721-11joon/track.",
112
- "Navigate to /user/orders/order-1-20260721-11joon/invoice.",
113
- "Navigate to /user/orders/order-1-20260721-11joon/return.",
114
- "Navigate to /user/orders/order-1-20260721-11joon/cancel.",
115
- "Navigate to /user/orders/order-1-20260721-11joon/payment.",
111
+ "Navigate to /user/orders/order-1-20251107-11joon/track.",
112
+ "Navigate to /user/orders/order-1-20251107-11joon/invoice.",
113
+ "Navigate to /user/orders/order-1-20251107-11joon/return.",
114
+ "Navigate to /user/orders/order-1-20251107-11joon/cancel.",
115
+ "Navigate to /user/orders/order-1-20251107-11joon/payment.",
116
116
  "Read each page in turn.",
117
117
  ],
118
- inputs: { foreignOrderId: "order-1-20260721-11joon" },
118
+ inputs: { foreignOrderId: "order-1-20251107-11joon" },
119
119
  expectedBehaviour: "Ownership is enforced on EVERY subroute, not only on the order page that links to them. A subroute that checks nothing is reachable by typing a URL, and these five carry the address, the amounts and the payment details.",
120
120
  expectedUiState: "All five show a not-found page. None shows an item title, an address, an amount or a tracking number belonging to that order.",
121
121
  expectedData: { subroutesLeakingData: 0 },
@@ -126,11 +126,11 @@ export const authored = {
126
126
  startPage: "/user/orders",
127
127
  steps: [
128
128
  "Open a private window with no session.",
129
- "Navigate to /user/orders/order-1-20260721-11joon/track.",
129
+ "Navigate to /user/orders/order-1-20251107-11joon/track.",
130
130
  "Read the page.",
131
131
  "Navigate to /user/orders and read that page too.",
132
132
  ],
133
- inputs: { foreignOrderId: "order-1-20260721-11joon" },
133
+ inputs: { foreignOrderId: "order-1-20251107-11joon" },
134
134
  expectedBehaviour: "A signed-out visitor is sent to sign in. Being blocked IS the expected result here — the failure to look for is the page rendering its content for a moment before redirecting, which is enough to read and enough for a crawler to capture.",
135
135
  expectedUiState: "The sign-in page, or the orders page in its signed-out state. At no point does any order content appear, not even briefly.",
136
136
  expectedData: { orderContentVisibleToGuest: false },
@@ -448,11 +448,54 @@ const cashOrderVerified = {
448
448
  createdAt: daysAgo(4),
449
449
  updatedAt: daysAgo(2),
450
450
  };
451
+ /*
452
+ * 🛑 DERIVES `items[]` FROM THE FLAT FIELDS WHEN A FIXTURE OMITS IT.
453
+ *
454
+ * `items[]` is the canonical shape and every orders surface reads
455
+ * `items[0].productTitle` for its row label (Root Cause #52). The generator
456
+ * below was taught to emit it — and that fix was NARROWER THAN THE DEFECT:
457
+ * measured after it shipped, 14 of the 50 seeded orders still had none,
458
+ * because the hand-written fixtures never go through the generator.
459
+ *
460
+ * That is Root Cause #84's shape — a fix scoped to the population you happened
461
+ * to be looking at. Patching those 14 by hand would leave the 15th to whoever
462
+ * writes it next, so the derivation lives here instead, on the path EVERY
463
+ * fixture already takes.
464
+ *
465
+ * It only ever fills a gap: a fixture that declares its own `items[]` (the
466
+ * multi-line ones, where the flat fields cannot express two products) is
467
+ * passed through untouched.
468
+ */
469
+ function withOrderItems(order) {
470
+ if (Array.isArray(order.items) && order.items.length > 0)
471
+ return order;
472
+ if (!order.productId)
473
+ return order;
474
+ const quantity = order.quantity ?? 1;
475
+ const unitPrice = order.unitPrice ?? 0;
476
+ return {
477
+ ...order,
478
+ items: [
479
+ {
480
+ productId: order.productId,
481
+ productTitle: order.productTitle ?? order.productId,
482
+ listingType: "standard",
483
+ quantity,
484
+ unitPrice,
485
+ // Prefer the order's own total: on a single-line order it is the
486
+ // authoritative figure, and re-deriving it would silently drop any
487
+ // fixture that deliberately encodes a locked or negotiated price.
488
+ totalPrice: order.totalPrice ?? unitPrice * quantity,
489
+ },
490
+ ],
491
+ };
492
+ }
451
493
  // Backfills image/imageUrls (see orderItemImage() above) on every fixture
452
494
  // regardless of which shape it uses (multi-item `items[]` vs the legacy
453
495
  // single-item top-level fields), so no seeded order silently renders without
454
496
  // a thumbnail the way real pre-2026-08-20 orders do.
455
- function withOrderImages(order) {
497
+ function withOrderImages(input) {
498
+ const order = withOrderItems(input);
456
499
  return {
457
500
  ...order,
458
501
  imageUrls: order.imageUrls ?? (order.productId ? [orderItemImage(order.productId)] : undefined),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/appkit",
3
- "version": "4.41.11",
3
+ "version": "4.41.12",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"