import asyncio import xml.etree.ElementTree as ET import pytest from fastapi import HTTPException from starlette.requests import Request from app.modules.hardware.labels import hardware_label_url, hardware_label_qr from app.modules.hardware.frontend import views def test_label_links_to_exact_asset(): assert hardware_label_url('https://hub.example.dk/', 42) == 'https://hub.example.dk/hardware/42' assert hardware_label_url('http://192.168.1.10:8001', 42) == 'http://192.168.1.10:8001/hardware/42' @pytest.mark.parametrize('url', ['javascript:alert(1)', 'https://user:secret@hub.dk', 'https://hub.dk?token=secret', 'https://hub.dk/#secret', '']) def test_invalid_label_url_is_rejected(url): with pytest.raises(HTTPException): hardware_label_url(url, 1) def test_qr_is_a_local_vector_with_quiet_zone(): xml = ET.fromstring(hardware_label_qr('https://hub.example.dk/hardware/42')) assert xml.tag == '{http://www.w3.org/2000/svg}svg' assert xml.find('{http://www.w3.org/2000/svg}path') is not None assert 'http' not in xml.find('{http://www.w3.org/2000/svg}path').attrib['d'] def test_label_route_renders_asset_and_escapes_text(monkeypatch): monkeypatch.setattr(views, 'execute_query', lambda sql, params: [{'id':42, 'brand':'BMC', 'model':'', 'serial_number':'ABC-123'}]) request = Request({'type':'http','method':'GET','path':'/hardware/42/label','headers':[],'scheme':'http','server':('localhost',8001),'query_string':b''}) response = asyncio.run(views.hardware_label(request,42,size='62x40',base_url='https://hub.example.dk')) body=response.body.decode() assert 'BMC-00042' in body assert 'https://hub.example.dk/hardware/42' in body assert '' not in body assert '<script>bad</script>' in body assert 'size:62mm 40mm' in body assert response.headers['cache-control']=='no-store' def test_missing_asset_and_invalid_size(monkeypatch): monkeypatch.setattr(views,'execute_query',lambda *args: []) with pytest.raises(HTTPException) as error: asyncio.run(views.hardware_label(None,42,size='62x40',base_url='https://hub.example.dk')) assert error.value.status_code==404 with pytest.raises(HTTPException) as error: asyncio.run(views.hardware_label(None,42,size='bad',base_url='https://hub.example.dk')) assert error.value.status_code==400