from datetime import timedelta from django.contrib.auth import get_user_model from django.utils import timezone from rest_framework import status from rest_framework.test import APITestCase from accounts.models import VendorProfile from booking.models import Booking from equipment.models import EquipmentCategory, EquipmentItem from marketing.models import ListingClick User = get_user_model() class MarketingTrackingTests(APITestCase): def setUp(self): self.vendor_user = User.objects.create_user( email="vendor-mkt@example.com", password="Pass123456!", is_vendor=True, is_customer=False, ) self.vendor_profile = VendorProfile.objects.create(user=self.vendor_user, business_name="Mkt Vendor") self.customer = User.objects.create_user( email="customer-mkt@example.com", password="Pass123456!", is_vendor=False, is_customer=True, ) category = EquipmentCategory.objects.create(name="Kayak", slug="kayak") self.item = EquipmentItem.objects.create( vendor=self.vendor_profile, category=category, title="Kayak 1", public_id="kayak-mkt-001", price_per_day="50.00", is_active=True, ) def test_equipment_detail_logs_click_and_returns_ids(self): res = self.client.get(f"/api/v1/equipment/items/{self.item.public_id}/") self.assertEqual(res.status_code, status.HTTP_200_OK) self.assertIn("marketing_click_id", res.data) self.assertIn("click_traffic_type", res.data) self.assertEqual(res.data["click_traffic_type"], ListingClick.TrafficType.ORGANIC) self.assertEqual(ListingClick.objects.count(), 1) def test_equipment_detail_utm_classified_marketing(self): res = self.client.get( f"/api/v1/equipment/items/{self.item.public_id}/", {"utm_source": "google", "utm_medium": "cpc", "utm_campaign": "spring"}, ) self.assertEqual(res.status_code, status.HTTP_200_OK) self.assertEqual(res.data["click_traffic_type"], ListingClick.TrafficType.MARKETING) click = ListingClick.objects.get(pk=res.data["marketing_click_id"]) self.assertEqual(click.utm_campaign, "spring") def test_track_click_endpoint(self): res = self.client.post( "/api/v1/marketing/track/click/", {"listing_type": "equipment", "public_id": self.item.public_id, "utm_campaign": "email"}, format="json", ) self.assertEqual(res.status_code, status.HTTP_201_CREATED) self.assertIn("marketing_click_id", res.data) def test_booking_with_marketing_click_id(self): detail = self.client.get(f"/api/v1/equipment/items/{self.item.public_id}/") click_id = detail.data["marketing_click_id"] starts = timezone.now() + timedelta(days=10) ends = starts + timedelta(days=1) self.client.force_authenticate(self.customer) res = self.client.post( "/api/v1/booking/bookings/request/", { "equipment_item_id": self.item.id, "starts_at": starts.isoformat(), "ends_at": ends.isoformat(), "marketing_click_id": click_id, }, format="json", ) self.assertEqual(res.status_code, status.HTTP_201_CREATED) booking = Booking.objects.get(pk=res.data["id"]) self.assertEqual(booking.listing_click_id, click_id) def test_vendor_summary_requires_range(self): self.client.force_authenticate(self.vendor_user) res = self.client.get("/api/v1/marketing/vendor/summary/") self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)