feat(M09-D4): 完成商品选购与运营工作台
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { existsSync, readFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
|
||||
const root = process.cwd();
|
||||
const read = (path) => readFileSync(join(root, path), 'utf8');
|
||||
|
||||
const routes = read('backend/src/routes/products.ts');
|
||||
for (const pattern of [
|
||||
'/app-api/stores/:storeId/product-catalog',
|
||||
'authenticateAccessToken',
|
||||
'listStoreCatalog',
|
||||
'tenantId: auth.session.tenantId'
|
||||
]) assert.ok(routes.includes(pattern), `customer catalog route is missing ${pattern}`);
|
||||
|
||||
const routeTest = read('backend/tests/product-route.test.mjs');
|
||||
assert.match(routeTest, /app-api\/stores\/11\/product-catalog/);
|
||||
assert.match(routeTest, /customerCatalog\.statusCode, 200/);
|
||||
assert.match(routeTest, /statusCode, 401/);
|
||||
|
||||
const navigation = read('admin/src/navigation.mjs');
|
||||
const router = read('admin/src/router.ts');
|
||||
const app = read('admin/src/App.vue');
|
||||
assert.match(navigation, /menuKey: 'products'/);
|
||||
assert.match(navigation, /path: '\/products'/);
|
||||
for (const capability of [
|
||||
'product.catalog.read', 'inventory.read', 'inventory.adjust',
|
||||
'goods.order.read', 'goods.order.manage', 'goods.storage.read', 'goods.storage.manage'
|
||||
]) assert.ok(navigation.includes(capability), `product navigation is missing ${capability}`);
|
||||
assert.match(router, /ProductOperationsPanel\.vue/);
|
||||
assert.match(app, /ShoppingBasket/);
|
||||
|
||||
const api = read('admin/src/api.ts');
|
||||
for (const pattern of [
|
||||
'listProductListings', 'listInventoryStocks', 'mutateInventory',
|
||||
'listProductOrders', 'getProductOrder', 'runProductOrderAction',
|
||||
'listProductStorages', 'getProductStorage', 'createOrderProductStorage',
|
||||
'runProductStorageAction'
|
||||
]) assert.ok(api.includes(pattern), `admin product API is missing ${pattern}`);
|
||||
|
||||
const panel = read('admin/src/components/ProductOperationsPanel.vue');
|
||||
for (const pattern of [
|
||||
'canCatalogRead', 'canInventoryRead', 'canInventoryWrite',
|
||||
'canOrderRead', 'canOrderWrite', 'canStorageRead', 'canStorageWrite',
|
||||
'inventoryQuantity', 'stocktake', 'orderActions', 'submitRetrieve',
|
||||
'rotateStorage', 'submitCreateStorage', '一次性领取码'
|
||||
]) assert.ok(panel.includes(pattern), `product operations panel is missing ${pattern}`);
|
||||
assert.match(panel, /Promise\.all/);
|
||||
assert.match(panel, /:disabled="!canCatalogRead"/);
|
||||
|
||||
const appJson = JSON.parse(read('miniapp/app.json'));
|
||||
assert.ok(appJson.pages.includes('pages/goods/index'));
|
||||
for (const path of [
|
||||
'miniapp/pages/goods/index.js', 'miniapp/pages/goods/index.json',
|
||||
'miniapp/pages/goods/index.wxml', 'miniapp/pages/goods/index.wxss'
|
||||
]) assert.ok(existsSync(join(root, path)), `${path} is missing`);
|
||||
|
||||
const goodsScript = read('miniapp/pages/goods/index.js');
|
||||
for (const pattern of [
|
||||
'/product-orders', '/product-storages', '/product-catalog',
|
||||
'createOrder', 'cancelOrder', 'storeOrder', 'retrieveItem',
|
||||
'rotateCredential', 'cancelStorage', 'showCredential', 'clearCredential'
|
||||
]) assert.ok(goodsScript.includes(pattern), `miniapp goods flow is missing ${pattern}`);
|
||||
assert.doesNotMatch(goodsScript, /(?:wx\.)?setStorage(?:Sync)?\s*\(/,
|
||||
'one-time storage credential must not be persisted locally');
|
||||
|
||||
const goodsView = read('miniapp/pages/goods/index.wxml');
|
||||
for (const pattern of [
|
||||
'选购', '商品订单', '我的寄存', '领取码仅展示本次',
|
||||
'提交订单', '整单寄存', '更换领取码', '取出流水'
|
||||
]) assert.ok(goodsView.includes(pattern), `miniapp goods view is missing ${pattern}`);
|
||||
|
||||
const entryPoints = read('miniapp/pages/store/detail.js')
|
||||
+ read('miniapp/pages/store/detail.wxml')
|
||||
+ read('miniapp/pages/profile/index.js')
|
||||
+ read('miniapp/pages/profile/index.wxml');
|
||||
assert.match(entryPoints, /pages\/goods\/index/);
|
||||
assert.match(entryPoints, /选购商品/);
|
||||
|
||||
console.log(
|
||||
'PASS: M09-D4 authenticated catalog, capability-scoped admin workspace, customer order/storage flow and one-time credential gates are present.'
|
||||
);
|
||||
Reference in New Issue
Block a user