84 lines
2.6 KiB
Python
84 lines
2.6 KiB
Python
|
|
import importlib.util
|
||
|
|
import pathlib
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
|
||
|
|
def load_sync_module(monkeypatch):
|
||
|
|
# Minimal env required by module import
|
||
|
|
env = {
|
||
|
|
"KEYCLOAK_BASE_URL": "http://keycloak",
|
||
|
|
"KEYCLOAK_REALM": "atlas",
|
||
|
|
"KEYCLOAK_CLIENT_ID": "mailu-sync",
|
||
|
|
"KEYCLOAK_CLIENT_SECRET": "secret",
|
||
|
|
"MAILU_DOMAIN": "example.com",
|
||
|
|
"MAILU_DB_HOST": "localhost",
|
||
|
|
"MAILU_DB_PORT": "5432",
|
||
|
|
"MAILU_DB_NAME": "mailu",
|
||
|
|
"MAILU_DB_USER": "mailu",
|
||
|
|
"MAILU_DB_PASSWORD": "pw",
|
||
|
|
}
|
||
|
|
for k, v in env.items():
|
||
|
|
monkeypatch.setenv(k, v)
|
||
|
|
module_path = pathlib.Path(__file__).resolve().parents[1] / "mailu_sync.py"
|
||
|
|
spec = importlib.util.spec_from_file_location("mailu_sync_testmod", module_path)
|
||
|
|
module = importlib.util.module_from_spec(spec)
|
||
|
|
assert spec.loader is not None
|
||
|
|
spec.loader.exec_module(module)
|
||
|
|
return module
|
||
|
|
|
||
|
|
|
||
|
|
def test_random_password_length_and_charset(monkeypatch):
|
||
|
|
sync = load_sync_module(monkeypatch)
|
||
|
|
pw = sync.random_password()
|
||
|
|
assert len(pw) == 24
|
||
|
|
assert all(ch.isalnum() for ch in pw)
|
||
|
|
|
||
|
|
|
||
|
|
class _FakeResponse:
|
||
|
|
def __init__(self, json_data=None, status=200):
|
||
|
|
self._json_data = json_data or {}
|
||
|
|
self.status_code = status
|
||
|
|
|
||
|
|
def raise_for_status(self):
|
||
|
|
if self.status_code >= 400:
|
||
|
|
raise AssertionError(f"status {self.status_code}")
|
||
|
|
|
||
|
|
def json(self):
|
||
|
|
return self._json_data
|
||
|
|
|
||
|
|
|
||
|
|
class _FakeSession:
|
||
|
|
def __init__(self, put_resp, get_resp):
|
||
|
|
self.put_resp = put_resp
|
||
|
|
self.get_resp = get_resp
|
||
|
|
self.put_called = False
|
||
|
|
self.get_called = False
|
||
|
|
|
||
|
|
def post(self, *args, **kwargs):
|
||
|
|
return _FakeResponse({"access_token": "dummy"})
|
||
|
|
|
||
|
|
def put(self, *args, **kwargs):
|
||
|
|
self.put_called = True
|
||
|
|
return self.put_resp
|
||
|
|
|
||
|
|
def get(self, *args, **kwargs):
|
||
|
|
self.get_called = True
|
||
|
|
return self.get_resp
|
||
|
|
|
||
|
|
|
||
|
|
def test_kc_update_attributes_succeeds(monkeypatch):
|
||
|
|
sync = load_sync_module(monkeypatch)
|
||
|
|
ok_resp = _FakeResponse({"attributes": {"mailu_app_password": ["abc"]}})
|
||
|
|
sync.SESSION = _FakeSession(_FakeResponse({}), ok_resp)
|
||
|
|
sync.kc_update_attributes("token", {"id": "u1", "username": "u1"}, {"mailu_app_password": "abc"})
|
||
|
|
assert sync.SESSION.put_called and sync.SESSION.get_called
|
||
|
|
|
||
|
|
|
||
|
|
def test_kc_update_attributes_raises_without_attribute(monkeypatch):
|
||
|
|
sync = load_sync_module(monkeypatch)
|
||
|
|
missing_attr_resp = _FakeResponse({"attributes": {}}, status=200)
|
||
|
|
sync.SESSION = _FakeSession(_FakeResponse({}), missing_attr_resp)
|
||
|
|
with pytest.raises(Exception):
|
||
|
|
sync.kc_update_attributes("token", {"id": "u1", "username": "u1"}, {"mailu_app_password": "abc"})
|