"""Scoutline parser tests — feed rows to normalized Case objects.""" from __future__ import annotations from psyc.lines.scout import _feodo_record_to_case, _kev_vuln_to_case, _parse_urlhaus_csv URLHAUS_CSV = """\ # comment line "3846688","2026-05-14 11:01:14","http://1.2.3.4/x","online","2026-05-14","malware_download","elf,mirai","https://urlhaus.abuse.ch/url/3846688/","reporter1" """ def test__parse_urlhaus_csv_skips_comments_and_parses_rows(): rows = list(_parse_urlhaus_csv(URLHAUS_CSV)) assert len(rows) == 1 assert rows[0]["url"] == "http://1.2.3.4/x" assert rows[0]["url_status"] == "online" def test_kev_vuln_to_case(): vuln = { "cveID": "CVE-2026-0300", "vendorProject": "Microsoft", "product": "Exchange", "vulnerabilityName": "Exchange XSS", "dateAdded": "2026-05-15", "knownRansomwareCampaignUse": "Known", } case = _kev_vuln_to_case(vuln) assert case.case_id == "PSYC-KEV-CVE-2026-0300" assert case.observables.cves == ["CVE-2026-0300"] assert case.source_metadata["feed"] == "cisa-kev" assert case.source_metadata["ransomware"] == "Known" def test_feodo_record_to_case(): record = { "ip_address": "162.243.103.246", "port": 8080, "status": "online", "malware": "Emotet", "country": "US", "first_seen": "2022-06-04 21:24:53", } case = _feodo_record_to_case(record) assert case.observables.ips == ["162.243.103.246"] assert case.source_metadata["feed"] == "feodo" assert case.source_metadata["malware"] == "Emotet" assert case.source_metadata["status"] == "online"