add unit test for archive dao
This commit is contained in:
parent
7c820f7b32
commit
e3f5f6404b
|
@ -0,0 +1,129 @@
|
||||||
|
package im.conversations.android.xmpp;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import im.conversations.android.database.model.Account;
|
||||||
|
import im.conversations.android.database.model.StanzaId;
|
||||||
|
import im.conversations.android.transformer.MessageTransformation;
|
||||||
|
import im.conversations.android.xmpp.manager.ArchiveManager;
|
||||||
|
import im.conversations.android.xmpp.model.jabber.Body;
|
||||||
|
import im.conversations.android.xmpp.model.stanza.Message;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import org.hamcrest.MatcherAssert;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ArchivePagingTest extends BaseTransformationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void initialQuery() throws ExecutionException, InterruptedException {
|
||||||
|
final var ranges = database.archiveDao().resetLivePage(account(), ACCOUNT);
|
||||||
|
final Range range = Iterables.getOnlyElement(ranges);
|
||||||
|
Assert.assertNull(range.id);
|
||||||
|
Assert.assertEquals(Range.Order.REVERSE, range.order);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void queryAfterSingleLiveMessage() throws ExecutionException, InterruptedException {
|
||||||
|
final var stub = new StubMessage(2);
|
||||||
|
transformer.transform(stub.messageTransformation(), stub.stanzaId());
|
||||||
|
final var ranges = database.archiveDao().resetLivePage(account(), ACCOUNT);
|
||||||
|
Assert.assertEquals(2, ranges.size());
|
||||||
|
MatcherAssert.assertThat(
|
||||||
|
ranges,
|
||||||
|
contains(new Range(Range.Order.REVERSE, "2"), new Range(Range.Order.NORMAL, "2")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void twoLiveMessageQueryNoSubmitAndQuery()
|
||||||
|
throws ExecutionException, InterruptedException {
|
||||||
|
final var stub2 = new StubMessage(2);
|
||||||
|
transformer.transform(stub2.messageTransformation(), stub2.stanzaId());
|
||||||
|
final var stub3 = new StubMessage(3);
|
||||||
|
transformer.transform(stub3.messageTransformation(), stub3.stanzaId());
|
||||||
|
|
||||||
|
final var ranges = database.archiveDao().resetLivePage(account(), ACCOUNT);
|
||||||
|
Assert.assertEquals(2, ranges.size());
|
||||||
|
MatcherAssert.assertThat(
|
||||||
|
ranges,
|
||||||
|
contains(new Range(Range.Order.REVERSE, "2"), new Range(Range.Order.NORMAL, "3")));
|
||||||
|
|
||||||
|
final var stub4 = new StubMessage(4);
|
||||||
|
transformer.transform(stub4.messageTransformation(), stub4.stanzaId());
|
||||||
|
|
||||||
|
final var rangesSecondAttempt = database.archiveDao().resetLivePage(account(), ACCOUNT);
|
||||||
|
Assert.assertEquals(2, rangesSecondAttempt.size());
|
||||||
|
MatcherAssert.assertThat(
|
||||||
|
rangesSecondAttempt,
|
||||||
|
contains(new Range(Range.Order.REVERSE, "2"), new Range(Range.Order.NORMAL, "3")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void liveMessageQuerySubmitAndQuery() throws ExecutionException, InterruptedException {
|
||||||
|
final var stub2 = new StubMessage(2);
|
||||||
|
transformer.transform(stub2.messageTransformation(), stub2.stanzaId());
|
||||||
|
final var stub3 = new StubMessage(3);
|
||||||
|
transformer.transform(stub3.messageTransformation(), stub3.stanzaId());
|
||||||
|
|
||||||
|
final var ranges = database.archiveDao().resetLivePage(account(), ACCOUNT);
|
||||||
|
Assert.assertEquals(2, ranges.size());
|
||||||
|
MatcherAssert.assertThat(
|
||||||
|
ranges,
|
||||||
|
contains(new Range(Range.Order.REVERSE, "2"), new Range(Range.Order.NORMAL, "3")));
|
||||||
|
|
||||||
|
final var stub4 = new StubMessage(4);
|
||||||
|
transformer.transform(stub4.messageTransformation(), stub4.stanzaId());
|
||||||
|
|
||||||
|
for (final Range range : ranges) {
|
||||||
|
database.archiveDao()
|
||||||
|
.submitPage(
|
||||||
|
account(),
|
||||||
|
ACCOUNT,
|
||||||
|
range,
|
||||||
|
new ArchiveManager.QueryResult(
|
||||||
|
true, Page.emptyWithCount(range.id, null)),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
final var rangesSecondAttempt = database.archiveDao().resetLivePage(account(), ACCOUNT);
|
||||||
|
// we mark the reversing range as complete in the submit above; hence it is not included in
|
||||||
|
// the second ranges
|
||||||
|
Assert.assertEquals(1, rangesSecondAttempt.size());
|
||||||
|
MatcherAssert.assertThat(rangesSecondAttempt, contains(new Range(Range.Order.NORMAL, "4")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Account account() throws ExecutionException, InterruptedException {
|
||||||
|
return this.database.accountDao().getEnabledAccount(ACCOUNT).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class StubMessage {
|
||||||
|
public final int id;
|
||||||
|
|
||||||
|
private StubMessage(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StanzaId stanzaId() {
|
||||||
|
return new StanzaId(String.valueOf(id), ACCOUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageTransformation messageTransformation() {
|
||||||
|
final var message = new Message();
|
||||||
|
message.setTo(ACCOUNT);
|
||||||
|
message.setFrom(REMOTE);
|
||||||
|
message.addExtension(new Body()).setContent(String.format("%s (%d)", GREETING, id));
|
||||||
|
return MessageTransformation.of(
|
||||||
|
message,
|
||||||
|
Instant.ofEpochSecond(id * 2000L),
|
||||||
|
REMOTE,
|
||||||
|
String.valueOf(id),
|
||||||
|
message.getFrom().asBareJid(),
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package im.conversations.android.xmpp;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import androidx.room.Room;
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
import im.conversations.android.IDs;
|
||||||
|
import im.conversations.android.database.ConversationsDatabase;
|
||||||
|
import im.conversations.android.database.entity.AccountEntity;
|
||||||
|
import im.conversations.android.transformer.Transformer;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
|
||||||
|
public abstract class BaseTransformationTest {
|
||||||
|
|
||||||
|
protected static final BareJid ACCOUNT = JidCreate.bareFromOrThrowUnchecked("user@example.com");
|
||||||
|
protected static final BareJid REMOTE =
|
||||||
|
JidCreate.bareFromOrThrowUnchecked("juliet@example.com");
|
||||||
|
protected static final BareJid REMOTE_2 =
|
||||||
|
JidCreate.bareFromOrThrowUnchecked("romeo@example.com");
|
||||||
|
|
||||||
|
protected static final String GREETING = "Hi Juliet. How are you?";
|
||||||
|
|
||||||
|
protected ConversationsDatabase database;
|
||||||
|
protected Transformer transformer;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setupTransformer() throws ExecutionException, InterruptedException {
|
||||||
|
final Context context = ApplicationProvider.getApplicationContext();
|
||||||
|
this.database = Room.inMemoryDatabaseBuilder(context, ConversationsDatabase.class).build();
|
||||||
|
final var account = new AccountEntity();
|
||||||
|
account.address = ACCOUNT;
|
||||||
|
account.enabled = true;
|
||||||
|
account.randomSeed = IDs.seed();
|
||||||
|
final long id = database.accountDao().insert(account);
|
||||||
|
|
||||||
|
this.transformer =
|
||||||
|
new Transformer(
|
||||||
|
database.accountDao().getEnabledAccount(id).get(), context, database);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +1,12 @@
|
||||||
package im.conversations.android.xmpp;
|
package im.conversations.android.xmpp;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import androidx.room.Room;
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import im.conversations.android.IDs;
|
|
||||||
import im.conversations.android.database.ConversationsDatabase;
|
|
||||||
import im.conversations.android.database.entity.AccountEntity;
|
|
||||||
import im.conversations.android.database.model.Encryption;
|
import im.conversations.android.database.model.Encryption;
|
||||||
import im.conversations.android.database.model.MessageEmbedded;
|
import im.conversations.android.database.model.MessageEmbedded;
|
||||||
import im.conversations.android.database.model.Modification;
|
import im.conversations.android.database.model.Modification;
|
||||||
import im.conversations.android.database.model.PartType;
|
import im.conversations.android.database.model.PartType;
|
||||||
import im.conversations.android.transformer.MessageTransformation;
|
import im.conversations.android.transformer.MessageTransformation;
|
||||||
import im.conversations.android.transformer.Transformer;
|
|
||||||
import im.conversations.android.xmpp.model.correction.Replace;
|
import im.conversations.android.xmpp.model.correction.Replace;
|
||||||
import im.conversations.android.xmpp.model.jabber.Body;
|
import im.conversations.android.xmpp.model.jabber.Body;
|
||||||
import im.conversations.android.xmpp.model.reactions.Reaction;
|
import im.conversations.android.xmpp.model.reactions.Reaction;
|
||||||
|
@ -23,42 +16,15 @@ import im.conversations.android.xmpp.model.reply.Reply;
|
||||||
import im.conversations.android.xmpp.model.retract.Retract;
|
import im.conversations.android.xmpp.model.retract.Retract;
|
||||||
import im.conversations.android.xmpp.model.stanza.Message;
|
import im.conversations.android.xmpp.model.stanza.Message;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.jxmpp.jid.BareJid;
|
|
||||||
import org.jxmpp.jid.impl.JidCreate;
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
import org.jxmpp.jid.parts.Resourcepart;
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
import org.jxmpp.stringprep.XmppStringprepException;
|
import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class MessageTransformationTest {
|
public class MessageTransformationTest extends BaseTransformationTest {
|
||||||
|
|
||||||
private static final BareJid ACCOUNT = JidCreate.bareFromOrThrowUnchecked("user@example.com");
|
|
||||||
private static final BareJid REMOTE = JidCreate.bareFromOrThrowUnchecked("juliet@example.com");
|
|
||||||
private static final BareJid REMOTE_2 = JidCreate.bareFromOrThrowUnchecked("romeo@example.com");
|
|
||||||
|
|
||||||
private static final String GREETING = "Hi Juliet. How are you?";
|
|
||||||
|
|
||||||
private ConversationsDatabase database;
|
|
||||||
private Transformer transformer;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setupTransformer() throws ExecutionException, InterruptedException {
|
|
||||||
final Context context = ApplicationProvider.getApplicationContext();
|
|
||||||
this.database = Room.inMemoryDatabaseBuilder(context, ConversationsDatabase.class).build();
|
|
||||||
final var account = new AccountEntity();
|
|
||||||
account.address = ACCOUNT;
|
|
||||||
account.enabled = true;
|
|
||||||
account.randomSeed = IDs.seed();
|
|
||||||
final long id = database.accountDao().insert(account);
|
|
||||||
|
|
||||||
this.transformer =
|
|
||||||
new Transformer(
|
|
||||||
database.accountDao().getEnabledAccount(id).get(), context, database);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void reactionBeforeOriginal() throws XmppStringprepException {
|
public void reactionBeforeOriginal() throws XmppStringprepException {
|
||||||
|
|
|
@ -137,6 +137,7 @@ public abstract class ArchiveDao extends BaseDao {
|
||||||
final var existingLivePage = getPage(account.id, archive, ArchivePageEntity.Type.LIVE);
|
final var existingLivePage = getPage(account.id, archive, ArchivePageEntity.Type.LIVE);
|
||||||
if (existingLivePage != null) {
|
if (existingLivePage != null) {
|
||||||
existingLivePage.start = page.last;
|
existingLivePage.start = page.last;
|
||||||
|
insert(existingLivePage);
|
||||||
} else {
|
} else {
|
||||||
insert(
|
insert(
|
||||||
ArchivePageEntity.of(
|
ArchivePageEntity.of(
|
||||||
|
|
|
@ -2,6 +2,7 @@ package im.conversations.android.xmpp;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
public class Range {
|
public class Range {
|
||||||
|
|
||||||
|
@ -19,6 +20,19 @@ public class Range {
|
||||||
return MoreObjects.toStringHelper(this).add("order", order).add("id", id).toString();
|
return MoreObjects.toStringHelper(this).add("order", order).add("id", id).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Range range = (Range) o;
|
||||||
|
return order == range.order && Objects.equal(id, range.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(order, id);
|
||||||
|
}
|
||||||
|
|
||||||
public enum Order {
|
public enum Order {
|
||||||
NORMAL,
|
NORMAL,
|
||||||
REVERSE
|
REVERSE
|
||||||
|
|
|
@ -251,7 +251,7 @@ public class ArchiveManager extends AbstractManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class QueryResult {
|
public static final class QueryResult {
|
||||||
public final boolean isComplete;
|
public final boolean isComplete;
|
||||||
public final Page page;
|
public final Page page;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue