diff --git a/components/email-mgt/org.wso2.carbon.email.mgt/pom.xml b/components/email-mgt/org.wso2.carbon.email.mgt/pom.xml index fceacb7d..50adb383 100644 --- a/components/email-mgt/org.wso2.carbon.email.mgt/pom.xml +++ b/components/email-mgt/org.wso2.carbon.email.mgt/pom.xml @@ -112,6 +112,11 @@ jacoco-maven-plugin ${jacoco.version} + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.testutil + test + diff --git a/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/EmailTemplateManagerImpl.java b/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/EmailTemplateManagerImpl.java index aeb90a5a..c8ae9fe8 100644 --- a/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/EmailTemplateManagerImpl.java +++ b/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/EmailTemplateManagerImpl.java @@ -22,7 +22,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.email.mgt.constants.I18nMgtConstants; -import org.wso2.carbon.email.mgt.store.DefaultTemplateManager; +import org.wso2.carbon.email.mgt.store.TemplatePersistenceManagerFactory; +import org.wso2.carbon.email.mgt.store.UnifiedTemplateManager; import org.wso2.carbon.email.mgt.store.TemplatePersistenceManager; import org.wso2.carbon.email.mgt.exceptions.I18nEmailMgtClientException; import org.wso2.carbon.email.mgt.exceptions.I18nEmailMgtException; @@ -79,7 +80,8 @@ public class EmailTemplateManagerImpl implements EmailTemplateManager, Notificat public EmailTemplateManagerImpl() { - this.templatePersistenceManager = new DefaultTemplateManager(); + TemplatePersistenceManagerFactory templatePersistenceManagerFactory = new TemplatePersistenceManagerFactory(); + this.templatePersistenceManager = templatePersistenceManagerFactory.getTemplatePersistenceManager(); } @Override diff --git a/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/InMemoryBasedTemplateManager.java b/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/SystemDefaultTemplateManager.java similarity index 92% rename from components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/InMemoryBasedTemplateManager.java rename to components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/SystemDefaultTemplateManager.java index 4d33cbbb..75ca2331 100644 --- a/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/InMemoryBasedTemplateManager.java +++ b/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/SystemDefaultTemplateManager.java @@ -39,10 +39,10 @@ * This class have support for get, list, exists operations and any invocations to modification operations * throws {@link UnsupportedOperationException}. * This class expected to be use only with conjunction with another {@link TemplatePersistenceManager} implementation - * which supports full CRUD operations, hence {@link DefaultTemplateManager} provides that aggregation using this as a + * which supports full CRUD operations, hence {@link UnifiedTemplateManager} provides that aggregation using this as a * fallback provider. */ -public class InMemoryBasedTemplateManager implements TemplatePersistenceManager { +public class SystemDefaultTemplateManager implements TemplatePersistenceManager { private final Map> defaultEmailTemplates; private final Map> defaultSMSTemplates; @@ -50,7 +50,7 @@ public class InMemoryBasedTemplateManager implements TemplatePersistenceManager /** * Initializes the in-memory template manager by populating default email and SMS templates. */ - public InMemoryBasedTemplateManager() { + public SystemDefaultTemplateManager() { defaultEmailTemplates = populateTemplates(I18nMgtDataHolder.getInstance().getDefaultEmailTemplates()); defaultSMSTemplates = populateTemplates(I18nMgtDataHolder.getInstance().getDefaultSMSTemplates()); @@ -260,4 +260,22 @@ private Map> getTemplateMap(String not } return defaultEmailTemplates; } + + /** + * Checks if there is a template available as a system default template with the exact same details. + * This method is used to avoid managing duplicate templates. + * + * @param template Notification template to check. + * @return True if a template with the same details is available, false otherwise. + */ + boolean hasSameTemplate(NotificationTemplate template) { + + if (template == null) { + return false; + } + + Map defaultTemplatesForScenario = + getTemplateMap(template.getNotificationChannel()).get(template.getDisplayName().toLowerCase()); + return defaultTemplatesForScenario == null ? false : defaultTemplatesForScenario.containsValue(template); + } } diff --git a/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/TemplatePersistenceManagerFactory.java b/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/TemplatePersistenceManagerFactory.java index 54b2626e..022e4274 100644 --- a/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/TemplatePersistenceManagerFactory.java +++ b/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/TemplatePersistenceManagerFactory.java @@ -64,6 +64,6 @@ public TemplatePersistenceManager getTemplatePersistenceManager() { if (log.isDebugEnabled()) { log.debug("Template persistent manager initialized with the type: " + persistenceManager.getClass()); } - return persistenceManager; + return new UnifiedTemplateManager(persistenceManager); } } diff --git a/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/DefaultTemplateManager.java b/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/UnifiedTemplateManager.java similarity index 84% rename from components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/DefaultTemplateManager.java rename to components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/UnifiedTemplateManager.java index 65fc6da1..602fa9c7 100644 --- a/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/DefaultTemplateManager.java +++ b/components/email-mgt/org.wso2.carbon.email.mgt/src/main/java/org/wso2/carbon/email/mgt/store/UnifiedTemplateManager.java @@ -33,15 +33,14 @@ * to both template persistent manger crafted from the factory and an in-memory manager. * This class will function as a wrapper class for the template manager produced from the factory. */ -public class DefaultTemplateManager implements TemplatePersistenceManager { +public class UnifiedTemplateManager implements TemplatePersistenceManager { private final TemplatePersistenceManager templatePersistenceManager; - private final TemplatePersistenceManager inMemoryTemplateManager = new InMemoryBasedTemplateManager(); + private final SystemDefaultTemplateManager inMemoryTemplateManager = new SystemDefaultTemplateManager(); - public DefaultTemplateManager() { + public UnifiedTemplateManager(TemplatePersistenceManager persistenceManager) { - TemplatePersistenceManagerFactory templatePersistenceManagerFactory = new TemplatePersistenceManagerFactory(); - this.templatePersistenceManager = templatePersistenceManagerFactory.getTemplatePersistenceManager(); + this.templatePersistenceManager = persistenceManager; } @Override @@ -87,7 +86,27 @@ public void deleteNotificationTemplateType(String displayName, String notificati public void addOrUpdateNotificationTemplate(NotificationTemplate notificationTemplate, String applicationUuid, String tenantDomain) throws NotificationTemplateManagerServerException { - templatePersistenceManager.addOrUpdateNotificationTemplate(notificationTemplate, applicationUuid, tenantDomain); + if (!inMemoryTemplateManager.hasSameTemplate(notificationTemplate)) { + templatePersistenceManager.addOrUpdateNotificationTemplate(notificationTemplate, applicationUuid, + tenantDomain); + } else { + // Template is already managed as a system default template. Handle add or update. + String displayName = notificationTemplate.getDisplayName(); + String locale = notificationTemplate.getLocale(); + String notificationChannel = notificationTemplate.getNotificationChannel(); + boolean isExistsInStorage = + templatePersistenceManager.isNotificationTemplateExists(displayName, locale, notificationChannel, + applicationUuid, tenantDomain); + if (isExistsInStorage) { + // This request is to reset existing template to default content. Hence, delete the existing template. + templatePersistenceManager.deleteNotificationTemplate(displayName, locale, notificationChannel, + applicationUuid, tenantDomain); + } else { + // This request is to add a new template with a same content that is already managed as a system default + // template. Storing such templates is redundant. Hence, avoid storing those templates as duplicate + // contents to optimize the storage. + } + } } @Override diff --git a/components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/InMemoryBasedTemplateManagerTest.java b/components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/SystemDefaultTemplateManagerTest.java similarity index 84% rename from components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/InMemoryBasedTemplateManagerTest.java rename to components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/SystemDefaultTemplateManagerTest.java index b1d5811c..d339ac39 100644 --- a/components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/InMemoryBasedTemplateManagerTest.java +++ b/components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/SystemDefaultTemplateManagerTest.java @@ -46,10 +46,10 @@ import static org.testng.Assert.assertTrue; /** - * Class that contains the test cases for {@link InMemoryBasedTemplateManager}. + * Class that contains the test cases for {@link SystemDefaultTemplateManager}. */ @PrepareForTest({I18nMgtDataHolder.class, CarbonUtils.class}) -public class InMemoryBasedTemplateManagerTest extends PowerMockTestCase { +public class SystemDefaultTemplateManagerTest extends PowerMockTestCase { private final String baseDirectoryPath = Paths.get(System.getProperty("user.dir"), "src", "test", "resources").toString(); @@ -59,7 +59,7 @@ public class InMemoryBasedTemplateManagerTest extends PowerMockTestCase { private static final String EN_US = "en_US"; @Mock I18nMgtDataHolder i18nMgtDataHolder; - InMemoryBasedTemplateManager inMemoryBasedTemplateManager; + SystemDefaultTemplateManager systemDefaultTemplateManager; NotificationTemplate positiveNotificationTemplate; NotificationTemplate negativeNotificationTemplate; @@ -75,7 +75,7 @@ public void setUp() { NotificationChannels.EMAIL_CHANNEL.getChannelType()); when(i18nMgtDataHolder.getDefaultEmailTemplates()).thenReturn(defaultEmailTemplate); - inMemoryBasedTemplateManager = new InMemoryBasedTemplateManager(); + systemDefaultTemplateManager = new SystemDefaultTemplateManager(); initTestNotificationTemplates(); } @@ -92,12 +92,12 @@ private void initTestNotificationTemplates() { @Test public void testIsNotificationTemplateTypeExists() throws Exception { - assertFalse(inMemoryBasedTemplateManager.isNotificationTemplateTypeExists(StringUtils.EMPTY, + assertFalse(systemDefaultTemplateManager.isNotificationTemplateTypeExists(StringUtils.EMPTY, NotificationChannels.EMAIL_CHANNEL.getChannelType(), tenantDomain)); - assertFalse(inMemoryBasedTemplateManager.isNotificationTemplateTypeExists( + assertFalse(systemDefaultTemplateManager.isNotificationTemplateTypeExists( negativeNotificationTemplate.getDisplayName(), NotificationChannels.EMAIL_CHANNEL.getChannelType(), tenantDomain)); - assertTrue(inMemoryBasedTemplateManager.isNotificationTemplateTypeExists( + assertTrue(systemDefaultTemplateManager.isNotificationTemplateTypeExists( positiveNotificationTemplate.getDisplayName(), NotificationChannels.EMAIL_CHANNEL.getChannelType(), tenantDomain)); } @@ -105,7 +105,7 @@ public void testIsNotificationTemplateTypeExists() throws Exception { @Test public void testListNotificationTemplateTypes() throws Exception { - List displayNames = inMemoryBasedTemplateManager.listNotificationTemplateTypes( + List displayNames = systemDefaultTemplateManager.listNotificationTemplateTypes( NotificationChannels.EMAIL_CHANNEL.getChannelType(), tenantDomain); Set displayNamesSet = new HashSet<>(displayNames); assertNotNull(displayNames); @@ -117,16 +117,16 @@ public void testListNotificationTemplateTypes() throws Exception { @Test public void testIsNotificationTemplateExists() throws Exception { - assertFalse(inMemoryBasedTemplateManager.isNotificationTemplateExists(StringUtils.EMPTY, EN_US, + assertFalse(systemDefaultTemplateManager.isNotificationTemplateExists(StringUtils.EMPTY, EN_US, NotificationChannels.EMAIL_CHANNEL.getChannelType(), dummyAppId, tenantDomain)); - assertFalse(inMemoryBasedTemplateManager.isNotificationTemplateExists(dummyDisplayName, StringUtils.EMPTY, + assertFalse(systemDefaultTemplateManager.isNotificationTemplateExists(dummyDisplayName, StringUtils.EMPTY, NotificationChannels.EMAIL_CHANNEL.getChannelType(), dummyAppId, tenantDomain)); - assertFalse(inMemoryBasedTemplateManager.isNotificationTemplateExists(dummyDisplayName, EN_US, + assertFalse(systemDefaultTemplateManager.isNotificationTemplateExists(dummyDisplayName, EN_US, NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain)); - assertFalse(inMemoryBasedTemplateManager.isNotificationTemplateExists( + assertFalse(systemDefaultTemplateManager.isNotificationTemplateExists( negativeNotificationTemplate.getDisplayName(), EN_US, NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain)); - assertTrue(inMemoryBasedTemplateManager.isNotificationTemplateExists( + assertTrue(systemDefaultTemplateManager.isNotificationTemplateExists( positiveNotificationTemplate.getDisplayName(), EN_US, NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain)); } @@ -134,16 +134,16 @@ public void testIsNotificationTemplateExists() throws Exception { @Test public void testGetNotificationTemplate() throws Exception { - assertNull(inMemoryBasedTemplateManager.getNotificationTemplate(StringUtils.EMPTY, EN_US, + assertNull(systemDefaultTemplateManager.getNotificationTemplate(StringUtils.EMPTY, EN_US, NotificationChannels.EMAIL_CHANNEL.getChannelType(), dummyAppId, tenantDomain)); - assertNull(inMemoryBasedTemplateManager.getNotificationTemplate(dummyDisplayName, StringUtils.EMPTY, + assertNull(systemDefaultTemplateManager.getNotificationTemplate(dummyDisplayName, StringUtils.EMPTY, NotificationChannels.EMAIL_CHANNEL.getChannelType(), dummyAppId, tenantDomain)); - assertNull(inMemoryBasedTemplateManager.getNotificationTemplate(dummyDisplayName, EN_US, + assertNull(systemDefaultTemplateManager.getNotificationTemplate(dummyDisplayName, EN_US, NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain)); - assertNull(inMemoryBasedTemplateManager.getNotificationTemplate( + assertNull(systemDefaultTemplateManager.getNotificationTemplate( negativeNotificationTemplate.getDisplayName(), EN_US, NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain)); - assertNotNull(inMemoryBasedTemplateManager.getNotificationTemplate( + assertNotNull(systemDefaultTemplateManager.getNotificationTemplate( positiveNotificationTemplate.getDisplayName(), EN_US, NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain)); } @@ -151,14 +151,14 @@ public void testGetNotificationTemplate() throws Exception { @Test public void testListNotificationTemplates() throws Exception { - assertTrue(inMemoryBasedTemplateManager.listNotificationTemplates(StringUtils.EMPTY, + assertTrue(systemDefaultTemplateManager.listNotificationTemplates(StringUtils.EMPTY, NotificationChannels.EMAIL_CHANNEL.getChannelType(), dummyAppId, tenantDomain).isEmpty()); - assertTrue(inMemoryBasedTemplateManager.listNotificationTemplates(dummyDisplayName, + assertTrue(systemDefaultTemplateManager.listNotificationTemplates(dummyDisplayName, NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain).isEmpty()); - assertTrue(inMemoryBasedTemplateManager.listNotificationTemplates( + assertTrue(systemDefaultTemplateManager.listNotificationTemplates( negativeNotificationTemplate.getDisplayName(), NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain).isEmpty()); - assertFalse(inMemoryBasedTemplateManager.listNotificationTemplates( + assertFalse(systemDefaultTemplateManager.listNotificationTemplates( positiveNotificationTemplate.getDisplayName(), NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain).isEmpty()); } @@ -166,9 +166,9 @@ public void testListNotificationTemplates() throws Exception { @Test public void testListAllNotificationTemplates() throws Exception { - assertFalse(inMemoryBasedTemplateManager.listAllNotificationTemplates( + assertFalse(systemDefaultTemplateManager.listAllNotificationTemplates( NotificationChannels.EMAIL_CHANNEL.getChannelType(), tenantDomain).isEmpty()); - assertTrue(inMemoryBasedTemplateManager.listAllNotificationTemplates( + assertTrue(systemDefaultTemplateManager.listAllNotificationTemplates( NotificationChannels.SMS_CHANNEL.getChannelType(), tenantDomain).isEmpty()); } diff --git a/components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/TemplatePersistenceManagerFactoryTest.java b/components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/TemplatePersistenceManagerFactoryTest.java index 47c1b3ec..11aa239a 100644 --- a/components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/TemplatePersistenceManagerFactoryTest.java +++ b/components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/TemplatePersistenceManagerFactoryTest.java @@ -26,20 +26,24 @@ import org.testng.annotations.Test; import org.wso2.carbon.base.CarbonBaseConstants; import org.wso2.carbon.email.mgt.internal.I18nMgtDataHolder; +import org.wso2.carbon.identity.common.testng.WithCarbonHome; import org.wso2.carbon.identity.core.persistence.registry.RegistryResourceMgtService; import org.wso2.carbon.identity.core.util.IdentityUtil; +import java.lang.reflect.Field; import java.nio.file.Paths; import static org.mockito.MockitoAnnotations.initMocks; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; import static org.wso2.carbon.email.mgt.constants.I18nMgtConstants.NOTIFICATION_TEMPLATES_STORAGE_CONFIG; /** * Class that contains the test cases for {@link TemplatePersistenceManagerFactory}. */ +@WithCarbonHome @PrepareForTest({I18nMgtDataHolder.class, IdentityUtil.class}) public class TemplatePersistenceManagerFactoryTest extends PowerMockTestCase { @@ -52,8 +56,6 @@ public class TemplatePersistenceManagerFactoryTest extends PowerMockTestCase { @BeforeMethod public void setUp() { - setUpCarbonHome(); - initMocks(this); mockStatic(I18nMgtDataHolder.class); i18nMgtDataHolder = PowerMockito.mock(I18nMgtDataHolder.class); @@ -65,64 +67,73 @@ public void setUp() { } @Test - public void shouldReturnDBBasedTemplateManagerWhenConfigIsDatabase() { + public void shouldUseDBBasedTemplateManagerWhenConfigIsDatabase() { when(IdentityUtil.getProperty(NOTIFICATION_TEMPLATES_STORAGE_CONFIG)).thenReturn("database"); TemplatePersistenceManager templatePersistenceManager = templatePersistenceManagerFactory.getTemplatePersistenceManager(); - assertTrue(templatePersistenceManager instanceof DBBasedTemplateManager); + assertTrue(templatePersistenceManager instanceof UnifiedTemplateManager); + assertUnderlyingManagerType(templatePersistenceManager, DBBasedTemplateManager.class); } @Test - public void shouldReturnHybridTemplateManagerWhenConfigIsOnMigration() { + public void shouldUseHybridTemplateManagerWhenConfigIsOnMigration() { when(IdentityUtil.getProperty(NOTIFICATION_TEMPLATES_STORAGE_CONFIG)).thenReturn("hybrid"); TemplatePersistenceManager templatePersistenceManager = templatePersistenceManagerFactory.getTemplatePersistenceManager(); - assertTrue(templatePersistenceManager instanceof HybridTemplateManager); + assertTrue(templatePersistenceManager instanceof UnifiedTemplateManager); + assertUnderlyingManagerType(templatePersistenceManager, HybridTemplateManager.class); } @Test - public void shouldReturnRegistryBasedTemplateManagerWhenConfigIsRegistry() { + public void shouldUseRegistryBasedTemplateManagerWhenConfigIsRegistry() { when(IdentityUtil.getProperty(NOTIFICATION_TEMPLATES_STORAGE_CONFIG)).thenReturn("registry"); TemplatePersistenceManager templatePersistenceManager = templatePersistenceManagerFactory.getTemplatePersistenceManager(); - assertTrue(templatePersistenceManager instanceof RegistryBasedTemplateManager); + assertTrue(templatePersistenceManager instanceof UnifiedTemplateManager); + assertUnderlyingManagerType(templatePersistenceManager, RegistryBasedTemplateManager.class); } @Test - public void shouldReturnDBBasedTemplateManagerWhenConfigIsInvalid() { + public void shouldUseDBBasedTemplateManagerWhenConfigIsInvalid() { when(IdentityUtil.getProperty(NOTIFICATION_TEMPLATES_STORAGE_CONFIG)).thenReturn("invalid"); TemplatePersistenceManager templatePersistenceManager = templatePersistenceManagerFactory.getTemplatePersistenceManager(); - assertTrue(templatePersistenceManager instanceof DBBasedTemplateManager); + assertTrue(templatePersistenceManager instanceof UnifiedTemplateManager); + assertUnderlyingManagerType(templatePersistenceManager, DBBasedTemplateManager.class); } @Test - public void shouldReturnDBBasedTemplateManagerWhenConfigIsBlank() { + public void shouldUseDBBasedTemplateManagerWhenConfigIsBlank() { when(IdentityUtil.getProperty(NOTIFICATION_TEMPLATES_STORAGE_CONFIG)).thenReturn(""); TemplatePersistenceManager templatePersistenceManager = templatePersistenceManagerFactory.getTemplatePersistenceManager(); - assertTrue(templatePersistenceManager instanceof DBBasedTemplateManager); + assertTrue(templatePersistenceManager instanceof UnifiedTemplateManager); + assertUnderlyingManagerType(templatePersistenceManager, DBBasedTemplateManager.class); } @Test - public void shouldReturnDBBasedTemplateManagerWhenConfigIsNull() { + public void shouldUseDBBasedTemplateManagerWhenConfigIsNull() { when(IdentityUtil.getProperty(NOTIFICATION_TEMPLATES_STORAGE_CONFIG)).thenReturn(null); TemplatePersistenceManager templatePersistenceManager = templatePersistenceManagerFactory.getTemplatePersistenceManager(); - assertTrue(templatePersistenceManager instanceof DBBasedTemplateManager); + assertTrue(templatePersistenceManager instanceof UnifiedTemplateManager); + assertUnderlyingManagerType(templatePersistenceManager, DBBasedTemplateManager.class); } - private static void setUpCarbonHome() { - - String carbonHome = Paths.get(System.getProperty("user.dir"), "target", "test-classes").toString(); - System.setProperty(CarbonBaseConstants.CARBON_HOME, carbonHome); - System.setProperty(CarbonBaseConstants.CARBON_CONFIG_DIR_PATH, Paths.get(carbonHome, - "repository/conf").toString()); + private void assertUnderlyingManagerType(TemplatePersistenceManager templatePersistenceManager, Class expectedClass) { + try { + Field field = UnifiedTemplateManager.class.getDeclaredField("templatePersistenceManager"); + field.setAccessible(true); + Object underlyingManager = field.get(templatePersistenceManager); + assertTrue(expectedClass.isInstance(underlyingManager)); + } catch (NoSuchFieldException | IllegalAccessException e) { + fail("Failed to access the underlying TemplatePersistenceManager", e); + } } } diff --git a/components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/UnifiedTemplateManagerTest.java b/components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/UnifiedTemplateManagerTest.java new file mode 100644 index 00000000..62026fcf --- /dev/null +++ b/components/email-mgt/org.wso2.carbon.email.mgt/src/test/java/org/wso2/carbon/email/mgt/store/UnifiedTemplateManagerTest.java @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * 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. + */ + +package org.wso2.carbon.email.mgt.store; + +import org.apache.commons.lang.StringUtils; +import org.mockito.Mock; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.testng.PowerMockTestCase; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.wso2.carbon.email.mgt.internal.I18nMgtDataHolder; +import org.wso2.carbon.identity.common.testng.WithCarbonHome; +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.utils.CarbonUtils; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; +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.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; +import static org.wso2.carbon.email.mgt.constants.I18nMgtConstants.NOTIFICATION_TEMPLATES_STORAGE_CONFIG; + +/** + * Class that contains the test cases for {@link UnifiedTemplateManager}. + */ +@WithCarbonHome +@PrepareForTest({I18nMgtDataHolder.class, CarbonUtils.class, IdentityUtil.class}) +public class UnifiedTemplateManagerTest extends PowerMockTestCase { + + private static final String tenantDomain = "carbon.super"; + + @Mock + I18nMgtDataHolder i18nMgtDataHolder; + @Mock + TemplatePersistenceManagerFactory templatePersistenceManagerFactory; + @Mock + TemplatePersistenceManager templatePersistenceManager; + + UnifiedTemplateManager unifiedTemplateManager; + List defaultSystemTemplates; + NotificationTemplate positiveNotificationTemplate; + NotificationTemplate negativeNotificationTemplate; + + + @BeforeMethod + public void setUp() { + + initTestNotificationTemplates(); + + initMocks(this); + mockStatic(I18nMgtDataHolder.class); + i18nMgtDataHolder = PowerMockito.mock(I18nMgtDataHolder.class); + when(I18nMgtDataHolder.getInstance()).thenReturn(i18nMgtDataHolder); + when(i18nMgtDataHolder.getDefaultEmailTemplates()).thenReturn(defaultSystemTemplates); + + mockStatic(IdentityUtil.class); + when(IdentityUtil.getProperty(NOTIFICATION_TEMPLATES_STORAGE_CONFIG)).thenReturn("registry"); + + templatePersistenceManager = PowerMockito.mock(TemplatePersistenceManager.class); + unifiedTemplateManager = new UnifiedTemplateManager(templatePersistenceManager); + templatePersistenceManagerFactory = PowerMockito.mock(TemplatePersistenceManagerFactory.class); + when(templatePersistenceManagerFactory.getTemplatePersistenceManager()).thenReturn(unifiedTemplateManager); + } + + @Test + public void testListAllNotificationTemplates() throws Exception { + + assertFalse(unifiedTemplateManager.listAllNotificationTemplates( + NotificationChannels.EMAIL_CHANNEL.getChannelType(), tenantDomain).isEmpty()); + assertTrue(unifiedTemplateManager.listAllNotificationTemplates( + NotificationChannels.SMS_CHANNEL.getChannelType(), tenantDomain).isEmpty()); + } + + @Test + public void testListNotificationTemplates() throws Exception { + + List templateListForDummyScenario = + unifiedTemplateManager.listNotificationTemplates(positiveNotificationTemplate.getType(), + NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain); + assertTrue(templateListForDummyScenario.isEmpty()); + + List templateListForNegativeScenario = unifiedTemplateManager.listNotificationTemplates( + negativeNotificationTemplate.getType(), + NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain); + assertTrue(templateListForNegativeScenario.isEmpty()); + + List templateListForValidScenario = unifiedTemplateManager.listNotificationTemplates( + defaultSystemTemplates.get(0).getType(), + NotificationChannels.EMAIL_CHANNEL.getChannelType(), StringUtils.EMPTY, tenantDomain); + assertFalse(templateListForValidScenario.isEmpty()); + } + + @Test + public void testAddOrUpdateNotificationTemplateWhenAddingDefaultTemplate() throws Exception { + + NotificationTemplate notificationTemplate = defaultSystemTemplates.get(0); + + // Mock the behavior to simulate add template -> the template not exists in the persistent storage + when(templatePersistenceManager.isNotificationTemplateExists( + notificationTemplate.getDisplayName(), + notificationTemplate.getLocale(), + notificationTemplate.getNotificationChannel(), + null, + tenantDomain)).thenReturn(false); + unifiedTemplateManager.addOrUpdateNotificationTemplate(notificationTemplate, null, tenantDomain); + + // Assert logic + verify(templatePersistenceManager, never()).addOrUpdateNotificationTemplate(notificationTemplate, null, + tenantDomain); + verify(templatePersistenceManager, never()).deleteNotificationTemplate( + notificationTemplate.getDisplayName(), + notificationTemplate.getLocale(), + notificationTemplate.getNotificationChannel(), + null, + tenantDomain); + } + + @Test + public void testAddOrUpdateNotificationTemplateWhenUpdatingToDefaultTemplate() throws Exception { + + NotificationTemplate notificationTemplate = defaultSystemTemplates.get(0); + + // Mock the behavior to simulate update template -> the template exists in the persistent storage + when(templatePersistenceManager.isNotificationTemplateExists( + notificationTemplate.getDisplayName(), + notificationTemplate.getLocale(), + notificationTemplate.getNotificationChannel(), + null, + tenantDomain)).thenReturn(true); + unifiedTemplateManager.addOrUpdateNotificationTemplate(notificationTemplate, null, tenantDomain); + + // Assert logic + verify(templatePersistenceManager, never()).addOrUpdateNotificationTemplate(notificationTemplate, null, + tenantDomain); + verify(templatePersistenceManager).deleteNotificationTemplate( + notificationTemplate.getDisplayName(), + notificationTemplate.getLocale(), + notificationTemplate.getNotificationChannel(), + null, + tenantDomain); + } + + @Test + public void testAddOrUpdateNotificationTemplateWhenAddingCustomTemplate() throws Exception { + + NotificationTemplate notificationTemplate = positiveNotificationTemplate; + unifiedTemplateManager.addOrUpdateNotificationTemplate(notificationTemplate, null, tenantDomain); + + // Assert logic + verify(templatePersistenceManager).addOrUpdateNotificationTemplate(notificationTemplate, null, tenantDomain); + verify(templatePersistenceManager, never()).isNotificationTemplateExists( + notificationTemplate.getDisplayName(), + notificationTemplate.getLocale(), + notificationTemplate.getNotificationChannel(), + null, + tenantDomain); + verify(templatePersistenceManager, never()).deleteNotificationTemplate( + notificationTemplate.getDisplayName(), + notificationTemplate.getLocale(), + notificationTemplate.getNotificationChannel(), + null, + tenantDomain); + } + + @Test + public void testAddOrUpdateNotificationTemplateWhenUpdatingCustomTemplate() throws Exception { + + NotificationTemplate notificationTemplate = positiveNotificationTemplate; + unifiedTemplateManager.addOrUpdateNotificationTemplate(notificationTemplate, null, tenantDomain); + + // Assert logic + verify(templatePersistenceManager).addOrUpdateNotificationTemplate(notificationTemplate, null, tenantDomain); + verify(templatePersistenceManager, never()).isNotificationTemplateExists( + notificationTemplate.getDisplayName(), + notificationTemplate.getLocale(), + notificationTemplate.getNotificationChannel(), + null, + tenantDomain); + verify(templatePersistenceManager, never()).deleteNotificationTemplate( + notificationTemplate.getDisplayName(), + notificationTemplate.getLocale(), + notificationTemplate.getNotificationChannel(), + null, + tenantDomain); + } + + @Test + public void testAddOrUpdateNotificationTemplateWhenNullTemplate() throws Exception { + + unifiedTemplateManager.addOrUpdateNotificationTemplate(null, null, tenantDomain); + + // Assert logic + verify(templatePersistenceManager).addOrUpdateNotificationTemplate(null, null, tenantDomain); + } + + private void initTestNotificationTemplates() { + + defaultSystemTemplates = new ArrayList<>(); + NotificationTemplate defaultNotificationTemplate = new NotificationTemplate(); + defaultNotificationTemplate.setNotificationChannel(NotificationChannels.EMAIL_CHANNEL.getChannelType()); + defaultNotificationTemplate.setType("passwordReset"); + defaultNotificationTemplate.setDisplayName("PasswordReset"); + defaultNotificationTemplate.setLocale("en_US"); + defaultNotificationTemplate.setBody("passwordReset_Body"); + defaultNotificationTemplate.setSubject("passwordReset_Subject"); + defaultNotificationTemplate.setFooter("passwordReset_Footer"); + defaultNotificationTemplate.setContentType("text/html"); + defaultSystemTemplates.add(defaultNotificationTemplate); + + positiveNotificationTemplate = new NotificationTemplate(); + positiveNotificationTemplate.setNotificationChannel(NotificationChannels.EMAIL_CHANNEL.getChannelType()); + positiveNotificationTemplate.setType("dummyType"); + positiveNotificationTemplate.setDisplayName("dummyDisplayName"); + positiveNotificationTemplate.setLocale("en_US"); + positiveNotificationTemplate.setBody("dummyBody"); + positiveNotificationTemplate.setSubject("dummySubject"); + positiveNotificationTemplate.setFooter("dummyFooter"); + + negativeNotificationTemplate = new NotificationTemplate(); + negativeNotificationTemplate.setNotificationChannel(NotificationChannels.EMAIL_CHANNEL.getChannelType()); + negativeNotificationTemplate.setType("dummyType"); + negativeNotificationTemplate.setDisplayName("dummyDisplayName"); + negativeNotificationTemplate.setLocale("en_US"); + } +} diff --git a/components/email-mgt/org.wso2.carbon.email.mgt/src/test/resources/repository/conf/carbon.xml b/components/email-mgt/org.wso2.carbon.email.mgt/src/test/resources/repository/conf/carbon.xml new file mode 100644 index 00000000..0194bb42 --- /dev/null +++ b/components/email-mgt/org.wso2.carbon.email.mgt/src/test/resources/repository/conf/carbon.xml @@ -0,0 +1,686 @@ + + + + + + + + WSO2 Identity Server + + + IS + + + 5.3.0 + + + localhost + + + localhost + + + local:/${carbon.context}/services/ + + + + + + + IdentityServer + + + + + + + org.wso2.carbon + + + / + + + + + + + + + 15 + + + + + + + + + 0 + + + + + 9999 + + 11111 + + + + + + 10389 + + 8000 + + + + + + 10500 + + + + + + + + + org.wso2.carbon.tomcat.jndi.CarbonJavaURLContextFactory + + + + + + + + + java + + + + + + + + + + false + + + false + + + 600 + + + + false + + + + + + + + 30 + + + + + + + + + 15 + + + + + + ${carbon.home}/repository/deployment/server/ + + + 15 + + + ${carbon.home}/repository/conf/axis2/axis2.xml + + + 30000 + + + ${carbon.home}/repository/deployment/client/ + + ${carbon.home}/repository/conf/axis2/axis2_client.xml + + true + + + + + + + + + + admin + Default Administrator Role + + + user + Default User Role + + + + + + + + + + + + ${carbon.home}/repository/resources/security/wso2carbon.jks + + JKS + + wso2carbon + + wso2carbon + + wso2carbon + + + + + + ${carbon.home}/repository/resources/security/client-truststore.jks + + JKS + + wso2carbon + + + + + + + + + + + + + + + + + + + UserManager + + + false + + org.wso2.carbon.identity.provider.AttributeCallbackHandler + + + org.wso2.carbon.identity.sts.store.DBTokenStore + + + true + allow + + + + + + + claim_mgt_menu + identity_mgt_emailtemplate_menu + identity_security_questions_menu + + + + ${carbon.home}/tmp/work + + + + + + true + + + 10 + + + 30 + + + + + + 100 + + + + keystore + certificate + * + + org.wso2.carbon.ui.transports.fileupload.AnyFileUploadExecutor + + + + + jarZip + + org.wso2.carbon.ui.transports.fileupload.JarZipUploadExecutor + + + + dbs + + org.wso2.carbon.ui.transports.fileupload.DBSFileUploadExecutor + + + + tools + + org.wso2.carbon.ui.transports.fileupload.ToolsFileUploadExecutor + + + + toolsAny + + org.wso2.carbon.ui.transports.fileupload.ToolsAnyFileUploadExecutor + + + + + + + + + + info + org.wso2.carbon.core.transports.util.InfoProcessor + + + wsdl + org.wso2.carbon.core.transports.util.Wsdl11Processor + + + wsdl2 + org.wso2.carbon.core.transports.util.Wsdl20Processor + + + xsd + org.wso2.carbon.core.transports.util.XsdProcessor + + + + + + false + false + true + svn + http://svnrepo.example.com/repos/ + username + password + true + + + + + + + + + + + + + + + ${require.carbon.servlet} + + + + + true + + + + + + + default repository + http://product-dist.wso2.com/p2/carbon/releases/wilkes/ + + + + + + + + true + + + + + + true + + \ No newline at end of file diff --git a/components/email-mgt/org.wso2.carbon.email.mgt/src/test/resources/testng.xml b/components/email-mgt/org.wso2.carbon.email.mgt/src/test/resources/testng.xml index efe76d25..d03e69ad 100644 --- a/components/email-mgt/org.wso2.carbon.email.mgt/src/test/resources/testng.xml +++ b/components/email-mgt/org.wso2.carbon.email.mgt/src/test/resources/testng.xml @@ -20,7 +20,8 @@ - + + diff --git a/pom.xml b/pom.xml index f5fd9a5f..da5f6f0d 100644 --- a/pom.xml +++ b/pom.xml @@ -313,6 +313,12 @@ ${mockito.inline.version} test + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.testutil + ${carbon.identity.framework.version} + org.jacoco