Micha Kops avatar Micha Kops committed 300de46

issue #11, #12 implemented, project website updated

Comments (0)

Files changed (9)

src/main/java/com/hascode/confluence/plugin/socialcomments/service/SocialNotificationServiceImpl.java

 	 */
 	private final SocialCommentsConfigurationService	configService;
 
-	public SocialNotificationServiceImpl(final SettingsManager settingsManager, final SocialCommentsConfigurationService configService) {
+	/**
+	 * the template creator
+	 */
+	private final SocialNotificationTemplateCreator		templateCreator;
+
+	public SocialNotificationServiceImpl(final SettingsManager settingsManager, final SocialCommentsConfigurationService configService, final SocialNotificationTemplateCreator templateCreator) {
 		this.settingsManager = settingsManager;
 		this.configService = configService;
+		this.templateCreator = templateCreator;
 	}
 
 	/*
 		}
 
 		final String body = generateMailBody(user, comment);
+		if (body == null) {
+			logger.warn("e-mail body empty .. skipping here ..");
+			return;
+		}
+
 		final ConfluenceMailQueueItem mailItem = new ConfluenceMailQueueItem(user.getEmail(), config.getEmailSubject(), body, MIME_TYPE);
 		mailItem.setFromName(config.getFromEmail());
 		logger.debug("trying to send mail: " + mailItem.toString());
 	 * @return the generated mail body
 	 */
 	private String generateMailBody(final User user, final Comment comment) {
-		final SocialCommentsConfiguration config = configService.load();
-		final String url = settingsManager.getGlobalSettings().getBaseUrl() + comment.getUrlPath();
-		final String userName = user.getFullName();
-		final String content = comment.getContent();
-
-		String body = config.getNotificationText();
-		body = body.replaceAll("#name#", userName);
-		body = body.replaceAll("#url#", url);
-		body = body.replaceAll("#content#", content);
-		return body;
+		return templateCreator.generateBody(user, comment);
 	}
-
 }

src/main/java/com/hascode/confluence/plugin/socialcomments/service/SocialNotificationTemplateCreator.java

+package com.hascode.confluence.plugin.socialcomments.service;
+
+import com.atlassian.confluence.pages.Comment;
+import com.atlassian.user.User;
+
+public interface SocialNotificationTemplateCreator {
+	/**
+	 * creates the notification's body
+	 * 
+	 * @param user
+	 *            the user notified
+	 * @param comment
+	 *            the original comment
+	 * @return the created notification
+	 */
+	public abstract String generateBody(final User user, final Comment comment);
+}

src/main/java/com/hascode/confluence/plugin/socialcomments/service/SocialNotificationTemplateCreatorImpl.java

+package com.hascode.confluence.plugin.socialcomments.service;
+
+import org.apache.log4j.Logger;
+
+import com.atlassian.confluence.pages.Comment;
+import com.atlassian.confluence.setup.settings.SettingsManager;
+import com.atlassian.user.User;
+import com.hascode.confluence.plugin.socialcomments.persistence.SocialCommentsConfigurationService;
+
+public class SocialNotificationTemplateCreatorImpl implements SocialNotificationTemplateCreator {
+	/**
+	 * the settings manager
+	 */
+	private final SettingsManager						settingsManager;
+
+	/**
+	 * the logger instance
+	 */
+	private final Logger								logger	= Logger.getLogger(this.getClass());
+
+	/**
+	 * the config dao
+	 */
+	private final SocialCommentsConfigurationService	configService;
+
+	public SocialNotificationTemplateCreatorImpl(final SocialCommentsConfigurationService configService, final SettingsManager settingsManager) {
+		this.settingsManager = settingsManager;
+		this.configService = configService;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.hascode.confluence.plugin.socialcomments.service.
+	 * SocialNotificationTemplateCreator#generateBody(com.atlassian.user.User,
+	 * com.atlassian.confluence.pages.Comment)
+	 */
+	@Override
+	public String generateBody(final User user, final Comment comment) {
+		final String url = settingsManager.getGlobalSettings().getBaseUrl() + comment.getUrlPath();
+		final String userName = user.getFullName();
+		final String content = comment.getContent();
+		final String notification = configService.load().getNotificationText();
+		if (notification == null) {
+			logger.warn("notification is not set in the configuration, skipping further processing..");
+			return null;
+		}
+
+		String body = notification;
+		body = body.replaceAll("#name#", userName);
+		body = body.replaceAll("#url#", url);
+		body = body.replaceAll("#content#", content);
+		body = body.replaceAll("#creator#", comment.getCreatorName());
+
+		logger.debug("generated notification template is: " + body);
+		return body;
+	}
+}

