support reaction arriving before message
This commit is contained in:
parent
fbb900d4ad
commit
4c09b20aa4
|
@ -4,6 +4,7 @@ import android.content.Context;
|
||||||
import androidx.room.Room;
|
import androidx.room.Room;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
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 eu.siacs.conversations.xmpp.Jid;
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
import im.conversations.android.IDs;
|
import im.conversations.android.IDs;
|
||||||
import im.conversations.android.database.ConversationsDatabase;
|
import im.conversations.android.database.ConversationsDatabase;
|
||||||
|
@ -16,6 +17,7 @@ import im.conversations.android.xmpp.model.reactions.Reactions;
|
||||||
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 java.util.concurrent.ExecutionException;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
@ -26,13 +28,15 @@ public class TransformationTest {
|
||||||
private static final Jid ACCOUNT = Jid.of("user@example.com");
|
private static final Jid ACCOUNT = Jid.of("user@example.com");
|
||||||
private static final Jid REMOTE = Jid.of("juliet@example.com");
|
private static final Jid REMOTE = Jid.of("juliet@example.com");
|
||||||
|
|
||||||
|
private static final String GREETING = "Hi Juliet. How are you?";
|
||||||
|
|
||||||
|
private ConversationsDatabase database;
|
||||||
private Transformer transformer;
|
private Transformer transformer;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setupTransformer() throws ExecutionException, InterruptedException {
|
public void setupTransformer() throws ExecutionException, InterruptedException {
|
||||||
Context context = ApplicationProvider.getApplicationContext();
|
Context context = ApplicationProvider.getApplicationContext();
|
||||||
final var database =
|
this.database = Room.inMemoryDatabaseBuilder(context, ConversationsDatabase.class).build();
|
||||||
Room.inMemoryDatabaseBuilder(context, ConversationsDatabase.class).build();
|
|
||||||
final var account = new AccountEntity();
|
final var account = new AccountEntity();
|
||||||
account.address = ACCOUNT;
|
account.address = ACCOUNT;
|
||||||
account.enabled = true;
|
account.enabled = true;
|
||||||
|
@ -60,8 +64,17 @@ public class TransformationTest {
|
||||||
originalMessage.setTo(REMOTE);
|
originalMessage.setTo(REMOTE);
|
||||||
originalMessage.setFrom(ACCOUNT.withResource("junit"));
|
originalMessage.setFrom(ACCOUNT.withResource("junit"));
|
||||||
final var body = originalMessage.addExtension(new Body());
|
final var body = originalMessage.addExtension(new Body());
|
||||||
body.setContent("Hi Juliet. How are you?");
|
body.setContent(GREETING);
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(originalMessage, Instant.now(), REMOTE, "stanza-a", null));
|
Transformation.of(originalMessage, Instant.now(), REMOTE, "stanza-a", null));
|
||||||
|
|
||||||
|
final var messages = database.messageDao().getMessages(1L);
|
||||||
|
Assert.assertEquals(1, messages.size());
|
||||||
|
final var message = Iterables.getOnlyElement(messages);
|
||||||
|
final var onlyContent = Iterables.getOnlyElement(message.contents);
|
||||||
|
Assert.assertEquals(GREETING, onlyContent.body);
|
||||||
|
final var onlyReaction = Iterables.getOnlyElement(message.reactions);
|
||||||
|
Assert.assertEquals("Y", onlyReaction.reaction);
|
||||||
|
Assert.assertEquals(REMOTE, onlyReaction.reactionBy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import androidx.room.Dao;
|
||||||
import androidx.room.Insert;
|
import androidx.room.Insert;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import androidx.room.Transaction;
|
import androidx.room.Transaction;
|
||||||
|
import androidx.room.Update;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
@ -19,6 +20,7 @@ import im.conversations.android.database.model.ChatIdentifier;
|
||||||
import im.conversations.android.database.model.MessageContent;
|
import im.conversations.android.database.model.MessageContent;
|
||||||
import im.conversations.android.database.model.MessageIdentifier;
|
import im.conversations.android.database.model.MessageIdentifier;
|
||||||
import im.conversations.android.database.model.MessageState;
|
import im.conversations.android.database.model.MessageState;
|
||||||
|
import im.conversations.android.database.model.MessageWithContentReactions;
|
||||||
import im.conversations.android.database.model.Modification;
|
import im.conversations.android.database.model.Modification;
|
||||||
import im.conversations.android.transformer.Transformation;
|
import im.conversations.android.transformer.Transformation;
|
||||||
import im.conversations.android.xmpp.model.reactions.Reactions;
|
import im.conversations.android.xmpp.model.reactions.Reactions;
|
||||||
|
@ -80,9 +82,23 @@ public abstract class MessageDao {
|
||||||
"Found stub for stanzaId '{}' and messageId '{}'",
|
"Found stub for stanzaId '{}' and messageId '{}'",
|
||||||
transformation.stanzaId,
|
transformation.stanzaId,
|
||||||
transformation.messageId);
|
transformation.messageId);
|
||||||
// TODO create version
|
final long messageVersionId =
|
||||||
// TODO fill up information
|
insert(
|
||||||
return messageIdentifier;
|
MessageVersionEntity.of(
|
||||||
|
messageIdentifier.id,
|
||||||
|
Modification.ORIGINAl,
|
||||||
|
transformation));
|
||||||
|
final MessageEntity updatedEntity =
|
||||||
|
MessageEntity.of(chatIdentifier.id, transformation);
|
||||||
|
updatedEntity.id = messageIdentifier.id;
|
||||||
|
updatedEntity.latestVersion = messageVersionId;
|
||||||
|
update(updatedEntity);
|
||||||
|
return new MessageIdentifier(
|
||||||
|
updatedEntity.id,
|
||||||
|
transformation.stanzaId,
|
||||||
|
transformation.messageId,
|
||||||
|
transformation.fromBare(),
|
||||||
|
messageVersionId);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
String.format(
|
String.format(
|
||||||
|
@ -201,6 +217,9 @@ public abstract class MessageDao {
|
||||||
@Insert
|
@Insert
|
||||||
protected abstract long insert(MessageEntity messageEntity);
|
protected abstract long insert(MessageEntity messageEntity);
|
||||||
|
|
||||||
|
@Update
|
||||||
|
protected abstract void update(final MessageEntity messageEntity);
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
protected abstract long insert(MessageVersionEntity messageVersionEntity);
|
protected abstract long insert(MessageVersionEntity messageVersionEntity);
|
||||||
|
|
||||||
|
@ -293,4 +312,13 @@ public abstract class MessageDao {
|
||||||
reactions.getReactions(),
|
reactions.getReactions(),
|
||||||
r -> MessageReactionEntity.of(messageIdentifier.id, r, transformation)));
|
r -> MessageReactionEntity.of(messageIdentifier.id, r, transformation)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
@Query(
|
||||||
|
"SELECT message.id as"
|
||||||
|
+ " id,sentAt,outgoing,toBare,toResource,fromBare,fromResource,modification,latestVersion"
|
||||||
|
+ " as version FROM message JOIN message_version ON"
|
||||||
|
+ " message.latestVersion=message_version.id WHERE message.chatId=:chatId AND"
|
||||||
|
+ " latestVersion IS NOT NULL ORDER BY message.receivedAt")
|
||||||
|
public abstract List<MessageWithContentReactions> getMessages(long chatId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package im.conversations.android.database.model;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
|
||||||
|
public class MessageReaction {
|
||||||
|
|
||||||
|
public final Jid reactionBy;
|
||||||
|
public final String reactionByResource;
|
||||||
|
public final String occupantId;
|
||||||
|
|
||||||
|
public final String reaction;
|
||||||
|
|
||||||
|
public MessageReaction(
|
||||||
|
Jid reactionBy, String reactionByResource, String occupantId, String reaction) {
|
||||||
|
this.reactionBy = reactionBy;
|
||||||
|
this.reactionByResource = reactionByResource;
|
||||||
|
this.occupantId = occupantId;
|
||||||
|
this.reaction = reaction;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package im.conversations.android.database.model;
|
||||||
|
|
||||||
|
import androidx.room.Relation;
|
||||||
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
import im.conversations.android.database.entity.MessageContentEntity;
|
||||||
|
import im.conversations.android.database.entity.MessageReactionEntity;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MessageWithContentReactions {
|
||||||
|
|
||||||
|
public long id;
|
||||||
|
|
||||||
|
public Instant sentAt;
|
||||||
|
|
||||||
|
public boolean outgoing;
|
||||||
|
|
||||||
|
public Jid toBare;
|
||||||
|
public String toResource;
|
||||||
|
public Jid fromBare;
|
||||||
|
public String fromResource;
|
||||||
|
|
||||||
|
public Modification modification;
|
||||||
|
public long version;
|
||||||
|
|
||||||
|
@Relation(
|
||||||
|
entity = MessageContentEntity.class,
|
||||||
|
parentColumn = "version",
|
||||||
|
entityColumn = "messageVersionId")
|
||||||
|
public List<MessageContent> contents;
|
||||||
|
|
||||||
|
@Relation(
|
||||||
|
entity = MessageReactionEntity.class,
|
||||||
|
parentColumn = "id",
|
||||||
|
entityColumn = "messageEntityId")
|
||||||
|
public List<MessageReaction> reactions;
|
||||||
|
}
|
Loading…
Reference in a new issue