mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-01-18 14:57:00 +01:00
166 lines
8.0 KiB
Python
166 lines
8.0 KiB
Python
from django.test import TestCase
|
|
from django.contrib.auth.models import User
|
|
from django.utils import timezone
|
|
from unittest.mock import patch
|
|
from decimal import Decimal
|
|
from datetime import date
|
|
from django.test import Client # Added
|
|
from django.urls import reverse # Added
|
|
|
|
from apps.currencies.models import Currency, ExchangeRate
|
|
from apps.mini_tools.utils.exchange_rate_map import get_currency_exchange_map
|
|
|
|
class MiniToolsUtilsTests(TestCase):
|
|
def setUp(self):
|
|
# User is not strictly necessary for this utility but good practice for test setup
|
|
self.user = User.objects.create_user(username='testuser', password='password')
|
|
|
|
self.usd = Currency.objects.create(name="US Dollar", code="USD", decimal_places=2, prefix="$")
|
|
self.eur = Currency.objects.create(name="Euro", code="EUR", decimal_places=2, prefix="€")
|
|
self.gbp = Currency.objects.create(name="British Pound", code="GBP", decimal_places=2, prefix="£")
|
|
|
|
# USD -> EUR rates
|
|
# Rate for 2023-01-10 (will be processed last for USD->EUR due to ordering)
|
|
ExchangeRate.objects.create(from_currency=self.usd, to_currency=self.eur, rate=Decimal("0.90"), date=date(2023, 1, 10))
|
|
# Rate for 2023-01-15 (closer to target_date 2023-01-16, processed first for USD->EUR)
|
|
ExchangeRate.objects.create(from_currency=self.usd, to_currency=self.eur, rate=Decimal("0.92"), date=date(2023, 1, 15))
|
|
|
|
# GBP -> USD rate
|
|
self.gbp_usd_rate = ExchangeRate.objects.create(from_currency=self.gbp, to_currency=self.usd, rate=Decimal("1.25"), date=date(2023, 1, 12))
|
|
|
|
def test_get_currency_exchange_map_structure_and_rates(self):
|
|
target_date = date(2023, 1, 16)
|
|
rate_map = get_currency_exchange_map(date=target_date)
|
|
|
|
# Assert USD in map
|
|
self.assertIn("US Dollar", rate_map)
|
|
usd_data = rate_map["US Dollar"]
|
|
self.assertEqual(usd_data["decimal_places"], 2)
|
|
self.assertEqual(usd_data["prefix"], "$")
|
|
self.assertIn("rates", usd_data)
|
|
|
|
# USD -> EUR: Expecting rate from 2023-01-10 (0.90)
|
|
# Query order: (USD,EUR,2023-01-15), (USD,EUR,2023-01-10)
|
|
# Loop overwrite means the last one processed (0.90) sticks.
|
|
self.assertIn("Euro", usd_data["rates"])
|
|
self.assertEqual(usd_data["rates"]["Euro"]["rate"], Decimal("0.90"))
|
|
|
|
# USD -> GBP: Inverse of GBP->USD rate from 2023-01-12 (1.25)
|
|
# Query for GBP->USD, date 2023-01-12, diff 4 days.
|
|
self.assertIn("British Pound", usd_data["rates"])
|
|
self.assertEqual(usd_data["rates"]["British Pound"]["rate"], Decimal("1") / self.gbp_usd_rate.rate)
|
|
|
|
# Assert EUR in map
|
|
self.assertIn("Euro", rate_map)
|
|
eur_data = rate_map["Euro"]
|
|
self.assertEqual(eur_data["decimal_places"], 2)
|
|
self.assertEqual(eur_data["prefix"], "€")
|
|
self.assertIn("rates", eur_data)
|
|
|
|
# EUR -> USD: Inverse of USD->EUR rate from 2023-01-10 (0.90)
|
|
self.assertIn("US Dollar", eur_data["rates"])
|
|
self.assertEqual(eur_data["rates"]["US Dollar"]["rate"], Decimal("1") / Decimal("0.90"))
|
|
|
|
# Assert GBP in map
|
|
self.assertIn("British Pound", rate_map)
|
|
gbp_data = rate_map["British Pound"]
|
|
self.assertEqual(gbp_data["decimal_places"], 2)
|
|
self.assertEqual(gbp_data["prefix"], "£")
|
|
self.assertIn("rates", gbp_data)
|
|
|
|
# GBP -> USD: Direct rate from 2023-01-12 (1.25)
|
|
self.assertIn("US Dollar", gbp_data["rates"])
|
|
self.assertEqual(gbp_data["rates"]["US Dollar"]["rate"], self.gbp_usd_rate.rate)
|
|
|
|
@patch('apps.mini_tools.utils.exchange_rate_map.timezone')
|
|
def test_get_currency_exchange_map_uses_today_if_no_date(self, mock_django_timezone):
|
|
# Mock timezone.localtime().date() to return a specific date
|
|
mock_today = date(2023, 1, 16)
|
|
mock_django_timezone.localtime.return_value.date.return_value = mock_today
|
|
|
|
rate_map = get_currency_exchange_map() # No date argument, should use mocked "today"
|
|
|
|
# Re-assert one key rate to confirm the mocked date was used.
|
|
# Based on test_get_currency_exchange_map_structure_and_rates, with target_date 2023-01-16,
|
|
# USD -> EUR should be 0.90.
|
|
self.assertIn("US Dollar", rate_map)
|
|
self.assertIn("Euro", rate_map["US Dollar"]["rates"])
|
|
self.assertEqual(rate_map["US Dollar"]["rates"]["Euro"]["rate"], Decimal("0.90"))
|
|
|
|
# Verify that timezone.localtime().date() was called
|
|
mock_django_timezone.localtime.return_value.date.assert_called_once()
|
|
|
|
|
|
class MiniToolsViewTests(TestCase):
|
|
def setUp(self):
|
|
self.user = User.objects.create_user(username='viewtestuser', password='password')
|
|
self.client = Client()
|
|
self.client.login(username='viewtestuser', password='password')
|
|
|
|
self.usd = Currency.objects.create(name="US Dollar Test", code="USDTEST", decimal_places=2, prefix="$T ")
|
|
self.eur = Currency.objects.create(name="Euro Test", code="EURTEST", decimal_places=2, prefix="€T ")
|
|
|
|
@patch('apps.mini_tools.views.convert')
|
|
def test_currency_converter_convert_view_successful(self, mock_convert):
|
|
mock_convert.return_value = (Decimal("85.00"), "€T ", "", 2) # prefix, suffix, dp
|
|
|
|
get_params = {
|
|
'from_value': "100",
|
|
'from_currency': self.usd.id,
|
|
'to_currency': self.eur.id
|
|
}
|
|
response = self.client.get(reverse('mini_tools:currency_converter_convert'), data=get_params)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
mock_convert.assert_called_once()
|
|
args, kwargs = mock_convert.call_args
|
|
|
|
# The view calls: convert(amount=amount_decimal, from_currency=from_currency_obj, to_currency=to_currency_obj)
|
|
# So, these are keyword arguments.
|
|
self.assertEqual(kwargs['amount'], Decimal('100'))
|
|
self.assertEqual(kwargs['from_currency'], self.usd)
|
|
self.assertEqual(kwargs['to_currency'], self.eur)
|
|
|
|
self.assertEqual(response.context['converted_amount'], Decimal("85.00"))
|
|
self.assertEqual(response.context['prefix'], "€T ")
|
|
self.assertEqual(response.context['suffix'], "")
|
|
self.assertEqual(response.context['decimal_places'], 2)
|
|
self.assertEqual(response.context['from_value'], "100") # Check original value passed through
|
|
self.assertEqual(response.context['from_currency_selected'], str(self.usd.id))
|
|
self.assertEqual(response.context['to_currency_selected'], str(self.eur.id))
|
|
|
|
|
|
@patch('apps.mini_tools.views.convert')
|
|
def test_currency_converter_convert_view_missing_params(self, mock_convert):
|
|
get_params = {
|
|
'from_value': "100",
|
|
'from_currency': self.usd.id
|
|
# 'to_currency' is missing
|
|
}
|
|
response = self.client.get(reverse('mini_tools:currency_converter_convert'), data=get_params)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
mock_convert.assert_not_called()
|
|
self.assertIsNone(response.context.get('converted_amount')) # Use .get() for safety if key might be absent
|
|
self.assertEqual(response.context['from_value'], "100")
|
|
self.assertEqual(response.context['from_currency_selected'], str(self.usd.id))
|
|
self.assertIsNone(response.context.get('to_currency_selected'))
|
|
|
|
|
|
@patch('apps.mini_tools.views.convert')
|
|
def test_currency_converter_convert_view_invalid_currency_id(self, mock_convert):
|
|
get_params = {
|
|
'from_value': "100",
|
|
'from_currency': self.usd.id,
|
|
'to_currency': 999 # Non-existent currency ID
|
|
}
|
|
response = self.client.get(reverse('mini_tools:currency_converter_convert'), data=get_params)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
mock_convert.assert_not_called()
|
|
self.assertIsNone(response.context.get('converted_amount'))
|
|
self.assertEqual(response.context['from_value'], "100")
|
|
self.assertEqual(response.context['from_currency_selected'], str(self.usd.id))
|
|
self.assertEqual(response.context['to_currency_selected'], '999') # View passes invalid ID to context
|