Commits

David Chui committed 420dcc9

[CONTRB-40] Second pass. Added a notification (watch) event listener so that the watched content gets indexed with the watcher contribution information.

Comments (0)

Files changed (7)

contrb-40/src/main/java/com/atlassian/confluence/contributors/listeners/NotificationEventListener.java

+package com.atlassian.confluence.contributors.listeners;
+
+import com.atlassian.bonnie.Indexer;
+import com.atlassian.confluence.event.events.content.mail.notification.ContentNotificationAddedEvent;
+import com.atlassian.confluence.event.events.content.mail.notification.ContentNotificationEvent;
+import com.atlassian.confluence.event.events.content.mail.notification.ContentNotificationRemovedEvent;
+import com.atlassian.confluence.event.events.content.mail.notification.SpaceNotificationAddedEvent;
+import com.atlassian.confluence.event.events.content.mail.notification.SpaceNotificationEvent;
+import com.atlassian.confluence.event.events.content.mail.notification.SpaceNotificationRemovedEvent;
+import com.atlassian.confluence.pages.AbstractPage;
+import com.atlassian.confluence.spaces.Space;
+import com.atlassian.event.Event;
+import com.atlassian.event.EventListener;
+
+public class NotificationEventListener implements EventListener
+{
+    private Indexer indexer;
+
+    private static final Class[] HANDLED_CLASSES = new Class[] {
+            ContentNotificationAddedEvent.class,
+            ContentNotificationRemovedEvent.class,
+            SpaceNotificationAddedEvent.class,
+            SpaceNotificationRemovedEvent.class
+    };
+
+    public void handleEvent(final Event event)
+    {
+        if (event instanceof ContentNotificationEvent)
+        {
+            final ContentNotificationEvent contentNotificationEvent = (ContentNotificationEvent) event;
+            final AbstractPage pageToBeReindexed = contentNotificationEvent.getPage();
+
+            indexer.reIndex(pageToBeReindexed);
+        }
+        else if (event instanceof SpaceNotificationEvent)
+        {
+            final SpaceNotificationEvent spaceNotificationEvent = (SpaceNotificationEvent) event;
+            final Space spaceToBeReindexed = spaceNotificationEvent.getSpace();
+
+            indexer.reIndex(spaceToBeReindexed);
+        }
+    }
+
+    public Class[] getHandledEventClasses()
+    {
+        return HANDLED_CLASSES;
+    }
+
+    public void setIndexer(Indexer indexer)
+    {
+        this.indexer = indexer;
+    }
+}

contrb-40/src/main/java/com/atlassian/confluence/contributors/search/extractors/NotificationContributionExtractor.java

 package com.atlassian.confluence.contributors.search.extractors;
 
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.commons.lang.SystemUtils;
 import com.atlassian.bonnie.Searchable;
-import com.atlassian.confluence.mail.notification.NotificationManager;
-import com.atlassian.confluence.mail.notification.Notification;
-import com.atlassian.confluence.spaces.Space;
 import com.atlassian.confluence.pages.AbstractPage;
+import com.atlassian.confluence.spaces.Space;
+import net.sf.hibernate.Hibernate;
+import net.sf.hibernate.HibernateException;
+import net.sf.hibernate.Session;
+import net.sf.hibernate.SessionFactory;
+import net.sf.hibernate.type.Type;
+import org.apache.commons.lang.SystemUtils;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.springframework.orm.hibernate.HibernateCallback;
+import org.springframework.orm.hibernate.HibernateTemplate;
 
