"""web_ui handler coverage for BOTH pipelines (constraint 5c) -- 0% before Phase 8. Root placement is deliberate: web_ui_auth is cross-pipeline and PO web_ui lacks __init__.py, so the modules are reached ONLY through the shared loader (``load_lambda_module("po"|"wo", "web_ui/handler")``), never package imports. The loader's web_ui_auth sibling entry binds each handler's bare ``from web_ui_auth import is_authenticated``. Pins: wrong/absent token -> 401; 401 WITHOUT any table access (auth is the first line of handler()); the authenticated render path; and a hostile-field escaping regression lock (every rendered field carrying &\"'" class _WebFakeTable: def __init__(self, items): self._items = items def scan(self, **kwargs): return {"Items": list(self._items)} def get_item(self, Key): # noqa: N803 (boto3 kwarg name) pk, val = next(iter(Key.items())) for item in self._items: if item.get(pk) == val: return {"Item": item} return {} def query(self, **kwargs): return {"Items": []} class _WebFakeDynamo: def __init__(self, tables): self._tables = tables def Table(self, name): # noqa: N802 (boto3 method name) return _WebFakeTable(self._tables.get(name, [])) class _ExplodingDynamo: """Any table access is a contract violation: auth must run first.""" def Table(self, name): # noqa: N802 raise AssertionError(f"auth must precede any table access ({name})") @pytest.fixture(params=["po", "wo"]) def web_ui(request): mod = load_lambda_module(request.param, "web_ui/handler") if request.param == "po": table = mod.PO_TABLE hostile_item = { "po_number": _HOSTILE, "po_status": _HOSTILE, "email_type": _HOSTILE, "supplier": {"name": _HOSTILE}, "site_code": _HOSTILE, "trade": _HOSTILE, "total_amount": _HOSTILE, "processed_at": _HOSTILE, } else: table = mod.WORK_ORDERS_TABLE hostile_item = { "work_order_id": _HOSTILE, "description": _HOSTILE, "site_code": _HOSTILE, "wo_status": _HOSTILE, "record_type": _HOSTILE, "due_date": _HOSTILE, "updated_at": _HOSTILE, } return SimpleNamespace(mod=mod, table=table, hostile_item=hostile_item) def test_wrong_token_returns_401(web_ui, monkeypatch): monkeypatch.setattr(web_ui.mod, "is_authenticated", lambda event: False) result = web_ui.mod.handler({"headers": {"x-auth-token": "wrong"}}, None) assert result["statusCode"] == 401 def test_absent_token_returns_401(web_ui, monkeypatch): monkeypatch.setattr(web_ui.mod, "is_authenticated", lambda event: False) result = web_ui.mod.handler({}, None) assert result["statusCode"] == 401 def test_401_does_not_touch_the_table(web_ui, monkeypatch): """Auth is the first line of handler(): a rejected request must return 401 WITHOUT scanning (or otherwise touching) the DynamoDB table.""" monkeypatch.setattr(web_ui.mod, "is_authenticated", lambda event: False) monkeypatch.setattr(web_ui.mod, "dynamodb", _ExplodingDynamo()) result = web_ui.mod.handler({}, None) # _ExplodingDynamo raises if touched assert result["statusCode"] == 401 def test_authenticated_render_path(web_ui, monkeypatch): monkeypatch.setattr(web_ui.mod, "is_authenticated", lambda event: True) monkeypatch.setattr( web_ui.mod, "dynamodb", _WebFakeDynamo({web_ui.table: [web_ui.hostile_item]}) ) result = web_ui.mod.handler({}, None) assert result["statusCode"] == 200 assert result["headers"]["Content-Type"] == "text/html" assert " in element context, and the payload's quotes must be entity-escaped in attribute context (the onclick row-link sink), or a " breaks out of the attribute value and injects an event handler.""" monkeypatch.setattr(web_ui.mod, "is_authenticated", lambda event: True) monkeypatch.setattr( web_ui.mod, "dynamodb", _WebFakeDynamo({web_ui.table: [web_ui.hostile_item]}) ) body = web_ui.mod.handler({}, None)["body"] # element context: angle brackets escaped assert "" not in body # never reflected raw assert "<script>alert(1)</script>" in body # escaped form present # attribute context: the id flows through json.dumps into # onclick="window.location={esc(..., quote=True)}", so the JSON string's # opening quote must render as " -- a raw " right after the = means # quote-escaping regressed and the attribute is breakable assert "window.location="" in body assert 'window.location="' not in body # the payload's own quote characters appear only entity-escaped assert """ in body assert "'" in body assert _HOSTILE not in body