92 lines
3.7 KiB
Python
92 lines
3.7 KiB
Python
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)
|