diff --git a/billing/tests.py b/billing/tests.py index 7ce503c..7be55fe 100644 --- a/billing/tests.py +++ b/billing/tests.py @@ -1,3 +1,192 @@ 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 -# Create your tests here. +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) diff --git a/justfile b/justfile index bc25798..025916d 100644 --- a/justfile +++ b/justfile @@ -7,6 +7,14 @@ dev: migrate: python manage.py migrate - make-migrations: - python manage.py makemigrations \ No newline at end of file + python manage.py makemigrations + +seed-topups: + python manage.py seed_topups --number=50 +seed-payments: + python manage.py seed_payments --number=50 + +# TESTS +test-billing: + python manage.py test billing \ No newline at end of file