54 lines
3.2 KiB
Python
54 lines
3.2 KiB
Python
"""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:{}};
|
|
const $=id=>controls[id],ids=()=>[1],selectedRows=()=>[{id:1,workflow_active:active}];
|
|
function selectionMode(rows) BODY
|
|
const data=payload();
|
|
assert.deepEqual(data,active?{ids:[1],line_mode:'combined'}:{ids:[1],billing_method:'prepaid',prepaid_card_id:8});
|
|
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
|