"""HTTP tests for GET /api/widget/job-cards.

The faceted filter fetches matching job ids from the Elasticsearch
search endpoint, then calls this to get server-rendered kj-job-card
markup for them. These tests pin: valid ids render cards, key
validation, empty/garbage input degrades cleanly, and — critically —
affiliate curation drops ids the config does not permit.
"""

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 TestWidgetJobCards(WidgetTestCommon):

    def _get(self, key, ids):
        return self.url_open(
            "/api/widget/job-cards?key=%s&ids=%s" % (key, ids),
        )

    def test_valid_ids_render_cards(self):
        r = self._get(self.config.widget_key, str(self.job.id))
        self.assertEqual(r.status_code, 200)
        body = r.json()
        self.assertEqual(body.get("count"), 1)
        self.assertIn("kj-job-card", body.get("html", ""))

    def test_invalid_key_returns_403(self):
        r = self._get("not-a-real-key", str(self.job.id))
        self.assertEqual(r.status_code, 403)

    def test_missing_key_returns_400(self):
        r = self.url_open("/api/widget/job-cards?ids=%s" % self.job.id)
        self.assertEqual(r.status_code, 400)

    def test_empty_ids_returns_empty_html(self):
        r = self._get(self.config.widget_key, "")
        self.assertEqual(r.status_code, 200)
        self.assertEqual(r.json().get("html"), "")

    def test_garbage_ids_are_ignored(self):
        """Non-numeric tokens are dropped; a stray valid id still renders."""
        r = self._get(self.config.widget_key, "abc,,%s,99999999" % self.job.id)
        self.assertEqual(r.status_code, 200)
        # the bogus 99999999 id has no record → not rendered; only cls.job is.
        self.assertEqual(r.json().get("count"), 1)

    def test_curated_filter_drops_unpermitted_ids(self):
        """A curated config must not render a job outside its allow-list."""
        other_job = self.env["hr.job"].create({
            "name": "Curated-only Job",
            "company_id": self.company.id,
            "is_published": True,
            "active": True,
        })
        # Flip the shared config to curated (write, not create — a second
        # config row would collide on the widget_key/mode unique index).
        self.config.write({
            "filter_mode": "curated",
            "filter_job_ids": [(6, 0, other_job.ids)],
        })
        # Ask for cls.job, which is NOT in the curated allow-list.
        r = self._get(self.config.widget_key, str(self.job.id))
        self.assertEqual(r.status_code, 200)
        self.assertEqual(
            r.json().get("count"), 0,
            "a job outside the curated allow-list must not be rendered",
        )
        # The curated job itself still renders.
        r2 = self._get(self.config.widget_key, str(other_job.id))
        self.assertEqual(r2.json().get("count"), 1)

    def test_unpublished_job_is_not_rendered(self):
        draft = self.env["hr.job"].create({
            "name": "Unpublished Job",
            "company_id": self.company.id,
            "is_published": False,
            "active": True,
        })
        r = self._get(self.config.widget_key, str(draft.id))
        self.assertEqual(r.status_code, 200)
        self.assertEqual(r.json().get("count"), 0)
