add unit test for archive dao

This commit is contained in:
Daniel Gultsch 2023-03-11 23:16:55 +01:00
parent 7c820f7b32
commit e3f5f6404b
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
6 changed files with 188 additions and 36 deletions

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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 {

View file

@ -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(

View file

@ -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

View file

@ -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;