php-commerce/tests/Feature/CurrencyServiceTest.php
Snider a774f4e285 refactor: migrate namespace from Core\Commerce to Core\Mod\Commerce
Align commerce module with the monorepo module structure by updating
all namespaces to use the Core\Mod\Commerce convention. This change
supports the recent monorepo separation and ensures consistency with
other modules.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 16:23:12 +00:00

197 lines
5.8 KiB
PHP

<?php
declare(strict_types=1);
namespace Core\Mod\Commerce\Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Core\Mod\Commerce\Models\ExchangeRate;
use Core\Mod\Commerce\Services\CurrencyService;
use Tests\TestCase;
class CurrencyServiceTest extends TestCase
{
use RefreshDatabase;
protected CurrencyService $service;
protected function setUp(): void
{
parent::setUp();
$this->service = app(CurrencyService::class);
}
public function test_get_base_currency_returns_configured_currency(): void
{
config(['commerce.currencies.base' => 'GBP']);
$this->assertEquals('GBP', $this->service->getBaseCurrency());
}
public function test_is_supported_returns_true_for_supported_currencies(): void
{
$this->assertTrue($this->service->isSupported('GBP'));
$this->assertTrue($this->service->isSupported('USD'));
$this->assertTrue($this->service->isSupported('EUR'));
}
public function test_is_supported_returns_false_for_unsupported_currencies(): void
{
$this->assertFalse($this->service->isSupported('XYZ'));
$this->assertFalse($this->service->isSupported('BTC'));
}
public function test_format_formats_gbp_correctly(): void
{
$formatted = $this->service->format(99.99, 'GBP');
$this->assertEquals('£99.99', $formatted);
}
public function test_format_formats_usd_correctly(): void
{
$formatted = $this->service->format(99.99, 'USD');
$this->assertEquals('$99.99', $formatted);
}
public function test_format_formats_eur_correctly(): void
{
$formatted = $this->service->format(99.99, 'EUR');
// EUR uses space as thousands separator and comma as decimal
$this->assertEquals('€99,99', $formatted);
}
public function test_format_handles_cents(): void
{
$formatted = $this->service->format(9999, 'GBP', isCents: true);
$this->assertEquals('£99.99', $formatted);
}
public function test_format_handles_large_numbers(): void
{
$formatted = $this->service->format(1234567.89, 'GBP');
$this->assertEquals('£1,234,567.89', $formatted);
}
public function test_get_symbol_returns_correct_symbols(): void
{
$this->assertEquals('£', $this->service->getSymbol('GBP'));
$this->assertEquals('$', $this->service->getSymbol('USD'));
$this->assertEquals('€', $this->service->getSymbol('EUR'));
$this->assertEquals('A$', $this->service->getSymbol('AUD'));
}
public function test_exchange_rate_model_stores_and_retrieves_rates(): void
{
ExchangeRate::storeRate('GBP', 'USD', 1.27, 'test');
$rate = ExchangeRate::getRate('GBP', 'USD');
$this->assertEquals(1.27, $rate);
}
public function test_exchange_rate_converts_amounts(): void
{
ExchangeRate::storeRate('GBP', 'USD', 1.27, 'test');
$converted = ExchangeRate::convert(100, 'GBP', 'USD');
$this->assertEquals(127.0, $converted);
}
public function test_exchange_rate_converts_cents(): void
{
ExchangeRate::storeRate('GBP', 'USD', 1.27, 'test');
$converted = ExchangeRate::convertCents(10000, 'GBP', 'USD');
$this->assertEquals(12700, $converted);
}
public function test_exchange_rate_same_currency_returns_one(): void
{
$rate = ExchangeRate::getRate('GBP', 'GBP');
$this->assertEquals(1.0, $rate);
}
public function test_exchange_rate_calculates_inverse(): void
{
ExchangeRate::storeRate('GBP', 'USD', 1.27, 'test');
$inverseRate = ExchangeRate::getRate('USD', 'GBP');
$this->assertEqualsWithDelta(0.7874, $inverseRate, 0.001);
}
public function test_exchange_rate_uses_fixed_fallback(): void
{
config(['commerce.currencies.exchange_rates.fixed' => [
'GBP_USD' => 1.25,
]]);
// Clear any cached rates
cache()->forget('exchange_rate:GBP:USD');
$rate = ExchangeRate::getRate('GBP', 'USD');
$this->assertEquals(1.25, $rate);
}
public function test_currency_service_convert_uses_exchange_rates(): void
{
ExchangeRate::storeRate('GBP', 'EUR', 1.17, 'test');
$converted = $this->service->convert(100, 'GBP', 'EUR');
$this->assertEquals(117.0, $converted);
}
public function test_currency_service_convert_cents(): void
{
ExchangeRate::storeRate('GBP', 'EUR', 1.17, 'test');
$converted = $this->service->convertCents(10000, 'GBP', 'EUR');
$this->assertEquals(11700, $converted);
}
public function test_set_and_get_current_currency(): void
{
$this->service->setCurrentCurrency('USD');
$this->assertEquals('USD', $this->service->getCurrentCurrency());
}
public function test_set_currency_rejects_unsupported(): void
{
$original = $this->service->getCurrentCurrency();
$this->service->setCurrentCurrency('XYZ');
// Should not change from original
$this->assertEquals($original, $this->service->getCurrentCurrency());
}
public function test_get_js_data_returns_all_currencies(): void
{
ExchangeRate::storeRate('GBP', 'USD', 1.27, 'test');
ExchangeRate::storeRate('GBP', 'EUR', 1.17, 'test');
$data = $this->service->getJsData();
$this->assertArrayHasKey('base', $data);
$this->assertArrayHasKey('current', $data);
$this->assertArrayHasKey('currencies', $data);
$this->assertEquals('GBP', $data['base']);
$this->assertArrayHasKey('GBP', $data['currencies']);
$this->assertArrayHasKey('USD', $data['currencies']);
$this->assertArrayHasKey('EUR', $data['currencies']);
$this->assertEquals(1.27, $data['currencies']['USD']['rate']);
}
}