"""Coverage for the generic email webhook: the admin test endpoint, and the new notification-dispatch helpers that route test/campaign/MITRE events through it (see webhook_email_service.py, notification_service.py). """ import uuid from unittest.mock import patch import pytest from app.services.notification_service import ( _preference_allows, notify_all_users_by_email, notify_user_by_email, ) def test_email_webhook_test_endpoint_requires_admin(api, red_lead_headers): resp = api( "post", "/api/v1/system/email-webhook-test", red_lead_headers, json={"to": "someone@test.com"}, ) assert resp.status_code == 403 def test_email_webhook_test_endpoint_fails_without_config(api, auth_headers): resp = api( "post", "/api/v1/system/email-webhook-test", auth_headers, json={"to": "someone@test.com"}, ) assert resp.status_code == 502 def test_email_webhook_test_endpoint_sends_via_configured_webhook(api, auth_headers): api( "patch", "/api/v1/system/email-webhook-config", auth_headers, json={"url": "https://example.com/power-automate-hook", "api_key": "super-secret-key"}, ) with patch("app.services.webhook_email_service.requests.post") as mock_post: resp = api( "post", "/api/v1/system/email-webhook-test", auth_headers, json={"to": "marcos.luna@kaseya.com"}, ) assert resp.status_code == 200, resp.text mock_post.assert_called_once() call_kwargs = mock_post.call_args assert call_kwargs.args[0] == "https://example.com/power-automate-hook" assert call_kwargs.kwargs["headers"] == {"x-api-key": "super-secret-key"} payload = call_kwargs.kwargs["json"] assert payload["to"] == "marcos.luna@kaseya.com" assert "Purple Team Engineering" in payload["body"] class _FakeUser: def __init__(self, email="user@test.com", full_name="A User", prefs=None): self.email = email self.full_name = full_name self.notification_preferences = prefs def test_preference_allows_defaults_to_true_when_missing(): assert _preference_allows(_FakeUser(prefs=None), "email_on_test_validated") is True assert _preference_allows(_FakeUser(prefs={}), "email_on_test_validated") is True def test_preference_allows_respects_explicit_false(): user = _FakeUser(prefs={"email_on_test_validated": False}) assert _preference_allows(user, "email_on_test_validated") is False def test_preference_allows_false_without_email(): assert _preference_allows(_FakeUser(email=None), "email_on_test_validated") is False assert _preference_allows(None, "email_on_test_validated") is False def test_notify_user_by_email_sends_when_allowed(db, auth_headers, api): resp = api( "post", "/api/v1/users", auth_headers, json={"full_name": "Notify Me", "email": "notifyme@test.com", "role": "viewer"}, ) assert resp.status_code == 201, resp.text user_id = resp.json()["id"] with patch("app.services.webhook_email_service.send_webhook_email") as mock_send: notify_user_by_email( db, uuid.UUID(user_id), preference_key="email_on_test_validated", subject="Test Validated: Some Test", message='Your test "Some Test" has been validated successfully.', ) mock_send.assert_called_once() assert mock_send.call_args.kwargs["to"] == "notifyme@test.com" def test_notify_all_users_by_email_skips_opted_out(db): allowed = _FakeUser(email="allowed@test.com", prefs={"email_on_new_mitre_techniques": True}) blocked = _FakeUser(email="blocked@test.com", prefs={"email_on_new_mitre_techniques": False}) class _FakeQuery: def filter(self, *args, **kwargs): return self def all(self): return [allowed, blocked] with patch.object(db, "query", return_value=_FakeQuery()), \ patch("app.services.webhook_email_service.send_webhook_email") as mock_send: notify_all_users_by_email( db, preference_key="email_on_new_mitre_techniques", subject="MITRE ATT&CK Updated: 3 new techniques", message="3 new techniques were added and 1 were updated.", ) mock_send.assert_called_once() assert mock_send.call_args.kwargs["to"] == "allowed@test.com"