CurrencyConverterTests.cs
2,160 bytes
| 1 | using SplitApp.Modules.Expenses.Application; |
|---|---|
| 2 | |
| 3 | namespace SplitApp.Modules.Expenses.Tests; |
| 4 | |
| 5 | public class CurrencyConverterTests |
| 6 | { |
| 7 | [Fact] |
| 8 | public void Convert_SameCurrency_ReturnsAmountUnchanged() |
| 9 | { |
| 10 | Assert.Equal(100m, CurrencyConverter.Convert(100m, "EUR", "EUR")); |
| 11 | } |
| 12 | |
| 13 | [Theory] |
| 14 | [InlineData(100, "USD", "EUR", 92.0)] |
| 15 | [InlineData(100, "EUR", "USD", 108.70)] |
| 16 | [InlineData(100, "GBP", "EUR", 116.0)] |
| 17 | public void Convert_KnownCurrencies_ReturnsCorrectExchange(decimal amount, string from, string to, decimal expected) |
| 18 | { |
| 19 | Assert.Equal(expected, CurrencyConverter.Convert(amount, from, to)); |
| 20 | } |
| 21 | |
| 22 | [Fact] |
| 23 | public void Convert_UnknownCurrency_FallsBackToOneToOne() |
| 24 | { |
| 25 | Assert.Equal(100m, CurrencyConverter.Convert(100m, "XYZ", "EUR")); |
| 26 | Assert.Equal(100m, CurrencyConverter.Convert(100m, "EUR", "XYZ")); |
| 27 | } |
| 28 | |
| 29 | [Fact] |
| 30 | public void Convert_ZeroAmount_ReturnsZero() |
| 31 | { |
| 32 | Assert.Equal(0m, CurrencyConverter.Convert(0m, "USD", "EUR")); |
| 33 | Assert.Equal(0m, CurrencyConverter.Convert(0m, "EUR", "EUR")); |
| 34 | } |
| 35 | |
| 36 | [Theory] |
| 37 | [InlineData(-100, "USD", "EUR", -92.0)] |
| 38 | [InlineData(-50, "EUR", "USD", -54.35)] |
| 39 | public void Convert_NegativeAmount_ConvertsLikeRefund(decimal amount, string from, string to, decimal expected) |
| 40 | { |
| 41 | Assert.Equal(expected, CurrencyConverter.Convert(amount, from, to)); |
| 42 | } |
| 43 | |
| 44 | [Fact] |
| 45 | public void Convert_ResultIsAlwaysRoundedToTwoDecimals() |
| 46 | { |
| 47 | var result = CurrencyConverter.Convert(33.337m, "USD", "EUR"); |
| 48 | var fractionalDigits = decimal.GetBits(result)[3] >> 16 & 0xFF; |
| 49 | Assert.True(fractionalDigits <= 2, $"Expected ≤2 decimal places, got {fractionalDigits} (value {result})"); |
| 50 | } |
| 51 | |
| 52 | [Fact] |
| 53 | public void Convert_RoundTrip_StaysWithinOneCentTolerance() |
| 54 | { |
| 55 | var original = 100m; |
| 56 | var toUsd = CurrencyConverter.Convert(original, "EUR", "USD"); |
| 57 | var backToEur = CurrencyConverter.Convert(toUsd, "USD", "EUR"); |
| 58 | Assert.True(Math.Abs(original - backToEur) <= 0.02m, |
| 59 | $"Round-trip lost too much precision: {original} → {toUsd} → {backToEur}"); |
| 60 | } |
| 61 | } |
| 62 | |