src/main/resources/atlassian-plugin.xml

 		<interface>com.hascode.confluence.plugin.socialcomments.persistence.SocialCommentsConfigurationService
 		</interface>
 	</component>
+	<component key="socialCommentsTemplateCreator"
+		i18n-name-key="socialcomments.component.component.templatecreator"
+		class="com.hascode.confluence.plugin.socialcomments.service.SocialNotificationTemplateCreatorImpl">
+		<interface>com.hascode.confluence.plugin.socialcomments.service.SocialNotificationTemplateCreator
+		</interface>
+	</component>
 	<!-- /COMPONENTS -->
 
 	<!-- XWORK ACTIONS -->
 
 	<!-- WEB ITEMS -->
 	<web-item key="socialcomments.component.webitem.configurelink"
-		i18n-name-key="socialcomments.component.webitem.configurelink" section="system.admin/administration"
-		weight="200">
+		i18n-name-key="socialcomments.component.webitem.configurelink"
+		section="system.admin/administration" weight="200">
 		<label key="socialcomments.component.webitem.configurelink.label" />
-		<link>$req.getContextPath()/plugins/socialcomments/configure.action</link>
+		<link>$req.getContextPath()/plugins/socialcomments/configure.action
+		</link>
 	</web-item>
 	<!-- /WEB ITEMS -->
 

src/main/resources/com/hascode/confluence/plugin/socialcomments/messages.properties

 socialcomments.msg.subject=E-Mail Subject
 socialcomments.msg.subject.example=e.g. Social Comment Notification Received
 socialcomments.msg.notification=Notification Text
-socialcomments.msg.notification.hint=The following placeholders are allowed: #name# #url# #content#
+socialcomments.msg.notification.hint=The following placeholders are allowed: #name# #url# #content# #creator#
 socialcomments.msg.notification.example=e.g. Dear #name#, someone wanted you to receive this notification for the following wiki comment: #url#
 socialcomments.msg.from.email=Sender's E-Mail Address
 socialcomments.msg.from.email.example=e.g. admin@host.com
 socialcomments.msg.submit=Save settings
 socialcomments.component.component.configservice=The Configuration Service.
 socialcomments.component.webitem.configurelink=Configuration Link.
-socialcomments.component.webitem.configurelink.label=Social Comments Configuration
+socialcomments.component.webitem.configurelink.label=Social Comments Configuration
+socialcomments.component.component.templatecreator=Template Creator Service

src/site/apt/index.apt

   
 * Roadmap
 
