"""Tests para dav_delete_resource. Smoke deterministas: monkeypatchean urllib.request.urlopen para capturar el Request (method DELETE, auth, URL, headers If-Match) y simular respuestas. """ import base64 import sys import infra.dav_delete_resource # noqa: F401 mod = sys.modules["infra.dav_delete_resource"] dav_delete_resource = mod.dav_delete_resource class _FakeResp: def __init__(self, status=204): self.status = status def __enter__(self): return self def __exit__(self, *a): return False def _capture(monkeypatch, status=204): captured = {} def fake_urlopen(req, timeout=None, context=None): captured["url"] = req.full_url captured["method"] = req.get_method() captured["headers"] = {k.lower(): v for k, v in req.header_items()} return _FakeResp(status) monkeypatch.setattr(mod.urllib.request, "urlopen", fake_urlopen) return captured def test_construye_request_delete_con_auth(monkeypatch): cap = _capture(monkeypatch) res = dav_delete_resource( "https://dav.example.com", "enmanuel", "secret-pw", "/enmanuel/contacts/addressbook/ada.vcf", ) assert res["status"] == "ok" assert cap["method"] == "DELETE" expected = "Basic " + base64.b64encode(b"enmanuel:secret-pw").decode("ascii") assert cap["headers"]["authorization"] == expected def test_resource_path_relativo_se_resuelve_con_base_url(monkeypatch): cap = _capture(monkeypatch) dav_delete_resource( "https://dav.example.com", "u", "p", "/enmanuel/contacts/addressbook/ada.vcf", ) assert cap["url"] == "https://dav.example.com/enmanuel/contacts/addressbook/ada.vcf" def test_resource_path_absoluto_se_respeta(monkeypatch): cap = _capture(monkeypatch) abs_url = "https://otra.example.com/path/x.vcf" dav_delete_resource("https://dav.example.com", "u", "p", abs_url) assert cap["url"] == abs_url def test_if_match_se_envia_cuando_hay_etag(monkeypatch): cap = _capture(monkeypatch) dav_delete_resource( "https://dav.example.com", "u", "p", "/x.vcf", etag='"abc123"', ) assert cap["headers"]["if-match"] == '"abc123"' def test_sin_etag_no_envia_if_match(monkeypatch): cap = _capture(monkeypatch) dav_delete_resource("https://dav.example.com", "u", "p", "/x.vcf") assert "if-match" not in cap["headers"] def test_204_devuelve_ok(monkeypatch): _capture(monkeypatch, status=204) res = dav_delete_resource("https://dav.example.com", "u", "p", "/x.vcf") assert res["status"] == "ok" assert res["http_status"] == 204 def test_404_devuelve_status_error(monkeypatch): def fake_urlopen(req, timeout=None, context=None): raise mod.urllib.error.HTTPError(req.full_url, 404, "Not Found", {}, None) monkeypatch.setattr(mod.urllib.request, "urlopen", fake_urlopen) res = dav_delete_resource("https://dav.example.com", "u", "p", "/x.vcf") assert res["status"] == "error" assert res["http_status"] == 404