51 lines
2.4 KiB
Python
51 lines
2.4 KiB
Python
|
|
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':'<script>bad</script>', '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 '<script>bad</script>' 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
|