import json import pytest from app.crawler import detect_rules, extract_events def base_source(**overrides): value = {"url": "https://example.org/events", "timezone": "Australia/Sydney", "item_selector": "json-ld", "title_selector": "", "date_selector": "", "time_selector": "", "link_selector": "", "description_selector": "", "location_selector": "", "date_format": "", "recurring_weekly": 0} value.update(overrides) return value def test_jsonld_extracts_graph_event_with_end_address_and_relative_url(): payload = {"@graph": [{"@type": "Event", "name": "Gallery Talk", "startDate": "2026-09-07T18:00:00+10:00", "endDate": "2026-09-07T20:00:00+10:00", "description": "A talk", "url": "/talk", "location": {"address": {"streetAddress": "1 Art St", "addressLocality": "Wollongong", "addressRegion": "NSW", "postalCode": "2500"}}}]} html = f'' event = extract_events(html, base_source())[0] assert event.title == "Gallery Talk" assert event.ends_at.hour == 20 assert event.address == "1 Art St, Wollongong, NSW, 2500" assert event.url == "https://example.org/talk" def test_jsonld_ignores_invalid_and_missing_dates(): html = ''' ''' events = extract_events(html, base_source()) assert [event.title for event in events] == ["Good"] def test_html_extraction_skips_invalid_sibling(): html = '''

Bad

Good

Details
''' source = base_source(item_selector="article", title_selector="h2", date_selector="time", link_selector="a") events = extract_events(html, source) assert len(events) == 1 assert events[0].title == "Good" def test_detector_prefers_jsonld(): html = '' rules, events, message = detect_rules(html, "https://example.org/events") assert rules["item_selector"] == "json-ld" assert len(events) == 1 assert "JSON-LD" in message def test_detector_finds_repeated_html_cards(): html = '''

One

More

Two

More
''' rules, events, message = detect_rules(html, "https://example.org/events") assert len(events) >= 2 assert rules["item_selector"] assert rules["title_selector"] assert rules["date_selector"] assert "Guessed CSS" in message def test_detector_rejects_social_feed_false_positive(): html = '''
Party this FridayFriday night
More next FridayFriday night
''' with pytest.raises(Exception, match="No repeated event-like"): detect_rules(html, "https://example.org/events")