"""New-order notification task tests."""

from unittest import mock

from django.test import TestCase, override_settings

from shop.models import Buyer, Order, OrderLine, Shop
from shop.tasks import notify_new_order
from shop.tests.test_stock import make_owner_character, make_ship_type


@override_settings(SITE_URL="https://auth.example.com")
class NotifyNewOrderTests(TestCase):
    def setUp(self):
        self.user, _ = make_owner_character()
        self.shop = Shop.objects.create(
            slug="s", name="S", created_by=self.user, enabled_sections=["hulls"]
        )
        self.ship = make_ship_type()
        self.buyer = Buyer.objects.create(
            character_id=7, character_name="Sir Uhad", discord_handle="uhad"
        )
        self.order = Order.objects.create(
            shop=self.shop, buyer=self.buyer, additional_info="ME10"
        )
        OrderLine.objects.create(
            order=self.order,
            section="hulls",
            eve_type=self.ship,
            quantity=2,
            unit_price=1000,
            label="ME 10 · TE 20 · 50 runs",
        )

    @mock.patch("shop.tasks.notify")
    @mock.patch("shop.tasks.requests.post")
    def test_in_app_only_when_no_webhook(self, post, notify):
        notify_new_order(self.order.pk)
        notify.info.assert_called_once()
        args, _ = notify.info.call_args
        self.assertEqual(args[0], self.user)  # owner notified
        self.assertIn(self.order.reference, args[1])  # title carries the ref
        post.assert_not_called()

    @mock.patch("shop.tasks.notify")
    @mock.patch("shop.tasks.requests.post")
    def test_webhook_posts_embed_with_link(self, post, notify):
        self.shop.discord_webhook = "https://discord.com/api/webhooks/1/abc"
        self.shop.save(update_fields=["discord_webhook"])
        notify_new_order(self.order.pk)
        post.assert_called_once()
        args, kwargs = post.call_args
        self.assertEqual(args[0], "https://discord.com/api/webhooks/1/abc")
        embed = kwargs["json"]["embeds"][0]
        self.assertIn(self.order.reference, embed["title"])
        self.assertIn("Sir Uhad", embed["description"])
        self.assertIn("ME 10", embed["description"])  # variant label
        self.assertIn(
            f"/shop-backoffice/{self.shop.pk}/orders/{self.order.reference}/",
            embed["url"],
        )

    @mock.patch("shop.tasks.notify")
    @mock.patch("shop.tasks.requests.post", side_effect=Exception("boom"))
    def test_webhook_failure_is_swallowed(self, post, notify):
        self.shop.discord_webhook = "https://discord.com/api/webhooks/1/abc"
        self.shop.save(update_fields=["discord_webhook"])
        notify_new_order(self.order.pk)  # must not raise
        notify.info.assert_called_once()
