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