106 lines
5.7 KiB
TypeScript
106 lines
5.7 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
||
|
||
const task = {
|
||
id: 11,
|
||
executionMode: 'live',
|
||
status: 'order_created',
|
||
sybProductId: 21,
|
||
shopeeProductId: 31,
|
||
pddProductId: 41,
|
||
deviceId: 5,
|
||
deviceName: 'Samsung 测试机',
|
||
shopeeItemIdSnapshot: '26154802794',
|
||
shopeeTitleSnapshot: '大码纯棉短袖',
|
||
shopeeShopNameSnapshot: '大碼臻選',
|
||
pddGoodsIdSnapshot: '731370706977',
|
||
pddTitleSnapshot: '宽松纯棉短袖女装',
|
||
targetColorSnapshot: '黑色',
|
||
targetSizeSnapshot: 'XL',
|
||
mappedColorSnapshot: '黑色款',
|
||
mappedSizeSnapshot: 'XL(建议 60-70kg)',
|
||
specSource: 'manual',
|
||
quantity: 2,
|
||
referenceUnitPriceCent: 2000,
|
||
minUnitPriceCent: 400,
|
||
maxUnitPriceCent: 3000,
|
||
currency: 'CNY',
|
||
pddAccountRefSnapshot: '',
|
||
addressSuffix: '_cg11',
|
||
pddOrderNo: 'PDD20260820001',
|
||
orderSubmittedAt: '2026-08-20T08:30:00Z',
|
||
paymentReviewStatus: 'pending',
|
||
logisticsStatus: 'pending',
|
||
writebackStatus: 'not_selected',
|
||
statusChangedAt: '2026-08-20T08:30:00Z',
|
||
createdAt: '2026-08-20T08:00:00Z',
|
||
};
|
||
|
||
async function mockAdmin(page: any, status = 'order_created') {
|
||
let current = { ...task, status };
|
||
let paymentPayload: any;
|
||
let listQuery: URLSearchParams | undefined;
|
||
await page.context().addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }]);
|
||
await page.route('**/api/**', async route => {
|
||
const url = new URL(route.request().url());
|
||
if (url.pathname.startsWith('/src/api/')) return route.continue();
|
||
if (url.pathname.endsWith('/api/v1/getinfo')) return route.fulfill({ json: { code: 200, data: { roles: ['admin'], name: '管理员', avatar: '', introduction: '', permissions: [] } } });
|
||
if (url.pathname.endsWith('/api/admin/v1/purchase-tasks/11/payment-review')) {
|
||
paymentPayload = route.request().postDataJSON();
|
||
current = { ...current, paymentReviewStatus: paymentPayload.status, paymentReviewedAt: '2026-08-20T09:00:00Z' };
|
||
return route.fulfill({ json: { code: 200, data: current } });
|
||
}
|
||
if (url.pathname.endsWith('/api/admin/v1/purchase-tasks/11/resolve-unknown')) {
|
||
const payload = route.request().postDataJSON();
|
||
current = { ...current, status: payload.status, pddOrderNo: payload.pddOrderNo, orderSubmittedAt: payload.orderSubmittedAt };
|
||
return route.fulfill({ json: { code: 200, data: current } });
|
||
}
|
||
if (url.pathname.endsWith('/api/admin/v1/purchase-tasks/11')) return route.fulfill({ json: { code: 200, data: { task: current, attempts: [{ attemptId: 'a-1', attemptNumber: 1, phase: 'order', status: 'completed', resultType: 'order_created', createdAt: task.createdAt }] } } });
|
||
if (url.pathname.endsWith('/api/admin/v1/purchase-tasks')) { listQuery = url.searchParams; return route.fulfill({ json: { code: 200, data: { items: [current], total: 1, page: 1, pageSize: 20 } } }); }
|
||
return route.fulfill({ json: { code: 200, data: [] } });
|
||
});
|
||
return { paymentPayload: () => paymentPayload, listQuery: () => listQuery };
|
||
}
|
||
|
||
test('采购管理只管理已有任务,并可复核支付状态', async ({ page }) => {
|
||
const state = await mockAdmin(page);
|
||
await page.goto('http://localhost:9527/#/purchase-tasks/index');
|
||
|
||
await expect(page.locator('.page-heading')).toHaveCount(0);
|
||
await expect(page.getByLabel('模式')).toHaveCount(0);
|
||
await expect.poll(() => state.listQuery()?.get('executionMode')).toBe('live');
|
||
const filterBoxes = await Promise.all(['.task-input', '.syb-input', '.order-input'].map(selector => page.locator(selector).boundingBox()));
|
||
expect(filterBoxes.map(box => Math.round(box?.width || 0))).toEqual([72, 100, 120]);
|
||
const actionBoxes = await Promise.all(['查询', '重置'].map(name => page.getByRole('button', { name, exact: true }).boundingBox()));
|
||
expect(new Set([...filterBoxes, ...actionBoxes].map(box => Math.round(box?.y || 0))).size).toBe(1);
|
||
expect([...filterBoxes, ...actionBoxes].map(box => box?.x || 0)).toEqual([...filterBoxes, ...actionBoxes].map(box => box?.x || 0).sort((a, b) => a - b));
|
||
await expect(page.getByText('CG-11')).toBeVisible();
|
||
await expect(page.getByText('大码纯棉短袖')).toBeVisible();
|
||
await expect(page.getByRole('button', { name: /创建采购任务|支付/ })).toHaveCount(0);
|
||
|
||
await page.getByRole('button', { name: '详情' }).click();
|
||
await expect(page.getByText('采购任务详情')).toBeVisible();
|
||
await expect(page.getByText('_cg11')).toBeVisible();
|
||
await expect(page.getByText('仅人工记录,系统不支付')).toBeVisible();
|
||
await page.getByRole('button', { name: '标记已支付' }).click();
|
||
await expect(page.getByText('确认支付复核')).toBeVisible();
|
||
await page.getByRole('button', { name: '确认已支付' }).click();
|
||
await expect.poll(() => state.paymentPayload()?.status).toBe('paid');
|
||
await expect(page.getByText('已支付', { exact: true }).first()).toBeVisible();
|
||
});
|
||
|
||
test('订单结果未知时明确禁止重复采购并可人工解除', async ({ page }) => {
|
||
await mockAdmin(page, 'order_result_unknown');
|
||
await page.goto('http://localhost:9527/#/purchase-tasks/index');
|
||
await page.getByRole('button', { name: '详情' }).click();
|
||
|
||
await expect(page.getByText('订单结果未知,禁止重复采购')).toBeVisible();
|
||
await expect(page.getByRole('button', { name: '允许重新采购' })).toHaveCount(0);
|
||
await page.getByRole('button', { name: '处理未知结果' }).click();
|
||
const dialog = page.getByRole('dialog', { name: '处理订单结果未知' });
|
||
await dialog.getByLabel('PDD 订单号').fill('PDD-CHECKED-001');
|
||
await dialog.getByLabel('下单时间').fill('2026-08-20 18:00:00');
|
||
await dialog.getByLabel('下单时间').press('Tab');
|
||
await dialog.getByRole('button', { name: '确认处理结果' }).click();
|
||
await expect(page.getByText('订单已创建', { exact: true }).first()).toBeVisible();
|
||
});
|