Skip to content

Commit

Permalink
Merge pull request #272 from Yoshani/fix-npe
Browse files Browse the repository at this point in the history
Handle empty locale when normalizing
  • Loading branch information
Yoshani authored Oct 31, 2024
2 parents 7c0827b + e020c01 commit f94a98f
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ private I18nMgtConstants() {}
public static final String SERVICE_PROPERTY_KEY_SERVICE_NAME = "service.name";
public static final String SERVICE_PROPERTY_VAL_EMAIL_TEMPLATE_MANAGER = "EmailTemplateManager";
public static final String SERVICE_PROPERTY_VAL_NOTIFICATION_TEMPLATE_MANAGER = "NotificationTemplateManager";
public static final String NOTIFICATION_DEFAULT_LOCALE = "Notification.DefaultLocale";
public static final String DEFAULT_NOTIFICATION_LOCALE = "en_US";

public static class ErrorMsg {
private ErrorMsg() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.email.mgt.util;
Expand All @@ -27,6 +29,7 @@
import org.wso2.carbon.email.mgt.exceptions.I18nMgtEmailConfigException;
import org.wso2.carbon.email.mgt.internal.I18nMgtDataHolder;
import org.wso2.carbon.email.mgt.model.EmailTemplate;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.governance.model.NotificationTemplate;
import org.wso2.carbon.identity.governance.service.notification.NotificationChannels;
import org.wso2.carbon.registry.core.Collection;
Expand Down Expand Up @@ -260,6 +263,22 @@ public static String prependOperationScenarioToErrorCode(String exceptionErrorCo
public static String normalizeLocaleFormat(String localeString) {

Locale locale = Locale.forLanguageTag(localeString.replace(UNDERSCORE, HYPHEN).toLowerCase());
return locale.toString();
String normalizedLocale = locale.toString();
if (StringUtils.isNotBlank(normalizedLocale)) {
return normalizedLocale;
}
return getNotificationLocale();
}

/**
* Get the notification locale.
*
* @return Locale
*/
public static String getNotificationLocale() {

return StringUtils.isNotBlank(IdentityUtil.getProperty(I18nMgtConstants.NOTIFICATION_DEFAULT_LOCALE))
? IdentityUtil.getProperty(I18nMgtConstants.NOTIFICATION_DEFAULT_LOCALE)
: I18nMgtConstants.DEFAULT_NOTIFICATION_LOCALE;
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.email.mgt.util;

Expand All @@ -21,11 +23,14 @@
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.wso2.carbon.email.mgt.constants.I18nMgtConstants;
import org.wso2.carbon.email.mgt.exceptions.I18nEmailMgtServerException;
import org.wso2.carbon.email.mgt.exceptions.I18nMgtEmailConfigException;
import org.wso2.carbon.email.mgt.model.EmailTemplate;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.exceptions.RegistryException;

Expand All @@ -34,26 +39,28 @@
import java.util.Map;

import static org.mockito.Matchers.any;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.powermock.api.mockito.PowerMockito.doNothing;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.testng.Assert.assertEquals;
import static org.wso2.carbon.email.mgt.constants.I18nMgtConstants.TEMPLATE_CONTENT_TYPE;
import static org.wso2.carbon.email.mgt.constants.I18nMgtConstants.TEMPLATE_LOCALE;
import static org.wso2.carbon.email.mgt.constants.I18nMgtConstants.TEMPLATE_TYPE;
import static org.wso2.carbon.email.mgt.constants.I18nMgtConstants.TEMPLATE_TYPE_DISPLAY_NAME;

@PrepareForTest({LogFactory.class, Resource.class})
@PrepareForTest({LogFactory.class, Resource.class, IdentityUtil.class})
public class I18nEmailUtilTest extends PowerMockTestCase {

private static final String DISPLAY_NAME = "Display Name";
private static final String TYPE = "templateType";
private static final String CONTENT_TYPE = "text/html";
private static final String TEMPLATE_CONTENT_TYPE_WITH_UTF_8 = "text/html; charset="
+ StandardCharsets.UTF_8.displayName();
+ StandardCharsets.UTF_8.displayName();
private static final String LOCALE = "en_US";
private static final String CONTENT= "[\"Subject\",\"Body\",\"Footer\"]";
private static final String CONTENT_INVALID= "{[\"Subject\",\"Body\",\"Footer\"]}";
private static final String CONTENT_INCOMPLETE= "[]";
private static final String CONTENT = "[\"Subject\",\"Body\",\"Footer\"]";
private static final String CONTENT_INVALID = "{[\"Subject\",\"Body\",\"Footer\"]}";
private static final String CONTENT_INCOMPLETE = "[]";

private static final int CASE_1 = 1;
private static final int CASE_2 = 2;
Expand All @@ -67,6 +74,13 @@ public class I18nEmailUtilTest extends PowerMockTestCase {
@Mock
private Log log;

@BeforeMethod
public void setUp() {

initMocks(this);
mockStatic(IdentityUtil.class);
}

@DataProvider(name = "provideTestData")
public Object[][] provideTestData() {

Expand All @@ -76,12 +90,12 @@ public Object[][] provideTestData() {
map1.put(TEMPLATE_CONTENT_TYPE, CONTENT_TYPE);
map1.put(TEMPLATE_LOCALE, LOCALE);

return new Object[][] {
{ map1, CONTENT.getBytes(StandardCharsets.UTF_8), CASE_1},
{ map1, null, CASE_2},
{ map1, CONTENT_INVALID.getBytes(StandardCharsets.UTF_8), CASE_3},
{ map1, CONTENT_INCOMPLETE.getBytes(StandardCharsets.UTF_8), CASE_4},
{ map1, CONTENT.getBytes(StandardCharsets.UTF_8), CASE_5}
return new Object[][]{
{map1, CONTENT.getBytes(StandardCharsets.UTF_8), CASE_1},
{map1, null, CASE_2},
{map1, CONTENT_INVALID.getBytes(StandardCharsets.UTF_8), CASE_3},
{map1, CONTENT_INCOMPLETE.getBytes(StandardCharsets.UTF_8), CASE_4},
{map1, CONTENT.getBytes(StandardCharsets.UTF_8), CASE_5}
};
}

Expand Down Expand Up @@ -110,13 +124,13 @@ public void testGetEmailTemplate(Map<String, String> configMap, byte[] content,
if (caseNo == CASE_1) {
EmailTemplate emailTemplate = I18nEmailUtil.getEmailTemplate(templateResource);

Assert.assertEquals(emailTemplate.getTemplateDisplayName(), DISPLAY_NAME);
Assert.assertEquals(emailTemplate.getTemplateType(), TYPE);
Assert.assertEquals(emailTemplate.getEmailContentType(), TEMPLATE_CONTENT_TYPE_WITH_UTF_8);
Assert.assertEquals(emailTemplate.getLocale(), LOCALE);
Assert.assertEquals(emailTemplate.getSubject(), "Subject");
Assert.assertEquals(emailTemplate.getBody(), "Body");
Assert.assertEquals(emailTemplate.getFooter(), "Footer");
assertEquals(emailTemplate.getTemplateDisplayName(), DISPLAY_NAME);
assertEquals(emailTemplate.getTemplateType(), TYPE);
assertEquals(emailTemplate.getEmailContentType(), TEMPLATE_CONTENT_TYPE_WITH_UTF_8);
assertEquals(emailTemplate.getLocale(), LOCALE);
assertEquals(emailTemplate.getSubject(), "Subject");
assertEquals(emailTemplate.getBody(), "Body");
assertEquals(emailTemplate.getFooter(), "Footer");

} else if (caseNo == CASE_2) {
EmailTemplate emailTemplate = I18nEmailUtil.getEmailTemplate(templateResource);
Expand Down Expand Up @@ -148,6 +162,34 @@ public void testGetEmailTemplate(Map<String, String> configMap, byte[] content,
Assert.assertTrue(e.getMessage().contains("Error retrieving a template"));
}
}
}

@DataProvider(name = "provideLocaleData")
public Object[][] provideLocaleData() {

return new Object[][]{
{"en_US", "en_US"},
{"en*US", I18nMgtConstants.DEFAULT_NOTIFICATION_LOCALE},
{"", I18nMgtConstants.DEFAULT_NOTIFICATION_LOCALE}
};
}

@Test(dataProvider = "provideLocaleData")
public void testNormalizeLocaleFormat(String locale, String expectedLocale) {

String result = I18nEmailUtil.normalizeLocaleFormat(locale);
assertEquals(result, expectedLocale);
}

@Test
public void testGetNotificationLocale() {

String customDefaultLocale = "fr-FR";
when(IdentityUtil.getProperty(I18nMgtConstants.NOTIFICATION_DEFAULT_LOCALE)).thenReturn(customDefaultLocale);
String result = I18nEmailUtil.getNotificationLocale();
assertEquals(result, customDefaultLocale);
when(IdentityUtil.getProperty(I18nMgtConstants.NOTIFICATION_DEFAULT_LOCALE)).thenReturn(null);
String result2 = I18nEmailUtil.getNotificationLocale();
assertEquals(result2, I18nMgtConstants.DEFAULT_NOTIFICATION_LOCALE);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.wso2.carbon.email.mgt.constants.I18nMgtConstants;
import org.wso2.carbon.email.mgt.exceptions.I18nEmailMgtException;
import org.wso2.carbon.email.mgt.model.EmailTemplate;
import org.wso2.carbon.email.mgt.util.I18nEmailUtil;
import org.wso2.carbon.event.publisher.core.EventPublisherService;
import org.wso2.carbon.event.publisher.core.config.EventPublisherConfiguration;
import org.wso2.carbon.event.publisher.core.exception.EventPublisherConfigurationException;
Expand All @@ -43,6 +44,7 @@
import org.wso2.carbon.identity.branding.preference.management.core.exception.BrandingPreferenceMgtException;
import org.wso2.carbon.identity.branding.preference.management.core.model.BrandingPreference;
import org.wso2.carbon.identity.branding.preference.management.core.model.CustomText;
import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils;
import org.wso2.carbon.identity.core.ServiceURLBuilder;
import org.wso2.carbon.identity.core.URLBuilderException;
import org.wso2.carbon.identity.core.util.IdentityConfigParser;
Expand All @@ -59,7 +61,6 @@
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementClientException;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils;
import org.wso2.carbon.user.api.Claim;
import org.wso2.carbon.user.api.Tenant;
import org.wso2.carbon.user.api.UserStoreException;
Expand All @@ -68,7 +69,6 @@
import org.wso2.carbon.user.core.common.AbstractUserStoreManager;
import org.wso2.carbon.user.core.service.RealmService;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
Expand All @@ -81,6 +81,8 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.namespace.QName;

import static org.wso2.carbon.identity.core.util.IdentityTenantUtil.isSuperTenantRequiredInUrl;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.ACCOUNT_RECOVERY_ENDPOINT_PLACEHOLDER;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.AUTHENTICATION_ENDPOINT_PLACEHOLDER;
Expand All @@ -91,11 +93,11 @@
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.BRANDING_PREFERENCES_SUPPORT_EMAIL_PATH;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.CARBON_PRODUCT_URL_TEMPLATE_PLACEHOLDER;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.CARBON_PRODUCT_URL_WITH_USER_TENANT_TEMPLATE_PLACEHOLDER;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.CUSTOM_TEXT_COPYRIGHT_PATH;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.CUSTOM_TEXT_COMMON_SCREEN;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.CUSTOM_TEXT_COPYRIGHT_PATH;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.CUSTOM_TEXT_COPYRIGHT_YEAR_KEY;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.NEW_LINE_CHARACTER_STRING;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.NEW_LINE_CHARACTER_HTML;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.NEW_LINE_CHARACTER_STRING;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.ORGANIZATION_COPYRIGHT_PLACEHOLDER;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.EmailNotification.ORGANIZATION_NAME_PLACEHOLDER;
import static org.wso2.carbon.identity.event.handler.notification.NotificationConstants.TENANT_DOMAIN;
Expand Down Expand Up @@ -826,9 +828,7 @@ private static String resolveHumanReadableOrganizationName(String tenantDomain)
*/
public static String getNotificationLocale() {

return StringUtils.isNotBlank(IdentityUtil.getProperty(NotificationConstants.NOTIFICATION_DEFAULT_LOCALE))
? IdentityUtil.getProperty(NotificationConstants.NOTIFICATION_DEFAULT_LOCALE)
: NotificationConstants.EmailNotification.LOCALE_DEFAULT;
return I18nEmailUtil.getNotificationLocale();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.wso2.carbon.email.mgt.constants.I18nMgtConstants;

import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -242,4 +243,11 @@ public void testGetBrandingPreference(JsonNode brandingPreferences, Map<String,
Assert.assertEquals(themeBorderColor, ORGANIZATION_LIGHT_BORDER_COLOR_FALLBACK);
}
}

@Test
public void testGetNotificationLocale() {

String result = NotificationUtil.getNotificationLocale();
Assert.assertEquals(result, I18nMgtConstants.DEFAULT_NOTIFICATION_LOCALE);
}
}

0 comments on commit f94a98f

Please sign in to comment.