import test from 'node:test'; import assert from 'node:assert/strict'; import { computeRow } from '../src/pages/PricingCalculator/calc.js'; import { applyDropshipDefaultsToRows, createDropshipRows, DROPSHIP_FIXED_RATES, getDropshipDimensions, mergeDropshipSelectionPricingRows, parseAlibaba1688ProductId, } from '../src/pages/PricingCalculator/dropship.js'; test('parses raw 1688 IDs and product detail links, but rejects store links', () => { assert.deepEqual(parseAlibaba1688ProductId('1073252781818'), { productId: '1073252781818', error: '', }); assert.equal( parseAlibaba1688ProductId('https://detail.1688.com/offer/1073252781818.html?spm=test').productId, '1073252781818' ); assert.equal( parseAlibaba1688ProductId('https://m.1688.com/offer/1009799442964.html').productId, '1009799442964' ); assert.equal(parseAlibaba1688ProductId('https://example.1688.com/page/index.html').productId, ''); assert.match( parseAlibaba1688ProductId('https://example.1688.com/page/index.html').error, /商品详情链接/ ); }); test('adapts every 1688 specification group and applies the independent rates', () => { const detail = { productId: '1073252781818', product: { productId: '1073252781818', mainImage: 'https://img.example.com/main.jpg', skuDimensions: [ { name: '颜色', values: ['原木色'] }, { name: '尺寸', values: ['60cm'] }, ], skus: [{ index: 1, name: '原木色 / 60cm', specs: [ { name: '颜色', value: '原木色' }, { name: '尺寸', value: '60cm' }, ], price: 180, freight: 40, stock: null, available: true, }], }, }; const rows = createDropshipRows(detail); assert.equal(rows.length, 1); assert.equal(rows[0].skuCode, '1'); assert.deepEqual(rows[0].specs, [ { name: '颜色', value: '原木色' }, { name: '尺寸', value: '60cm' }, ]); assert.equal(rows[0].specsText, '颜色:原木色 / 尺寸:60cm'); assert.equal(rows[0].cost, 180); assert.equal(rows[0].shipping, 40); assert.equal(rows[0].price, 400); assert.equal(rows[0].targetMargin, 0.12); Object.entries(DROPSHIP_FIXED_RATES).forEach(([key, value]) => { assert.equal(rows[0][key], value); }); assert.deepEqual(getDropshipDimensions(detail, rows), ['颜色', '尺寸']); const computed = computeRow(rows[0]); assert.equal(Number(computed.profitAmount.toFixed(2)), 48); const listingRows = createDropshipRows(detail, null, { useSourceSkuCode: true }); assert.equal(listingRows[0].skuCode, '1073252781818-SKU-1'); }); test('changing 1688 defaults only updates rows that still use the previous default', () => { const rows = [ { id: 'default', coupon: 20, activityDiscount: 0.6, installFee: 0, targetMargin: 0.12 }, { id: 'custom', coupon: 10, activityDiscount: 0.6, installFee: 0, targetMargin: 0.2 }, ]; const updated = applyDropshipDefaultsToRows( rows, { coupon: 20, activityDiscount: 0.6, installFee: 0, targetMargin: 0.12 }, { coupon: 25, activityDiscount: 0.65, installFee: 5, targetMargin: 0.14 } ); assert.deepEqual(updated[0], { id: 'default', coupon: 25, activityDiscount: 0.65, installFee: 5, targetMargin: 0.14, }); assert.deepEqual(updated[1], { id: 'custom', coupon: 10, activityDiscount: 0.65, installFee: 5, targetMargin: 0.2, }); }); test('merges saved listing prices by the real 1688 SKU code', () => { const sourceRows = [ { id: 'a', skuCode: 'SKU-A', cost: 60, price: 100 }, { id: 'b', skuCode: 'SKU-B', cost: 80, price: 200 }, ]; const merged = mergeDropshipSelectionPricingRows(sourceRows, [ { skuCode: 'sku-b', cost: 168, finalPrice: 288, selectedSkuName: 'B款' }, ]); assert.equal(merged[0].price, 100); assert.equal(merged[0].cost, 60); assert.equal(merged[0].skuCode, 'SKU-A'); assert.equal(merged[1].price, 288); assert.equal(merged[1].cost, 168); assert.equal(merged[1].selectedSkuName, 'B款'); }); test('does not fall back to row order when listing SKU codes do not match', () => { const sourceRows = [ { id: 'a', skuCode: 'SOURCE-A', price: 100 }, { id: 'b', skuCode: 'SOURCE-B', price: 200 }, ]; const merged = mergeDropshipSelectionPricingRows(sourceRows, [ { skuCode: 'TASK-A', finalPrice: 188 }, { skuCode: 'TASK-B', finalPrice: 288 }, ]); assert.deepEqual(merged.map((row) => row.skuCode), ['SOURCE-A', 'SOURCE-B']); assert.deepEqual(merged.map((row) => row.price), [100, 200]); });