"""HTTP tests for POST /api/widget/job-alert.

The save-search ("Suche speichern") endpoint turns a visitor's current
search into an anonymous job.saved.search subscription — no KJ login,
the verified email is the identity (same pattern as the apply flow).
These tests pin: happy path creates the alert, key/email validation,
and the honeypot drops bot submissions silently.
"""

import json

from odoo.tests import tagged

from odoo.addons.kj_affiliate_widget.tests.common import WidgetTestCommon


@tagged("post_install", "-at_install", "kj_affiliate_widget")
class TestWidgetJobAlert(WidgetTestCommon):

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        # job.saved.search ships in kj_job_search_notification, which the
        # widget treats as optional (the endpoint returns 503 if it's
        # absent). Skip the suite rather than fail on a checkout without it.
        if "job.saved.search" not in cls.env:
            cls.skipTest(cls, "kj_job_search_notification not installed")

    def _post(self, payload):
        return self.url_open(
            "/api/widget/job-alert",
            data=json.dumps(payload),
            headers={"Content-Type": "application/json"},
        )

    def _alert(self, email):
        return self.env["job.saved.search"].sudo().search(
            [("email", "=", email)], limit=1,
        )

    def test_valid_request_creates_anonymous_alert(self):
        r = self._post({
            "key": self.config.widget_key,
            "email": "alert-ok@example.com",
            "query": "jurist",
            "frequency": "weekly",
        })
        self.assertEqual(r.status_code, 200)
        self.assertTrue(r.json().get("success"))
        alert = self._alert("alert-ok@example.com")
        self.assertTrue(alert, "job.saved.search row should exist")
        self.assertEqual(alert.es_query_text, "jurist")
        self.assertEqual(alert.notification_frequency, "weekly")
        self.assertFalse(
            alert.is_verified,
            "anonymous alert must start unverified (double opt-in)",
        )
        self.assertFalse(alert.user_id, "anonymous alert has no user")

    def test_invalid_key_returns_403(self):
        r = self._post({"key": "not-a-real-key", "email": "x@example.com"})
        self.assertEqual(r.status_code, 403)
        self.assertFalse(self._alert("x@example.com"))

    def test_missing_email_returns_400(self):
        r = self._post({"key": self.config.widget_key})
        self.assertEqual(r.status_code, 400)

    def test_invalid_email_returns_400(self):
        """create_anonymous_alert rejects an address with no '@'."""
        r = self._post({
            "key": self.config.widget_key,
            "email": "not-an-email",
        })
        self.assertEqual(r.status_code, 400)
        self.assertFalse(r.json().get("success"))

    def test_honeypot_drops_submission_silently(self):
        """A filled honeypot field → pretend success, create nothing."""
        r = self._post({
            "key": self.config.widget_key,
            "email": "bot@example.com",
            "website": "http://spam.example",
        })
        self.assertEqual(r.status_code, 200)
        self.assertTrue(r.json().get("success"))
        self.assertFalse(
            self._alert("bot@example.com"),
            "honeypot-flagged submission must not create an alert",
        )

    def test_frequency_defaults_to_daily(self):
        r = self._post({
            "key": self.config.widget_key,
            "email": "alert-freq@example.com",
            "frequency": "garbage",
        })
        self.assertEqual(r.status_code, 200)
        self.assertEqual(
            self._alert("alert-freq@example.com").notification_frequency,
            "daily",
        )