-  Make the regular expression for extracting a user name from the comment configurable in the admin area
-  
-  Add a configuration to restrict this function to specific spaces/exclude specific spaces
-  
+  Take a look at the current issues at {{{https://bitbucket.org/hascode/social-comments-plugin/issues}Bitbucket.org}}. Past releases are listed {{{/releases.html}here}}.  
   
     

src/site/apt/releases.apt

+Releases
+
+* 0.9.6 Feature Enhancements (22 May 2011)
+
+	* {{{https://bitbucket.org/hascode/social-comments-plugin/issue/10/include-the-content-of-the-comment-in-the}#10 Include the content of the comment in the email notification}}
+	
+	* {{{https://bitbucket.org/hascode/social-comments-plugin/issue/11/refactor-the-notification-template}#11 Refactor the notification template creation process}}
+	
+	* {{{https://bitbucket.org/hascode/social-comments-plugin/issue/12/add-placeholder-for-the-comments-creator}#12 Add placeholder for the comment's creator}}
+	
+    
+    
+* 0.9.5 Initial Release (07 Apr 2011)
+
+	* User extraction and notification from Confluence comments
+	
+	* Configurable notification e-mail settings (subject, sender, e-mail template)
+	
+	* Placeholder support for the e-mail template (notified user's name, comment url)
+	
+	* Active config validation, no notification is send if the configuration is not valid
+ 

src/test/java/com/hascode/confluence/plugin/socialcomments/service/SocialNotificationServiceTest.java

 package com.hascode.confluence.plugin.socialcomments.service;
 
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import org.junit.Before;
 	@Mock
 	private SocialCommentsConfigurationService	configService;
 
+	@Mock
+	private SocialNotificationTemplateCreator	templateCreator;
+
 	@Before
 	public void setUp() {
 		MockitoAnnotations.initMocks(this);
 	public void testNotifyUser() {
 		// stub
 		when(comment.getUrlPath()).thenReturn("/somecommentulrstring");
+		when(comment.getContent()).thenReturn("This is a test comment");
 		when(user.getFullName()).thenReturn("I R admin");
 		when(user.getEmail()).thenReturn("tester@hascode.com");
 		when(settingsManager.getGlobalSettings()).thenReturn(settings);
 		PowerMockito.mock(ConfluenceMailQueueItem.class);
 
 		// init
-		final SocialNotificationService service = new SocialNotificationServiceImpl(settingsManager, configService);
+		final SocialNotificationService service = new SocialNotificationServiceImpl(settingsManager, configService, templateCreator);
 
 		// test
 		service.notifyUser(user, comment);
 
 		// spy
+		verify(templateCreator.generateBody(any(User.class), any(Comment.class)), times(1));
 	}
 }

src/test/java/com/hascode/confluence/plugin/socialcomments/service/SocialNotificationTemplateCreatorTest.java

+package com.hascode.confluence.plugin.socialcomments.service;
+
+import static org.mockito.Mockito.when;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.atlassian.confluence.pages.Comment;
+import com.atlassian.confluence.setup.settings.Settings;
+import com.atlassian.confluence.setup.settings.SettingsManager;
+import com.atlassian.user.User;
+import com.hascode.confluence.plugin.socialcomments.config.SocialCommentsConfiguration;
+import com.hascode.confluence.plugin.socialcomments.persistence.SocialCommentsConfigurationService;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SocialNotificationTemplateCreatorTest {
+	private static final String					BASE_URL			= "http://localhost:8080/";
+	private static final String					COMMENT_PATH		= "somecomment123#2133412";
+	private static final String					TEMPLATE_CONTENT	= "Dear #name# #url# #content# #creator#";
+	private static final String					USER_NAME			= "tester";
+	private static final String					COMMENT_CONTENT		= "Hey @admin: i wanted to nofify you ..";
+	private static final String					CREATOR_NAME		= "John the Admin";
+	private static final String					OUTPUT_EXPECTED		= "Dear " + USER_NAME + " " + BASE_URL + COMMENT_PATH + " " + COMMENT_CONTENT + " " + CREATOR_NAME;
+
+	@Mock
+	private SocialCommentsConfigurationService	configService;
+
+	@Mock
+	private SettingsManager						settingsManager;
+
+	@Mock
+	private User								user;
+
+	@Mock
+	private Comment								comment;
+
+	@Mock
+	private Settings							settings;
+
+	@Mock
+	private SocialCommentsConfiguration			config;
+
+	@Before
+	public void before() {
+		MockitoAnnotations.initMocks(this);
+	}
+
+	@Test
+	public void testInvalidState() {
+		// init
+		final SocialNotificationTemplateCreator creator = new SocialNotificationTemplateCreatorImpl(configService, settingsManager);
+
+		// test
+		try {
+			creator.generateBody(user, comment);
+			Assert.fail("npe should be thrown..");
+		} catch (NullPointerException e) {
+		}
+
+		when(settingsManager.getGlobalSettings()).thenReturn(settings);
+		when(settings.getBaseUrl()).thenReturn(BASE_URL);
+		when(comment.getUrlPath()).thenReturn(COMMENT_PATH);
+		try {
+			creator.generateBody(user, comment);
+			Assert.fail("npe should be thrown..");
+		} catch (NullPointerException e) {
+		}
+	}
+
+	@Test
+	public void testSuccess() {
+		// init
+		final SocialNotificationTemplateCreator creator = new SocialNotificationTemplateCreatorImpl(configService, settingsManager);
+
+		// test
+		when(settingsManager.getGlobalSettings()).thenReturn(settings);
+		when(settings.getBaseUrl()).thenReturn(BASE_URL);
+		when(comment.getUrlPath()).thenReturn(COMMENT_PATH);
+		when(comment.getContent()).thenReturn(COMMENT_CONTENT);
+		when(comment.getCreatorName()).thenReturn(CREATOR_NAME);
+		when(configService.load()).thenReturn(config);
+		when(config.getNotificationText()).thenReturn(TEMPLATE_CONTENT);
+		when(user.getFullName()).thenReturn(USER_NAME);
+
+		String result = creator.generateBody(user, comment);
+		Assert.assertNotNull(result);
+		Assert.assertEquals(OUTPUT_EXPECTED, result);
+	}
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.