X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Ftest%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fdata%2FMocks.java;h=19626864526db6378e510804d1facd85cb365295;hb=22d68072fb1770cdc4262ede974bd0a6202d7062;hp=34aff9bc1b32bae3ff26dca7d3526878038a804b;hpb=02bf56efeee6654cd6ed0b92074e09180b7fb0b6;p=Sone.git diff --git a/src/test/java/net/pterodactylus/sone/data/Mocks.java b/src/test/java/net/pterodactylus/sone/data/Mocks.java index 34aff9b..1962686 100644 --- a/src/test/java/net/pterodactylus/sone/data/Mocks.java +++ b/src/test/java/net/pterodactylus/sone/data/Mocks.java @@ -17,21 +17,52 @@ package net.pterodactylus.sone.data; +import static com.google.common.base.Optional.absent; +import static com.google.common.base.Optional.fromNullable; import static com.google.common.base.Optional.of; -import static org.mockito.ArgumentCaptor.forClass; +import static com.google.common.collect.ArrayListMultimap.create; +import static com.google.common.collect.Maps.newHashMap; +import static com.google.common.collect.Ordering.from; +import static java.util.Collections.emptySet; +import static org.mockito.Matchers.any; 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.when; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + import net.pterodactylus.sone.core.Core; +import net.pterodactylus.sone.core.Options; +import net.pterodactylus.sone.core.Options.DefaultOption; +import net.pterodactylus.sone.core.Preferences; import net.pterodactylus.sone.data.impl.DefaultPostBuilder; import net.pterodactylus.sone.data.impl.DefaultPostReplyBuilder; import net.pterodactylus.sone.database.Database; +import net.pterodactylus.sone.database.PostBuilder.PostCreated; import net.pterodactylus.sone.database.PostReplyBuilder; +import net.pterodactylus.sone.database.PostReplyBuilder.PostReplyCreated; +import net.pterodactylus.sone.freenet.wot.OwnIdentity; +import net.pterodactylus.sone.utils.IntegerRangePredicate; +import net.pterodactylus.sone.web.WebInterface; +import net.pterodactylus.sone.web.page.FreenetRequest; + +import freenet.clients.http.SessionManager.Session; +import freenet.clients.http.ToadletContext; +import freenet.support.api.HTTPRequest; +import com.google.common.base.Function; import com.google.common.base.Optional; -import org.mockito.ArgumentCaptor; +import com.google.common.base.Predicates; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Ordering; +import com.google.common.collect.SetMultimap; import org.mockito.Matchers; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -43,64 +74,388 @@ import org.mockito.stubbing.Answer; */ public class Mocks { - public static Core mockCore(Database database) { + private final Multimap sonePosts = create(); + private final Map sones = newHashMap(); + private Optional currentSone = absent(); + private final Map posts = newHashMap(); + private final Multimap postReplies = create(); + private final Multimap directedPosts = create(); + private final SetMultimap postLikingSones = HashMultimap.create(); + private final SetMultimap postReplyLikingSones = HashMultimap.create(); + public final Database database; + public final Core core; + public final WebInterface webInterface; + + public Mocks() { + database = mockDatabase(); + core = mockCore(database); + webInterface = mockWebInterface(core); + when(database.getSone()).thenReturn(new Function>() { + @Override + public Optional apply(String soneId) { + return (soneId == null) ? Optional.absent() : fromNullable(sones.get(soneId)); + } + }); + Answer returnCurrentSone = new Answer() { + @Override + public Sone answer(InvocationOnMock invocation) throws Throwable { + return currentSone.orNull(); + } + }; + when(webInterface.getCurrentSone(any(ToadletContext.class))).then(returnCurrentSone); + when(webInterface.getCurrentSone(any(Session.class))).then(returnCurrentSone); + when(core.getSones()).then(new Answer>() { + @Override + public Collection answer(InvocationOnMock invocation) throws Throwable { + return sones.values(); + } + }); + when(core.getLocalSone(anyString())).then(new Answer>() { + @Override + public Optional answer(InvocationOnMock invocation) throws Throwable { + Sone localSone = sones.get(invocation.getArguments()[0]); + return ((localSone == null) || (!localSone.isLocal())) ? Optional.absent() : of(localSone); + } + }); + when(core.getLocalSones()).then(new Answer>() { + @Override + public Collection answer(InvocationOnMock invocation) throws Throwable { + return FluentIterable.from(sones.values()).filter(Sone.LOCAL_SONE_FILTER).toList(); + } + }); + when(core.postCreated()).thenReturn(Optional.of(new PostCreated() { + @Override + public void postCreated(Post post) { + posts.put(post.getId(), post); + sonePosts.put(post.getSone(), post); + } + })); + when(core.postReplyCreated()).then(new Answer>() { + @Override + public Optional answer(InvocationOnMock invocation) throws Throwable { + return Optional.of(new PostReplyCreated() { + @Override + public void postReplyCreated(PostReply postReply) { + postReplies.put(postReply.getPost().get(), postReply); + } + }); + } + }); + Options options = createOptions(); + when(core.getPreferences()).thenReturn(new Preferences(options)); + when(database.getDirectedPosts(anyString())).then(new Answer>() { + @Override + public Collection answer(InvocationOnMock invocation) throws Throwable { + return directedPosts.get((String) invocation.getArguments()[0]); + } + }); + } + + private Options createOptions() { + Options options = new Options(); + options.addIntegerOption("InsertionDelay", new DefaultOption(60, new IntegerRangePredicate(0, Integer.MAX_VALUE))); + options.addIntegerOption("PostsPerPage", new DefaultOption(10, new IntegerRangePredicate(1, Integer.MAX_VALUE))); + options.addIntegerOption("ImagesPerPage", new DefaultOption(9, new IntegerRangePredicate(1, Integer.MAX_VALUE))); + options.addIntegerOption("CharactersPerPost", new DefaultOption(400, Predicates.or(new IntegerRangePredicate(50, Integer.MAX_VALUE), Predicates.equalTo(-1)))); + options.addIntegerOption("PostCutOffLength", new DefaultOption(200, Predicates.or(new IntegerRangePredicate(50, Integer.MAX_VALUE), Predicates.equalTo(-1)))); + options.addBooleanOption("RequireFullAccess", new DefaultOption(false)); + options.addIntegerOption("PositiveTrust", new DefaultOption(75, new IntegerRangePredicate(0, 100))); + options.addIntegerOption("NegativeTrust", new DefaultOption(-25, new IntegerRangePredicate(-100, 100))); + options.addStringOption("TrustComment", new DefaultOption("Set from Sone Web Interface")); + options.addBooleanOption("ActivateFcpInterface", new DefaultOption(false)); + options.addIntegerOption("FcpFullAccessRequired", new DefaultOption(2)); + return options; + } + + private static Core mockCore(Database database) { Core core = mock(Core.class); when(core.getDatabase()).thenReturn(database); when(core.getSone(anyString())).thenReturn(Optional.absent()); return core; } - public static Database mockDatabase() { + private Database mockDatabase() { Database database = mock(Database.class); when(database.getSone(anyString())).thenReturn(Optional.absent()); - when(database.getPost(anyString())).thenReturn(Optional.absent()); + when(database.getPost(anyString())).then(new Answer>() { + @Override + public Optional answer(InvocationOnMock invocation) throws Throwable { + return fromNullable(posts.get(invocation.getArguments()[0])); + } + }); when(database.getPostReply(anyString())).thenReturn(Optional.absent()); return database; } - public static Sone mockLocalSone(Core core, final String id) { - Sone sone = mockRemoteSone(core, id); - when(sone.isLocal()).thenReturn(true); - final Database database = core.getDatabase(); - when(sone.newPostBuilder()).thenReturn(new DefaultPostBuilder(database, id)); - when(sone.newPostReplyBuilder(anyString())).then(new Answer() { - @Override - public PostReplyBuilder answer(InvocationOnMock invocation) throws Throwable { - return new DefaultPostReplyBuilder(database, id, (String) invocation.getArguments()[0]); - } - }); - return sone; + private static WebInterface mockWebInterface(Core core) { + WebInterface webInterface = mock(WebInterface.class); + when(webInterface.getCore()).thenReturn(core); + return webInterface; + } + + public SoneMocker mockSone(String id) { + return new SoneMocker(id); + } + + public PostMocker mockPost(Sone sone, String postId) { + return new PostMocker(postId, sone); + } + + public PostReplyMocker mockPostReply(Sone sone, String replyId) { + return new PostReplyMocker(replyId, sone); + } + + public FreenetRequest mockRequest(String path) { + HTTPRequest httpRequest = mock(HTTPRequest.class); + when(httpRequest.getMethod()).thenReturn("GET"); + when(httpRequest.getPath()).thenReturn(path); + FreenetRequest request = mock(FreenetRequest.class); + when(request.getHttpRequest()).thenReturn(httpRequest); + return request; } - public static Sone mockRemoteSone(Core core, final String id) { - Sone sone = mock(Sone.class); - when(sone.getId()).thenReturn(id); - when(sone.isLocal()).thenReturn(false); - when(sone.getProfile()).thenReturn(new Profile(sone)); - final Database database = core.getDatabase(); - when(sone.newPostBuilder()).thenThrow(IllegalStateException.class); - when(sone.newPostReplyBuilder(Matchers.anyObject())).thenThrow(IllegalStateException.class); - when(core.getSone(eq(id))).thenReturn(of(sone)); - when(database.getSone(eq(id))).thenReturn(of(sone)); - return sone; + public class SoneMocker { + + private final Sone mockedSone = mock(Sone.class); + private final String id; + private String insertUrI; + private boolean local; + private boolean current; + private Optional name = absent(); + private long time; + private Profile profile = new Profile(mockedSone); + private Collection friends = emptySet(); + + private SoneMocker(String id) { + this.id = id; + } + + public SoneMocker local() { + local = true; + return this; + } + + public SoneMocker insertUri(String insertUri) { + this.insertUrI = insertUri; + return this; + } + + public SoneMocker current() { + current = true; + return this; + } + + public SoneMocker withName(String name) { + this.name = fromNullable(name); + return this; + } + + public SoneMocker withTime(long time) { + this.time = time; + return this; + } + + public SoneMocker withProfileName(String firstName, String middleName, String lastName) { + profile.modify().setFirstName(firstName).setMiddleName(middleName).setLastName(lastName).update(); + return this; + } + + public SoneMocker addProfileField(String fieldName, String fieldValue) { + profile.setField(profile.addField(fieldName), fieldValue); + return this; + } + + public SoneMocker withFriends(Collection friends) { + this.friends = friends; + return this; + } + + public Sone create() { + when(mockedSone.getId()).thenReturn(id); + when(mockedSone.isLocal()).thenReturn(local); + if (local) { + OwnIdentity ownIdentity = mock(OwnIdentity.class); + when(ownIdentity.getInsertUri()).thenReturn(insertUrI); + when(mockedSone.getIdentity()).thenReturn(ownIdentity); + } + if (current) { + currentSone = of(mockedSone); + } + if (name.isPresent()) { + when(mockedSone.getName()).thenReturn(name.get()); + } + when(mockedSone.getTime()).thenReturn(time); + when(mockedSone.getProfile()).thenReturn(profile); + if (local) { + when(mockedSone.newPostBuilder()).thenReturn(new DefaultPostBuilder(database, id)); + when(mockedSone.newPostReplyBuilder(anyString())).then(new Answer() { + @Override + public PostReplyBuilder answer(InvocationOnMock invocation) throws Throwable { + return new DefaultPostReplyBuilder(database, id, (String) invocation.getArguments()[0]); + } + }); + when(mockedSone.hasFriend(anyString())).thenReturn(false); + when(mockedSone.getFriends()).thenReturn(friends); + when(mockedSone.hasFriend(anyString())).then(new Answer() { + @Override + public Boolean answer(InvocationOnMock invocation) throws Throwable { + return friends.contains(invocation.getArguments()[0]); + } + }); + } else { + when(mockedSone.newPostBuilder()).thenThrow(IllegalStateException.class); + when(mockedSone.newPostReplyBuilder(anyString())).thenThrow(IllegalStateException.class); + } + when(core.getSone(eq(id))).thenReturn(of(mockedSone)); + when(database.getSone(eq(id))).thenReturn(of(mockedSone)); + when(mockedSone.getPosts()).then(new Answer>() { + @Override + public List answer(InvocationOnMock invocationOnMock) throws Throwable { + return from(Post.TIME_COMPARATOR).sortedCopy(sonePosts.get(mockedSone)); + } + }); + when(mockedSone.toString()).thenReturn(String.format("Sone[%s]", id)); + sones.put(id, mockedSone); + return mockedSone; + } + } - public static Post mockPost(Core core, Sone sone, String postId) { - Post post = mock(Post.class); - when(post.getId()).thenReturn(postId); - when(post.getSone()).thenReturn(sone); - Database database = core.getDatabase(); - when(database.getPost(eq(postId))).thenReturn(of(post)); - return post; + public class PostMocker { + + private final Post post = mock(Post.class); + private final String id; + private final Sone sone; + private Optional recipientId = absent(); + private long time; + private Optional text = absent(); + + public PostMocker(String id, Sone sone) { + this.id = id; + this.sone = sone; + } + + public PostMocker withRecipient(String recipientId) { + this.recipientId = fromNullable(recipientId); + return this; + } + + public PostMocker withTime(long time) { + this.time = time; + return this; + } + + public PostMocker withText(String text) { + this.text = fromNullable(text); + return this; + } + + public Post create() { + when(post.getId()).thenReturn(id); + when(post.getSone()).thenReturn(sone); + when(post.getRecipientId()).thenReturn(recipientId); + if (recipientId.isPresent()) { + directedPosts.put(recipientId.get(), post); + } + when(post.getTime()).thenReturn(time); + if (text.isPresent()) { + when(post.getText()).thenReturn(text.get()); + } + when(database.getPost(eq(id))).thenReturn(of(post)); + sonePosts.put(sone, post); + when(post.getReplies()).then(new Answer>() { + @Override + public List answer(InvocationOnMock invocation) throws Throwable { + return Ordering.from(Reply.TIME_COMPARATOR).sortedCopy(postReplies.get(post)); + } + }); + doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocation) throws Throwable { + postLikingSones.put(post, (Sone) invocation.getArguments()[0]); + return null; + } + }).when(post).like(Matchers.any()); + doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocation) throws Throwable { + postLikingSones.remove(post, (Sone) invocation.getArguments()[0]); + return null; + } + }).when(post).unlike(Matchers.any()); + when(post.getLikes()).thenAnswer(new Answer>() { + @Override + public Set answer(InvocationOnMock invocation) throws Throwable { + return postLikingSones.get(post); + } + }); + return post; + } + } - public static PostReply mockPostReply(Core core, Sone sone, String replyId) { - PostReply postReply = mock(PostReply.class); - when(postReply.getId()).thenReturn(replyId); - when(postReply.getSone()).thenReturn(sone); - Database database = core.getDatabase(); - when(database.getPostReply(eq(replyId))).thenReturn(of(postReply)); - return postReply; + public class PostReplyMocker { + + private final PostReply postReply = mock(PostReply.class); + private final String id; + private final Sone sone; + private Optional post = absent(); + private long time; + private Optional text = absent(); + + public PostReplyMocker(String id, Sone sone) { + this.id = id; + this.sone = sone; + } + + public PostReplyMocker inReplyTo(Post post) { + this.post = fromNullable(post); + return this; + } + + public PostReplyMocker withTime(long time) { + this.time = time; + return this; + } + + public PostReplyMocker withText(String text) { + this.text = fromNullable(text); + return this; + } + + public PostReply create() { + when(postReply.getId()).thenReturn(id); + when(postReply.getSone()).thenReturn(sone); + when(postReply.getTime()).thenReturn(time); + when(database.getPostReply(eq(id))).thenReturn(of(postReply)); + if (post.isPresent()) { + postReplies.put(post.get(), postReply); + } + if (text.isPresent()) { + when(postReply.getText()).thenReturn(text.get()); + } + doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocation) throws Throwable { + postReplyLikingSones.put(postReply, (Sone) invocation.getArguments()[0]); + return null; + } + }).when(postReply).like(Matchers.any()); + doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocation) throws Throwable { + postReplyLikingSones.remove(postReply, invocation.getArguments()[0]); + return null; + } + }).when(postReply).unlike(Matchers.any()); + when(postReply.getLikes()).thenAnswer(new Answer>() { + @Override + public Set answer(InvocationOnMock invocation) throws Throwable { + return postReplyLikingSones.get(postReply); + } + }); + return postReply; + } } }