haikal/inventory/tests.py
2025-07-15 17:27:03 +03:00

475 lines
18 KiB
Python

import json
from . import models as m
from django.urls import reverse
from django.test import Client, TestCase
from django.contrib.auth import get_user_model
from django_ledger.io.io_core import get_localdate
from django.core.exceptions import ObjectDoesNotExist
from decimal import Decimal
from unittest.mock import MagicMock
from inventory.models import VatRate
from inventory.utils import CarFinanceCalculator
User = get_user_model()
# Create your tests here.
class ModelTest(TestCase):
"""
Test case class designed to test models in the application. The tests
verify model creation, related object creation, and appropriate
functionality for specific business logic, ensuring correctness and
reliability of the defined models.
This class tests the following:
- Dealer model, including associated user and entity creation.
- Car model, ensuring product creation and validations.
- Testing of car finances, including finance totals and relationships.
- Creation of additional services, ensuring the generation of corresponding
item services.
:ivar vat: Vat rate created for testing purposes.
:type vat: VatRate instance
:ivar dealer: Dealer instance created for testing.
:type dealer: Dealer instance
:ivar car_make: Car make created for testing purposes.
:type car_make: CarMake instance
:ivar car_model: Car model created for testing purposes.
:type car_model: CarModel instance
:ivar car_serie: Car series created for testing purposes.
:type car_serie: CarSerie instance
:ivar trim: Car trim created for testing purposes.
:type trim: CarTrim instance
:ivar car: Car object created for testing.
:type car: Car instance
:ivar car_finances: Car finance object for the car under test.
:type car_finances: CarFinance instance
"""
def setUp(self):
email = "RkzgO@example.com"
name = "John Doe"
password = "password"
crn = "123456789"
vrn = "123456789"
phone = "123456789"
address = "123 Main St"
arabic_name = "الاسم بالعربية"
self.vat = m.VatRate.objects.create(rate=0.15)
user = User.objects.create(username=email, email=email)
user.set_password(password)
user.save()
self.dealer = m.Dealer.objects.create(
user=user,
name=name,
arabic_name=arabic_name,
crn=crn,
vrn=vrn,
phone_number=phone,
address=address,
)
self.car_make = m.CarMake.objects.create(name="Make")
self.car_model = m.CarModel.objects.create(
name="Model", id_car_make=self.car_make
)
self.car_serie = m.CarSerie.objects.create(
name="Serie", id_car_model=self.car_model
)
self.trim = m.CarTrim.objects.create(name="Trim", id_car_serie=self.car_serie)
self.car = m.Car.objects.create(
vin="123456789",
dealer=self.dealer,
id_car_make=self.car_make,
id_car_model=self.car_model,
id_car_serie=self.car_serie,
year=2020,
id_car_trim=self.trim,
receiving_date=get_localdate(),
)
self.car_finances = m.CarFinance.objects.create(
car=self.car, selling_price=1000, cost_price=500, discount_amount=200
)
def test_dealer_creation_creates_user_and_entity(self):
dealer = self.dealer
self.assertEqual(User.objects.count(), 1)
self.assertEqual(m.Dealer.objects.count(), 1)
self.assertEqual(User.objects.first().username, "RkzgO@example.com")
self.assertEqual(User.objects.first().email, "RkzgO@example.com")
self.assertTrue(User.objects.first().check_password("password"))
self.assertEqual(dealer.user, User.objects.first())
self.assertEqual(dealer.name, "John Doe")
self.assertEqual(dealer.arabic_name, "الاسم بالعربية")
self.assertEqual(dealer.crn, "123456789")
self.assertEqual(dealer.vrn, "123456789")
self.assertEqual(dealer.phone_number, "123456789")
self.assertEqual(dealer.address, "123 Main St")
self.assertIsNotNone(dealer.entity)
self.assertEqual(dealer.entity.name, dealer.name)
self.assertEqual(dealer.entity.get_all_accounts().count(), 57)
self.assertEqual(dealer.entity.get_uom_all().count(), 16)
def test_car_creation_creates_product(self):
dealer = self.dealer
self.assertEqual(m.Car.objects.count(), 1)
self.assertEqual(self.car.vin, "123456789")
self.assertEqual(self.car.dealer, dealer)
self.assertEqual(self.car.id_car_make, self.car_make)
self.assertEqual(self.car.id_car_model, self.car_model)
self.assertEqual(self.car.id_car_serie, self.car_serie)
self.assertEqual(self.car.year, 2020)
self.assertEqual(self.car.id_car_trim, self.trim)
product = dealer.entity.get_items_all().filter(name=self.car.vin).first()
self.assertEqual(product.name, self.car.vin)
def test_car_finances_creation(self):
self.assertEqual(m.CarFinance.objects.count(), 1)
self.assertEqual(self.car_finances.car, self.car)
self.assertEqual(self.car_finances.selling_price, 1000)
self.assertEqual(self.car_finances.cost_price, 500)
self.assertEqual(self.car_finances.discount_amount, 200)
def test_car_finance_total(self):
self.assertEqual(m.CarFinance.objects.count(), 1)
self.assertEqual(self.car_finances.total, 1000)
self.assertEqual(self.car_finances.total_discount, 800)
self.assertEqual(self.car_finances.total_vat, 920)
def test_car_additional_services_create_item_service(self):
m.AdditionalServices.objects.create(
name="Service",
price=100,
description="Description",
dealer=self.dealer,
taxable=True,
uom=m.UnitOfMeasure.PIECE,
)
self.assertEqual(
m.ItemModel.objects.filter(
name="Service",
default_amount=100,
is_product_or_service=True,
item_role="service",
).count(),
1,
)
class AuthenticationTest(TestCase):
"""
Represents a set of test cases for user authentication and signup validation within
a web application. These tests ensure the correctness of authentication functionalities
such as login and signing up with appropriate JSON data handling.
:ivar client: Django test client used to simulate HTTP requests within the test framework.
:type client: Client
:ivar url: URL for account signup endpoint used in the test cases.
:type url: str
"""
def setUp(self):
self.client = Client()
self.url = reverse("account_signup")
def test_login(self):
url = reverse("account_login")
response = self.client.post(
url, {"email": "RkzgO@example.com", "password": "password"}
)
self.assertEqual(response.status_code, 200)
def test_valid_data(self):
# Create valid JSON data
data = {
"wizardValidationForm1": {
"email": "test@example.com",
"password": "password123",
"confirm_password": "password123",
},
"wizardValidationForm2": {
"name": "John Doe",
"arabic_name": "جون دو",
"phone_number": "1234567890",
},
"wizardValidationForm3": {
"crn": "123456",
"vrn": "789012",
"address": "123 Main St",
},
}
# Send a POST request with the JSON data
response = self.client.post(
self.url, data=json.dumps(data), content_type="application/json"
)
# Check the response
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json(), {"message": "User created successfully."})
def test_passwords_do_not_match(self):
# Create JSON data with mismatched passwords
data = {
"wizardValidationForm1": {
"email": "test@example.com",
"password": "password123",
"confirm_password": "differentpassword",
},
"wizardValidationForm2": {
"name": "John Doe",
"arabic_name": "جون دو",
"phone_number": "1234567890",
},
"wizardValidationForm3": {
"crn": "123456",
"vrn": "789012",
"address": "123 Main St",
},
}
# Send a POST request with the JSON data
response = self.client.post(
self.url, data=json.dumps(data), content_type="application/json"
)
# Check the response
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {"error": "Passwords do not match."})
def test_missing_required_fields(self):
# Create JSON data with missing required fields
data = {
"wizardValidationForm1": {
"email": "test@example.com",
"password": "password123",
# Missing "confirm_password"
},
"wizardValidationForm2": {
"name": "John Doe",
"arabic_name": "جون دو",
"phone_number": "1234567890",
},
"wizardValidationForm3": {
"crn": "123456",
"vrn": "789012",
"address": "123 Main St",
},
}
# Send a POST request with the JSON data
response = self.client.post(
self.url, data=json.dumps(data), content_type="application/json"
)
# Check the response
self.assertEqual(response.status_code, 400)
self.assertIn(
"error", response.json()
) # Assuming the view returns an error for missing fields
# class CarFinanceCalculatorTests(TestCase):
# """
# Unit tests for the CarFinanceCalculator class.
# This class contains various test cases to validate the correct functionality
# of the CarFinanceCalculator. It includes tests for VAT rate retrieval,
# item transactions, car data extraction, calculation of totals, fetching
# additional services, and finance-related data processing.
# :ivar mock_model: Mocked model used to simulate interactions with the
# CarFinanceCalculator instance.
# :type mock_model: unittest.mock.MagicMock
# :ivar vat_rate: Active VAT rate used for testing VAT rate retrieval.
# :type vat_rate: VatRate
# """
# def setUp(self):
# # Common setup for all tests
# self.mock_model = MagicMock()
# self.vat_rate = VatRate.objects.create(rate=Decimal("0.20"), is_active=True)
# def test_no_active_vat_rate_raises_error(self):
# VatRate.objects.all().delete() # Ensure no active VAT
# with self.assertRaises(ObjectDoesNotExist):
# CarFinanceCalculator(self.mock_model)
# def test_vat_rate_retrieval(self):
# calculator = CarFinanceCalculator(self.mock_model)
# self.assertEqual(calculator.vat_rate, Decimal("0.20"))
# def test_item_transactions_retrieval(self):
# mock_item = MagicMock()
# self.mock_model.get_itemtxs_data.return_value = [
# MagicMock(all=lambda: [mock_item])
# ]
# calculator = CarFinanceCalculator(self.mock_model)
# self.assertEqual(calculator.item_transactions, [mock_item])
# def test_get_car_data(self):
# mock_item = MagicMock()
# mock_item.ce_quantity = 2
# mock_item.item_model = MagicMock()
# mock_item.item_model.item_number = "123"
# mock_item.item_model.additional_info = {
# CarFinanceCalculator.CAR_FINANCE_KEY: {
# "selling_price": "10000",
# "cost_price": "8000",
# "discount_amount": "500",
# "total_vat": "2000",
# },
# CarFinanceCalculator.CAR_INFO_KEY: {
# "vin": "VIN123",
# "make": "Toyota",
# "model": "Camry",
# "year": 2020,
# "trim": "LE",
# "mileage": 15000,
# },
# CarFinanceCalculator.ADDITIONAL_SERVICES_KEY: [
# {"name": "Service 1", "price": "200", "taxable": True, "price_": "240"}
# ],
# }
# calculator = CarFinanceCalculator(self.mock_model)
# car_data = calculator._get_car_data(mock_item)
# self.assertEqual(car_data["item_number"], "123")
# self.assertEqual(car_data["vin"], "VIN123")
# self.assertEqual(car_data["make"], "Toyota")
# self.assertEqual(car_data["selling_price"], "10000")
# self.assertEqual(car_data["unit_price"], Decimal("10000"))
# self.assertEqual(car_data["quantity"], 2)
# self.assertEqual(car_data["total"], Decimal("20000"))
# self.assertEqual(car_data["total_vat"], "2000")
# self.assertEqual(
# car_data["additional_services"],
# [{"name": "Service 1", "price": "200", "taxable": True, "price_": "240"}],
# )
# def test_get_additional_services(self):
# mock_item1 = MagicMock()
# mock_item1.item_model.additional_info = {
# CarFinanceCalculator.ADDITIONAL_SERVICES_KEY: [
# {"name": "Service 1", "price": "100", "taxable": True, "price_": "120"}
# ]
# }
# mock_item2 = MagicMock()
# mock_item2.item_model.additional_info = {
# CarFinanceCalculator.ADDITIONAL_SERVICES_KEY: [
# {"name": "Service 2", "price": "200", "taxable": False, "price_": "200"}
# ]
# }
# self.mock_model.get_itemtxs_data.return_value = [
# MagicMock(all=lambda: [mock_item1, mock_item2])
# ]
# calculator = CarFinanceCalculator(self.mock_model)
# services = calculator._get_additional_services()
# self.assertEqual(len(services), 2)
# self.assertEqual(services[0]["name"], "Service 1")
# self.assertEqual(services[1]["name"], "Service 2")
# self.assertEqual(services[0]["price_"], "120")
# self.assertEqual(services[1]["price_"], "200")
# def test_calculate_totals(self):
# mock_item1 = MagicMock()
# mock_item1.ce_quantity = 2
# mock_item1.item_model.additional_info = {
# CarFinanceCalculator.CAR_FINANCE_KEY: {
# "selling_price": "10000",
# "discount_amount": "500",
# },
# CarFinanceCalculator.ADDITIONAL_SERVICES_KEY: [
# {"price_": "100"},
# {"price_": "200"},
# ],
# }
# mock_item2 = MagicMock()
# mock_item2.quantity = 3
# mock_item2.item_model.additional_info = {
# CarFinanceCalculator.CAR_FINANCE_KEY: {
# "selling_price": "20000",
# "discount_amount": "1000",
# },
# CarFinanceCalculator.ADDITIONAL_SERVICES_KEY: [{"price_": "300"}],
# }
# self.mock_model.get_itemtxs_data.return_value = [
# MagicMock(all=lambda: [mock_item1, mock_item2])
# ]
# calculator = CarFinanceCalculator(self.mock_model)
# totals = calculator.calculate_totals()
# expected_total_price = (Decimal("10000") * 2 + Decimal("20000") * 3) - (
# Decimal("500") + Decimal("1000")
# )
# expected_vat = expected_total_price * Decimal("0.15")
# expected_additionals = Decimal("100") + Decimal("200") + Decimal("300")
# expected_grand_total = (
# expected_total_price + expected_vat + expected_additionals
# ).quantize(Decimal("0.00"))
# self.assertEqual(totals["total_price"], expected_total_price)
# self.assertEqual(totals["total_discount"], Decimal("1500"))
# self.assertEqual(totals["total_vat_amount"], expected_vat)
# self.assertEqual(totals["total_additionals"], expected_additionals)
# self.assertEqual(totals["grand_total"], expected_grand_total)
# def test_get_finance_data(self):
# mock_item = MagicMock()
# mock_item.ce_quantity = 1
# mock_item.item_model = MagicMock()
# mock_item.item_model.item_number = "456"
# mock_item.item_model.additional_info = {
# CarFinanceCalculator.CAR_FINANCE_KEY: {
# "selling_price": "15000",
# "discount_amount": "1000",
# "total_vat": "2800",
# },
# CarFinanceCalculator.CAR_INFO_KEY: {
# "vin": "VIN456",
# "make": "Honda",
# "model": "Civic",
# "year": 2021,
# },
# CarFinanceCalculator.ADDITIONAL_SERVICES_KEY: [
# {"name": "Service", "price": "150", "taxable": True, "price_": "180"}
# ],
# }
# self.mock_model.get_itemtxs_data.return_value = [
# MagicMock(all=lambda: [mock_item])
# ]
# calculator = CarFinanceCalculator(self.mock_model)
# finance_data = calculator.get_finance_data()
# self.assertEqual(len(finance_data["cars"]), 1)
# self.assertEqual(finance_data["quantity"], 1)
# self.assertEqual(finance_data["total_price"], Decimal("14000")) # 15000 - 1000
# self.assertEqual(
# finance_data["total_vat"],
# Decimal("14000") + (Decimal("14000") * Decimal("0.20")),
# )
# self.assertEqual(
# finance_data["total_vat_amount"], Decimal("14000") * Decimal("0.20")
# )
# self.assertEqual(finance_data["total_additionals"], Decimal("180"))
# self.assertEqual(finance_data["additionals"][0]["name"], "Service")
# self.assertEqual(finance_data["vat"], Decimal("0.20"))