+import java.sql.SQLException;
 import java.util.List;
 
 public class NotificationContributionExtractor extends AbstractContributionExtractor
 {
     public static final String WATCHERS = "watchers";
 
-    private NotificationManager notificationManager;
+    private SessionFactory sessionFactory;
 
     public void addFields(
             final Document document,
             final Searchable searchable)
     {
         final StringBuffer watchersStringBuffer;
+        final HibernateTemplate hibernateTemple = new HibernateTemplate(sessionFactory);
+        final List<String> userNames;
 
         if (searchable instanceof Space)
         {
-            final Space space = (Space) searchable;
-
-            watchersStringBuffer = new StringBuffer();
-
-            for (final Notification notification : (List<Notification>) notificationManager.getNotificationsBySpace(space))
-                watchersStringBuffer.append(notification.getUserName()).append(SystemUtils.LINE_SEPARATOR);
-
-            document.add(new Field(WATCHERS, watchersStringBuffer.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
+            userNames = (List<String>) hibernateTemple.execute(
+                    new HibernateCallback()
+                    {
+                        public Object doInHibernate(final Session session) throws HibernateException, SQLException
+                        {
+                            return session.find(
+                                    "select notif.userName from Notification as notif where notif.space.id = :spaceId ",
+                                    new Object[] { new Long(searchable.getId()) },
+                                    new Type[] { Hibernate.LONG }
+                            );
+                        }
+                    }
+            );
         }
         else if (searchable instanceof AbstractPage)
         {
-            final AbstractPage abstractPage = (AbstractPage) searchable;
+            userNames = (List<String>) hibernateTemple.execute(
+                    new HibernateCallback()
+                    {
+                        public Object doInHibernate(final Session session) throws HibernateException, SQLException
+                        {
+                            return session.find(
+                                    "select notif.userName from Notification as notif where notif.page.id = :pageId ",
+                                    new Object[] { new Long(searchable.getId()) },
+                                    new Type[] { Hibernate.LONG }
+                            );
+                        }
+                    }
+            );
+        }
+        else
+        {
+            userNames = null;
+        }
 
+        if (null != userNames)
+        {
             watchersStringBuffer = new StringBuffer();
 
-            for (final Notification notification : (List<Notification>) notificationManager.getNotificationsByPage(abstractPage))
-                watchersStringBuffer.append(notification.getUserName()).append(SystemUtils.LINE_SEPARATOR);
+            for (final String userName : userNames)
+                watchersStringBuffer.append(userName).append(SystemUtils.LINE_SEPARATOR);
 
             document.add(new Field(WATCHERS, watchersStringBuffer.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
         }
     }
 
-    public void setNotificationManager(NotificationManager notificationManager)
+    public void setSessionFactory(SessionFactory sessionFactory)
     {
-        this.notificationManager = notificationManager;
+        this.sessionFactory = sessionFactory;
     }
 }

contrb-40/src/main/java/com/atlassian/confluence/contributors/util/PageDetailsHelper.java

 import com.atlassian.confluence.contributors.search.extractors.AuthorContributionExtractor;
 import com.atlassian.confluence.contributors.search.extractors.CommentContributionExtractor;
 import com.atlassian.confluence.contributors.search.extractors.LabelContributionExtractor;
+import com.atlassian.confluence.contributors.search.extractors.NotificationContributionExtractor;
 import com.atlassian.confluence.labels.LabelParser;
 import com.atlassian.confluence.labels.Namespace;
-import com.atlassian.confluence.mail.notification.NotificationManager;
 import com.atlassian.confluence.pages.AbstractPage;
 import com.atlassian.confluence.user.UserAccessor;
 import com.atlassian.user.User;
 import com.atlassian.util.profiling.UtilTimerStack;
-import net.sf.hibernate.Hibernate;
-import net.sf.hibernate.HibernateException;
-import net.sf.hibernate.Session;
 import net.sf.hibernate.SessionFactory;
-import net.sf.hibernate.type.Type;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.lucene.search.HitCollector;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.TermQuery;
-import org.springframework.orm.hibernate.HibernateCallback;
-import org.springframework.orm.hibernate.HibernateTemplate;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.StringReader;
-import java.sql.SQLException;
 import java.util.List;
 
 /**
             final AbstractPage abstractPage,
             final AuthorRankingSystem rankingSystem,
             final int groupingType) {
-//        luceneConnection.withSearch(new LuceneConnection.SearcherAction()
-//        {
-//            public boolean perform(final IndexSearcher indexSearcher) throws IOException
-//            {
-//                final BooleanQuery booleanQuery = new BooleanQuery();
-//
-//                booleanQuery.add(new TermQuery(new Term("handle", new HibernateHandle(abstractPage).toString())), BooleanClause.Occur.SHOULD);
-//                booleanQuery.add(new TermQuery(new Term("handle", new HibernateHandle(abstractPage.getSpace()).toString())), BooleanClause.Occur.SHOULD);
-//
-//                indexSearcher.search(
-//                        booleanQuery,
-//                        new HitCollector()
-//                        {
-//                            public void collect(int i, float v)
-//                            {
-//                                BufferedReader reader = null;
-//                                try
-//                                {
-//                                    final Document document = indexSearcher.doc(i);
-//                                    String line;
-//
-//                                    reader = new BufferedReader(new StringReader(document.get(LabelContributionExtractor.LABEL_CONTRIBUTIONS)));
-//                                    while (null != (line = reader.readLine()))
-//                                    {
-//                                        if (StringUtils.isNotBlank(line))
-//                                        {
-//                                            final User watcher = userAccessor.getUser(line);
-//                                            final String authorName = null == watcher ? ANONYMOUS_USER : watcher.getName();
-//                                            final String authorFullName = null == watcher ? ANONYMOUS_USER : watcher.getFullName();
-//                                            AuthorRanking ranking;
-//
-//                                            if (GROUPBY_CONTRIBUTORS == groupingType)
-//                                            {
-//                                                ranking = rankingSystem.getAuthorRanking(authorName);
-//
-//                                                if (ranking == null)
-//                                                    ranking = rankingSystem.createAuthorRanking(authorName, authorFullName);
-//
-//                                                ranking.incrementWatches(abstractPage.getUrlPath(), abstractPage.getTitle());
-//                                            }
-//                                            else if (GROUPBY_PAGES == groupingType)
-//                                            {
-//                                                final String pageUrlPath = abstractPage.getUrlPath();
-//                                                ranking = rankingSystem.getAuthorRanking(pageUrlPath);
-//
-//                                                if (ranking == null)
-//                                                    ranking = rankingSystem.createAuthorRanking(pageUrlPath, abstractPage.getTitle());
-//
-//                                                ranking.incrementWatches(authorName, authorFullName);
-//                                            }
-//                                        }
-//                                    }
-//                                }
-//                                catch (final IOException ioe)
-//                                {
-//                                    logger.error("Error collecting information to calculate label contributions of " + abstractPage, ioe);
-//                                }
-//                                finally
-//                                {
-//                                    IOUtils.closeQuietly(reader);
-//                                }
-//                            }
-//                        }
-//                );
-//
-//                return true;
-//            }
-//        });
-        final String name = "PageDetailsHelper::processWatches(AbstractPage, AuthorRankingSystem, int):void";
-
-        try
+        luceneConnection.withSearch(new LuceneConnection.SearcherAction()
         {
-            UtilTimerStack.push(name);
-
-            final HibernateTemplate hibernateTemple = new HibernateTemplate(sessionFactory);
-            final List<String> userNames;
-
-            userNames = (List<String>) hibernateTemple.execute(
-                    new HibernateCallback()
-                    {
-                        public Object doInHibernate(final Session session) throws HibernateException, SQLException
+            public boolean perform(final IndexSearcher indexSearcher) throws IOException
+            {
+                indexSearcher.search(
+                        new TermQuery(new Term("handle", new HibernateHandle(abstractPage).toString())),
+                        new HitCollector()
                         {
-                            final String queryString =
-                                    new StringBuffer("select notif.userName from "
-                                            + " Notification as notif where notif.page.id = :pageId "
-                                            + " or notif.space.id = :spaceId ")
-                                            .toString();
-                            return session.find(
-                                    queryString,
-                                    new Object[] { new Long(abstractPage.getId()), new Long(abstractPage.getSpace().getId()) },
-                                    new Type[] { Hibernate.LONG, Hibernate.LONG }
-                            );
-                        }
-                    }
-            );
+                            public void collect(int i, float v)
+                            {
+                                BufferedReader reader = null;
+                                try
+                                {
+                                    final Document document = indexSearcher.doc(i);
+                                    String line;
 
-            for (final String userName : userNames)
-            {
-                final User user = userAccessor.getUser(userName);
-                final String fullName = null == user ? StringUtils.EMPTY : user.getFullName();
-                AuthorRanking ranking;
+                                    reader = new BufferedReader(new StringReader(document.get(NotificationContributionExtractor.WATCHERS)));
+                                    while (null != (line = reader.readLine()))
+                                    {
+                                        if (StringUtils.isNotBlank(line))
+                                        {
+                                            final User watcher = userAccessor.getUser(line);
+                                            final String authorName = null == watcher ? ANONYMOUS_USER : watcher.getName();
+                                            final String authorFullName = null == watcher ? ANONYMOUS_USER : watcher.getFullName();
+                                            AuthorRanking ranking;
 
-                if (GROUPBY_CONTRIBUTORS == groupingType)
-                {
-                    ranking = rankingSystem.getAuthorRanking(userName);
+                                            if (GROUPBY_CONTRIBUTORS == groupingType)
+                                            {
+                                                ranking = rankingSystem.getAuthorRanking(authorName);
+
+                                                if (ranking == null)
+                                                    ranking = rankingSystem.createAuthorRanking(authorName, authorFullName);
 
-                    if (ranking == null)
-                        ranking = rankingSystem.createAuthorRanking(userName, fullName);
+                                                ranking.incrementWatches(abstractPage.getUrlPath(), abstractPage.getTitle());
+                                            }
+                                            else if (GROUPBY_PAGES == groupingType)
+                                            {
+                                                final String pageUrlPath = abstractPage.getUrlPath();
+                                                ranking = rankingSystem.getAuthorRanking(pageUrlPath);
 
-                    ranking.incrementWatches(abstractPage.getUrlPath(), abstractPage.getTitle());
-                }
-                else if (GROUPBY_PAGES == groupingType)
-                {
-                    final String pageUrlPath = abstractPage.getUrlPath();
-                    ranking = rankingSystem.getAuthorRanking(pageUrlPath);
+                                                if (ranking == null)
+                                                    ranking = rankingSystem.createAuthorRanking(pageUrlPath, abstractPage.getTitle());
 
-                    if (ranking == null)
-                        ranking = rankingSystem.createAuthorRanking(pageUrlPath, abstractPage.getTitle());
+                                                ranking.incrementWatches(authorName, authorFullName);
+                                            }
+                                        }
+                                    }
+                                }
+                                catch (final IOException ioe)
+                                {
+                                    logger.error("Error collecting information to calculate label contributions of " + abstractPage, ioe);
+                                }
+                                finally
+                                {
+                                    IOUtils.closeQuietly(reader);
+                                }
+                            }
+                        }
+                );
 
-                    ranking.incrementWatches(userName, fullName);
-                }
+                return true;
             }
-        }
-        finally
-        {
-            UtilTimerStack.pop(name);
-        }
+        });
     }
 
     public void setLuceneConnection(ILuceneConnection luceneConnection)

contrb-40/src/main/resources/atlassian-plugin.xml

                                  class="com.atlassian.confluence.contributors.search.mapper.PublishedDateAndTitleResultFilterMapper"
                                  handles="publishedDateAndTitle"/>
 
+    <listener name="Notification Event Listener" class="com.atlassian.confluence.contributors.listeners.NotificationEventListener" key="notificationEventListener" />
+
     <extractor name="Page Edit Contribution Extractor" key="authorContributionExtractor" class="com.atlassian.confluence.contributors.search.extractors.AuthorContributionExtractor" priority="1000">
         <description>Indexes content edit statistics.</description>
     </extractor>

contrb-40/src/test/java/com/atlassian/confluence/contributors/listeners/TestNotificationEventListener.java

+package com.atlassian.confluence.contributors.listeners;
+
+import com.atlassian.bonnie.Indexer;
+import com.atlassian.confluence.event.events.admin.ConfluenceReadyEvent;
+import com.atlassian.confluence.event.events.content.mail.notification.ContentNotificationAddedEvent;
+import com.atlassian.confluence.event.events.content.mail.notification.ContentNotificationRemovedEvent;
+import com.atlassian.confluence.event.events.content.mail.notification.NotificationEvent;
+import com.atlassian.confluence.event.events.content.mail.notification.SpaceNotificationAddedEvent;
+import com.atlassian.confluence.event.events.content.mail.notification.SpaceNotificationRemovedEvent;
+import com.atlassian.confluence.mail.notification.DefaultNotificationManager;
+import com.atlassian.confluence.mail.notification.Notification;
+import com.atlassian.confluence.pages.AbstractPage;
+import com.atlassian.confluence.pages.Page;
+import com.atlassian.confluence.spaces.Space;
+import com.atlassian.event.Event;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class TestNotificationEventListener extends MockObjectTestCase
+{
+    private Mock mockIndexer;
+
+    private Indexer indexer;
+
+    private Object eventSource;
+
+    private Notification notification;
+
+    private NotificationEventListener notificationEventListener;
+
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+
+        mockIndexer = new Mock(Indexer.class);
+        indexer = (Indexer) mockIndexer.proxy();
+
+        eventSource = new DefaultNotificationManager();
+
+        notification = new Notification();
+
+        notificationEventListener = new NotificationEventListener();
+        notificationEventListener.setIndexer(indexer);
+    }
+
+    public void testIndexingTriggerWhenPageWatchAdded()
+    {
+        final AbstractPage pageToBeReindexed = new Page();
+        final Event event;
+
+        notification.setPage(pageToBeReindexed);
+        event = new ContentNotificationAddedEvent(eventSource, notification);
+
+        mockIndexer.expects(once()).method("reIndex").with(same(pageToBeReindexed));
+
+        notificationEventListener.handleEvent(event);
+    }
+
+    public void testIndexingTriggerWhenPageWatchRemoved()
+    {
+        final AbstractPage pageToBeReindexed = new Page();
+        final Event event;
+
+        notification.setPage(pageToBeReindexed);
+        event = new ContentNotificationRemovedEvent(eventSource, notification);
+
+        mockIndexer.expects(once()).method("reIndex").with(same(pageToBeReindexed));
+
+        notificationEventListener.handleEvent(event);
+    }
+
+    public void testIndexingTriggerWhenBlogPostWatchAdded()
+    {
+        final AbstractPage pageToBeReindexed = new Page();
+        final Event event;
+
+        notification.setPage(pageToBeReindexed);
+        event = new ContentNotificationAddedEvent(eventSource, notification);
+
+        mockIndexer.expects(once()).method("reIndex").with(same(pageToBeReindexed));
+
+        notificationEventListener.handleEvent(event);
+    }
+
+    public void testIndexingTriggerWhenBlogPostWatchRemoved()
+    {
+        final AbstractPage pageToBeReindexed = new Page();
+        final Event event;
+
+        notification.setPage(pageToBeReindexed);
+        event = new ContentNotificationRemovedEvent(eventSource, notification);
+
+        mockIndexer.expects(once()).method("reIndex").with(same(pageToBeReindexed));
+
+        notificationEventListener.handleEvent(event);
+    }
+
+    public void testIndexingTriggerWhenSpaceWatchAdded()
+    {
+        final Space spaceToBeReindexed = new Space();
+        final Event event;
+
+        notification.setSpace(spaceToBeReindexed);
+        event = new SpaceNotificationAddedEvent(eventSource, notification);
+
+        mockIndexer.expects(once()).method("reIndex").with(same(spaceToBeReindexed));
+
+        notificationEventListener.handleEvent(event);
+    }
+
+    public void testIndexingTriggerWhenSpaceWatchRemoved()
+    {
+        final Space spaceToBeReindexed = new Space();
+        final Event event;
+
+        notification.setSpace(spaceToBeReindexed);
+        event = new SpaceNotificationRemovedEvent(eventSource, notification);
+
+        mockIndexer.expects(once()).method("reIndex").with(same(spaceToBeReindexed));
+
+        notificationEventListener.handleEvent(event);
+    }
+
+    public void testIndexingNotTriggerWhenOnNonSpaceOrAbstractPageNotificationEvents()
+    {
+        final Event event = new ConfluenceReadyEvent(eventSource);
+        notificationEventListener.handleEvent(event);
+    }
+
+    public void testHandledEventsLimitedToNotifications()
+    {
+        final List<Class> handledClasses = Arrays.asList(notificationEventListener.getHandledEventClasses());
+        final List<Class<? extends NotificationEvent>> expectedHandledClasses = Arrays.asList(
+                ContentNotificationAddedEvent.class,
+                ContentNotificationRemovedEvent.class,
+                SpaceNotificationAddedEvent.class,
+                SpaceNotificationRemovedEvent.class
+        );
+
+        assertEquals(expectedHandledClasses.size(), handledClasses.size());
+        assertTrue(handledClasses.containsAll(expectedHandledClasses));
+    }
+}

contrb-40/src/test/java/com/atlassian/confluence/contributors/search/extractors/TestNotificationContributionExtractor.java

 package com.atlassian.confluence.contributors.search.extractors;
 
 import com.atlassian.confluence.mail.notification.Notification;
-import com.atlassian.confluence.mail.notification.NotificationManager;
 import com.atlassian.confluence.pages.Comment;
 import com.atlassian.confluence.pages.Page;
 import com.atlassian.confluence.spaces.Space;
+import net.sf.hibernate.Hibernate;
+import net.sf.hibernate.Session;
+import net.sf.hibernate.SessionFactory;
+import net.sf.hibernate.type.Type;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.SystemUtils;
 import org.apache.lucene.document.Document;
 import org.jmock.MockObjectTestCase;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 public class TestNotificationContributionExtractor extends MockObjectTestCase
 {
-    private Mock mockNotificationManager;
+    private static final String PAGE_NOTIFICATION_QUERY = "select notif.userName from Notification as notif where notif.page.id = :pageId ";
 
-    private NotificationManager notificationManager;
+    private static final String SPACE_NOTIFICATION_QUERY = "select notif.userName from Notification as notif where notif.space.id = :spaceId ";
+
+    private Mock mockSessionFactory;
+
+    private SessionFactory sessionFactory;
+
+    private Mock mockSession;
+
+    private Session session;
 
     private NotificationContributionExtractor notificationContributionExtractor;
 
     {
         super.setUp();
 
-        mockNotificationManager = new Mock(NotificationManager.class);
-        notificationManager = (NotificationManager) mockNotificationManager.proxy();
+        mockSession = new Mock(Session.class);
+        session = (Session) mockSession.proxy();
+
+        mockSessionFactory = new Mock(SessionFactory.class);
+        sessionFactory = (SessionFactory) mockSessionFactory.proxy();
+
+        mockSession.expects(once()).method("getSessionFactory").withNoArguments().will(returnValue(sessionFactory));
+        mockSession.expects(once()).method("flush").withNoArguments();
+        mockSessionFactory.expects(once()).method("openSession").withNoArguments().will(returnValue(session));
 
         notificationContributionExtractor = new NotificationContributionExtractor();
-        notificationContributionExtractor.setNotificationManager(notificationManager);
+        notificationContributionExtractor.setSessionFactory(sessionFactory);
     }
 
     public void testFieldAddedWhenIndexingSpaceWithWatchers()
         spaceNotification.setUserName("admin2");
         notifications.add(spaceNotification);
 
-        mockNotificationManager.expects(once()).method("getNotificationsBySpace")
-                .with(same(spaceToBeIndexed)).will(returnValue(notifications));
+        mockSession.expects(once()).method("find").with(
+                eq(SPACE_NOTIFICATION_QUERY),
+                eq(new Object[] { spaceToBeIndexed.getId() }),
+                eq(new Type[] { Hibernate.LONG })
+        ).will(returnValue(Arrays.asList("admin", "admin2")));
 
         notificationContributionExtractor.addFields(
                 documentToBeIndex,
         final Document documentToBeIndex = new Document();
         final Space spaceToBeIndexed = new Space();
 
-        mockNotificationManager.expects(once()).method("getNotificationsBySpace")
-                .with(same(spaceToBeIndexed)).will(returnValue(new ArrayList()));
+        mockSession.expects(once()).method("find").with(
+                eq(SPACE_NOTIFICATION_QUERY),
+                eq(new Object[] { spaceToBeIndexed.getId() }),
+                eq(new Type[] { Hibernate.LONG })
+        ).will(returnValue(Collections.EMPTY_LIST));
 
         notificationContributionExtractor.addFields(
                 documentToBeIndex,
         spaceNotification.setUserName("admin2");
         notifications.add(spaceNotification);
 
-        mockNotificationManager.expects(once()).method("getNotificationsByPage")
-                .with(same(pageToBeIndexed)).will(returnValue(notifications));
+        mockSession.expects(once()).method("find").with(
+                eq(PAGE_NOTIFICATION_QUERY),
+                eq(new Object[] { pageToBeIndexed.getId() }),
+                eq(new Type[] { Hibernate.LONG })
+        ).will(returnValue(Arrays.asList("admin", "admin2")));
 
         notificationContributionExtractor.addFields(
                 documentToBeIndex,
         final Document documentToBeIndex = new Document();
         final Page pageToBeIndexed = new Page();
 
-        mockNotificationManager.expects(once()).method("getNotificationsByPage")
-                .with(same(pageToBeIndexed)).will(returnValue(new ArrayList()));
+        mockSession.expects(once()).method("find").with(
+                eq(PAGE_NOTIFICATION_QUERY),
+                eq(new Object[] { pageToBeIndexed.getId() }),
+                eq(new Type[] { Hibernate.LONG })
+        ).will(returnValue(Collections.EMPTY_LIST));
 
         notificationContributionExtractor.addFields(
                 documentToBeIndex,
     {
         final Document documentToBeIndex = new Document();
 
+        mockSession.reset(); /* No expectations */
+        mockSessionFactory.reset(); /* No expectations */
+
         notificationContributionExtractor.addFields(
                 documentToBeIndex,
                 new StringBuffer(),

contrb-40/src/test/java/it/com/atlassian/confluence/contributors/macro/ContributorsTestCase.java

 
         addMoreWatchesAsJaneDoe();
 
+        waitForReindex();
+
         logout();
         login(userNameJane, userNameJane);