From: David ‘Bombe’ Roden Date: Mon, 8 Sep 2014 18:43:58 +0000 (+0200) Subject: Set Sone in album builder, remote getOrCreate method from core. X-Git-Tag: 0.9-rc1^2~3^2~138 X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=ec06ae64c86f0b06bb0cf9f8b289e7907e81dffa;p=Sone.git Set Sone in album builder, remote getOrCreate method from core. --- diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index 2fdd01a..a6b4c96 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -67,6 +67,7 @@ import net.pterodactylus.sone.data.Sone.ShowCustomAvatars; import net.pterodactylus.sone.data.Sone.SoneStatus; import net.pterodactylus.sone.data.SoneImpl; import net.pterodactylus.sone.data.TemporaryImage; +import net.pterodactylus.sone.database.AlbumBuilder; import net.pterodactylus.sone.database.Database; import net.pterodactylus.sone.database.DatabaseException; import net.pterodactylus.sone.database.PostBuilder; @@ -584,16 +585,8 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, return posts; } - /** - * Returns the album with the given ID, creating a new album if no album - * with the given ID can be found. - * - * @param albumId - * The ID of the album - * @return The album with the given ID - */ - public Album getOrCreateAlbum(String albumId) { - return getAlbum(albumId, true); + public AlbumBuilder albumBuilder() { + return database.newAlbumBuilder(); } /** @@ -602,23 +595,11 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, * * @param albumId * The ID of the album - * @param create - * {@code true} to create a new album if none exists for the - * given ID * @return The album with the given ID, or {@code null} if no album with the - * given ID exists and {@code create} is {@code false} + * given ID exists */ - public Album getAlbum(String albumId, boolean create) { - Optional album = database.getAlbum(albumId); - if (album.isPresent()) { - return album.get(); - } - if (!create) { - return null; - } - Album newAlbum = database.newAlbumBuilder().withId(albumId).build(); - database.storeAlbum(newAlbum); - return newAlbum; + public Album getAlbum(String albumId) { + return database.getAlbum(albumId).orNull(); } /** @@ -1159,9 +1140,17 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, logger.log(Level.WARNING, "Invalid album found, aborting load!"); return; } - Album album = getOrCreateAlbum(albumId).setSone(sone).modify().setTitle(albumTitle).setDescription(albumDescription).setAlbumImage(albumImageId).update(); + Album album = database.newAlbumBuilder() + .withId(albumId) + .by(sone) + .build() + .modify() + .setTitle(albumTitle) + .setDescription(albumDescription) + .setAlbumImage(albumImageId) + .update(); if (albumParentId != null) { - Album parentAlbum = getAlbum(albumParentId, false); + Album parentAlbum = getAlbum(albumParentId); if (parentAlbum == null) { logger.log(Level.WARNING, String.format("Invalid parent album ID: %s", albumParentId)); return; @@ -1193,7 +1182,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, logger.log(Level.WARNING, "Invalid image found, aborting load!"); return; } - Album album = getAlbum(albumId, false); + Album album = getAlbum(albumId); if (album == null) { logger.log(Level.WARNING, "Invalid album image encountered, aborting load!"); return; @@ -1444,9 +1433,8 @@ public class Core extends AbstractService implements SoneProvider, PostProvider, * @return The new album */ public Album createAlbum(Sone sone, Album parent) { - Album album = database.newAlbumBuilder().randomId().build(); + Album album = database.newAlbumBuilder().randomId().by(sone).build(); database.storeAlbum(album); - album.setSone(sone); parent.addAlbum(album); return album; } diff --git a/src/main/java/net/pterodactylus/sone/core/SoneDownloaderImpl.java b/src/main/java/net/pterodactylus/sone/core/SoneDownloaderImpl.java index ca47132..ebdbecb 100644 --- a/src/main/java/net/pterodactylus/sone/core/SoneDownloaderImpl.java +++ b/src/main/java/net/pterodactylus/sone/core/SoneDownloaderImpl.java @@ -449,13 +449,20 @@ public class SoneDownloaderImpl extends AbstractService implements SoneDownloade } Album parent = null; if (parentId != null) { - parent = core.getAlbum(parentId, false); + parent = core.getAlbum(parentId); if (parent == null) { logger.log(Level.WARNING, String.format("Downloaded Sone %s has album with invalid parent!", sone)); return null; } } - Album album = core.getOrCreateAlbum(id).setSone(sone).modify().setTitle(title).setDescription(description).update(); + Album album = core.albumBuilder() + .withId(id) + .by(sone) + .build() + .modify() + .setTitle(title) + .setDescription(description) + .update(); if (parent != null) { parent.addAlbum(album); } else { diff --git a/src/main/java/net/pterodactylus/sone/data/Album.java b/src/main/java/net/pterodactylus/sone/data/Album.java index 09a7da4..f968f00 100644 --- a/src/main/java/net/pterodactylus/sone/data/Album.java +++ b/src/main/java/net/pterodactylus/sone/data/Album.java @@ -116,16 +116,6 @@ public interface Album extends Identified, Fingerprintable { Sone getSone(); /** - * Sets the owner of the album. The owner can only be set as long as the - * current owner is {@code null}. - * - * @param sone - * The album owner - * @return This album - */ - Album setSone(Sone sone); - - /** * Returns the nested albums. * * @return The nested albums diff --git a/src/main/java/net/pterodactylus/sone/data/AlbumImpl.java b/src/main/java/net/pterodactylus/sone/data/AlbumImpl.java index f489b0b..b60e99e 100644 --- a/src/main/java/net/pterodactylus/sone/data/AlbumImpl.java +++ b/src/main/java/net/pterodactylus/sone/data/AlbumImpl.java @@ -47,7 +47,7 @@ public class AlbumImpl implements Album { private final String id; /** The Sone this album belongs to. */ - private Sone sone; + private final Sone sone; /** Nested albums. */ private final List albums = new ArrayList(); @@ -71,8 +71,8 @@ public class AlbumImpl implements Album { private String albumImage; /** Creates a new album with a random ID. */ - public AlbumImpl() { - this(UUID.randomUUID().toString()); + public AlbumImpl(Sone sone) { + this(sone, UUID.randomUUID().toString()); } /** @@ -81,7 +81,8 @@ public class AlbumImpl implements Album { * @param id * The ID of the album */ - public AlbumImpl(String id) { + public AlbumImpl(Sone sone, String id) { + this.sone = checkNotNull(sone, "Sone must not be null"); this.id = checkNotNull(id, "id must not be null"); } @@ -100,14 +101,6 @@ public class AlbumImpl implements Album { } @Override - public Album setSone(Sone sone) { - checkNotNull(sone, "sone must not be null"); - checkState((this.sone == null) || (this.sone.equals(sone)), "album owner must not already be set to some other Sone"); - this.sone = sone; - return this; - } - - @Override public List getAlbums() { return new ArrayList(albums); } diff --git a/src/main/java/net/pterodactylus/sone/data/SoneImpl.java b/src/main/java/net/pterodactylus/sone/data/SoneImpl.java index 848fc04..1fe971f 100644 --- a/src/main/java/net/pterodactylus/sone/data/SoneImpl.java +++ b/src/main/java/net/pterodactylus/sone/data/SoneImpl.java @@ -99,7 +99,7 @@ public class SoneImpl implements Sone { private final Set likedReplyIds = new CopyOnWriteArraySet(); /** The root album containing all albums. */ - private final Album rootAlbum = new AlbumImpl().setSone(this); + private final Album rootAlbum = new AlbumImpl(this); /** Sone-specific options. */ private SoneOptions options = new DefaultSoneOptions(); diff --git a/src/main/java/net/pterodactylus/sone/data/impl/AbstractAlbumBuilder.java b/src/main/java/net/pterodactylus/sone/data/impl/AbstractAlbumBuilder.java index 312c795..8e15b6f 100644 --- a/src/main/java/net/pterodactylus/sone/data/impl/AbstractAlbumBuilder.java +++ b/src/main/java/net/pterodactylus/sone/data/impl/AbstractAlbumBuilder.java @@ -19,6 +19,7 @@ package net.pterodactylus.sone.data.impl; import static com.google.common.base.Preconditions.checkState; +import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.database.AlbumBuilder; /** @@ -34,6 +35,7 @@ public abstract class AbstractAlbumBuilder implements AlbumBuilder { /** The ID of the album to create. */ protected String id; + protected Sone sone; @Override public AlbumBuilder randomId() { @@ -47,6 +49,11 @@ public abstract class AbstractAlbumBuilder implements AlbumBuilder { return this; } + public AlbumBuilder by(Sone sone) { + this.sone = sone; + return this; + } + // // PROTECTED METHODS // @@ -59,6 +66,7 @@ public abstract class AbstractAlbumBuilder implements AlbumBuilder { */ protected void validate() throws IllegalStateException { checkState((randomId && (id == null)) || (!randomId && (id != null)), "exactly one of random ID or custom ID must be set"); + checkState(sone != null, "Sone must not be null"); } } diff --git a/src/main/java/net/pterodactylus/sone/data/impl/AlbumBuilderImpl.java b/src/main/java/net/pterodactylus/sone/data/impl/AlbumBuilderImpl.java index 3403a62..785a4af 100644 --- a/src/main/java/net/pterodactylus/sone/data/impl/AlbumBuilderImpl.java +++ b/src/main/java/net/pterodactylus/sone/data/impl/AlbumBuilderImpl.java @@ -31,7 +31,7 @@ public class AlbumBuilderImpl extends AbstractAlbumBuilder { @Override public Album build() throws IllegalStateException { validate(); - return randomId ? new AlbumImpl() : new AlbumImpl(id); + return randomId ? new AlbumImpl(sone) : new AlbumImpl(sone, id); } } diff --git a/src/main/java/net/pterodactylus/sone/database/AlbumBuilder.java b/src/main/java/net/pterodactylus/sone/database/AlbumBuilder.java index b888828..a084ae7 100644 --- a/src/main/java/net/pterodactylus/sone/database/AlbumBuilder.java +++ b/src/main/java/net/pterodactylus/sone/database/AlbumBuilder.java @@ -18,6 +18,7 @@ package net.pterodactylus.sone.database; import net.pterodactylus.sone.data.Album; +import net.pterodactylus.sone.data.Sone; /** * Builder for {@link Album} objects. @@ -42,6 +43,8 @@ public interface AlbumBuilder { */ AlbumBuilder withId(String id); + AlbumBuilder by(Sone sone); + /** * Creates the album. * diff --git a/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java b/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java index a8d024a..76a71d6 100644 --- a/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java +++ b/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java @@ -63,7 +63,7 @@ public class CreateAlbumPage extends SoneTemplatePage { String description = request.getHttpRequest().getPartAsStringFailsafe("description", 256).trim(); Sone currentSone = getCurrentSone(request.getToadletContext()); String parentId = request.getHttpRequest().getPartAsStringFailsafe("parent", 36); - Album parent = webInterface.getCore().getAlbum(parentId, false); + Album parent = webInterface.getCore().getAlbum(parentId); if (parentId.equals("")) { parent = currentSone.getRootAlbum(); } diff --git a/src/main/java/net/pterodactylus/sone/web/DeleteAlbumPage.java b/src/main/java/net/pterodactylus/sone/web/DeleteAlbumPage.java index 391e9ff..98e8909 100644 --- a/src/main/java/net/pterodactylus/sone/web/DeleteAlbumPage.java +++ b/src/main/java/net/pterodactylus/sone/web/DeleteAlbumPage.java @@ -50,7 +50,7 @@ public class DeleteAlbumPage extends SoneTemplatePage { super.processTemplate(request, templateContext); if (request.getMethod() == Method.POST) { String albumId = request.getHttpRequest().getPartAsStringFailsafe("album", 36); - Album album = webInterface.getCore().getAlbum(albumId, false); + Album album = webInterface.getCore().getAlbum(albumId); if (album == null) { throw new RedirectException("invalid.html"); } @@ -68,7 +68,7 @@ public class DeleteAlbumPage extends SoneTemplatePage { throw new RedirectException("imageBrowser.html?album=" + parentAlbum.getId()); } String albumId = request.getHttpRequest().getParam("album"); - Album album = webInterface.getCore().getAlbum(albumId, false); + Album album = webInterface.getCore().getAlbum(albumId); if (album == null) { throw new RedirectException("invalid.html"); } diff --git a/src/main/java/net/pterodactylus/sone/web/EditAlbumPage.java b/src/main/java/net/pterodactylus/sone/web/EditAlbumPage.java index 9e4aae9..7debd3d 100644 --- a/src/main/java/net/pterodactylus/sone/web/EditAlbumPage.java +++ b/src/main/java/net/pterodactylus/sone/web/EditAlbumPage.java @@ -51,7 +51,7 @@ public class EditAlbumPage extends SoneTemplatePage { super.processTemplate(request, templateContext); if (request.getMethod() == Method.POST) { String albumId = request.getHttpRequest().getPartAsStringFailsafe("album", 36); - Album album = webInterface.getCore().getAlbum(albumId, false); + Album album = webInterface.getCore().getAlbum(albumId); if (album == null) { throw new RedirectException("invalid.html"); } diff --git a/src/main/java/net/pterodactylus/sone/web/ImageBrowserPage.java b/src/main/java/net/pterodactylus/sone/web/ImageBrowserPage.java index 766f018..0dbe4e7 100644 --- a/src/main/java/net/pterodactylus/sone/web/ImageBrowserPage.java +++ b/src/main/java/net/pterodactylus/sone/web/ImageBrowserPage.java @@ -69,7 +69,7 @@ public class ImageBrowserPage extends SoneTemplatePage { super.processTemplate(request, templateContext); String albumId = request.getHttpRequest().getParam("album", null); if (albumId != null) { - Album album = webInterface.getCore().getAlbum(albumId, false); + Album album = webInterface.getCore().getAlbum(albumId); templateContext.set("albumRequested", true); templateContext.set("album", album); templateContext.set("page", request.getHttpRequest().getParam("page")); diff --git a/src/main/java/net/pterodactylus/sone/web/SearchPage.java b/src/main/java/net/pterodactylus/sone/web/SearchPage.java index 3f6d065..508d30b 100644 --- a/src/main/java/net/pterodactylus/sone/web/SearchPage.java +++ b/src/main/java/net/pterodactylus/sone/web/SearchPage.java @@ -354,7 +354,7 @@ public class SearchPage extends SoneTemplatePage { */ private String getAlbumId(String phrase) { String albumId = phrase.startsWith("album://") ? phrase.substring(8) : phrase; - return (webInterface.getCore().getAlbum(albumId, false) != null) ? albumId : null; + return (webInterface.getCore().getAlbum(albumId) != null) ? albumId : null; } /** diff --git a/src/main/java/net/pterodactylus/sone/web/UploadImagePage.java b/src/main/java/net/pterodactylus/sone/web/UploadImagePage.java index 2079cac..b7e9e93 100644 --- a/src/main/java/net/pterodactylus/sone/web/UploadImagePage.java +++ b/src/main/java/net/pterodactylus/sone/web/UploadImagePage.java @@ -81,7 +81,7 @@ public class UploadImagePage extends SoneTemplatePage { if (request.getMethod() == Method.POST) { Sone currentSone = getCurrentSone(request.getToadletContext()); String parentId = request.getHttpRequest().getPartAsStringFailsafe("parent", 36); - Album parent = webInterface.getCore().getAlbum(parentId, false); + Album parent = webInterface.getCore().getAlbum(parentId); if (parent == null) { /* TODO - signal error */ return; diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/EditAlbumAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/EditAlbumAjaxPage.java index 74a73b8..4c3d2ba 100644 --- a/src/main/java/net/pterodactylus/sone/web/ajax/EditAlbumAjaxPage.java +++ b/src/main/java/net/pterodactylus/sone/web/ajax/EditAlbumAjaxPage.java @@ -49,7 +49,7 @@ public class EditAlbumAjaxPage extends JsonPage { @Override protected JsonReturnObject createJsonObject(FreenetRequest request) { String albumId = request.getHttpRequest().getParam("album"); - Album album = webInterface.getCore().getAlbum(albumId, false); + Album album = webInterface.getCore().getAlbum(albumId); if (album == null) { return createErrorJsonObject("invalid-album-id"); } diff --git a/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java b/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java index c17c12f..b05d2ca 100644 --- a/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java +++ b/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java @@ -1,6 +1,7 @@ package net.pterodactylus.sone.core; import static com.google.common.base.Optional.of; +import static java.util.UUID.randomUUID; import static net.pterodactylus.sone.data.Sone.SoneStatus.downloading; import static net.pterodactylus.sone.data.Sone.SoneStatus.idle; import static net.pterodactylus.sone.data.Sone.SoneStatus.unknown; @@ -16,6 +17,7 @@ import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -34,7 +36,7 @@ import java.util.Set; import net.pterodactylus.sone.core.FreenetInterface.Fetched; import net.pterodactylus.sone.data.Album; -import net.pterodactylus.sone.data.AlbumImpl; +import net.pterodactylus.sone.data.Album.Modifier; import net.pterodactylus.sone.data.Client; import net.pterodactylus.sone.data.Image; import net.pterodactylus.sone.data.ImageImpl; @@ -43,6 +45,7 @@ import net.pterodactylus.sone.data.PostReply; import net.pterodactylus.sone.data.Profile; import net.pterodactylus.sone.data.Sone; import net.pterodactylus.sone.data.Sone.SoneStatus; +import net.pterodactylus.sone.database.AlbumBuilder; import net.pterodactylus.sone.database.PostBuilder; import net.pterodactylus.sone.database.PostReplyBuilder; import net.pterodactylus.sone.freenet.wot.Identity; @@ -53,7 +56,9 @@ import freenet.keys.FreenetURI; import freenet.support.api.Bucket; import com.google.common.base.Optional; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ListMultimap; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -78,6 +83,10 @@ public class SoneDownloaderTest { private final PostReplyBuilder postReplyBuilder = mock(PostReplyBuilder.class); private final Set createdPostReplies = new HashSet(); private PostReply postReply = mock(PostReply.class); + private final AlbumBuilder albumBuilder = mock(AlbumBuilder.class); + private final ListMultimap nestedAlbums = ArrayListMultimap.create(); + private final ListMultimap albumImages = ArrayListMultimap.create(); + private Album album = mock(Album.class); private final Map albums = new HashMap(); @Before @@ -208,16 +217,113 @@ public class SoneDownloaderTest { } @Before - public void setupAlbums() { - albums.put("album-id-1", new AlbumImpl("album-id-1")); - albums.put("album-id-2", new AlbumImpl("album-id-2")); - when(core.getOrCreateAlbum(anyString())).thenAnswer(new Answer() { + public void setupAlbum() { + setupAlbum(album); + } + + private void setupAlbum(final Album album) { + when(album.getAlbumImage()).thenReturn(mock(Image.class)); + doAnswer(new Answer() { @Override - public Album answer(InvocationOnMock invocation) throws Throwable { - return albums.get(invocation.getArguments()[0]); + public Void answer(InvocationOnMock invocation) { + nestedAlbums.put(album, (Album) invocation.getArguments()[0]); + return null; + } + }).when(album).addAlbum(any(Album.class)); + doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocation) { + albumImages.put(album, (Image) invocation.getArguments()[0]); + return null; + } + }).when(album).addImage(any(Image.class)); + when(album.getAlbums()).thenAnswer(new Answer>() { + @Override + public List answer(InvocationOnMock invocation) { + return nestedAlbums.get(album); + } + }); + when(album.getImages()).thenAnswer(new Answer>() { + @Override + public List answer(InvocationOnMock invocation) { + return albumImages.get(album); } }); - when(core.getAlbum(anyString(), anyBoolean())).thenAnswer(new Answer() { + final Modifier albumModifier = new Modifier() { + private String title = album.getTitle(); + private String description = album.getDescription(); + private String imageId = album.getAlbumImage().getId(); + + @Override + public Modifier setTitle(String title) { + this.title = title; + return this; + } + + @Override + public Modifier setDescription(String description) { + this.description = description; + return this; + } + + @Override + public Modifier setAlbumImage(String imageId) { + this.imageId = imageId; + return this; + } + + @Override + public Album update() throws IllegalStateException { + when(album.getTitle()).thenReturn(title); + when(album.getDescription()).thenReturn(description); + Image image = mock(Image.class); + when(image.getId()).thenReturn(imageId); + when(album.getAlbumImage()).thenReturn(image); + return album; + } + }; + when(album.modify()).thenReturn(albumModifier); + } + + @Before + public void setupAlbumBuilder() { + when(albumBuilder.withId(anyString())).thenAnswer(new Answer() { + @Override + public AlbumBuilder answer(InvocationOnMock invocation) { + when(album.getId()).thenReturn((String) invocation.getArguments()[0]); + return albumBuilder; + } + }); + when(albumBuilder.randomId()).thenAnswer(new Answer() { + @Override + public AlbumBuilder answer(InvocationOnMock invocation) { + when(album.getId()).thenReturn(randomUUID().toString()); + return albumBuilder; + } + }); + when(albumBuilder.by(any(Sone.class))).thenAnswer(new Answer() { + @Override + public AlbumBuilder answer(InvocationOnMock invocation) { + when(album.getSone()).thenReturn((Sone) invocation.getArguments()[0]); + return albumBuilder; + } + }); + when(albumBuilder.build()).thenAnswer(new Answer() { + @Override + public Album answer(InvocationOnMock invocation) { + Album album = SoneDownloaderTest.this.album; + albums.put(album.getId(), album); + SoneDownloaderTest.this.album = mock(Album.class); + setupAlbum(SoneDownloaderTest.this.album); + return album; + } + }); + when(core.albumBuilder()).thenReturn(albumBuilder); + } + + @Before + public void setupAlbums() { + when(core.getAlbum(anyString())).thenAnswer(new Answer() { @Override public Album answer(InvocationOnMock invocation) throws Throwable { return albums.get(invocation.getArguments()[0]); diff --git a/src/test/java/net/pterodactylus/sone/database/memory/MemoryDatabaseTest.java b/src/test/java/net/pterodactylus/sone/database/memory/MemoryDatabaseTest.java index 056a06d..74c58ca 100644 --- a/src/test/java/net/pterodactylus/sone/database/memory/MemoryDatabaseTest.java +++ b/src/test/java/net/pterodactylus/sone/database/memory/MemoryDatabaseTest.java @@ -20,9 +20,11 @@ package net.pterodactylus.sone.database.memory; import static com.google.common.base.Optional.of; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.mock; import net.pterodactylus.sone.data.Album; import net.pterodactylus.sone.data.AlbumImpl; +import net.pterodactylus.sone.data.Sone; import com.google.common.base.Optional; import org.junit.Test; @@ -38,7 +40,7 @@ public class MemoryDatabaseTest { @Test public void testBasicAlbumFunctionality() { - Album newAlbum = new AlbumImpl(); + Album newAlbum = new AlbumImpl(mock(Sone.class)); assertThat(memoryDatabase.getAlbum(newAlbum.getId()), is(Optional.absent())); memoryDatabase.storeAlbum(newAlbum); assertThat(memoryDatabase.getAlbum(newAlbum.getId()), is(of(newAlbum)));