76 lines
4.0 KiB
JavaScript
76 lines
4.0 KiB
JavaScript
// Actual UI price saving against a synthetic API, without live business writes.
|
|
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const {harness,response} = require('./helpers/arr_ui_harness.cjs');
|
|
const fixture=(price=null)=>({case_id:'fixture-case',case_status:'open',revision:1,
|
|
completed_items:price===null?0:1,total_items:1,
|
|
items:[{item_id:1,company_key:'Fixture Company',rate_code:'FIXTURE',effective_rate_amount:100,
|
|
real_price:price,affected_records:1,affected_rooms:1,affected_room_nights:2,candidate_prices:[]}],
|
|
pagination:{offset:0,limit:50,total:1}});
|
|
|
|
test('zero is a valid explicit price while blank and negative prices remain invalid',()=>{
|
|
const h=harness(()=>{throw new Error('unexpected request');});
|
|
for(const value of [0,'0',' 0 ','1500']) assert.equal(h.strictReviewPrice(value),true);
|
|
for(const value of [null,undefined,'',' ','-1',-1,'0.00','1.5','abc']) assert.equal(h.strictReviewPrice(value),false);
|
|
assert.equal(h.reviewPriceInput(0),'0');
|
|
assert.equal(h.reviewPriceInput('0'),'0');
|
|
assert.equal(h.reviewPriceInput(null),'');
|
|
});
|
|
|
|
test('zero is rendered as a saved value and permits continuation when all items are saved',()=>{
|
|
const h=harness(()=>{throw new Error('unexpected request');});
|
|
h.renderDailyPriceReview(fixture(0));
|
|
const html=h.element('#daily-price-review-body').innerHTML;
|
|
assert.match(html,/value="0"/);
|
|
assert.match(html,/daily-price-review-row is-complete/);
|
|
assert.match(html,/daily_review.saved/);
|
|
assert.equal(h.element('#daily-price-review-finalize').disabled,false);
|
|
h.renderDailyPriceReview(fixture(null));
|
|
assert.match(h.element('#daily-price-review-body').innerHTML,/value=""/);
|
|
assert.match(h.element('#daily-price-review-body').innerHTML,/daily_review.price_placeholder/);
|
|
assert.equal(h.element('#daily-price-review-body').innerHTML.includes('placeholder="0"'),false);
|
|
assert.equal(h.element('#daily-price-review-finalize').disabled,true);
|
|
});
|
|
|
|
test('explicit zero is saved as zero and survives reloading without becoming empty',async()=>{
|
|
let current=fixture();
|
|
const h=harness((url,options)=>{
|
|
if(options.method==='PATCH') {
|
|
assert.equal(url,'/api/jobs/fixture-job/review/items/1');
|
|
const decision=JSON.parse(options.body);
|
|
assert.deepEqual(decision,{case_id:'fixture-case',revision:1,real_price:'0'});
|
|
current={...fixture('0'),revision:2};
|
|
return response(200,{revision:2});
|
|
}
|
|
if(url.startsWith('/api/jobs/fixture-job/review?')) return response(200,current);
|
|
if(url.startsWith('/api/jobs?')) return response(200,[]);
|
|
throw new Error('unexpected request '+url);
|
|
});
|
|
h.state.dailyPriceReview=fixture();
|
|
h.state.dailyPriceReviewJobId='fixture-job';
|
|
const input={value:'0',focus(){}};
|
|
const row={dataset:{dailyPriceReviewItemId:'1'},querySelector:()=>input};
|
|
await h.saveDailyPriceReviewItem({closest:()=>row});
|
|
assert.equal(h.calls.filter(c=>c.method==='PATCH').length,1);
|
|
assert.equal(h.state.dailyPriceReview.items[0].real_price,'0');
|
|
assert.equal(h.state.dailyPriceReview.completed_items,1);
|
|
assert.equal(h.dailyPriceReviewCanFinalize(h.state.dailyPriceReview),true);
|
|
assert.equal(h.element('#daily-price-review-finalize').disabled,false);
|
|
assert.match(h.element('#daily-price-review-body').innerHTML,/value="0"/);
|
|
await h.loadDailyPriceReview();
|
|
assert.equal(h.state.dailyPriceReview.items[0].real_price,'0');
|
|
assert.equal(h.calls.filter(c=>c.method==='PATCH').length,1,'reload must not submit another decision');
|
|
});
|
|
|
|
test('an empty input cannot be silently saved as zero',async()=>{
|
|
const h=harness(()=>{throw new Error('unexpected request');});
|
|
h.state.dailyPriceReview=fixture();
|
|
h.state.dailyPriceReviewJobId='fixture-job';
|
|
const input={value:'',focus(){}};
|
|
const row={dataset:{dailyPriceReviewItemId:'1'},querySelector:()=>input};
|
|
await h.saveDailyPriceReviewItem({closest:()=>row});
|
|
assert.equal(h.calls.length,0);
|
|
assert.equal(h.state.dailyPriceReview.items[0].real_price,null);
|
|
assert.equal(h.dailyPriceReviewCanFinalize(h.state.dailyPriceReview),false);
|
|
});
|