package net.pterodactylus.sone.database.memory; import static com.google.common.base.Optional.fromNullable; import static net.pterodactylus.sone.Matchers.isPostWithId; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import net.pterodactylus.sone.data.Post; import com.google.common.base.Optional; import org.junit.Before; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; /** * Unit test for {@link MemoryBookmarkDatabase}. * * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a> */ public class MemoryBookmarkDatabaseTest { private final MemoryDatabase memoryDatabase = mock(MemoryDatabase.class); private final ConfigurationLoader configurationLoader = mock(ConfigurationLoader.class); private final MemoryBookmarkDatabase bookmarkDatabase = new MemoryBookmarkDatabase(memoryDatabase, configurationLoader); private final Map<String, Post> posts = new HashMap<String, Post>(); @Before public void setupMemoryDatabase() { when(memoryDatabase.getPost(anyString())).thenAnswer( new Answer<Optional<Post>>() { @Override public Optional<Post> answer( InvocationOnMock invocation) { return fromNullable( posts.get(invocation.getArguments()[0])); } }); } @Before public void setupPosts() { createAndRegisterPost("PostId1"); createAndRegisterPost("PostId2"); } private Post createAndRegisterPost(String postId) { Post post = createPost(postId); posts.put(postId, post); return post; } private Post createPost(String postId) { Post post = mock(Post.class); when(post.getId()).thenReturn(postId); return post; } @Test public void bookmarkDatabaseRetainsBookmarkedPosts() { Set<Post> allPosts = new HashSet<Post>(posts.values()); for (Post post : allPosts) { bookmarkDatabase.bookmarkPost(post); } assertThat(bookmarkDatabase.getBookmarkedPosts(), is(allPosts)); for (Post post : allPosts) { assertThat(bookmarkDatabase.isPostBookmarked(post), is(true)); } } @Test public void bookmarkingAPostSavesTheDatabase() { for (Post post : posts.values()) { bookmarkDatabase.bookmarkPost(post); } verify(configurationLoader, times(posts.size())) .saveBookmarkedPosts(any(Set.class)); } @Test public void unbookmarkingAPostSavesTheDatabase() { for (Post post : posts.values()) { bookmarkDatabase.bookmarkPost(post); bookmarkDatabase.unbookmarkPost(post); } verify(configurationLoader, times(posts.size() * 2)) .saveBookmarkedPosts(any(Set.class)); } @Test public void removingABookmarkRemovesTheCorrectBookmark() { Set<Post> allPosts = new HashSet<Post>(posts.values()); for (Post post : allPosts) { bookmarkDatabase.bookmarkPost(post); } Post randomPost = posts.values().iterator().next(); bookmarkDatabase.unbookmarkPost(randomPost); allPosts.remove(randomPost); assertThat(bookmarkDatabase.getBookmarkedPosts(), is(allPosts)); for (Post post : posts.values()) { assertThat(bookmarkDatabase.isPostBookmarked(post), is(!post.equals(randomPost))); } } @Test public void startingTheDatabaseLoadsBookmarkedPosts() { bookmarkDatabase.start(); verify(configurationLoader).loadBookmarkedPosts(); } @Test public void stoppingTheDatabaseSavesTheBookmarkedPosts() { bookmarkDatabase.stop(); verify(configurationLoader).saveBookmarkedPosts(any(Set.class)); } @Test public void bookmarkedPostsIncludeNotYetLoadedPosts() { bookmarkDatabase.bookmarkPost(posts.get("PostId1")); bookmarkDatabase.bookmarkPost(createPost("PostId3")); final Set<Post> bookmarkedPosts = bookmarkDatabase.getBookmarkedPosts(); assertThat(bookmarkedPosts, contains(isPostWithId("PostId1"), isPostWithId("PostId3"))); } }