diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/DonationReceiptDatabaseTest.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/DonationReceiptDatabaseTest.kt deleted file mode 100644 index da2a0a6c9..000000000 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/DonationReceiptDatabaseTest.kt +++ /dev/null @@ -1,37 +0,0 @@ -package org.thoughtcrime.securesms.database - -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Test -import org.signal.core.util.money.FiatMoney -import org.thoughtcrime.securesms.database.model.DonationReceiptRecord -import java.math.BigDecimal -import java.util.Currency - -class DonationReceiptDatabaseTest { - - private val records = listOf( - DonationReceiptRecord.createForBoost(FiatMoney(BigDecimal.valueOf(100), Currency.getInstance("USD"))), - DonationReceiptRecord.createForBoost(FiatMoney(BigDecimal.valueOf(200), Currency.getInstance("USD"))) - ) - - @Test - fun givenNoReceipts_whenICheckHasReceipts_thenIExpectFalse() { - assertFalse(SignalDatabase.donationReceipts.hasReceipts()) - } - - @Test - fun givenOneReceipt_whenICheckHasReceipts_thenIExpectTrue() { - SignalDatabase.donationReceipts.addReceipt(records.first()) - assertTrue(SignalDatabase.donationReceipts.hasReceipts()) - } - - @Test - fun givenMultipleReceipts_whenICheckHasReceipts_thenIExpectTrue() { - records.forEach { - SignalDatabase.donationReceipts.addReceipt(it) - } - - assertTrue(SignalDatabase.donationReceipts.hasReceipts()) - } -} diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/MmsDatabaseTest_stories.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/MmsDatabaseTest_stories.kt index afe5c5fdb..774ede0ca 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/MmsDatabaseTest_stories.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/MmsDatabaseTest_stories.kt @@ -191,4 +191,51 @@ class MmsDatabaseTest_stories { assertEquals(unviewedIds.reversed() + interspersedIds.reversed(), resultOrderedIds) } + + @Test + fun givenNoStories_whenICheckIsOutgoingStoryAlreadyInDatabase_thenIExpectFalse() { + // WHEN + val result = mms.isOutgoingStoryAlreadyInDatabase(recipients[0], 200) + + // THEN + assertFalse(result) + } + + @Test + fun givenNoOutgoingStories_whenICheckIsOutgoingStoryAlreadyInDatabase_thenIExpectFalse() { + // GIVEN + MmsHelper.insert( + IncomingMediaMessage( + from = recipients[0], + sentTimeMillis = 200, + serverTimeMillis = 2, + receivedTimeMillis = 2, + storyType = StoryType.STORY_WITH_REPLIES, + ), + -1L + ) + + // WHEN + val result = mms.isOutgoingStoryAlreadyInDatabase(recipients[0], 200) + + // THEN + assertFalse(result) + } + + @Test + fun givenOutgoingStoryExistsForRecipientAndTime_whenICheckIsOutgoingStoryAlreadyInDatabase_thenIExpectTrue() { + // GIVEN + MmsHelper.insert( + recipient = myStory, + sentTimeMillis = 200, + storyType = StoryType.STORY_WITH_REPLIES, + threadId = -1L + ) + + // WHEN + val result = mms.isOutgoingStoryAlreadyInDatabase(myStory.id, 200) + + // THEN + assertTrue(result) + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java index 155f5010d..c2476f339 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageDatabase.java @@ -203,6 +203,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns public abstract @NonNull MessageDatabase.Reader getUnreadStories(@NonNull RecipientId recipientId, int limit); public abstract @Nullable ParentStoryId.GroupReply getParentStoryIdForGroupReply(long messageId); public abstract void deleteGroupStoryReplies(long parentStoryId); + public abstract boolean isOutgoingStoryAlreadyInDatabase(@NonNull RecipientId recipientId, long sentTimestamp); public abstract @NonNull StoryViewState getStoryViewState(@NonNull RecipientId recipientId); public abstract void updateViewedStories(@NonNull Set syncMessageIds); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java index 254ac3193..ff41ed079 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -695,6 +695,22 @@ public class MmsDatabase extends MessageDatabase { } } + @Override + public boolean isOutgoingStoryAlreadyInDatabase(@NonNull RecipientId recipientId, long sentTimestamp) { + SQLiteDatabase database = databaseHelper.getSignalReadableDatabase(); + String[] projection = new String[]{"COUNT(*)"}; + String where = RECIPIENT_ID + " = ? AND " + STORY_TYPE + " > 0 AND " + DATE_SENT + " = ? AND (" + getOutgoingTypeClause() + ")"; + String[] whereArgs = SqlUtil.buildArgs(recipientId, sentTimestamp); + + try (Cursor cursor = database.query(TABLE_NAME, projection, where, whereArgs, null, null, null, "1")) { + if (cursor != null && cursor.moveToFirst()) { + return cursor.getInt(0) > 0; + } + } + + return false; + } + @Override public @NonNull MessageId getStoryId(@NonNull RecipientId authorId, long sentTimestamp) throws NoSuchMessageException { SQLiteDatabase database = databaseHelper.getSignalReadableDatabase(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index 7a20fb822..bf513ffec 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -1417,6 +1417,10 @@ public class SmsDatabase extends MessageDatabase { throw new UnsupportedOperationException(); } + public boolean isOutgoingStoryAlreadyInDatabase(@NonNull RecipientId recipientId, long sentTimestamp) { + throw new UnsupportedOperationException(); + } + @Override public @NonNull MessageId getStoryId(@NonNull RecipientId authorId, long sentTimestamp) throws NoSuchMessageException { throw new UnsupportedOperationException(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java index d85f9c780..26262911c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageContentProcessor.java @@ -49,7 +49,6 @@ import org.thoughtcrime.securesms.database.SentStorySyncManifest; import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.database.model.DistributionListId; import org.thoughtcrime.securesms.database.model.Mention; import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.database.model.MessageLogEntry; @@ -2062,6 +2061,11 @@ public final class MessageContentProcessor { @NonNull List linkPreviews) throws MmsException { + if (SignalDatabase.mms().isOutgoingStoryAlreadyInDatabase(recipient.getId(), sentAtTimestamp)) { + warn(sentAtTimestamp, "Already inserted this story."); + return; + } + OutgoingMediaMessage mediaMessage = new OutgoingMediaMessage(recipient, textStoryBody, pendingAttachments,