001/* 002 * Copyright (c) 2012, 2013, Werner Keil, Credit Suisse (Anatole Tresch). Licensed under the Apache 003 * License, Version 2.0 (the "License"); you may not use this file except in compliance with the 004 * License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 005 * Unless required by applicable law or agreed to in writing, software distributed under the License 006 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 007 * or implied. See the License for the specific language governing permissions and limitations under 008 * the License. Contributors: Anatole Tresch - initial version. 009 */ 010package org.javamoney.tck.tests.conversion; 011 012import org.javamoney.tck.tests.internal.TestCurrencyUnit; 013import org.jboss.test.audit.annotations.SpecAssertion; 014import org.jboss.test.audit.annotations.SpecVersion; 015import org.testng.Assert; 016import org.testng.AssertJUnit; 017import org.testng.annotations.Test; 018 019import javax.money.CurrencyUnit; 020import javax.money.MonetaryCurrencies; 021import javax.money.UnknownCurrencyException; 022import javax.money.convert.*; 023import java.util.Locale; 024 025/** 026 * Tests for Exchange Rates and Rate Providers. 027 * Created by Anatole on 10.03.14. 028 */ 029@SpecVersion(spec = "JSR 354", version = "1.0.0") 030public class ExchangeRatesAndRateProvidersTest { 031 032 // *************************** A. Test Basic MonetaryConversions Accessors ********************************* 033 034 private static final CurrencyUnit FOO_UNIT = new TestCurrencyUnit("FOO"); 035 036 /** 037 * Test access to conversion rates.<p> 038 * Hint: this assertion will require multiple tests to be written! 039 */ 040 @Test(description = "4.3.3 Test access of Conversion Rates, using TCK provided rate provider.") 041 @SpecAssertion(id = "433-A1", section = "4.3.3") 042 public void testAccessKnownRates() { 043 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider("TestRateProvider"); 044 // Use test provider 045 for (CurrencyUnit base : MonetaryCurrencies.getCurrencies()) { 046 if (base.equals(FOO_UNIT)) { 047 continue; 048 } 049 ExchangeRate rate = prov.getExchangeRate(base, FOO_UNIT); 050 AssertJUnit.assertNotNull( 051 "Identity rate, accessed by getExchangeRate(CurrencyUnit, CurrencyUnit), is not defined for " + 052 base.getCurrencyCode() + " -> " + FOO_UNIT.getCurrencyCode()); 053 AssertJUnit.assertEquals(rate.getBaseCurrency().getCurrencyCode(), base.getCurrencyCode()); 054 AssertJUnit.assertEquals(rate.getCurrency().getCurrencyCode(), FOO_UNIT.getCurrencyCode()); 055 AssertJUnit.assertEquals(rate.getFactor().intValueExact(), 2); 056 } 057 } 058 059 /** 060 * Test access to conversion rates.<p> 061 * Hint: this assertion will require multiple tests to be written! 062 */ 063 @Test(description = "4.3.3 Test access to exchange rates from TestRateProvider, using target currency code.") 064 @SpecAssertion(id = "433-A1", section = "4.3.3") 065 public void testAccessKnownRatesWithCodes() { 066 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider("TestRateProvider"); 067 // Use test provider 068 for (CurrencyUnit base : MonetaryCurrencies.getCurrencies()) { 069 if (base.equals(FOO_UNIT)) { 070 continue; 071 } 072 ExchangeRate rate = prov.getExchangeRate(base.getCurrencyCode(), "XXX"); 073 AssertJUnit 074 .assertNotNull("Identity rate, accessed by getExchangeRate(String, String), is not defined for " + 075 base.getCurrencyCode() + " -> " + FOO_UNIT.getCurrencyCode(), rate); 076 AssertJUnit.assertEquals(rate.getBaseCurrency().getCurrencyCode(), base.getCurrencyCode()); 077 AssertJUnit.assertEquals(rate.getCurrency().getCurrencyCode(), "FOO"); 078 AssertJUnit.assertEquals(rate.getFactor().intValueExact(), 2); 079 } 080 } 081 082 /** 083 * Test access to conversion rates.<p> 084 * Hint: this assertion will require multiple tests to be written! 085 */ 086 @Test(description = "4.3.3 Test access to exchange rates from TestRateProvider, using target CUrrencyUnit.") 087 @SpecAssertion(id = "433-A1", section = "4.3.3") 088 public void testAccessKnownRatesAndContext() { 089 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider("TestRateProvider"); 090 // Use test provider 091 for (CurrencyUnit base : MonetaryCurrencies.getCurrencies()) { 092 if (base.equals(FOO_UNIT)) { 093 continue; 094 } 095 ExchangeRate rate = prov.getExchangeRate(base, FOO_UNIT); 096 AssertJUnit.assertNotNull( 097 "Identity rate, accessed by getExchangeRate(CurrencyUnit, CurrencyUnit, ConversionContext), " + 098 "is not defined for " + 099 base.getCurrencyCode() + " -> " + FOO_UNIT.getCurrencyCode()); 100 AssertJUnit.assertEquals(rate.getBaseCurrency().getCurrencyCode(), base.getCurrencyCode()); 101 AssertJUnit.assertEquals(rate.getCurrency().getCurrencyCode(), FOO_UNIT.getCurrencyCode()); 102 AssertJUnit.assertEquals(rate.getFactor().intValueExact(), 2); 103 } 104 } 105 106 /** 107 * Test access to conversion rates.<p> 108 * Hint: this assertion will require multiple tests to be written! 109 */ 110 @Test(description = "4.3.3 Test access to conversion rates, including known factor, using TestRateProvider.") 111 @SpecAssertion(id = "433-A1", section = "4.3.3") 112 public void testAccessKnownRatesWithCodesAndContext() { 113 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider("TestRateProvider"); 114 // Use test provider 115 for (CurrencyUnit base : MonetaryCurrencies.getCurrencies()) { 116 ExchangeRate rate = prov.getExchangeRate(base, FOO_UNIT); 117 AssertJUnit 118 .assertNotNull("Identity rate, accessed by getExchangeRate(String, String, ConversionContext), " + 119 "is not defined for " + 120 base.getCurrencyCode() + " -> " + FOO_UNIT.getCurrencyCode(), rate); 121 AssertJUnit.assertEquals(rate.getBaseCurrency().getCurrencyCode(), base.getCurrencyCode()); 122 AssertJUnit.assertEquals(rate.getCurrency().getCurrencyCode(), FOO_UNIT.getCurrencyCode()); 123 AssertJUnit.assertEquals(rate.getFactor().intValueExact(), 2); 124 } 125 } 126 127 /** 128 * Test access to conversion rates.<p> 129 * Hint: this assertion will require multiple tests to be written! 130 */ 131 @Test(description = "4.3.3 Test access to identity conversion rate for CurrencyUnits, using default provider") 132 @SpecAssertion(id = "433-A1", section = "4.3.3") 133 public void testAccessRates_IdentityRatesWithUnits() { 134 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider(); // Use default provider 135 for (CurrencyUnit unit : MonetaryCurrencies.getCurrencies()) { 136 ExchangeRate rate = prov.getExchangeRate(unit, unit); 137 AssertJUnit.assertNotNull( 138 "Identity rate, accessed by getExchangeRate(CurrencyUnit, CurrencyUnit), is not defined for " + 139 unit.getCurrencyCode()); 140 } 141 } 142 143 /** 144 * Test access to conversion rates.<p> 145 * Hint: this assertion will require multiple tests to be written! 146 */ 147 @Test(description = "4.3.3 Test access to conversion rate for currency codes, using default provider.") 148 @SpecAssertion(id = "433-A1", section = "4.3.3") 149 public void testAccessRates_IdentityRatesWithCodes() { 150 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider(); // Use default provider 151 for (CurrencyUnit unit : MonetaryCurrencies.getCurrencies()) { 152 ExchangeRate rate = prov.getExchangeRate(unit.getCurrencyCode(), unit.getCurrencyCode()); 153 AssertJUnit.assertNotNull( 154 "Identity rate, accessed by getExchangeRate(String, String), is not defined for " + 155 unit.getCurrencyCode()); 156 } 157 } 158 159 /** 160 * Test access to conversion rates.<p> 161 * Hint: this assertion will require multiple tests to be written! 162 */ 163 @Test(description = "4.3.3 Test access to conversion rate for CurrencyQuery, using default provider.") 164 @SpecAssertion(id = "433-A1", section = "4.3.3") 165 public void testAccessRates_IdentityRatesWithUnitsAndContext() { 166 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider(); // Use default provider 167 for (CurrencyUnit unit : MonetaryCurrencies.getCurrencies()) { 168 ExchangeRate rate = prov.getExchangeRate( 169 ConversionQueryBuilder.of().setBaseCurrency(unit).setTermCurrency(unit).build()); 170 AssertJUnit.assertNotNull("Identity rate, accessed by getExchangeRate(ConversionQuery), " + 171 "is not defined for " + 172 unit.getCurrencyCode()); 173 } 174 } 175 176 /** 177 * Ensure additional ConversionContext is passed correctly to SPIs.<p> 178 * Hint: this assertion will require some custom SPIs to be registered and selected for chain inclusion! 179 */ 180 @Test(description = "4.3.3 Ensure additional ConversionQuery data is passed correctly to SPIs.") 181 @SpecAssertion(id = "433-A2", section = "4.3.3") 182 public void testPassingOverConversionContextToSPIs() { 183 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider("TestRateProvider"); 184 ConversionQuery ctx = ConversionQueryBuilder.of().set(Locale.CANADA).set("Foo", "bar").setBaseCurrency(FOO_UNIT) 185 .setTermCurrency(MonetaryCurrencies.getCurrency("XXX")).build(); 186 ExchangeRate rate = prov.getExchangeRate(ctx); 187 AssertJUnit.assertNotNull("No test rate returned by getExchangeRate(ConversionQuery), " + 188 "probably TestProvider is not correct registered."); 189 AssertJUnit.assertEquals( 190 "Text parameter Locale.class was not correctly passed to ExchangeRateProvider implementation.", "bar", 191 rate.getContext().getText("Foo")); 192 AssertJUnit.assertEquals( 193 "Object parameter Locale.class was not correctly passed to ExchangeRateProvider implementation.", 194 Locale.CANADA, rate.getContext().get(Locale.class)); 195 } 196 197 198 /** 199 * Bad case: try accessing rates with inconsistent/invalid data.<p> 200 * Hint: this assertion will require multiple tests to be written! 201 */ 202 @Test(description = "4.3.3 Bad case: try accessing exchange rates with invalid base currency code.") 203 @SpecAssertion(id = "433-A3", section = "4.3.3") 204 public void testInvalidUsage_InvalidSourceCurrency() { 205 for (String providerID : MonetaryConversions.getProviderNames()) { 206 if ("TestRateProvider".equals(providerID)) { 207 continue; 208 } 209 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider(providerID); 210 try { 211 prov.getExchangeRate("dhdjbdjd", "CHF"); 212 Assert.fail( 213 "ExchangeRateProvider should throw UnknownCurrencyException when an invalid source currency " + 214 "is passed to getExchangeRate(String,String), provider: " + 215 providerID); 216 } catch (UnknownCurrencyException e) { 217 // OK 218 } 219 } 220 } 221 222 /** 223 * Bad case: try accessing rates with inconsistent/invalid data.<p> 224 * Hint: this assertion will require multiple tests to be written! 225 */ 226 @Test(description = "4.3.3 Bad case: try accessing exchange rates with null base currency code.") 227 @SpecAssertion(id = "433-A3", section = "4.3.3") 228 public void testInvalidUsage_NullSourceCurrency() { 229 for (String providerID : MonetaryConversions.getProviderNames()) { 230 if ("TestRateProvider".equals(providerID)) { 231 continue; 232 } 233 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider(providerID); 234 try { 235 prov.getExchangeRate(null, "CHF"); 236 Assert.fail("ExchangeRateProvider should throw NullPointerException when an null source currency " + 237 "is passed to getExchangeRate(String,String), provider: " + 238 providerID); 239 } catch (NullPointerException e) { 240 // OK 241 } 242 } 243 } 244 245 /** 246 * Bad case: try accessing rates with inconsistent/invalid data.<p> 247 * Hint: this assertion will require multiple tests to be written! 248 */ 249 @Test(description = "4.3.3 Bad case: try accessing exchange rates with invalid term currency code.") 250 @SpecAssertion(id = "433-A3", section = "4.3.3") 251 public void testInvalidUsage_InvalidTargetCurrency() { 252 for (String providerID : MonetaryConversions.getProviderNames()) { 253 if ("TestRateProvider".equals(providerID)) { 254 continue; 255 } 256 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider(providerID); 257 try { 258 prov.getExchangeRate("CHF", "dhdjbdjd"); 259 Assert.fail( 260 "ExchangeRateProvider should throw UnknownCurrencyException when an invalid target currency " + 261 "is passed to getExchangeRate(String,String), provider: " + 262 providerID); 263 } catch (UnknownCurrencyException e) { 264 // OK 265 } 266 } 267 } 268 269 /** 270 * Bad case: try accessing rates with inconsistent/invalid data.<p> 271 * Hint: this assertion will require multiple tests to be written! 272 */ 273 @Test(description = "4.3.3 Bad case: try accessing exchange rates with null term currency code.") 274 @SpecAssertion(id = "433-A3", section = "4.3.3") 275 public void testInvalidUsage_NullTargetCurrency() { 276 for (String providerID : MonetaryConversions.getProviderNames()) { 277 if ("TestRateProvider".equals(providerID)) { 278 continue; 279 } 280 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider(providerID); 281 try { 282 prov.getExchangeRate("CHF", null); 283 Assert.fail("ExchangeRateProvider should throw NullPointerException when an null target currency " + 284 "is passed to getExchangeRate(String,String), provider: " + 285 providerID); 286 } catch (NullPointerException e) { 287 // OK 288 } 289 } 290 } 291 292 /** 293 * Bad case: try accessing rates with inconsistent/invalid data.<p> 294 * Hint: this assertion will require multiple tests to be written! 295 */ 296 @Test(description = "4.3.3 Bad case: try accessing exchange rates with null ConversionQuery.") 297 @SpecAssertion(id = "433-A3", section = "4.3.3") 298 public void testInvalidUsage_InvalidSourceCurrencyAndContext() { 299 for (String providerID : MonetaryConversions.getProviderNames()) { 300 if ("TestRateProvider".equals(providerID)) { 301 continue; 302 } 303 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider(providerID); 304 try { 305 prov.getExchangeRate((ConversionQuery) null); 306 Assert.fail("ExchangeRateProvider should throw NPE when an null ConversionQuery " + 307 "is passed to getExchangeRate(ConversionQuery), provider: " + 308 providerID); 309 } catch (NullPointerException e) { 310 // OK 311 } 312 } 313 } 314 315 316 /** 317 * Bad case: try accessing rates with inconsistent/invalid data.<p> 318 * Hint: this assertion will require multiple tests to be written! 319 */ 320 @Test(description = "4.3.3 Bad case: try accessing exchange rates with null base CurrencyUnit.") 321 @SpecAssertion(id = "433-A3", section = "4.3.3") 322 public void testInvalidUsage_NullSourceCurrencyUnit() { 323 for (String providerID : MonetaryConversions.getProviderNames()) { 324 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider(providerID); 325 try { 326 prov.getExchangeRate(null, MonetaryCurrencies.getCurrency("CHF")); 327 Assert.fail("ExchangeRateProvider should throw NullPointerException when an null source currency " + 328 "is passed to getExchangeRate(CurrencyUnit,CurrencyUnit), provider: " + 329 providerID); 330 } catch (NullPointerException e) { 331 // OK 332 } 333 } 334 } 335 336 /** 337 * Bad case: try accessing rates with inconsistent/invalid data.<p> 338 * Hint: this assertion will require multiple tests to be written! 339 */ 340 @Test(description = "4.3.3 Bad case: try accessing exchange rates with null term CurrencyUnit.") 341 @SpecAssertion(id = "433-A3", section = "4.3.3") 342 public void testInvalidUsage_NullTargetCurrencyUnit() { 343 for (String providerID : MonetaryConversions.getProviderNames()) { 344 ExchangeRateProvider prov = MonetaryConversions.getExchangeRateProvider(providerID); 345 try { 346 prov.getExchangeRate(MonetaryCurrencies.getCurrency("CHF"), null); 347 Assert.fail("ExchangeRateProvider should throw NullPointerException when an invalid target currency " + 348 "is passed to getExchangeRate(CurrencyUnit,CurrencyUnit), provider: " + 349 providerID); 350 } catch (NullPointerException e) { 351 // OK 352 } 353 } 354 } 355 356}