| from jawbreaker.schema import ScamAnalysis |
| from jawbreaker.analyzers import prediction_to_analysis |
| from jawbreaker.render import render_analysis_html, render_scanning_html |
|
|
|
|
| def test_family_impersonation_is_dangerous() -> None: |
| analysis = ScamAnalysis.from_heuristics( |
| "Hi Grandma, I lost my phone. This is my new number. Can you send $800 today?" |
| ) |
|
|
| assert analysis.risk_level == "dangerous" |
| assert analysis.scam_type == "family_impersonation" |
| assert "Trust a new number" == analysis.scam_dna["Ask"] |
|
|
|
|
| def test_legitimate_fraud_alert_needs_check_not_dangerous() -> None: |
| analysis = ScamAnalysis.from_heuristics( |
| "Chase fraud alert: Did you attempt a $249.00 purchase at TARGET? Reply YES or NO." |
| ) |
|
|
| assert analysis.risk_level == "needs_check" |
| assert analysis.scam_type == "possible_legitimate_alert" |
|
|
|
|
| def test_device_protection_subscription_alert_is_tech_support() -> None: |
| analysis = ScamAnalysis.from_heuristics( |
| "Device protection team: subscription expired. Call the number in this alert to avoid data loss." |
| ) |
|
|
| assert analysis.risk_level == "dangerous" |
| assert analysis.scam_type == "tech_support" |
|
|
|
|
| def test_billing_link_with_account_closure_is_dangerous() -> None: |
| analysis = ScamAnalysis.from_heuristics( |
| "Streaming billing: payment failed and your account closes tonight. Update through this message link: http://billing-review.example" |
| ) |
|
|
| assert analysis.risk_level == "dangerous" |
| assert analysis.scam_type == "credential_theft" |
|
|
|
|
| def test_prediction_to_analysis_normalizes_model_json() -> None: |
| analysis = prediction_to_analysis( |
| { |
| "risk_level": "not_valid", |
| "scam_type": "package_phishing", |
| "summary": "Fake delivery notice.", |
| "tactics": ["fake authority"], |
| "safest_action": "Open the official carrier website yourself.", |
| "trusted_person_message": "Can you check this?", |
| "scam_dna": { |
| "impersonates": "USPS", |
| "pressure": "Held package", |
| "ask": "Open link", |
| "risk": "credential theft", |
| }, |
| }, |
| similar_memory="This resembles a saved pattern.", |
| ) |
|
|
| assert analysis.risk_level == "needs_check" |
| assert analysis.scam_dna["Impersonates"] == "USPS" |
| assert analysis.similar_memory == "This resembles a saved pattern." |
|
|
|
|
| def test_render_humanizes_model_style_labels() -> None: |
| analysis = ScamAnalysis( |
| risk_level="dangerous", |
| scam_type="credential_theft", |
| summary="This message mentions credential_theft.", |
| tactics=["unknown_urgent_action", "unknown_urgent_payment", "credential_theft"], |
| safest_action="Do not click the link.", |
| scam_dna={ |
| "Impersonates": "legitimate_company", |
| "Pressure": "sense_of_urgency", |
| "Ask": "click_link_and_verify", |
| "Risk": "credential_theft", |
| }, |
| ) |
|
|
| html = render_analysis_html("USPS: verify now", analysis) |
|
|
| assert "legitimate company" in html |
| assert "click a link and verify" in html |
| assert "unknown_urgent_action" not in html |
| assert "urgent payment" in html |
| assert "data-copy=" in html |
|
|
|
|
| def test_render_scanning_html_tracks_progress() -> None: |
| html = render_scanning_html(active_step=2, progress=54) |
|
|
| assert "54% COMPLETE" in html |
| assert "✓ Preparing the safety model" in html |
| assert "> Checking scam pressure signals" in html |
|
|