Files
kadence/backend/tests/test_sources.py
T
2026-10-18 18:02:05 +03:00

101 lines
3.2 KiB
Python

"""Source mapping: the parts that work without a network."""
from __future__ import annotations
from datetime import date
from app.settings_schema import JiraSourceSettings, LaundrySourceSettings
from app.sources.jira import JiraSource, start_date_clause
from app.sources.laundry import parse_cookie_header, parse_my_slots
JIRA_CONFIG = JiraSourceSettings(
enabled=True,
base_url="https://example.atlassian.net",
email="me@example.com",
api_token="token",
)
def test_start_date_clause_handles_custom_fields_and_names():
assert start_date_clause("customfield_10015") == "cf[10015]"
assert start_date_clause("Start date") == '"Start date"'
def test_jira_jql_includes_the_extra_filter():
source = JiraSource(JIRA_CONFIG.model_copy(update={"extra_jql": "assignee = currentUser()"}))
jql = source._jql()
assert "statusCategory != Done" in jql
assert "assignee = currentUser()" in jql
source.close()
def test_jira_issue_maps_to_a_todo_item():
source = JiraSource(JIRA_CONFIG)
item = source._to_item(
{
"key": "ABC-1",
"fields": {
"summary": "Fix the thing",
"duedate": "2026-10-20",
"customfield_10015": "2026-10-15",
"status": {"name": "In Progress", "statusCategory": {"key": "indeterminate"}},
"priority": {"name": "High"},
"project": {"name": "Platform"},
"labels": ["backend"],
},
}
)
source.close()
assert item.external_id == "ABC-1"
assert item.title == "Fix the thing"
assert item.url == "https://example.atlassian.net/browse/ABC-1"
assert item.due_date == date(2026, 10, 20)
assert item.start_date == date(2026, 10, 15)
assert item.priority == "High"
assert item.is_done is False
assert item.days_overdue(date(2026, 10, 22)) == 2
def test_cookie_header_accepts_both_forms():
assert parse_cookie_header("abc123") == {"sessionid": "abc123"}
parsed = parse_cookie_header("csrftoken=x; sessionid=abc123")
assert parsed["sessionid"] == "abc123"
LAUNDRY_HTML = """
<div class="date-machines" id="Чт, 15 окт.">
<div class="machines">
<div class="floor-title">Этаж 1</div>
<div class="machine">
<div class="machine-title">Машинка 3</div>
<div class="period my finished"><div>09:00-12:00</div></div>
<div class="period my current"><div>18:00-21:00</div></div>
<div class="period"><div>21:00-00:00</div></div>
</div>
</div>
</div>
"""
def test_laundry_grid_yields_only_my_upcoming_slots():
label, slots = parse_my_slots(LAUNDRY_HTML)
assert label == "Чт, 15 окт."
assert len(slots) == 2
upcoming = [slot for slot in slots if slot.is_upcoming]
assert len(upcoming) == 1
assert upcoming[0].time_range == "18:00-21:00"
assert upcoming[0].machine == "Машинка 3"
assert upcoming[0].location == "Этаж 1"
def test_laundry_config_requires_a_session_cookie():
from app.sources.base import SourceError
try:
from app.sources.laundry import LaundrySource
LaundrySource(LaundrySourceSettings(enabled=True, session_cookie=""))
except SourceError:
return
raise AssertionError("expected a SourceError")