87 lines
3.4 KiB
JavaScript
87 lines
3.4 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const vm = require('node:vm');
|
|
|
|
const source = fs.readFileSync(path.join(__dirname, '../../static/js/admin_orders.js'), 'utf8');
|
|
const flush = () => new Promise(setImmediate);
|
|
|
|
class Element {
|
|
constructor(){
|
|
this.value = '';
|
|
this.files = [];
|
|
this.hidden = false;
|
|
this.disabled = false;
|
|
this.listeners = {};
|
|
this.dataset = {};
|
|
this.textContent = '';
|
|
this.classList = {toggle(){}};
|
|
}
|
|
addEventListener(name, callback){ this.listeners[name] = callback; }
|
|
insertAdjacentHTML(_position, html){ this.html = (this.html || '') + html; }
|
|
}
|
|
|
|
function response(data, status = 200){
|
|
return {ok: status >= 200 && status < 300, status, json: async () => data};
|
|
}
|
|
|
|
async function workspace(){
|
|
const elements = new Map();
|
|
const document = {
|
|
querySelector(selector){
|
|
return selector === 'meta[name="staff-csrf-token"]' ? {content:'csrf-test'} : null;
|
|
},
|
|
getElementById(id){
|
|
if(!elements.has(id)) elements.set(id, new Element());
|
|
return elements.get(id);
|
|
},
|
|
querySelectorAll(){ return []; },
|
|
};
|
|
let listLoads = 0;
|
|
let refreshOrdersFails = false;
|
|
const fetchCalls = [];
|
|
const context = vm.createContext({
|
|
document,
|
|
window:{location:{assign(){}}},
|
|
location:{assign(){}},
|
|
URLSearchParams,
|
|
FormData:class { append(){} },
|
|
AbortSignal,
|
|
SupportUI:{confirm:async()=>true},
|
|
fetch:async (url, options = {})=>{
|
|
fetchCalls.push({url, options});
|
|
if(url.startsWith('/api/admin/orders/list')){
|
|
listLoads++;
|
|
if(refreshOrdersFails && listLoads > 1) return response({error:'暂时无法刷新订单列表'}, 503);
|
|
return response({orders:[],total:0,next_before:null});
|
|
}
|
|
if(url === '/api/admin/orders/import/batches') return response({batches:[]});
|
|
if(url === '/api/admin/orders/import/preview') return response({ok:true,
|
|
summary:{total_rows:1,valid_rows:1,duplicate_rows:0,error_rows:0},
|
|
preview:[{row:2,tenant_id:'tenant-a',order_no:'ORDER000001',status:'DRAFT'}],errors:[]});
|
|
if(url === '/api/admin/orders/import') return response({ok:true,imported:1,preserved:0});
|
|
return response({ok:true});
|
|
},
|
|
});
|
|
vm.runInContext(source, context, {filename:'admin_orders.js'});
|
|
await flush();
|
|
return {element:id=>document.getElementById(id), fetchCalls,
|
|
failNextRefresh(){ refreshOrdersFails = true; }};
|
|
}
|
|
|
|
test('successful import stays reported as successful when refreshing the order list fails', async () => {
|
|
const app = await workspace();
|
|
const file = app.element('order-file');
|
|
file.files = [{name:'orders.csv'}];
|
|
file.listeners.change();
|
|
await app.element('order-import-form').listeners.submit({preventDefault(){}});
|
|
app.failNextRefresh();
|
|
|
|
await app.element('confirm-import').listeners.click();
|
|
|
|
assert.match(app.element('import-status').textContent, /导入已完成/);
|
|
assert.match(app.element('order-list-status').textContent, /暂时无法刷新订单列表/);
|
|
assert.equal(app.fetchCalls.filter(call=>call.url === '/api/admin/orders/import').length, 1);
|
|
});
|