feat(dav,obsidian): grupo dav completo (CardDAV/CalDAV client + split vcf/ics + import pipelines) + build_obsidian_graph + dav_list_calendars
Funciones reutilizables creadas esta sesion para el sistema self-hosted de contactos/calendario (Xandikos) y la app osint_web: - grupo dav (infra): split_vcards, split_vevents_to_vcalendars, extract_or_make_uid, carddav_put_vcard, caldav_put_event, dav_list_resources, dav_get_resource, dav_list_calendars - pipelines: import_vcf_to_carddav, import_ics_to_caldav - obsidian: build_obsidian_graph (grafo agregado del vault)
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
"""Tests para caldav_put_event.
|
||||
|
||||
Smoke deterministas: monkeypatchean urllib.request.urlopen para capturar el
|
||||
Request object (URL, method, headers) sin enviarlo a un servidor real.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
import infra.caldav_put_event # noqa: F401
|
||||
|
||||
mod = sys.modules["infra.caldav_put_event"]
|
||||
caldav_put_event = mod.caldav_put_event
|
||||
|
||||
_CAL = (
|
||||
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//x//EN\r\nCALSCALE:GREGORIAN\r\n"
|
||||
"BEGIN:VEVENT\r\nUID:evt-1@google.com\r\nSUMMARY:Reunion\r\nEND:VEVENT\r\n"
|
||||
"END:VCALENDAR\r\n"
|
||||
)
|
||||
|
||||
|
||||
class _FakeResp:
|
||||
status = 201
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, *a):
|
||||
return False
|
||||
|
||||
|
||||
def _capture(monkeypatch):
|
||||
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()
|
||||
|
||||
monkeypatch.setattr(mod.urllib.request, "urlopen", fake_urlopen)
|
||||
return captured
|
||||
|
||||
|
||||
def _call():
|
||||
return caldav_put_event(
|
||||
base_url="https://dav.example.com",
|
||||
username="enmanuel",
|
||||
password="secret-pw",
|
||||
collection_path="/enmanuel/calendars/calendar/",
|
||||
uid="evt-1@google.com",
|
||||
vcalendar_text=_CAL,
|
||||
)
|
||||
|
||||
|
||||
def test_construye_request_put_con_headers_correctos(monkeypatch):
|
||||
cap = _capture(monkeypatch)
|
||||
res = _call()
|
||||
assert res["status"] == "ok"
|
||||
assert res["http_status"] == 201
|
||||
assert cap["method"] == "PUT"
|
||||
|
||||
|
||||
def test_url_se_forma_con_uid_saneado(monkeypatch):
|
||||
cap = _capture(monkeypatch)
|
||||
_call()
|
||||
assert cap["url"].endswith("/enmanuel/calendars/calendar/evt-1_google.com.ics")
|
||||
|
||||
|
||||
def test_content_type_es_text_calendar(monkeypatch):
|
||||
cap = _capture(monkeypatch)
|
||||
_call()
|
||||
assert cap["headers"]["content-type"] == "text/calendar; charset=utf-8"
|
||||
|
||||
|
||||
def test_extension_es_ics(monkeypatch):
|
||||
cap = _capture(monkeypatch)
|
||||
_call()
|
||||
assert cap["url"].endswith(".ics")
|
||||
|
||||
|
||||
def test_httperror_devuelve_status_error(monkeypatch):
|
||||
def fake_urlopen(req, timeout=None, context=None):
|
||||
raise mod.urllib.error.HTTPError(req.full_url, 403, "Forbidden", {}, None)
|
||||
|
||||
monkeypatch.setattr(mod.urllib.request, "urlopen", fake_urlopen)
|
||||
res = _call()
|
||||
assert res["status"] == "error"
|
||||
assert res["http_status"] == 403
|
||||
Reference in New Issue
Block a user