Files
Aislo/resources/tester/test_est_review_workflow.py
T

128 lines
5.2 KiB
Python

from test_est_rea_parity import run
def test_review_summary_updates_the_print_document_and_active_settings():
result = run(
"math",
"""(()=>{
const handlers={},p=EstNative.empty();p.printSettings={form:'173',notes:'old'};
globalThis.document={addEventListener:(name,fn)=>handlers[name]=fn};
globalThis.EstApp={state:{project:p},change:fn=>fn(),render:()=>{}};
EstReview.install();handlers.change({target:{dataset:{reviewSummary:''},value:'review summary'}});
return {document:p.documents['173'],notes:p.printSettings.notes};
})()""",
)
assert result == {"document": "review summary", "notes": "review summary"}
def test_review_rejects_unallocated_fixed_amounts_and_ambiguous_targets():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.tables.EstMainDat=[
{Name:'fixed',PkID:1,GN:1,TC:100,CalcIndex:1},
{Name:'first',Code:'A',GN:1,GU:10},{Name:'second',Code:'A',GN:1,GU:20}];
p.contractReview={edits:{'row:A':{GU:999}}};
const out=EstReview.calculate(p);let rejected=false;
try{EstReview.copy(p)}catch{rejected=true}
return {errors:out.errors,rejected,units:out.reviewed.tables.EstMainDat.slice(1).map(row=>row.GU)};
})()""",
)
assert len(result["errors"]) == 2 and result["rejected"]
assert result["units"] == [10, 20]
def test_review_recalculates_user_inputs_and_opens_independent_copy():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.name='contract';p.id='123456789012345678901234';
p.options.SourceRefresh=false;p.tables.EstMainDat=[
{PkID:1,Code:'',Name:'normal',GN:10,GU:100},
{PkID:2,Code:'',Name:'fixed',GN:1,GC:100,TC:100,CalcIndex:1},
{LinkIndex:54}];
p.tables.Wonga=[{Gubun:'D',BaseField:'TC'},
{Gubun:'V',VSusic:'D*0.1'},{Gubun:'T',LinkIndex:55,VSusic:'D+V'}];
const q=EstNative.calculate(p);q.contractReview={edits:{'row:1':{GN:2,GU:80,Reason:'checked'},'row:2':{GC:20}}};
const before=JSON.stringify(q),review=EstReview.calculate(q),copy=EstReview.copy(q);
const same=JSON.stringify(q)===before;copy.tables.EstMainDat[0].GN=99;
return {review,same,original:q.tables.EstMainDat[0].GN,copy};
})()""",
)
assert result["same"] and result["original"] == 10
assert result["review"]["errors"] == []
assert result["review"]["before"] == 1210
assert result["review"]["after"] == 198
assert result["review"]["reviewed"]["tables"]["EstMainDat"][1]["TC"] == 20
assert "id" not in result["copy"]
assert "contractReview" not in result["copy"]
def test_review_rejects_invalid_and_stale_inputs():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.tables.EstMainDat=[{PkID:1,Code:'A',GN:1,GU:10}];
const invalid=[];for(const edit of [{GN:'bad'},{GN:Infinity},{unrelated:1}]){
p.contractReview={edits:{'row:1':edit}};
try{EstModel.validate(p);invalid.push(false)}catch{invalid.push(true)}
}
p.contractReview={edits:{'row:missing':{GN:2}}};
let rejected=false;try{EstReview.copy(p)}catch{rejected=true}
return {invalid,rejected};
})()""",
)
assert result["invalid"] == [True, True, True]
assert result["rejected"]
def test_review_summary_print_contains_totals_and_item_differences():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.tables.EstMainDat=[{PkID:1,Code:'',Name:'item',GN:2,GU:100}];
p.contractReview={edits:{'row:1':{GN:1,GU:80,Reason:'quantity reviewed'}}};return EstForms.data(171,p);
})()""",
)
assert result["errors"] == []
assert [result["rows"][0][key] for key in ["originalTC", "TC", "difference"]] == [
200,
80,
-120,
]
assert result["rows"][1]["Name"] == "item"
assert result["rows"][1]["difference"] == -120
assert result["rows"][1]["Reason"] == "quantity reviewed"
def test_review_reset_one_row_keeps_other_inputs():
result = run(
"math",
"""(()=>{
const handlers={},p=EstNative.empty();
p.contractReview={edits:{'row:1':{GU:80,Reason:'first'},'row:2':{GN:3,Reason:'second'}}};
globalThis.document={addEventListener:(name,fn)=>handlers[name]=fn};
globalThis.EstApp={state:{project:p},change:fn=>fn(),render:()=>{}};
EstReview.install();
const click=key=>handlers.click({target:{closest:s=>s==='[data-review-reset]'?{dataset:{reviewReset:key}}:null}});
click('row:1');const after=structuredClone(p.contractReview);click('row:2');
return {after,removed:!Object.hasOwn(p,'contractReview')};
})()""",
)
assert result["after"]["edits"] == {"row:2": {"GN": 3, "Reason": "second"}}
assert result["removed"]
def test_fixed_review_preserves_amount_for_reason_or_quantity_only():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.tables.EstMainDat=[{PkID:1,Name:'fixed',GN:1,TC:100,CalcIndex:1}];
return [{Reason:'checked'},{GN:3},{GC:20}].map(edit=>{
p.contractReview={edits:{'row:1':edit}};
return EstReview.calculate(p).reviewed.tables.EstMainDat[0].TC;
});
})()""",
)
assert result == [100, 100, 20]