fix: recognize corroborated empty Oracle associations
This commit is contained in:
1 parent
4559d5a642
commit
de9eb532f2
9 files changed
+735
-28
No files matched your search
@@ -1,5 +1,8 @@
|
||||
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 {harness,response} = require('./helpers/arr_ui_harness.cjs');
|
||||
const requestId='a'.repeat(32);
|
||||
const task={request_id:requestId,report_date:'2026-10-07',status:'needs_data_review',job_id:null,can_retry:false};
|
||||
@@ -7,6 +10,65 @@ const item=(extra={})=>({item_id:'1:BLOCK_CODE',source_sequence:1,confirmation_n
|
||||
const review=(items,revision=1)=>({request_id:requestId,report_date:task.report_date,status:'editing',revision,items,pending_count:items.filter(x=>!x.confirmed).length,total_count:items.length,can_finalize:items.every(x=>x.confirmed)});
|
||||
const plain=value=>JSON.parse(JSON.stringify(value));
|
||||
|
||||
for (const fixture of [
|
||||
{name:'missing room retains the original required rule', field:'DISP_ROOM_NO', can_be_empty:false,
|
||||
source_state:'missing', reason_code:'calendar_missing_rooms', expected:'required_value_missing'},
|
||||
{name:'missing block is optional information awaiting confirmation', field:'BLOCK_CODE', can_be_empty:true,
|
||||
source_state:'missing', reason_code:'missing_reservation_block', expected:'source_unconfirmed'},
|
||||
{name:'missing packages are optional information awaiting confirmation', field:'PRODUCTS', can_be_empty:true,
|
||||
source_state:'missing', reason_code:'missing_reservation_packages', expected:'source_unconfirmed'},
|
||||
{name:'failed source state takes precedence over a missing reason', source_state:'failed',
|
||||
reason_code:'missing_reservation_block', expected:'fetch_failed'},
|
||||
{name:'ambiguous source state takes precedence over an invalid reason', source_state:'ambiguous',
|
||||
reason_code:'invalid_package_code', expected:'conflict_value'},
|
||||
{name:'older HTTP failure snapshots remain failures', reason_code:'http_failure', expected:'fetch_failed'},
|
||||
{name:'invalid response JSON is a read failure rather than a field format error',
|
||||
reason_code:'invalid_json', expected:'fetch_failed'},
|
||||
{name:'a block disagreement is shown as conflicting information',
|
||||
reason_code:'block_code_disagreement', expected:'conflict_value'},
|
||||
{name:'a changed block association is shown as conflicting information',
|
||||
reason_code:'block_association_changed', expected:'conflict_value'},
|
||||
{name:'malformed package code has a separate format explanation',
|
||||
reason_code:'invalid_package_code', expected:'invalid_value'},
|
||||
{name:'invalid nights retain a separate format explanation',
|
||||
field:'DEPARTURE', can_be_empty:false, reason_code:'XML_NEGATIVE_NIGHTS', expected:'invalid_value'},
|
||||
{name:'confirmed decisions show the saved confirmation instead of the original problem',
|
||||
source_state:'failed', reason_code:'http_failure', confirmed:true, value:'VERIFIED', expected:'confirmed_value'},
|
||||
]) {
|
||||
test(`field review explanation: ${fixture.name}`,async()=>{
|
||||
const source=item(fixture);
|
||||
const original=plain(source);
|
||||
const h=harness(()=>response(200,review([source])));
|
||||
await h.acceptARRDownloadTask(task,{sync:false});
|
||||
const markup=h.element('#arr-data-review-body').innerHTML;
|
||||
assert.match(markup,new RegExp(`data_review\\.${fixture.expected}\\b`));
|
||||
assert.match(markup,new RegExp(`data_review\\.${source.can_be_empty?'optional':'required'}_field_rule\\b`));
|
||||
assert.equal(markup.includes('data_review.missing_value'),false);
|
||||
assert.equal(markup.includes('data-arr-data-review-empty'),source.can_be_empty);
|
||||
assert.deepEqual(plain(source),original,'rendering explanations never changes a source or confirmation');
|
||||
assert.equal(h.calls.every(call=>call.method==='GET'),true);
|
||||
});
|
||||
}
|
||||
|
||||
test('review explanations have distinct Chinese, English and Thai copy for required, optional and failed reads',()=>{
|
||||
const context=vm.createContext({window:{},document:{readyState:'loading',addEventListener(){}}});
|
||||
vm.runInContext(fs.readFileSync(path.resolve(__dirname,'../../arr_web/static/i18n.js'),'utf8'),context);
|
||||
const catalog=context.window.ARRI18n.CATALOG;
|
||||
const keys=['required_field_rule','optional_field_rule','required_value_missing','source_unconfirmed',
|
||||
'fetch_failed','conflict_value','invalid_value'];
|
||||
for(const key of keys) {
|
||||
const translations=catalog[`data_review.${key}`];
|
||||
assert.equal(translations.length,3);
|
||||
translations.forEach(text=>assert.equal(typeof text==='string' && text.length>0,true));
|
||||
}
|
||||
assert.match(catalog['data_review.required_field_rule'][0],/原处理规则必填/);
|
||||
assert.match(catalog['data_review.optional_field_rule'][0],/允许为空/);
|
||||
assert.match(catalog['data_review.source_unconfirmed'][0],/确认无此信息/);
|
||||
assert.match(catalog['data_review.fetch_failed'][0],/不能直接认定没有此信息/);
|
||||
assert.equal(catalog['data_review.fetch_failed'][0].includes('刷新'),false,
|
||||
'refreshing the review must not imply a retry of Oracle acquisition');
|
||||
});
|
||||
|
||||
test('source review opens before a job exists and another date can start its own download',async()=>{
|
||||
const h=harness((url,options)=>options.method==='POST'
|
||||
? response(202,{...JSON.parse(options.body),status:'queued',job_id:null,can_retry:false})
|
||||
|
||||
Reference in new issue
Block a user