bmc_hub/tests/test_workflow_employee_ui.py

54 lines
3.2 KiB
Python
Raw Normal View History

"""Execute the real V5 billing loader with a minimal DOM, rather than text assertions."""
import shutil
import subprocess
from pathlib import Path
import pytest
@pytest.mark.skipif(not shutil.which('node'), reason='Node required for UI behavior check')
@pytest.mark.parametrize('active', [True, False])
def test_v5_normal_registration_never_exposes_billing_choice(active):
source = Path('static/js/case-v5.js').read_text()
function = source.split('function setAutomaticRegistrationControls', 1)[1].split(" if(document.readyState", 1)[0]
script = r'''
const assert=require('node:assert/strict');
const controls={};
for(const id of ['v5QuickBilling','time_billing_method','v5CompactBilling'])controls[id]={dataset:{},parentElement:{querySelector:()=>({hidden:false})},replaceChildren(...items){this.options=items;},after(){}};
controls.v5BillingHint={textContent:''};
const byId=id=>controls[id],config={caseId:1};
const billingHost={querySelector:()=>({textContent:''})},compactBillingHost={querySelector:()=>({textContent:''})};
const document={createElement:()=>({}),querySelector:()=>null};
function Option(label,value){this.label=label;this.value=value;}
const active=ACTIVE;
const fetch=async()=>({ok:true,json:async()=>({workflow_active:active,has_customer:true,hourly_rate:100,prepaid_cards:[],agreements:[]})});
function setAutomaticRegistrationControls BODY
loadBillingOptions().then(()=>{
for(const id of ['v5QuickBilling','time_billing_method','v5CompactBilling']){
const select=controls[id];assert.equal(select.dataset.billingReady,'true');assert.equal(select.value,'draft');
assert.equal(select.disabled,true);assert.equal(!!select.hidden,true);
assert.equal(select.options.length,1);
}
}).catch(err=>{console.error(err);process.exitCode=1});
'''.replace('ACTIVE', 'true' if active else 'false').replace('BODY', function)
result = subprocess.run(['node', '-e', script], capture_output=True, text=True)
assert result.returncode == 0, result.stderr
@pytest.mark.skipif(not shutil.which('node'), reason='Node required for UI behavior check')
@pytest.mark.parametrize('active', [True, False])
def test_queue_active_selection_uses_decisions_and_line_mode(active):
source = Path('app/economy/frontend/time_queue.html').read_text()
functions = source.split('function selectionMode(rows)', 1)[1].split(' function status(', 1)[0]
script = r'''
const assert=require('node:assert/strict');
const active=ACTIVE;
const controls={settlementMethod:{value:'prepaid'},prepaidCard:{value:'8'},agreementId:{value:''},setMethodBtn:{},workflowLineMode:{value:'combined'},workflowLineModeHost:{classList:{toggle(){}}},previewBtn:{},stickyPreviewBtn:{},selectionText:{},approveBtn:{},stickyApproveBtn:{}};
const $=id=>controls[id],ids=()=>[1],selectedRows=()=>[{id:1,workflow_active:active,can_approve:true,can_settle:true}];
function selectionMode(rows) BODY
const data=payload();
assert.deepEqual(data,{ids:[1],line_mode:'combined'});
syncWorkflowControls();assert.equal(controls.settlementMethod.disabled,active);assert.equal(controls.setMethodBtn.disabled,active);
'''.replace('ACTIVE', 'true' if active else 'false').replace('BODY', functions)
result = subprocess.run(['node', '-e', script], capture_output=True, text=True)
assert result.returncode == 0, result.stderr