Files
Investidor-V2/tools/opportunity-office-documents-http-qa.py
nala 01405cbf8a
tests / ci (push) Canceled after 0s
oportunidades 5
2026-10-10 14:15:28 +02:00

91 lines
6.4 KiB
Python

"""Synthetic OOXML originals through the guarded QA web server; no secrets in proof."""
import hashlib
import io
import json
import uuid
import zipfile
import xml.etree.ElementTree as ET
from datetime import datetime, timezone
from portal_profiles_http_session import Session, PRIVATE, EXPECTED, REASON, events
source = json.loads((PRIVATE / 'opportunity-semantic-http-qa.json').read_text(encoding='utf-8-sig'))
assert source['result'] == 'passed' and source['target'] == EXPECTED
record = next(c['id'] for c in source['cases'] if c['category'] == 'concession')
base = f'/minhas-oportunidades/{record}'
proof = {'target': EXPECTED, 'id': record, 'started_at': datetime.now(timezone.utc).isoformat(), 'active_writes': 0, 'interface_observed': False, 'types': []}
def file_bytes(kind):
mime = 'application/vnd.openxmlformats-officedocument.' + ('wordprocessingml.document' if kind == 'docx' else 'spreadsheetml.sheet')
part = 'word/document.xml' if kind == 'docx' else 'xl/workbook.xml'
content = ('<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Synthetic QA no official value</w:t></w:r></w:p></w:body></w:document>' if kind == 'docx' else '<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><sheets><sheet name="Synthetic QA" sheetId="1" r:id="rId1"/></sheets></workbook>')
files = {
'[Content_Types].xml': f'<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/{part}" ContentType="{mime}.main+xml"/>' + ('<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>' if kind == 'xlsx' else '') + '</Types>',
'_rels/.rels': f'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="{part}"/></Relationships>',
part: content,
}
if kind == 'xlsx':
files['xl/_rels/workbook.xml.rels'] = '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/></Relationships>'
files['xl/worksheets/sheet1.xml'] = '<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData><row r="1"><c r="A1" t="inlineStr"><is><t>Synthetic QA no official value</t></is></c></row></sheetData></worksheet>'
buffer = io.BytesIO()
with zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED) as z:
for name, text in files.items():
ET.fromstring(text)
z.writestr(name, text)
with zipfile.ZipFile(io.BytesIO(buffer.getvalue())) as z:
assert z.testzip() is None and z.read(part).decode() == content
return mime, buffer.getvalue()
def page(s):
return s.call('GET', base + '/edit', inertia=True)['props']
def resources(s):
return s.call('GET', base + '/resources', inertia=True)['props']['resources']['documents']
try:
owner = Session('promoter').login()
reviewer = Session('validator').login()
publisher = Session('publisher').login()
outsider = Session('outsider').login()
for kind in ['docx', 'xlsx']:
mime, data = file_bytes(kind)
title = 'Original sintético QA OOXML ' + kind
old = next((r for r in resources(owner) if r['payload'].get('title') == title), None)
if old:
assert old['deleted_at'] is None
resource_id = old['id']
data = owner.call('GET', base + f'/resources/documents/{resource_id}/download', binary=True)
with zipfile.ZipFile(io.BytesIO(data)) as z:
assert z.testzip() is None
for name in z.namelist():
ET.fromstring(z.read(name))
else:
resource_id = owner.call('POST', base + '/resources/documents', {'etag': page(owner)['etag'], 'creation_key': str(uuid.uuid4()), 'reason': REASON,
'payload': json.dumps({'title': title, 'category': 'qa-synthetic', 'classification': 'restricted', 'visibility': 'internal'})},
multipart=('synthetic-qa.' + kind, mime, data), status=201)['id']
row = next(r for r in resources(owner) if r['id'] == resource_id)
digest = hashlib.sha256(data).hexdigest()
assert row['file']['media_type'] == mime and row['file']['malware_scan_status'] == 'clean' and row['file']['sha256'].strip() == digest
url = base + f'/resources/documents/{resource_id}/download'
for actor in [owner, reviewer, publisher]:
assert actor.call('GET', url, binary=True) == data
outsider.call('GET', url, status=403, binary=True)
for action in ['delete', 'restore']:
current = next(r for r in resources(owner) if r['id'] == resource_id)
owner.call('POST', base + f'/resources/documents/{resource_id}/lifecycle', {'etag': page(owner)['etag'], 'version': current['version'], 'action': action, 'reason': REASON, 'confirm': True})
if action == 'delete':
owner.call('GET', url, status=404, binary=True)
assert resource_id not in [d['id'] for d in page(owner)['canonicalOptions']['resources']['documents']]
fresh = Session('promoter').login()
assert fresh.call('GET', url, binary=True) == data
proof['types'].append({'type': kind, 'resource_id': resource_id, 'sha256': digest, 'package_xml_crc_valid': True, 'clamd_real_clean': True,
'allowed': [21, 24, 25], 'foreign_organization': 403, 'deleted_download': 404, 'original_restored_identical_new_session': True})
proof['result'] = 'passed'
except Exception as error:
proof.update({'result': 'failed', 'failure': str(error)})
raise
finally:
proof['events'] = events
proof['completed_at'] = datetime.now(timezone.utc).isoformat()
(PRIVATE / 'opportunity-office-documents-http-qa.json').write_text(json.dumps(proof, ensure_ascii=False, indent=2), encoding='utf-8')
print(json.dumps({'result': proof['result'], 'target': EXPECTED, 'types': [r['type'] for r in proof['types']], 'events': len(events), 'active_writes': 0}))