From 48eb8850c89cb88c275336f100b7cb589f907604 Mon Sep 17 00:00:00 2001 From: Laura Luiz Date: Thu, 19 Oct 2017 11:21:46 +0200 Subject: [PATCH 1/8] WIP Provide i18n form errors --- .../controllers/SunriseFrameworkController.java | 6 +++++- conf/i18n/de/errors.yaml | 14 ++++++++++++++ conf/i18n/en/errors.yaml | 1 + .../login/SunriseLogInController.java | 2 +- .../recover/SunriseRecoverPasswordController.java | 4 ++-- .../reset/SunriseResetPasswordController.java | 2 +- .../signup/SunriseSignUpController.java | 2 +- .../payment/SunriseCheckoutPaymentController.java | 2 +- 8 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 conf/i18n/de/errors.yaml create mode 100644 conf/i18n/en/errors.yaml diff --git a/common/app/com/commercetools/sunrise/common/controllers/SunriseFrameworkController.java b/common/app/com/commercetools/sunrise/common/controllers/SunriseFrameworkController.java index a6862321d..9a5a6a592 100644 --- a/common/app/com/commercetools/sunrise/common/controllers/SunriseFrameworkController.java +++ b/common/app/com/commercetools/sunrise/common/controllers/SunriseFrameworkController.java @@ -252,7 +252,11 @@ protected final void saveFormError(final Form form, final String message) { } protected final void saveUnexpectedFormError(final Form form, final Throwable throwable, final Logger logger) { - form.reject("Something went wrong, please try again"); // TODO i18n + form.reject(resolveError("default")); logger.error("The CTP request raised an unexpected exception", throwable); } + + protected final String resolveError(final String errorKey) { + return i18nResolver.getOrKey(userContext.locales(), I18nIdentifier.of("errors", errorKey)); + } } diff --git a/conf/i18n/de/errors.yaml b/conf/i18n/de/errors.yaml new file mode 100644 index 000000000..6c3a102e3 --- /dev/null +++ b/conf/i18n/de/errors.yaml @@ -0,0 +1,14 @@ +default: Something went wrong, please try again +checkout: + payment: + invalidPayment: Invalid payment +myAccount: + logIn: + invalidCredentials: Invalid credentials + signUp: + duplicatedEmail: A user with this email already exists + recoverPassword: + emailNotFound: Email not found + emailNotDelivered: Email could not be delivered + resetPassword: + invalidToken: Reset token is not valid diff --git a/conf/i18n/en/errors.yaml b/conf/i18n/en/errors.yaml new file mode 100644 index 000000000..17c882463 --- /dev/null +++ b/conf/i18n/en/errors.yaml @@ -0,0 +1 @@ +default: Something went wrong, please try again \ No newline at end of file diff --git a/my-account/app/com/commercetools/sunrise/myaccount/authentication/login/SunriseLogInController.java b/my-account/app/com/commercetools/sunrise/myaccount/authentication/login/SunriseLogInController.java index ac78aafe9..f3680223a 100644 --- a/my-account/app/com/commercetools/sunrise/myaccount/authentication/login/SunriseLogInController.java +++ b/my-account/app/com/commercetools/sunrise/myaccount/authentication/login/SunriseLogInController.java @@ -78,7 +78,7 @@ public CompletionStage doAction(final LogInFormD @Override public CompletionStage handleClientErrorFailedAction(final Form form, final Void context, final ClientErrorException clientErrorException) { if (isInvalidCredentialsError(clientErrorException)) { - saveFormError(form, "Invalid credentials"); // TODO i18n + saveFormError(form, resolveError("myAccount.logIn.invalidCredentials")); } else { saveUnexpectedFormError(form, clientErrorException, logger); } diff --git a/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/recover/SunriseRecoverPasswordController.java b/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/recover/SunriseRecoverPasswordController.java index 25f4335a2..f114e3da1 100755 --- a/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/recover/SunriseRecoverPasswordController.java +++ b/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/recover/SunriseRecoverPasswordController.java @@ -100,12 +100,12 @@ public CompletionStage handleClientErrorFailedAction(final Form handleNotFoundEmail(final Form form) { - saveFormError(form, "Email not found"); + saveFormError(form, resolveError("myAccount.recoverPassword.emailNotFound")); return asyncBadRequest(renderPage(form, null, null)); } protected CompletionStage handleEmailDeliveryException(final Form form, final EmailDeliveryException emailDeliveryException) { - saveFormError(form, "Email delivery error"); + saveFormError(form, resolveError("myAccount.recoverPassword.emailNotDelivered")); return asyncInternalServerError(renderPage(form, null, null)); } diff --git a/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/reset/SunriseResetPasswordController.java b/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/reset/SunriseResetPasswordController.java index 8c67ef5e6..2356324b0 100755 --- a/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/reset/SunriseResetPasswordController.java +++ b/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/reset/SunriseResetPasswordController.java @@ -88,7 +88,7 @@ public CompletionStage handleClientErrorFailedAction(final Form handleNotFoundToken(final Form form, final String resetToken) { - saveFormError(form, "Reset token is not valid"); + saveFormError(form, resolveError("myAccount.resetPassword.invalidToken")); return asyncBadRequest(renderPage(form, resetToken, null)); } diff --git a/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/SunriseSignUpController.java b/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/SunriseSignUpController.java index 66cdf6fce..c78dbeaf6 100644 --- a/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/SunriseSignUpController.java +++ b/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/SunriseSignUpController.java @@ -83,7 +83,7 @@ public CompletionStage doAction(final SignUpForm @Override public CompletionStage handleClientErrorFailedAction(final Form form, final Void context, final ClientErrorException clientErrorException) { if (isDuplicatedEmailFieldError(clientErrorException)) { - saveFormError(form, "A user with this email already exists"); // TODO i18n + saveFormError(form, resolveError("myAccount.signUp.duplicatedEmail")); } else { saveUnexpectedFormError(form, clientErrorException, logger); } diff --git a/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/payment/SunriseCheckoutPaymentController.java b/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/payment/SunriseCheckoutPaymentController.java index 95ae85fc3..4469f5e8f 100644 --- a/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/payment/SunriseCheckoutPaymentController.java +++ b/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/payment/SunriseCheckoutPaymentController.java @@ -134,7 +134,7 @@ public CompletionStage> asyncValidation( .thenApply(paymentMethods -> { final boolean isValidPaymentMethod = isValidPaymentMethod(paymentMethods, selectedPaymentMethod); if (!isValidPaymentMethod) { - filledForm.reject("Invalid payment error"); // TODO get from i18n + filledForm.reject(resolveError("checkout.payment.invalidPayment")); } return filledForm; }); From 25429f4dd6bdbc50257a1eb6a60c144ab5c0f95f Mon Sep 17 00:00:00 2001 From: Laura Luiz Date: Thu, 19 Oct 2017 14:57:02 +0200 Subject: [PATCH 2/8] Fix test --- conf/application.conf | 2 +- conf/i18n/en/errors.yaml | 15 ++++++++++++++- .../RecoverPasswordControllerIntegrationTest.java | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/conf/application.conf b/conf/application.conf index 11c6ab50f..9e6d96c63 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -220,7 +220,7 @@ application.currencies = ${?CURRENCIES} application.i18n.languages = ${?LANGUAGES} # List of i18n bundles to load. -application.i18n.bundles = ["sunrise", "main", "banner", "catalog", "checkout", "my-account-login", "my-account"] +application.i18n.bundles = ["sunrise", "main", "banner", "catalog", "checkout", "my-account-login", "my-account", "errors"] # If you want to change the way i18n messages are resolved, you can change the list of resolver loaders you want to use. # Keep in mind that the list order determines the order in which the resolvers are going to be invoked for each message. diff --git a/conf/i18n/en/errors.yaml b/conf/i18n/en/errors.yaml index 17c882463..6c3a102e3 100644 --- a/conf/i18n/en/errors.yaml +++ b/conf/i18n/en/errors.yaml @@ -1 +1,14 @@ -default: Something went wrong, please try again \ No newline at end of file +default: Something went wrong, please try again +checkout: + payment: + invalidPayment: Invalid payment +myAccount: + logIn: + invalidCredentials: Invalid credentials + signUp: + duplicatedEmail: A user with this email already exists + recoverPassword: + emailNotFound: Email not found + emailNotDelivered: Email could not be delivered + resetPassword: + invalidToken: Reset token is not valid diff --git a/it/demo/myaccount/RecoverPasswordControllerIntegrationTest.java b/it/demo/myaccount/RecoverPasswordControllerIntegrationTest.java index 0b4f8a0d7..33ed162c8 100755 --- a/it/demo/myaccount/RecoverPasswordControllerIntegrationTest.java +++ b/it/demo/myaccount/RecoverPasswordControllerIntegrationTest.java @@ -119,7 +119,7 @@ public void showsErrorOnEmailDeliveryException() throws Exception { .bodyForm(singletonMap("email", email))); assertThat(result.status()).isEqualTo(INTERNAL_SERVER_ERROR); - assertThat(contentAsString(result)).contains("Email delivery error"); + assertThat(contentAsString(result)).contains("Email could not be delivered"); return customerSignInResult.getCustomer(); }); From 982159c6a83fc12463c9e1cad8a7d7b0609e419f Mon Sep 17 00:00:00 2001 From: Laura Luiz Date: Thu, 19 Oct 2017 16:22:51 +0200 Subject: [PATCH 3/8] Change to messages file to add more cases --- .../SunriseFrameworkController.java | 6 +---- conf/application.conf | 2 +- conf/i18n/de/{errors.yaml => messages.yaml} | 0 conf/i18n/en/errors.yaml | 14 ----------- conf/i18n/en/messages.yaml | 24 +++++++++++++++++++ .../DefaultAddressBookAddressFormData.java | 2 +- .../login/SunriseLogInController.java | 2 +- .../SunriseRecoverPasswordController.java | 6 ++--- .../reset/SunriseResetPasswordController.java | 2 +- .../signup/DefaultSignUpFormData.java | 4 ++-- .../signup/SunriseSignUpController.java | 2 +- .../DefaultCheckoutAddressFormData.java | 4 ++-- .../DefaultCheckoutConfirmationFormData.java | 2 +- .../SunriseCheckoutPaymentController.java | 2 +- 14 files changed, 39 insertions(+), 33 deletions(-) rename conf/i18n/de/{errors.yaml => messages.yaml} (100%) delete mode 100644 conf/i18n/en/errors.yaml create mode 100644 conf/i18n/en/messages.yaml diff --git a/common/app/com/commercetools/sunrise/common/controllers/SunriseFrameworkController.java b/common/app/com/commercetools/sunrise/common/controllers/SunriseFrameworkController.java index 9a5a6a592..9df566ef3 100644 --- a/common/app/com/commercetools/sunrise/common/controllers/SunriseFrameworkController.java +++ b/common/app/com/commercetools/sunrise/common/controllers/SunriseFrameworkController.java @@ -252,11 +252,7 @@ protected final void saveFormError(final Form form, final String message) { } protected final void saveUnexpectedFormError(final Form form, final Throwable throwable, final Logger logger) { - form.reject(resolveError("default")); + form.reject("messages:defaultError"); logger.error("The CTP request raised an unexpected exception", throwable); } - - protected final String resolveError(final String errorKey) { - return i18nResolver.getOrKey(userContext.locales(), I18nIdentifier.of("errors", errorKey)); - } } diff --git a/conf/application.conf b/conf/application.conf index 9e6d96c63..06ad18a83 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -220,7 +220,7 @@ application.currencies = ${?CURRENCIES} application.i18n.languages = ${?LANGUAGES} # List of i18n bundles to load. -application.i18n.bundles = ["sunrise", "main", "banner", "catalog", "checkout", "my-account-login", "my-account", "errors"] +application.i18n.bundles = ["sunrise", "main", "banner", "catalog", "checkout", "my-account-login", "my-account", "messages"] # If you want to change the way i18n messages are resolved, you can change the list of resolver loaders you want to use. # Keep in mind that the list order determines the order in which the resolvers are going to be invoked for each message. diff --git a/conf/i18n/de/errors.yaml b/conf/i18n/de/messages.yaml similarity index 100% rename from conf/i18n/de/errors.yaml rename to conf/i18n/de/messages.yaml diff --git a/conf/i18n/en/errors.yaml b/conf/i18n/en/errors.yaml deleted file mode 100644 index 6c3a102e3..000000000 --- a/conf/i18n/en/errors.yaml +++ /dev/null @@ -1,14 +0,0 @@ -default: Something went wrong, please try again -checkout: - payment: - invalidPayment: Invalid payment -myAccount: - logIn: - invalidCredentials: Invalid credentials - signUp: - duplicatedEmail: A user with this email already exists - recoverPassword: - emailNotFound: Email not found - emailNotDelivered: Email could not be delivered - resetPassword: - invalidToken: Reset token is not valid diff --git a/conf/i18n/en/messages.yaml b/conf/i18n/en/messages.yaml new file mode 100644 index 000000000..7d5dfc46d --- /dev/null +++ b/conf/i18n/en/messages.yaml @@ -0,0 +1,24 @@ +defaultError: Something went wrong, please try again +checkout: + payment: + invalidPayment: Invalid payment + addresses: + invalidShippingCountry: Invalid shipping country + invalidBillingCountry: Invalid billing country +myAccount: + logIn: + invalidCredentials: Invalid credentials + signUp: + duplicatedEmail: A user with this email already exists + notMatchingPasswords: Not matching passwords + agreeToTerms: You must agree to terms + recoverPassword: + emailSent: A message with further instructions has been sent to your email address + emailNotFound: Email not found + emailNotDelivered: Email could not be delivered + resetPassword: + invalidToken: Reset token is not valid + addressBook: + invalidCountry: Invalid country + confirmation: + agreeToTerms: You must agree to terms diff --git a/my-account/app/com/commercetools/sunrise/myaccount/addressbook/DefaultAddressBookAddressFormData.java b/my-account/app/com/commercetools/sunrise/myaccount/addressbook/DefaultAddressBookAddressFormData.java index b430219a8..b39d81ccb 100644 --- a/my-account/app/com/commercetools/sunrise/myaccount/addressbook/DefaultAddressBookAddressFormData.java +++ b/my-account/app/com/commercetools/sunrise/myaccount/addressbook/DefaultAddressBookAddressFormData.java @@ -33,7 +33,7 @@ public DefaultAddressBookAddressFormData() { public String validate() { final CountryCode country = CountryCode.getByCode(this.country); if (country == null || country.equals(CountryCode.UNDEFINED)) { - return "Invalid country"; // TODO use i18n version + return "messages:myAccount.addressBook.invalidCountry"; } return null; } diff --git a/my-account/app/com/commercetools/sunrise/myaccount/authentication/login/SunriseLogInController.java b/my-account/app/com/commercetools/sunrise/myaccount/authentication/login/SunriseLogInController.java index f3680223a..3e793478b 100644 --- a/my-account/app/com/commercetools/sunrise/myaccount/authentication/login/SunriseLogInController.java +++ b/my-account/app/com/commercetools/sunrise/myaccount/authentication/login/SunriseLogInController.java @@ -78,7 +78,7 @@ public CompletionStage doAction(final LogInFormD @Override public CompletionStage handleClientErrorFailedAction(final Form form, final Void context, final ClientErrorException clientErrorException) { if (isInvalidCredentialsError(clientErrorException)) { - saveFormError(form, resolveError("myAccount.logIn.invalidCredentials")); + saveFormError(form, "messages:myAccount.logIn.invalidCredentials"); } else { saveUnexpectedFormError(form, clientErrorException, logger); } diff --git a/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/recover/SunriseRecoverPasswordController.java b/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/recover/SunriseRecoverPasswordController.java index f114e3da1..4945189f4 100755 --- a/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/recover/SunriseRecoverPasswordController.java +++ b/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/recover/SunriseRecoverPasswordController.java @@ -100,18 +100,18 @@ public CompletionStage handleClientErrorFailedAction(final Form handleNotFoundEmail(final Form form) { - saveFormError(form, resolveError("myAccount.recoverPassword.emailNotFound")); + saveFormError(form, "messages:myAccount.recoverPassword.emailNotFound"); return asyncBadRequest(renderPage(form, null, null)); } protected CompletionStage handleEmailDeliveryException(final Form form, final EmailDeliveryException emailDeliveryException) { - saveFormError(form, resolveError("myAccount.recoverPassword.emailNotDelivered")); + saveFormError(form, "messages:myAccount.recoverPassword.emailNotDelivered"); return asyncInternalServerError(renderPage(form, null, null)); } @Override public CompletionStage handleSuccessfulAction(final RecoverPasswordFormData formData, final Void context, final CustomerToken customerToken) { - flash("success", "A message with further instructions has been sent to your email address"); + flash("success", "messages:myAccount.recoverPassword.emailSent"); return redirectToSameForm(); } diff --git a/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/reset/SunriseResetPasswordController.java b/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/reset/SunriseResetPasswordController.java index 2356324b0..8f5fc3d24 100755 --- a/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/reset/SunriseResetPasswordController.java +++ b/my-account/app/com/commercetools/sunrise/myaccount/authentication/recoverpassword/reset/SunriseResetPasswordController.java @@ -88,7 +88,7 @@ public CompletionStage handleClientErrorFailedAction(final Form handleNotFoundToken(final Form form, final String resetToken) { - saveFormError(form, resolveError("myAccount.resetPassword.invalidToken")); + saveFormError(form, "messages:myAccount.resetPassword.invalidToken"); return asyncBadRequest(renderPage(form, resetToken, null)); } diff --git a/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/DefaultSignUpFormData.java b/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/DefaultSignUpFormData.java index 64491fb10..626a14897 100644 --- a/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/DefaultSignUpFormData.java +++ b/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/DefaultSignUpFormData.java @@ -22,10 +22,10 @@ public class DefaultSignUpFormData extends Base implements SignUpFormData { public String validate() { if (!password.equals(confirmPassword)) { - return "Not matching passwords"; // TODO use i18n version + return "messages:myAccount.signUp.notMatchingPasswords"; } if (!agreeToTerms) { - return "You must agree to terms"; // TODO use i18n version + return "messages:myAccount.signUp.agreeToTerms"; } return null; } diff --git a/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/SunriseSignUpController.java b/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/SunriseSignUpController.java index c78dbeaf6..3ea950610 100644 --- a/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/SunriseSignUpController.java +++ b/my-account/app/com/commercetools/sunrise/myaccount/authentication/signup/SunriseSignUpController.java @@ -83,7 +83,7 @@ public CompletionStage doAction(final SignUpForm @Override public CompletionStage handleClientErrorFailedAction(final Form form, final Void context, final ClientErrorException clientErrorException) { if (isDuplicatedEmailFieldError(clientErrorException)) { - saveFormError(form, resolveError("myAccount.signUp.duplicatedEmail")); + saveFormError(form, "messages:myAccount.signUp.duplicatedEmail"); } else { saveUnexpectedFormError(form, clientErrorException, logger); } diff --git a/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/address/DefaultCheckoutAddressFormData.java b/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/address/DefaultCheckoutAddressFormData.java index 3b6156c52..dc7e5243e 100644 --- a/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/address/DefaultCheckoutAddressFormData.java +++ b/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/address/DefaultCheckoutAddressFormData.java @@ -328,12 +328,12 @@ private void applyBillingAddress(final Address address) { public String validate() { final CountryCode shippingCountry = CountryCode.getByCode(countryShipping); if (shippingCountry == null || shippingCountry.equals(CountryCode.UNDEFINED)) { - return "Invalid shipping country"; // TODO use i18n version + return "messages:checkout.address.invalidShippingCountry"; } if (billingAddressDifferentToBillingAddress) { final CountryCode billingCountry = CountryCode.getByCode(countryBilling); if (billingCountry == null || billingCountry.equals(CountryCode.UNDEFINED)) { - return "Invalid billing country"; // TODO use i18n version + return "messages:checkout.address.invalidBillingCountry"; } } return null; diff --git a/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/confirmation/DefaultCheckoutConfirmationFormData.java b/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/confirmation/DefaultCheckoutConfirmationFormData.java index 6c5733f8f..6281d4fcf 100644 --- a/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/confirmation/DefaultCheckoutConfirmationFormData.java +++ b/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/confirmation/DefaultCheckoutConfirmationFormData.java @@ -12,7 +12,7 @@ public DefaultCheckoutConfirmationFormData() { public String validate() { // TODO Enable back once theme is adapted // if (!agreeTerms) { -// return "You must agree to terms"; // TODO use i18n version +// return "messages:checkout.confirmation.agreeToTerms"; // } return null; } diff --git a/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/payment/SunriseCheckoutPaymentController.java b/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/payment/SunriseCheckoutPaymentController.java index 4469f5e8f..deaf73d97 100644 --- a/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/payment/SunriseCheckoutPaymentController.java +++ b/shopping-cart/app/com/commercetools/sunrise/shoppingcart/checkout/payment/SunriseCheckoutPaymentController.java @@ -134,7 +134,7 @@ public CompletionStage> asyncValidation( .thenApply(paymentMethods -> { final boolean isValidPaymentMethod = isValidPaymentMethod(paymentMethods, selectedPaymentMethod); if (!isValidPaymentMethod) { - filledForm.reject(resolveError("checkout.payment.invalidPayment")); + filledForm.reject("messages:checkout.payment.invalidPayment"); } return filledForm; }); From b34ea1dbbed68019c35aaed990ed298a4bbd631e Mon Sep 17 00:00:00 2001 From: Laura Luiz Date: Tue, 24 Oct 2017 12:22:20 +0200 Subject: [PATCH 4/8] Test error formatter --- .../handlebars/PlayJavaFormResolver.java | 2 +- .../sunrise/common/utils/ErrorFormatter.java | 3 +- .../common/utils/ErrorFormatterImpl.java | 10 ++- .../handlebars/PlayJavaFormResolverTest.java | 3 - .../common/utils/ErrorFormatterImplTest.java | 73 +++++++++++++++++++ conf/i18n/de/messages.yaml | 12 ++- 6 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 common/test/com/commercetools/sunrise/common/utils/ErrorFormatterImplTest.java diff --git a/common/app/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolver.java b/common/app/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolver.java index 8e4a3249a..21e29a36d 100644 --- a/common/app/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolver.java +++ b/common/app/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolver.java @@ -53,7 +53,7 @@ private boolean isFalsy(@Nullable final String value) { return value != null && value.equals("false"); } - ErrorsBean extractErrors(@Nullable final Form form) { + ErrorsBean extractErrors(@Nullable final Form form) { final ErrorsBean errorsBean = new ErrorsBean(); final List errorList = new ArrayList<>(); if (form != null) { diff --git a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java index dde6e6b6b..7c5481472 100644 --- a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java +++ b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java @@ -28,6 +28,7 @@ public interface ErrorFormatter { */ default String format(final List locales, final ValidationError error) { final String message = format(locales, error.message()); - return !error.key().isEmpty() ? message + ": " + error.key() : message; + final boolean hasFieldKey = error.key() != null && !error.key().isEmpty(); + return hasFieldKey ? message + ": " + error.key() : message; } } diff --git a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java index e273e7d8a..84e7c6b19 100644 --- a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java +++ b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java @@ -10,10 +10,14 @@ class ErrorFormatterImpl implements ErrorFormatter { + private final I18nResolver i18nResolver; + private final I18nIdentifierFactory i18nIdentifierFactory; + @Inject - private I18nResolver i18nResolver; - @Inject - private I18nIdentifierFactory i18nIdentifierFactory; + ErrorFormatterImpl(final I18nResolver i18nResolver, final I18nIdentifierFactory i18nIdentifierFactory) { + this.i18nResolver = i18nResolver; + this.i18nIdentifierFactory = i18nIdentifierFactory; + } @Override public String format(final List locales, final String messageKey) { diff --git a/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java b/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java index 4292bb130..5ef4ec1bb 100644 --- a/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java +++ b/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java @@ -2,15 +2,12 @@ import com.commercetools.sunrise.common.forms.ErrorBean; import com.commercetools.sunrise.common.forms.ErrorsBean; -import com.commercetools.sunrise.common.utils.ErrorFormatter; -import com.google.common.collect.Maps; import org.junit.Test; import org.mockito.Mockito; import play.data.Form; import play.data.validation.ValidationError; import java.util.*; -import java.util.function.Predicate; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; diff --git a/common/test/com/commercetools/sunrise/common/utils/ErrorFormatterImplTest.java b/common/test/com/commercetools/sunrise/common/utils/ErrorFormatterImplTest.java new file mode 100644 index 000000000..416f47867 --- /dev/null +++ b/common/test/com/commercetools/sunrise/common/utils/ErrorFormatterImplTest.java @@ -0,0 +1,73 @@ +package com.commercetools.sunrise.common.utils; + +import com.commercetools.sunrise.common.template.i18n.I18nIdentifier; +import com.commercetools.sunrise.common.template.i18n.I18nIdentifierFactory; +import com.commercetools.sunrise.common.template.i18n.I18nResolver; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import play.data.validation.ValidationError; + +import java.util.List; +import java.util.Locale; +import java.util.Optional; + +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class ErrorFormatterImplTest { + + private static final List LOCALES = singletonList(Locale.ENGLISH); + private static final String MESSAGE_KEY = "error.required"; + private static final I18nIdentifier I18N_IDENTIFIER = I18nIdentifier.of("main", MESSAGE_KEY); + + @Mock + private I18nResolver i18nResolver; + @Spy + private I18nIdentifierFactory i18nIdentifierFactory; + + @InjectMocks + private ErrorFormatterImpl errorFormatter; + + @Before + public void setUp() throws Exception { + when(i18nResolver.getOrKey(any(), any())).thenCallRealMethod(); + when(i18nResolver.get(any(), any())).thenCallRealMethod(); + } + + @Test + public void translatesMessageKey() throws Exception { + mockI18nResolverWithError(); + final ValidationError error = new ValidationError("", MESSAGE_KEY); + assertThat(errorFormatter.format(LOCALES, error)).isEqualTo("Field from i18nResolver"); + } + + @Test + public void returnsMessageKeyWhenNoMatch() throws Exception { + mockI18nResolverWithoutError(); + final ValidationError error = new ValidationError("", MESSAGE_KEY); + assertThat(errorFormatter.format(LOCALES, error)).isEqualTo(MESSAGE_KEY); + } + + @Test + public void returnsMessageKeyWithFieldIfProvided() throws Exception { + mockI18nResolverWithoutError(); + final ValidationError error = new ValidationError("username", MESSAGE_KEY); + assertThat(errorFormatter.format(LOCALES, error)).isEqualTo(MESSAGE_KEY + ": username"); + } + + private void mockI18nResolverWithoutError() { + when(i18nResolver.get(any(), eq(I18N_IDENTIFIER), anyMap())).thenReturn(Optional.empty()); + } + + private void mockI18nResolverWithError() { + when(i18nResolver.get(any(), eq(I18N_IDENTIFIER), anyMap())).thenReturn(Optional.of("Field from i18nResolver")); + } +} diff --git a/conf/i18n/de/messages.yaml b/conf/i18n/de/messages.yaml index 6c3a102e3..7d5dfc46d 100644 --- a/conf/i18n/de/messages.yaml +++ b/conf/i18n/de/messages.yaml @@ -1,14 +1,24 @@ -default: Something went wrong, please try again +defaultError: Something went wrong, please try again checkout: payment: invalidPayment: Invalid payment + addresses: + invalidShippingCountry: Invalid shipping country + invalidBillingCountry: Invalid billing country myAccount: logIn: invalidCredentials: Invalid credentials signUp: duplicatedEmail: A user with this email already exists + notMatchingPasswords: Not matching passwords + agreeToTerms: You must agree to terms recoverPassword: + emailSent: A message with further instructions has been sent to your email address emailNotFound: Email not found emailNotDelivered: Email could not be delivered resetPassword: invalidToken: Reset token is not valid + addressBook: + invalidCountry: Invalid country + confirmation: + agreeToTerms: You must agree to terms From 88127e7f27bbbf135bef8df4e368f235f2432c93 Mon Sep 17 00:00:00 2001 From: Laura Luiz Date: Tue, 24 Oct 2017 14:41:24 +0200 Subject: [PATCH 5/8] Support hash args --- .../sunrise/common/utils/ErrorFormatter.java | 16 +++- .../common/utils/ErrorFormatterImpl.java | 5 +- .../handlebars/PlayJavaFormResolverTest.java | 2 +- .../common/utils/ErrorFormatterImplTest.java | 25 +++--- .../common/utils/ErrorFormatterTest.java | 83 +++++++++++++++++++ 5 files changed, 112 insertions(+), 19 deletions(-) create mode 100644 common/test/com/commercetools/sunrise/common/utils/ErrorFormatterTest.java diff --git a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java index 7c5481472..8dc338097 100644 --- a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java +++ b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java @@ -3,8 +3,11 @@ import com.google.inject.ImplementedBy; import play.data.validation.ValidationError; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; +import java.util.stream.IntStream; /** * Allows to format errors according to the available locales and error information. @@ -18,17 +21,22 @@ public interface ErrorFormatter { * @param message error message * @return the error message localized and formatted */ - String format(final List locales, final String message); + String format(final List locales, final String message, final Map hashArgs); /** * Formats the Play error message somehow, with the translation to the first available locale. + * As hash arguments, it defines the field key as "field" and all other arguments as its index, e.g. "0", "1", "2". * @param locales current given locales * @param error Play's validation error * @return the error message localized and formatted */ default String format(final List locales, final ValidationError error) { - final String message = format(locales, error.message()); - final boolean hasFieldKey = error.key() != null && !error.key().isEmpty(); - return hasFieldKey ? message + ": " + error.key() : message; + final Map hashArgs = new HashMap<>(); + if (error.key() != null && !error.key().isEmpty()) { + hashArgs.put("field", error.key()); + } + IntStream.range(0, error.arguments().size()) + .forEach(index -> hashArgs.put(String.valueOf(index), error.arguments().get(index))); + return format(locales, error.message(), hashArgs); } } diff --git a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java index 84e7c6b19..530e6c1d3 100644 --- a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java +++ b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java @@ -7,6 +7,7 @@ import javax.inject.Inject; import java.util.List; import java.util.Locale; +import java.util.Map; class ErrorFormatterImpl implements ErrorFormatter { @@ -20,8 +21,8 @@ class ErrorFormatterImpl implements ErrorFormatter { } @Override - public String format(final List locales, final String messageKey) { + public String format(final List locales, final String messageKey, final Map hashArgs) { final I18nIdentifier i18nIdentifier = i18nIdentifierFactory.create(messageKey); - return i18nResolver.getOrKey(locales, i18nIdentifier); + return i18nResolver.getOrKey(locales, i18nIdentifier, hashArgs); } } diff --git a/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java b/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java index 5ef4ec1bb..db4352fe9 100644 --- a/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java +++ b/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java @@ -14,7 +14,7 @@ public class PlayJavaFormResolverTest { - PlayJavaFormResolver formResolver = new PlayJavaFormResolver(singletonList(Locale.ENGLISH), (locales, message) -> + PlayJavaFormResolver formResolver = new PlayJavaFormResolver(singletonList(Locale.ENGLISH), (locales, message, args) -> message); @Test diff --git a/common/test/com/commercetools/sunrise/common/utils/ErrorFormatterImplTest.java b/common/test/com/commercetools/sunrise/common/utils/ErrorFormatterImplTest.java index 416f47867..6b26b929f 100644 --- a/common/test/com/commercetools/sunrise/common/utils/ErrorFormatterImplTest.java +++ b/common/test/com/commercetools/sunrise/common/utils/ErrorFormatterImplTest.java @@ -10,13 +10,13 @@ import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; -import play.data.validation.ValidationError; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Optional; -import static java.util.Collections.singletonList; +import static java.util.Collections.*; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.when; @@ -27,6 +27,7 @@ public class ErrorFormatterImplTest { private static final List LOCALES = singletonList(Locale.ENGLISH); private static final String MESSAGE_KEY = "error.required"; private static final I18nIdentifier I18N_IDENTIFIER = I18nIdentifier.of("main", MESSAGE_KEY); + private static final Map ARGS_WITH_FIELD = singletonMap("field", "username"); @Mock private I18nResolver i18nResolver; @@ -38,29 +39,28 @@ public class ErrorFormatterImplTest { @Before public void setUp() throws Exception { - when(i18nResolver.getOrKey(any(), any())).thenCallRealMethod(); - when(i18nResolver.get(any(), any())).thenCallRealMethod(); + when(i18nResolver.getOrKey(any(), any(), any())).thenCallRealMethod(); } @Test public void translatesMessageKey() throws Exception { mockI18nResolverWithError(); - final ValidationError error = new ValidationError("", MESSAGE_KEY); - assertThat(errorFormatter.format(LOCALES, error)).isEqualTo("Field from i18nResolver"); + final String errorMessage = errorFormatter.format(LOCALES, MESSAGE_KEY, emptyMap()); + assertThat(errorMessage).isEqualTo("Required field"); } @Test public void returnsMessageKeyWhenNoMatch() throws Exception { mockI18nResolverWithoutError(); - final ValidationError error = new ValidationError("", MESSAGE_KEY); - assertThat(errorFormatter.format(LOCALES, error)).isEqualTo(MESSAGE_KEY); + final String errorMessage = errorFormatter.format(LOCALES, MESSAGE_KEY, emptyMap()); + assertThat(errorMessage).isEqualTo(MESSAGE_KEY); } @Test public void returnsMessageKeyWithFieldIfProvided() throws Exception { - mockI18nResolverWithoutError(); - final ValidationError error = new ValidationError("username", MESSAGE_KEY); - assertThat(errorFormatter.format(LOCALES, error)).isEqualTo(MESSAGE_KEY + ": username"); + mockI18nResolverWithError(); + final String errorMessage = errorFormatter.format(LOCALES, MESSAGE_KEY, ARGS_WITH_FIELD); + assertThat(errorMessage).isEqualTo("Required field: username"); } private void mockI18nResolverWithoutError() { @@ -68,6 +68,7 @@ private void mockI18nResolverWithoutError() { } private void mockI18nResolverWithError() { - when(i18nResolver.get(any(), eq(I18N_IDENTIFIER), anyMap())).thenReturn(Optional.of("Field from i18nResolver")); + when(i18nResolver.get(any(), eq(I18N_IDENTIFIER), anyMap())).thenReturn(Optional.of("Required field")); + when(i18nResolver.get(any(), eq(I18N_IDENTIFIER), eq(singletonMap("field", "username")))).thenReturn(Optional.of("Required field: username")); } } diff --git a/common/test/com/commercetools/sunrise/common/utils/ErrorFormatterTest.java b/common/test/com/commercetools/sunrise/common/utils/ErrorFormatterTest.java new file mode 100644 index 000000000..44c0bba8a --- /dev/null +++ b/common/test/com/commercetools/sunrise/common/utils/ErrorFormatterTest.java @@ -0,0 +1,83 @@ +package com.commercetools.sunrise.common.utils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import play.data.validation.ValidationError; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.function.Consumer; + +import static java.util.Arrays.asList; +import static java.util.Collections.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class ErrorFormatterTest { + + private static final List LOCALES = singletonList(Locale.ENGLISH); + private static final String MESSAGE_KEY = "error.required"; + private static final String SOME_ERROR_MESSAGE = "errorMessage"; + + @Mock + private ErrorFormatter errorFormatter; + + @Before + public void setUp() throws Exception { + when(errorFormatter.format(any(), any(), any())).thenReturn(SOME_ERROR_MESSAGE); + when(errorFormatter.format(any(), any())).thenCallRealMethod(); + } + + @Test + public void transformsToMessage() throws Exception { + final ValidationError validationError = new ValidationError("", MESSAGE_KEY); + test(validationError, errorFormatter -> + verify(errorFormatter).format(LOCALES, MESSAGE_KEY, emptyMap())); + } + + @Test + public void transformsToMessageWithField() throws Exception { + final ValidationError validationError = new ValidationError("username", MESSAGE_KEY); + test(validationError, errorFormatter -> + verify(errorFormatter).format(LOCALES, MESSAGE_KEY, singletonMap("field", "username"))); + } + + @Test + public void transformsToMessageWithArgs() throws Exception { + final ValidationError validationError = new ValidationError("", MESSAGE_KEY, asList("arg1", "arg2", "arg3")); + test(validationError, errorFormatter -> { + final Map hashArgs = new HashMap<>(); + hashArgs.put("0", "arg1"); + hashArgs.put("1", "arg2"); + hashArgs.put("2", "arg3"); + verify(errorFormatter).format(LOCALES, MESSAGE_KEY, hashArgs); + }); + } + + @Test + public void transformsToMessageWithFieldAndArgs() throws Exception { + final ValidationError validationError = new ValidationError("username", MESSAGE_KEY, asList("arg1", "arg2", "arg3")); + test(validationError, errorFormatter -> { + final Map hashArgs = new HashMap<>(); + hashArgs.put("field", "username"); + hashArgs.put("0", "arg1"); + hashArgs.put("1", "arg2"); + hashArgs.put("2", "arg3"); + verify(errorFormatter).format(LOCALES, MESSAGE_KEY, hashArgs); + }); + } + + private void test(final ValidationError validationError, final Consumer test) { + final String errorMessage = errorFormatter.format(LOCALES, validationError); + assertThat(errorMessage).isEqualTo(SOME_ERROR_MESSAGE); + test.accept(errorFormatter); + } +} From 778d59896926a00e4357971b420a1e5bf0f05461 Mon Sep 17 00:00:00 2001 From: Laura Luiz Date: Tue, 24 Oct 2017 15:03:45 +0200 Subject: [PATCH 6/8] Fix test --- .../template/engine/handlebars/PlayJavaFormResolverTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java b/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java index db4352fe9..029761968 100644 --- a/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java +++ b/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java @@ -32,7 +32,7 @@ public void extractErrors() throws Exception { private void checkError(ErrorBean error, String field, String key, String message) { assertThat(error.getField()).isEqualTo(field); - assertThat(error.getMessage()).isEqualTo(message + ": " + key); + assertThat(error.getMessage()).isEqualTo(message); } From 56e72e533ecd4626eb40b49b89f9c548c24c4ed2 Mon Sep 17 00:00:00 2001 From: Laura Luiz Date: Tue, 24 Oct 2017 16:07:37 +0200 Subject: [PATCH 7/8] Remove unused error key --- .../engine/handlebars/PlayJavaFormResolverTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java b/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java index 029761968..682bd43e1 100644 --- a/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java +++ b/common/test/com/commercetools/sunrise/common/template/engine/handlebars/PlayJavaFormResolverTest.java @@ -25,12 +25,12 @@ public void extractErrors() throws Exception { ErrorsBean result = formResolver.extractErrors(form); List errors = result.getGlobalErrors(); - checkError(errors.get(0), errorField1, "errorkey1", "errorMessage1"); - checkError(errors.get(1), errorField1, "errorkey2", "errorMessage2"); - checkError(errors.get(2), errorField2, "errorkey21", "errorMessage21"); + checkError(errors.get(0), errorField1, "errorMessage1"); + checkError(errors.get(1), errorField1, "errorMessage2"); + checkError(errors.get(2), errorField2, "errorMessage21"); } - private void checkError(ErrorBean error, String field, String key, String message) { + private void checkError(ErrorBean error, String field, String message) { assertThat(error.getField()).isEqualTo(field); assertThat(error.getMessage()).isEqualTo(message); @@ -47,4 +47,4 @@ private Form formWithSomeErrorsForFields(String field1, String field2) { Mockito.when(form.errors()).thenReturn(errorMap); return form; } -} \ No newline at end of file +} From 2eec280241fe159caf5e980101c87c7a6062fcc9 Mon Sep 17 00:00:00 2001 From: Laura Luiz Date: Wed, 25 Oct 2017 14:09:32 +0200 Subject: [PATCH 8/8] Change hashArgs to a more neutral name --- .../common/template/i18n/I18nResolver.java | 16 ++++++++-------- .../i18n/composite/CompositeI18nResolver.java | 4 ++-- .../template/i18n/yaml/YamlI18nResolver.java | 14 +++++++------- .../sunrise/common/utils/ErrorFormatter.java | 11 ++++++----- .../sunrise/common/utils/ErrorFormatterImpl.java | 4 ++-- .../template/i18n/TestableI18nResolver.java | 4 ++-- 6 files changed, 27 insertions(+), 26 deletions(-) diff --git a/common/app/com/commercetools/sunrise/common/template/i18n/I18nResolver.java b/common/app/com/commercetools/sunrise/common/template/i18n/I18nResolver.java index 57987c0ae..8b97dbfa4 100644 --- a/common/app/com/commercetools/sunrise/common/template/i18n/I18nResolver.java +++ b/common/app/com/commercetools/sunrise/common/template/i18n/I18nResolver.java @@ -17,10 +17,10 @@ public interface I18nResolver { * Resolves i18n message identified by a bundle and a key for the first found given locale. * @param locales the list of locales used to translate the message * @param i18nIdentifier identifier of the i18n message - * @param hashArgs list of hash arguments + * @param args list of named arguments * @return the resolved message in the first found given language, or absent if it could not be found */ - Optional get(final List locales, final I18nIdentifier i18nIdentifier, final Map hashArgs); + Optional get(final List locales, final I18nIdentifier i18nIdentifier, final Map args); /** * Resolves i18n message identified by a bundle and a key for the first found given locale. @@ -36,11 +36,11 @@ default Optional get(final List locales, final I18nIdentifier i1 * Resolves i18n message identified by a bundle and a key for the first found given locale. * @param locales the list of locales used to translate the message * @param i18nIdentifier identifier of the i18n message - * @param hashArgs list of hash arguments + * @param args list of named arguments * @return the resolved message in the first found given language, or empty string if it could not be found */ - default String getOrEmpty(final List locales, final I18nIdentifier i18nIdentifier, final Map hashArgs) { - return get(locales, i18nIdentifier, hashArgs).orElse(""); + default String getOrEmpty(final List locales, final I18nIdentifier i18nIdentifier, final Map args) { + return get(locales, i18nIdentifier, args).orElse(""); } /** @@ -57,11 +57,11 @@ default String getOrEmpty(final List locales, final I18nIdentifier i18nI * Resolves i18n message identified by a bundle and a key for the first found given locale. * @param locales the list of locales used to translate the message * @param i18nIdentifier identifier of the i18n message - * @param hashArgs list of hash arguments + * @param args list of named arguments * @return the resolved message in the first found given language, or the message key if it could not be found */ - default String getOrKey(final List locales, final I18nIdentifier i18nIdentifier, final Map hashArgs) { - return get(locales, i18nIdentifier, hashArgs).orElse(i18nIdentifier.messageKey()); + default String getOrKey(final List locales, final I18nIdentifier i18nIdentifier, final Map args) { + return get(locales, i18nIdentifier, args).orElse(i18nIdentifier.messageKey()); } /** diff --git a/common/app/com/commercetools/sunrise/common/template/i18n/composite/CompositeI18nResolver.java b/common/app/com/commercetools/sunrise/common/template/i18n/composite/CompositeI18nResolver.java index 049a2a819..353c6ca13 100644 --- a/common/app/com/commercetools/sunrise/common/template/i18n/composite/CompositeI18nResolver.java +++ b/common/app/com/commercetools/sunrise/common/template/i18n/composite/CompositeI18nResolver.java @@ -22,9 +22,9 @@ private CompositeI18nResolver(final List i18nResolvers) { } @Override - public Optional get(final List locales, final I18nIdentifier i18nIdentifier, final Map hashArgs) { + public Optional get(final List locales, final I18nIdentifier i18nIdentifier, final Map args) { for (I18nResolver i18nResolver : i18nResolvers) { - final Optional message = i18nResolver.get(locales, i18nIdentifier, hashArgs); + final Optional message = i18nResolver.get(locales, i18nIdentifier, args); if (message.isPresent()) { return message; } diff --git a/common/app/com/commercetools/sunrise/common/template/i18n/yaml/YamlI18nResolver.java b/common/app/com/commercetools/sunrise/common/template/i18n/yaml/YamlI18nResolver.java index b696b8b72..2edfebadb 100644 --- a/common/app/com/commercetools/sunrise/common/template/i18n/yaml/YamlI18nResolver.java +++ b/common/app/com/commercetools/sunrise/common/template/i18n/yaml/YamlI18nResolver.java @@ -40,11 +40,11 @@ private YamlI18nResolver(final String filepath, final List locales, fina } @Override - public Optional get(final List locales, final I18nIdentifier i18nIdentifier, final Map hashArgs) { - final String message = findPluralizedTranslation(locales, i18nIdentifier, hashArgs) + public Optional get(final List locales, final I18nIdentifier i18nIdentifier, final Map args) { + final String message = findPluralizedTranslation(locales, i18nIdentifier, args) .orElseGet(() -> findFirstTranslation(locales, i18nIdentifier.bundle(), i18nIdentifier.messageKey()) .orElse(null)); - return Optional.ofNullable(message).map(resolvedValue -> replaceParameters(resolvedValue, hashArgs)); + return Optional.ofNullable(message).map(resolvedValue -> replaceParameters(resolvedValue, args)); } @Override @@ -59,8 +59,8 @@ public static YamlI18nResolver of(final String filepath, final List loca } private Optional findPluralizedTranslation(final List locales, final I18nIdentifier i18nIdentifier, - final Map hashArgs) { - if (containsPlural(hashArgs)) { + final Map args) { + if (containsPlural(args)) { final String pluralizedKey = i18nIdentifier.messageKey() + "_plural"; return findFirstTranslation(locales, i18nIdentifier.bundle(), pluralizedKey); } else { @@ -78,9 +78,9 @@ private Optional findFirstTranslation(final List locales, final return Optional.empty(); } - private String replaceParameters(final String resolvedValue, final Map hashArgs) { + private String replaceParameters(final String resolvedValue, final Map args) { String message = StringUtils.defaultString(resolvedValue); - for (final Map.Entry entry : hashArgs.entrySet()) { + for (final Map.Entry entry : args.entrySet()) { if (entry.getValue() != null) { final String parameter = "__" + entry.getKey() + "__"; message = message.replace(parameter, entry.getValue().toString()); diff --git a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java index 8dc338097..d21bebb67 100644 --- a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java +++ b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatter.java @@ -19,9 +19,10 @@ public interface ErrorFormatter { * Formats the error message somehow, with the translation to the first available locale. * @param locales current given locales * @param message error message + * @param args list of named arguments * @return the error message localized and formatted */ - String format(final List locales, final String message, final Map hashArgs); + String format(final List locales, final String message, final Map args); /** * Formats the Play error message somehow, with the translation to the first available locale. @@ -31,12 +32,12 @@ public interface ErrorFormatter { * @return the error message localized and formatted */ default String format(final List locales, final ValidationError error) { - final Map hashArgs = new HashMap<>(); + final Map args = new HashMap<>(); if (error.key() != null && !error.key().isEmpty()) { - hashArgs.put("field", error.key()); + args.put("field", error.key()); } IntStream.range(0, error.arguments().size()) - .forEach(index -> hashArgs.put(String.valueOf(index), error.arguments().get(index))); - return format(locales, error.message(), hashArgs); + .forEach(index -> args.put(String.valueOf(index), error.arguments().get(index))); + return format(locales, error.message(), args); } } diff --git a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java index 530e6c1d3..64c9b9ae0 100644 --- a/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java +++ b/common/app/com/commercetools/sunrise/common/utils/ErrorFormatterImpl.java @@ -21,8 +21,8 @@ class ErrorFormatterImpl implements ErrorFormatter { } @Override - public String format(final List locales, final String messageKey, final Map hashArgs) { + public String format(final List locales, final String messageKey, final Map args) { final I18nIdentifier i18nIdentifier = i18nIdentifierFactory.create(messageKey); - return i18nResolver.getOrKey(locales, i18nIdentifier, hashArgs); + return i18nResolver.getOrKey(locales, i18nIdentifier, args); } } diff --git a/common/test/com/commercetools/sunrise/common/template/i18n/TestableI18nResolver.java b/common/test/com/commercetools/sunrise/common/template/i18n/TestableI18nResolver.java index a4627641f..0264458bb 100644 --- a/common/test/com/commercetools/sunrise/common/template/i18n/TestableI18nResolver.java +++ b/common/test/com/commercetools/sunrise/common/template/i18n/TestableI18nResolver.java @@ -14,10 +14,10 @@ public TestableI18nResolver(final Map i18nMap) { } @Override - public Optional get(final List locales, final I18nIdentifier i18nIdentifier, final Map hashArgs) { + public Optional get(final List locales, final I18nIdentifier i18nIdentifier, final Map args) { final String mapKey = String.format("%s/%s:%s", locales.get(0), i18nIdentifier.bundle(), i18nIdentifier.messageKey()); final String message = i18nMap.get(mapKey); - final String parameters = hashArgs.entrySet().stream() + final String parameters = args.entrySet().stream() .map(hashPair -> hashPair.getKey() + "=" + hashPair.getValue()) .collect(Collectors.joining(",")); if (parameters.isEmpty()) {