from pathlib import Path import csv,hashlib,json,collections,zipfile,xml.etree.ElementTree as ET R=Path(__file__).resolve().parent.parent;P=R/'storage/app/private/investmoz-v2/portal-audit';O=R/'outputs/investmoz-operational-onboarding-20261011' plan=json.loads((P/'onboarding-governance-plan.json').read_text());S=Path(plan['source']);manifest=json.loads((O/'manifesto.json').read_text()) assert plan['target']['port']==55441 and plan['active_application_changes']==0 and plan['active_database_writes']==0 assert manifest['delta_sha256']==plan['delta_sha256'] for row in plan['files']: assert hashlib.sha256((S/row['path']).read_bytes()).hexdigest()==row['after_sha256'] if row['before_sha256']:assert hashlib.sha256((R/row['path']).read_bytes()).hexdigest()==row['before_sha256'] archive=O/manifest['package'];assert hashlib.sha256(archive.read_bytes()).hexdigest()==manifest['package_sha256'] with zipfile.ZipFile(archive) as package: names=package.namelist();expected={row['path']:row['after_sha256'] for row in plan['files']}|{row['path']:row['sha256'] for row in plan['assets']} assert len(names)==len(set(names)) and set(names)==set(expected) for name in names: assert not any(part in name.split('/') for part in ['.env','vendor','node_modules','storage']) assert hashlib.sha256(package.read(name)).hexdigest()==expected[name] csv.field_size_limit(10_000_000) base=json.loads((P/'onboarding-matrix-baseline.json').read_text());updates=base['updates'];rows=base['rows'];headers=rows[0] with (R/'docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv').open(encoding='utf-8-sig',newline='') as handle:actual=list(csv.reader(handle)) assert len(actual)==len(rows);changes=[] for i,(before,after) in enumerate(zip(rows,actual)): assert len(before)==len(after) for c,(a,b) in enumerate(zip(before,after)): if a!=b: assert before[0] in updates and headers[c]=='EvidĂȘncia funcional' and b==updates[before[0]][headers[c]] changes.append({'id':before[0],'column':headers[c]}) assert len(changes)==3 states=dict(collections.Counter(row[headers.index('Estado')] for row in actual[1:]));source_lines=sum(int(row[headers.index('Quantidade de linhas de origem')]) for row in actual[1:]) test_xml=ET.parse(P/'onboarding-governance-tests.xml');top=test_xml.getroot() assert all(int(node.get('failures','0'))==0 and int(node.get('errors','0'))==0 for node in top.iter('testsuite')) test_count=len(list(top.iter('testcase')));assert test_count==6 browser=json.loads((P/'onboarding-governance-browser.json').read_text());assert browser['result']=='passed' proof={'result':'passed','delta':plan['delta_sha256'][:12],'package_sha256':manifest['package_sha256'],'code_files':len(plan['files']), 'assets':len(plan['assets']),'QA_tests':test_count,'browser_criteria':browser['criteria'],'active_application_changes':0,'active_database_writes':0, 'matrix_requirements':len(actual)-1,'source_occurrences':source_lines,'states':states,'matrix_changes':changes,'sources_versions_other_cells_preserved':True, 'package_has_credentials_or_private_files':False,'base_candidate_preserved':'41caea0f900f','backup_for_this_delta':'not_yet_renewed_on_destination','operational_enablement':'pending_real_accounts_MFA_representation_grants'} (O/'verificacao-final.json').write_text(json.dumps(proof,indent=2,ensure_ascii=False),encoding='utf-8') shutil=__import__('shutil');shutil.copyfile(P/'onboarding-matrix-proof.json',O/'matriz-atualizacao.json') print(json.dumps(proof,ensure_ascii=False))