You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
42 lines
1.5 KiB
Python
42 lines
1.5 KiB
Python
# backend/tests/test_connector_contract.py — C1 인터페이스 계약
|
|
# mail/calendar 도메인의 실 커넥터가 모두 BaseConnector 의 fetch/normalize/write/sync 를 구현.
|
|
import importlib
|
|
|
|
import pytest
|
|
|
|
from app.connectors.base import BaseConnector
|
|
|
|
CONNECTORS = [
|
|
# phase-16+: mail/calendar 는 mock 제거 → 실 커넥터만(Gmail/Outlook/IMAP, Google 캘린더/ICS)
|
|
"mail.real_gmail.GmailConnector",
|
|
"mail.real_outlook.OutlookConnector",
|
|
"mail.real_imap.ImapConnector",
|
|
"calendar.real_google.GoogleCalendarConnector",
|
|
"calendar.real_outlook.OutlookCalendarConnector",
|
|
"calendar.ics_import.IcsConnector",
|
|
]
|
|
|
|
|
|
def _load(path: str):
|
|
mod, cls = path.rsplit(".", 1)
|
|
return getattr(importlib.import_module("app.connectors." + mod), cls)
|
|
|
|
|
|
@pytest.mark.parametrize("path", CONNECTORS)
|
|
def test_connector_is_concrete_subclass(path):
|
|
cls = _load(path)
|
|
assert issubclass(cls, BaseConnector), path
|
|
# 추상 미구현이 없어야 인스턴스화 가능
|
|
assert not getattr(cls, "__abstractmethods__", frozenset()), (
|
|
path,
|
|
cls.__abstractmethods__,
|
|
)
|
|
for m in ("fetch", "normalize", "write", "sync", "event_for"):
|
|
assert callable(getattr(cls, m)), (path, m)
|
|
|
|
|
|
def test_covers_mail_calendar_domains():
|
|
domains = {p.split(".", 1)[0] for p in CONNECTORS}
|
|
assert domains == {"mail", "calendar"}
|
|
assert len(CONNECTORS) == 6 # 실 커넥터만(Gmail/Outlook/IMAP, Google/Outlook 캘린더/ICS)
|