from django.test import TestCase from django.urls import reverse from rest_framework import status from rest_framework.test import APIClient from django.contrib.auth import get_user_model from .models import Topup from .serializers import TopupSerializer from django.utils import timezone from datetime import timedelta from decouple import config from unittest import mock User = get_user_model() REAL_USER_FIRST_NAME = config("REAL_USER_FIRST_NAME", default="josh") REAL_USER_LAST_NAME = config("REAL_USER_LAST_NAME", default="mosh") class TopupTests(TestCase): def setUp(self): self.client = APIClient() self.real_user = User.objects.create_user( username="testuser", password="testpassword", first_name=REAL_USER_FIRST_NAME, last_name=REAL_USER_LAST_NAME, acc_no="7770000010629", is_admin=True, ) self.user = User.objects.create_user( username="plskillme", password="modewasgayithink", first_name="mode", last_name="hussain", acc_no="1122334455", ) self.admin_user = User.objects.create_superuser( username="adminuser", password="adminpassword", email="admin@example.com", first_name="Admin", last_name="User", acc_no="987654321", ) self.client.force_authenticate(user=self.real_user) def test_create_topup(self): url = reverse("create-list-topups") data = {"amount": 100.00} response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Topup.objects.count(), 1) topup = Topup.objects.first() self.assertEqual(getattr(topup, "amount"), 100.00) self.assertEqual(getattr(topup, "user"), self.real_user) def test_create_topup_no_amount(self): url = reverse("create-list-topups") data = {} response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_list_topups(self): Topup.objects.create(amount=50.00, user=self.real_user) Topup.objects.create(amount=75.00, user=self.real_user) url = reverse("create-list-topups") response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.json()["data"]), 2) def test_list_topups_admin(self): self.client = APIClient() self.client.force_authenticate(user=self.admin_user) Topup.objects.create(amount=50.00, user=self.real_user) admin_user = User.objects.create_user( username="anotheruser", password="testpassword", first_name="Another", last_name="User", acc_no="1122334455", is_admin=True, ) Topup.objects.create(amount=75.00, user=admin_user) url = reverse("create-list-topups") response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.json()["data"]), 2) # Admin sees all def test_list_topups_filtered_by_user(self): other_user = User.objects.create_user( username="otheruser", password="testpassword", first_name="Other", last_name="User", acc_no="5544332211", ) Topup.objects.create(amount=50.00, user=self.user) Topup.objects.create(amount=75.00, user=other_user) url = reverse("create-list-topups") response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.json()["data"]), 2) @mock.patch("billing.views.localtime") def test_verify_topup_payment(self, mock_localtime): fixed_time = timezone.datetime( 2025, 7, 3, 19, 36, tzinfo=timezone.get_current_timezone() ) mock_localtime.return_value = fixed_time topup = Topup.objects.create(amount=1.5, user=self.real_user) url = reverse("verify-topup-payment", kwargs={"pk": topup.pk}) self.client = APIClient() self.client.force_authenticate(user=self.real_user) data = { "benefName": f"{REAL_USER_FIRST_NAME} {REAL_USER_LAST_NAME}", "accountNo": "7770000010629", "absAmount": 1.5, "time": fixed_time.strftime("%Y-%m-%d %H:%M"), # Use the same fixed time } response = self.client.patch(url, data, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) topup.refresh_from_db() self.assertEqual(topup.paid, True) def test_verify_topup_payment_already_verified(self): topup = Topup.objects.create(amount=100.00, user=self.real_user, paid=True) url = reverse("verify-topup-payment", kwargs={"pk": topup.pk}) data = {} response = self.client.patch(url, data, format="json") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_verify_topup_payment_unauthorized(self): other_user = User.objects.create_user( username="otheruser", password="testpassword", first_name="Other", last_name="User", acc_no="5544332211", ) topup = Topup.objects.create(amount=100.00, user=other_user) url = reverse("verify-topup-payment", kwargs={"pk": topup.pk}) data = {} response = self.client.patch(url, data, format="json") self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_topup_serializer(self): topup = Topup.objects.create(amount=120.00, user=self.real_user) serializer = TopupSerializer(topup) self.assertEqual(serializer.data["amount"], 120.00) self.assertEqual(serializer.data["user"]["id"], getattr(self.real_user, "id")) def test_topup_filter_amount(self): Topup.objects.create(amount=50.00, user=self.real_user) Topup.objects.create(amount=100.00, user=self.real_user) url = reverse("create-list-topups") + "?amount_min=75" response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.json()["data"]), 1) self.assertEqual(response.json()["data"][0]["amount"], 100.00) def test_topup_filter_user_search(self): Topup.objects.create(amount=50.00, user=self.real_user) other_user = User.objects.create_user( username="otheruser", password="testpassword", first_name="Other", last_name="User", id_card="12345", mobile="1234567890", acc_no="5544332211", ) Topup.objects.create(amount=75.00, user=other_user) url = reverse("create-list-topups") + "?user=Other" response = self.client.get(url, format="json") print(response.json()) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.json()["data"]), 1) self.assertEqual(response.json()["data"][0]["amount"], 75.00) def test_topup_filter_created_at(self): now = timezone.now() Topup.objects.create( amount=50.00, user=self.real_user, created_at=now - timedelta(days=2) ) Topup.objects.create(amount=100.00, user=self.real_user, created_at=now) url = reverse("create-list-topups") + f"?created_at_after={now.date()}" response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.json()["data"]), 1) self.assertEqual(response.json()["data"][0]["amount"], 100.00)