Send Sone removal notifications before removing Sone
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 1 Jul 2016 14:35:19 +0000 (16:35 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 1 Jul 2016 14:35:19 +0000 (16:35 +0200)
src/main/java/net/pterodactylus/sone/core/Core.java
src/main/java/net/pterodactylus/sone/web/WebInterface.java
src/test/java/net/pterodactylus/sone/core/CoreTest.java

index c662278..3b958f1 100644 (file)
@@ -1729,8 +1729,14 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                        /* TODO - we don’t have the Sone anymore. should this happen? */
                        return;
                }
-               database.removeSone(sone.get());
+               for (PostReply postReply : sone.get().getReplies()) {
+                       eventBus.post(new PostReplyRemovedEvent(postReply));
+               }
+               for (Post post : sone.get().getPosts()) {
+                       eventBus.post(new PostRemovedEvent(post));
+               }
                eventBus.post(new SoneRemovedEvent(sone.get()));
+               database.removeSone(sone.get());
        }
 
        /**
index df06422..271111e 100644 (file)
@@ -933,12 +933,6 @@ public class WebInterface {
        @Subscribe
        public void soneRemoved(SoneRemovedEvent soneRemovedEvent) {
                newSoneNotification.remove(soneRemovedEvent.sone());
-               for (Post post : soneRemovedEvent.sone().getPosts()) {
-                       removePost(post);
-               }
-               for (PostReply postReply : soneRemovedEvent.sone().getReplies()) {
-                       removeReply(postReply);
-               }
        }
 
        @Subscribe
index 263c2d0..8e83e21 100644 (file)
@@ -1,15 +1,36 @@
 package net.pterodactylus.sone.core;
 
+import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import net.pterodactylus.sone.core.Core.MarkPostKnown;
 import net.pterodactylus.sone.core.Core.MarkReplyKnown;
+import net.pterodactylus.sone.core.event.PostRemovedEvent;
+import net.pterodactylus.sone.core.event.PostReplyRemovedEvent;
+import net.pterodactylus.sone.core.event.SoneRemovedEvent;
 import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.data.PostReply;
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.database.Database;
+import net.pterodactylus.sone.freenet.wot.Identity;
+import net.pterodactylus.sone.freenet.wot.IdentityManager;
+import net.pterodactylus.sone.freenet.wot.OwnIdentity;
+import net.pterodactylus.sone.freenet.wot.event.IdentityRemovedEvent;
+import net.pterodactylus.util.config.Configuration;
 
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.eventbus.EventBus;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
 import org.junit.Test;
+import org.mockito.InOrder;
 
 /**
  * Unit test for {@link Core} and its subclasses.
@@ -36,4 +57,108 @@ public class CoreTest {
                verify(core).markReplyKnown(eq(postReply));
        }
 
+       @Test
+       public void removingAnIdentitySendsRemovalEventsForAllSoneElements() {
+               // given
+               Configuration configuration = mock(Configuration.class);
+               FreenetInterface freenetInterface = mock(FreenetInterface.class);
+               IdentityManager identityManager = mock(IdentityManager.class);
+               SoneDownloader soneDownloader = mock(SoneDownloader.class);
+               ImageInserter imageInserter = mock(ImageInserter.class);
+               UpdateChecker updateChecker = mock(UpdateChecker.class);
+               WebOfTrustUpdater webOfTrustUpdater = mock(WebOfTrustUpdater.class);
+               EventBus eventBus = mock(EventBus.class);
+               Database database = mock(Database.class);
+               Core core = new Core(configuration, freenetInterface, identityManager, soneDownloader, imageInserter, updateChecker, webOfTrustUpdater, eventBus, database);
+               OwnIdentity ownIdentity = mock(OwnIdentity.class);
+               Identity identity = mock(Identity.class);
+               when(identity.getId()).thenReturn("sone-id");
+               Sone sone = mock(Sone.class);
+               when(database.getSone("sone-id")).thenReturn(Optional.of(sone));
+               PostReply postReply1 = mock(PostReply.class);
+               PostReply postReply2 = mock(PostReply.class);
+               when(sone.getReplies()).thenReturn(ImmutableSet.of(postReply1, postReply2));
+               Post post1 = mock(Post.class);
+               Post post2 = mock(Post.class);
+               when(sone.getPosts()).thenReturn(ImmutableList.of(post1, post2));
+
+               // when
+               core.identityRemoved(new IdentityRemovedEvent(ownIdentity, identity));
+
+               // then
+               InOrder inOrder = inOrder(eventBus, database);
+               inOrder.verify(eventBus).post(argThat(isPostReplyRemoved(postReply1)));
+               inOrder.verify(eventBus).post(argThat(isPostReplyRemoved(postReply2)));
+               inOrder.verify(eventBus).post(argThat(isPostRemoved(post1)));
+               inOrder.verify(eventBus).post(argThat(isPostRemoved(post2)));
+               inOrder.verify(eventBus).post(argThat(isSoneRemoved(sone)));
+               inOrder.verify(database).removeSone(sone);
+       }
+
+       private Matcher<Object> isPostRemoved(final Post post) {
+               return new TypeSafeDiagnosingMatcher<Object>() {
+                       @Override
+                       protected boolean matchesSafely(Object item, Description mismatchDescription) {
+                               if (!(item instanceof PostRemovedEvent)) {
+                                       mismatchDescription.appendText("is not PostRemovedEvent");
+                                       return false;
+                               }
+                               if (((PostRemovedEvent) item).post() != post) {
+                                       mismatchDescription.appendText("post is ").appendValue(((PostRemovedEvent) item).post());
+                                       return false;
+                               }
+                               return true;
+                       }
+
+                       @Override
+                       public void describeTo(Description description) {
+                               description.appendText("is PostRemovedEvent and post is ").appendValue(post);
+                       }
+               };
+       }
+
+       private Matcher<Object> isPostReplyRemoved(final PostReply postReply) {
+               return new TypeSafeDiagnosingMatcher<Object>() {
+                       @Override
+                       protected boolean matchesSafely(Object item, Description mismatchDescription) {
+                               if (!(item instanceof PostReplyRemovedEvent)) {
+                                       mismatchDescription.appendText("is not PostReplyRemovedEvent");
+                                       return false;
+                               }
+                               if (((PostReplyRemovedEvent) item).postReply() != postReply) {
+                                       mismatchDescription.appendText("post reply is ").appendValue(((PostReplyRemovedEvent) item).postReply());
+                                       return false;
+                               }
+                               return true;
+                       }
+
+                       @Override
+                       public void describeTo(Description description) {
+                               description.appendText("is PostReplyRemovedEvent and post is ").appendValue(postReply);
+                       }
+               };
+       }
+
+       private Matcher<Object> isSoneRemoved(final Sone sone) {
+               return new TypeSafeDiagnosingMatcher<Object>() {
+                       @Override
+                       protected boolean matchesSafely(Object item, Description mismatchDescription) {
+                               if (!(item instanceof SoneRemovedEvent)) {
+                                       mismatchDescription.appendText("is not SoneRemovedEvent");
+                                       return false;
+                               }
+                               if (((SoneRemovedEvent) item).sone() != sone) {
+                                       mismatchDescription.appendText("sone is ").appendValue(((SoneRemovedEvent) item).sone());
+                                       return false;
+                               }
+                               return true;
+                       }
+
+                       @Override
+                       public void describeTo(Description description) {
+                               description.appendText("is SoneRemovedEvent and sone is ").appendValue(sone);
+                       }
+               };
+       }
+
 }