diff --git a/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientExporterTest.java b/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientExporterTest.java deleted file mode 100644 index 42c08da83a..0000000000 --- a/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientExporterTest.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.thoughtcrime.securesms.recipients; - -import android.app.Application; -import android.content.Intent; -import android.provider.ContactsContract; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import org.thoughtcrime.securesms.profiles.ProfileName; - -import java.util.Optional; - -import static android.provider.ContactsContract.Intents.Insert.EMAIL; -import static android.provider.ContactsContract.Intents.Insert.NAME; -import static android.provider.ContactsContract.Intents.Insert.PHONE; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE, application = Application.class) -public final class RecipientExporterTest { - - @Test - public void asAddContactIntent_with_phone_number() { - Recipient recipient = givenPhoneRecipient(ProfileName.fromParts("Alice", null), "+1555123456"); - - Intent intent = RecipientExporter.export(recipient).asAddContactIntent(); - - assertEquals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction()); - assertEquals(ContactsContract.Contacts.CONTENT_ITEM_TYPE, intent.getType()); - assertEquals("Alice", intent.getStringExtra(NAME)); - assertEquals("+1555123456", intent.getStringExtra(PHONE)); - assertNull(intent.getStringExtra(EMAIL)); - } - - @Test - public void asAddContactIntent_with_phone_number_should_not_show_number() { - Recipient recipient = givenPhoneRecipient(ProfileName.fromParts("Alice", null), "+1555123456", false); - - Intent intent = RecipientExporter.export(recipient).asAddContactIntent(); - - assertEquals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction()); - assertEquals(ContactsContract.Contacts.CONTENT_ITEM_TYPE, intent.getType()); - assertEquals("Alice", intent.getStringExtra(NAME)); - assertNull(intent.getStringExtra(PHONE)); - assertNull(intent.getStringExtra(EMAIL)); - } - - @Test - public void asAddContactIntent_with_email() { - Recipient recipient = givenEmailRecipient(ProfileName.fromParts("Bob", null), "bob@signal.org"); - - Intent intent = RecipientExporter.export(recipient).asAddContactIntent(); - - assertEquals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction()); - assertEquals(ContactsContract.Contacts.CONTENT_ITEM_TYPE, intent.getType()); - assertEquals("Bob", intent.getStringExtra(NAME)); - assertEquals("bob@signal.org", intent.getStringExtra(EMAIL)); - assertNull(intent.getStringExtra(PHONE)); - } - - - private Recipient givenPhoneRecipient(ProfileName profileName, String phone) { - return givenPhoneRecipient(profileName, phone, true); - } - - private Recipient givenPhoneRecipient(ProfileName profileName, String phone, boolean shouldShowPhoneNumber) { - Recipient recipient = mock(Recipient.class); - when(recipient.getProfileName()).thenReturn(profileName); - - when(recipient.requireE164()).thenReturn(phone); - when(recipient.getE164()).thenAnswer(i -> Optional.of(phone)); - when(recipient.getEmail()).thenAnswer(i -> Optional.empty()); - when(recipient.getShouldShowE164()).thenAnswer(i -> shouldShowPhoneNumber); - - return recipient; - } - - private Recipient givenEmailRecipient(ProfileName profileName, String email) { - Recipient recipient = mock(Recipient.class); - when(recipient.getProfileName()).thenReturn(profileName); - - when(recipient.requireEmail()).thenReturn(email); - when(recipient.getEmail()).thenAnswer(i -> Optional.of(email)); - when(recipient.getE164()).thenAnswer(i -> Optional.empty()); - - return recipient; - } -} diff --git a/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientExporterTest.kt b/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientExporterTest.kt new file mode 100644 index 0000000000..d5e449b94a --- /dev/null +++ b/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientExporterTest.kt @@ -0,0 +1,91 @@ +package org.thoughtcrime.securesms.recipients + +import android.app.Application +import android.content.Intent +import android.provider.ContactsContract +import io.mockk.every +import io.mockk.mockk +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.thoughtcrime.securesms.profiles.ProfileName +import java.util.Optional + +@RunWith(RobolectricTestRunner::class) +@Config(manifest = Config.NONE, application = Application::class) +class RecipientExporterTest { + @Test + fun asAddContactIntent_with_phone_number() { + val recipient = givenPhoneRecipient( + profileName = ProfileName.fromParts("Alice", null), + phone = "+1555123456" + ) + + val intent = RecipientExporter.export(recipient).asAddContactIntent() + + assertEquals(Intent.ACTION_INSERT_OR_EDIT, intent.action) + assertEquals(ContactsContract.Contacts.CONTENT_ITEM_TYPE, intent.type) + assertEquals("Alice", intent.getStringExtra(ContactsContract.Intents.Insert.NAME)) + assertEquals("+1555123456", intent.getStringExtra(ContactsContract.Intents.Insert.PHONE)) + assertNull(intent.getStringExtra(ContactsContract.Intents.Insert.EMAIL)) + } + + @Test + fun asAddContactIntent_with_phone_number_should_not_show_number() { + val recipient = givenPhoneRecipient( + profileName = ProfileName.fromParts("Alice", null), + phone = "+1555123456", + shouldShowPhoneNumber = false + ) + + val intent = RecipientExporter.export(recipient).asAddContactIntent() + + assertEquals(Intent.ACTION_INSERT_OR_EDIT, intent.action) + assertEquals(ContactsContract.Contacts.CONTENT_ITEM_TYPE, intent.type) + assertEquals("Alice", intent.getStringExtra(ContactsContract.Intents.Insert.NAME)) + assertNull(intent.getStringExtra(ContactsContract.Intents.Insert.PHONE)) + assertNull(intent.getStringExtra(ContactsContract.Intents.Insert.EMAIL)) + } + + @Test + fun asAddContactIntent_with_email() { + val recipient = givenEmailRecipient( + profileName = ProfileName.fromParts("Bob", null), + email = "bob@signal.org" + ) + + val intent = RecipientExporter.export(recipient).asAddContactIntent() + + assertEquals(Intent.ACTION_INSERT_OR_EDIT, intent.action) + assertEquals(ContactsContract.Contacts.CONTENT_ITEM_TYPE, intent.type) + assertEquals("Bob", intent.getStringExtra(ContactsContract.Intents.Insert.NAME)) + assertEquals("bob@signal.org", intent.getStringExtra(ContactsContract.Intents.Insert.EMAIL)) + assertNull(intent.getStringExtra(ContactsContract.Intents.Insert.PHONE)) + } + + private fun givenPhoneRecipient(profileName: ProfileName, phone: String, shouldShowPhoneNumber: Boolean = true): Recipient { + val recipient = mockk() + every { recipient.profileName } returns profileName + + every { recipient.requireE164() } returns phone + every { recipient.e164 } returns Optional.of(phone) + every { recipient.email } returns Optional.empty() + every { recipient.shouldShowE164 } returns shouldShowPhoneNumber + + return recipient + } + + private fun givenEmailRecipient(profileName: ProfileName, email: String): Recipient { + val recipient = mockk() + every { recipient.profileName } returns profileName + + every { recipient.requireEmail() } returns email + every { recipient.email } returns Optional.of(email) + every { recipient.e164 } returns Optional.empty() + + return recipient + } +} diff --git a/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientUtilTest.java b/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientUtilTest.java deleted file mode 100644 index 2a603bc0aa..0000000000 --- a/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientUtilTest.java +++ /dev/null @@ -1,234 +0,0 @@ -package org.thoughtcrime.securesms.recipients; - -import android.content.Context; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.thoughtcrime.securesms.database.MessageTable; -import org.thoughtcrime.securesms.database.RecipientTable; -import org.thoughtcrime.securesms.database.SignalDatabase; -import org.thoughtcrime.securesms.database.ThreadTable; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class RecipientUtilTest { - - @Rule - public MockitoRule rule = MockitoJUnit.rule(); - - private Context context = mock(Context.class); - private Recipient recipient = mock(Recipient.class); - private ThreadTable mockThreadTable = mock(ThreadTable.class); - private MessageTable mockMessageTable = mock(MessageTable.class); - private RecipientTable mockRecipientTable = mock(RecipientTable.class); - - @Mock - private MockedStatic signalDatabaseMockedStatic; - - @Before - public void setUp() { - signalDatabaseMockedStatic.when(SignalDatabase::threads).thenReturn(mockThreadTable); - signalDatabaseMockedStatic.when(SignalDatabase::messages).thenReturn(mockMessageTable); - signalDatabaseMockedStatic.when(SignalDatabase::recipients).thenReturn(mockRecipientTable); - - when(recipient.getId()).thenReturn(RecipientId.from(5)); - when(recipient.resolve()).thenReturn(recipient); - } - - @Test - public void givenThreadIsNegativeOne_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, -1L); - - // THEN - assertTrue(result); - } - - @Test - public void givenRecipientIsNullForThreadId_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, 1L); - - // THEN - assertTrue(result); - } - - @Test - public void givenIHaveSentASecureMessageInThisThread_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { - // GIVEN - when(mockThreadTable.getRecipientForThreadId(anyLong())).thenReturn(recipient); - when(mockMessageTable.getOutgoingSecureMessageCount(1L)).thenReturn(5); - - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, 1L); - - // THEN - assertTrue(result); - } - - @Test - public void givenIHaveNotSentASecureMessageInThisThreadAndIAmProfileSharing_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { - // GIVEN - when(recipient.isProfileSharing()).thenReturn(true); - when(mockThreadTable.getRecipientForThreadId(anyLong())).thenReturn(recipient); - when(mockMessageTable.getOutgoingSecureMessageCount(1L)).thenReturn(0); - - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, 1L); - - // THEN - assertTrue(result); - } - - @Test - public void givenIHaveNotSentASecureMessageInThisThreadAndRecipientIsSystemContact_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { - // GIVEN - when(recipient.isSystemContact()).thenReturn(true); - when(mockThreadTable.getRecipientForThreadId(anyLong())).thenReturn(recipient); - when(mockMessageTable.getOutgoingSecureMessageCount(1L)).thenReturn(0); - - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, 1L); - - // THEN - assertTrue(result); - } - - @Ignore - @Test - public void givenIHaveReceivedASecureMessageIHaveNotSentASecureMessageAndRecipientIsNotSystemContactAndNotProfileSharing_whenIsThreadMessageRequestAccepted_thenIExpectFalse() { - // GIVEN - when(mockThreadTable.getRecipientForThreadId(anyLong())).thenReturn(recipient); - when(mockMessageTable.getOutgoingSecureMessageCount(1L)).thenReturn(0); - when(mockMessageTable.getSecureMessageCount(1L)).thenReturn(5); - - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, 1L); - - // THEN - assertFalse(result); - } - - @Test - public void givenIHaveNotReceivedASecureMessageIHaveNotSentASecureMessageAndRecipientIsNotSystemContactAndNotProfileSharing_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { - // GIVEN - when(mockThreadTable.getRecipientForThreadId(anyLong())).thenReturn(recipient); - when(mockMessageTable.getOutgoingSecureMessageCount(1L)).thenReturn(0); - when(mockMessageTable.getSecureMessageCount(1L)).thenReturn(0); - - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, 1L); - - // THEN - assertTrue(result); - } - - @Test - public void givenRecipientIsNull_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() { - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, null); - - // THEN - assertTrue(result); - } - - @Test - public void givenNonZeroOutgoingSecureMessageCount_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() { - // GIVEN - when(mockMessageTable.getOutgoingSecureMessageCount(anyLong())).thenReturn(1); - - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, recipient); - - // THEN - assertTrue(result); - } - - @Test - public void givenIAmProfileSharing_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() { - // GIVEN - when(recipient.isProfileSharing()).thenReturn(true); - - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, recipient); - - // THEN - assertTrue(result); - } - - @Test - public void givenRecipientIsASystemContact_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() { - // GIVEN - when(recipient.isSystemContact()).thenReturn(true); - - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, recipient); - - // THEN - assertTrue(result); - } - - @Ignore - @Test - public void givenNoSecureMessagesSentSomeSecureMessagesReceivedNotSharingAndNotSystemContact_whenIsRecipientMessageRequestAccepted_thenIExpectFalse() { - // GIVEN - when(recipient.isRegistered()).thenReturn(true); - when(mockMessageTable.getSecureMessageCount(anyLong())).thenReturn(5); - - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, recipient); - - // THEN - assertFalse(result); - } - - @Test - public void givenNoSecureMessagesSentNoSecureMessagesReceivedNotSharingAndNotSystemContact_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() { - // GIVEN - when(mockMessageTable.getSecureMessageCount(anyLong())).thenReturn(0); - - // WHEN - boolean result = RecipientUtil.isMessageRequestAccepted(context, recipient); - - // THEN - assertTrue(result); - } - - @Ignore - @Test - public void givenNoSecureMessagesSent_whenIShareProfileIfFirstSecureMessage_thenIShareProfile() { - // GIVEN - when(mockMessageTable.getOutgoingSecureMessageCount(anyLong())).thenReturn(0); - - // WHEN - RecipientUtil.shareProfileIfFirstSecureMessage(recipient); - - // THEN - verify(mockRecipientTable).setProfileSharing(recipient.getId(), true); - } - - @Ignore - @Test - public void givenSecureMessagesSent_whenIShareProfileIfFirstSecureMessage_thenIShareProfile() { - // GIVEN - when(mockMessageTable.getOutgoingSecureMessageCount(anyLong())).thenReturn(5); - - // WHEN - RecipientUtil.shareProfileIfFirstSecureMessage(recipient); - - // THEN - verify(mockRecipientTable, never()).setProfileSharing(recipient.getId(), true); - } -} \ No newline at end of file diff --git a/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientUtilTest.kt b/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientUtilTest.kt new file mode 100644 index 0000000000..7aba0ca8fb --- /dev/null +++ b/app/src/test/java/org/thoughtcrime/securesms/recipients/RecipientUtilTest.kt @@ -0,0 +1,229 @@ +package org.thoughtcrime.securesms.recipients + +import android.content.Context +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkObject +import io.mockk.unmockkObject +import io.mockk.verify +import org.junit.After +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Ignore +import org.junit.Test +import org.thoughtcrime.securesms.database.MessageTable +import org.thoughtcrime.securesms.database.RecipientTable +import org.thoughtcrime.securesms.database.SignalDatabase +import org.thoughtcrime.securesms.database.ThreadTable + +class RecipientUtilTest { + private val context = mockk() + private val recipient = mockk(relaxed = true) + private val mockThreadTable = mockk(relaxed = true) + private val mockMessageTable = mockk() + private val mockRecipientTable = mockk() + + @Before + fun setUp() { + mockkObject(SignalDatabase.Companion) + every { SignalDatabase.Companion.instance } returns mockk { + every { threadTable } returns mockThreadTable + every { messageTable } returns mockMessageTable + every { recipientTable } returns mockRecipientTable + } + + every { recipient.id } returns RecipientId.from(5) + every { recipient.resolve() } returns recipient + } + + @After + fun cleanup() { + unmockkObject(SignalDatabase.Companion) + } + + @Test + fun givenThreadIsNegativeOne_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, -1L) + + // THEN + assertTrue(result) + } + + @Test + fun givenRecipientIsNullForThreadId_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, 1L) + + // THEN + assertTrue(result) + } + + @Test + fun givenIHaveSentASecureMessageInThisThread_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { + // GIVEN + every { mockThreadTable.getRecipientForThreadId(any()) } returns recipient + every { mockMessageTable.getOutgoingSecureMessageCount(1L) } returns 5 + + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, 1L) + + // THEN + assertTrue(result) + } + + @Test + fun givenIHaveNotSentASecureMessageInThisThreadAndIAmProfileSharing_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { + // GIVEN + every { recipient.isProfileSharing } returns true + every { mockThreadTable.getRecipientForThreadId(any()) } returns recipient + every { mockMessageTable.getOutgoingSecureMessageCount(1L) } returns 0 + + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, 1L) + + // THEN + assertTrue(result) + } + + @Test + fun givenIHaveNotSentASecureMessageInThisThreadAndRecipientIsSystemContact_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { + // GIVEN + every { recipient.isSystemContact } returns true + every { mockThreadTable.getRecipientForThreadId(any()) } returns recipient + every { mockMessageTable.getOutgoingSecureMessageCount(1L) } returns 0 + + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, 1L) + + // THEN + assertTrue(result) + } + + @Ignore + @Test + fun givenIHaveReceivedASecureMessageIHaveNotSentASecureMessageAndRecipientIsNotSystemContactAndNotProfileSharing_whenIsThreadMessageRequestAccepted_thenIExpectFalse() { + // GIVEN + every { mockThreadTable.getRecipientForThreadId(any()) } returns recipient + every { mockMessageTable.getOutgoingSecureMessageCount(1L) } returns 0 + every { mockMessageTable.getSecureMessageCount(1L) } returns 5 + + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, 1L) + + // THEN + assertFalse(result) + } + + @Test + fun givenIHaveNotReceivedASecureMessageIHaveNotSentASecureMessageAndRecipientIsNotSystemContactAndNotProfileSharing_whenIsThreadMessageRequestAccepted_thenIExpectTrue() { + // GIVEN + every { mockThreadTable.getRecipientForThreadId(any()) } returns recipient + every { mockMessageTable.getOutgoingSecureMessageCount(1L) } returns 0 + every { mockMessageTable.getSecureMessageCount(1L) } returns 0 + + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, 1L) + + // THEN + assertTrue(result) + } + + @Test + fun givenRecipientIsNull_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() { + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, null) + + // THEN + assertTrue(result) + } + + @Test + fun givenNonZeroOutgoingSecureMessageCount_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() { + // GIVEN + every { mockMessageTable.getOutgoingSecureMessageCount(any()) } returns 1 + + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, recipient) + + // THEN + assertTrue(result) + } + + @Test + fun givenIAmProfileSharing_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() { + // GIVEN + every { recipient.isProfileSharing } returns true + + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, recipient) + + // THEN + assertTrue(result) + } + + @Test + fun givenRecipientIsASystemContact_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() { + // GIVEN + every { recipient.isSystemContact } returns true + + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, recipient) + + // THEN + assertTrue(result) + } + + @Ignore + @Test + fun givenNoSecureMessagesSentSomeSecureMessagesReceivedNotSharingAndNotSystemContact_whenIsRecipientMessageRequestAccepted_thenIExpectFalse() { + // GIVEN + every { recipient.isRegistered } returns true + every { mockMessageTable.getSecureMessageCount(any()) } returns 5 + + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, recipient) + + // THEN + assertFalse(result) + } + + @Test + fun givenNoSecureMessagesSentNoSecureMessagesReceivedNotSharingAndNotSystemContact_whenIsRecipientMessageRequestAccepted_thenIExpectTrue() { + // GIVEN + every { mockMessageTable.getSecureMessageCount(any()) } returns 0 + + // WHEN + val result = RecipientUtil.isMessageRequestAccepted(context, recipient) + + // THEN + assertTrue(result) + } + + @Ignore + @Test + fun givenNoSecureMessagesSent_whenIShareProfileIfFirstSecureMessage_thenIShareProfile() { + // GIVEN + every { mockMessageTable.getOutgoingSecureMessageCount(any()) } returns 0 + + // WHEN + RecipientUtil.shareProfileIfFirstSecureMessage(recipient) + + // THEN + verify { mockRecipientTable.setProfileSharing(recipient.id, true) } + } + + @Ignore + @Test + fun givenSecureMessagesSent_whenIShareProfileIfFirstSecureMessage_thenIShareProfile() { + // GIVEN + every { mockMessageTable.getOutgoingSecureMessageCount(any()) } returns 5 + + // WHEN + RecipientUtil.shareProfileIfFirstSecureMessage(recipient) + + // THEN + verify(exactly = 0) { mockRecipientTable.setProfileSharing(recipient.id, true) } + } +} diff --git a/app/src/test/java/org/thoughtcrime/securesms/util/DelimiterUtilTest.java b/app/src/test/java/org/thoughtcrime/securesms/util/DelimiterUtilTest.java deleted file mode 100644 index 585c54b3f2..0000000000 --- a/app/src/test/java/org/thoughtcrime/securesms/util/DelimiterUtilTest.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.thoughtcrime.securesms.util; - - -import android.text.TextUtils; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.mockito.stubbing.Answer; - -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.anyString; - -public class DelimiterUtilTest { - - @Rule - public MockitoRule rule = MockitoJUnit.rule(); - - @Mock - private MockedStatic textUtilsMockedStatic; - - @Before - public void setup() { - textUtilsMockedStatic.when(() -> TextUtils.isEmpty(anyString())).thenAnswer((Answer) invocation -> { - if (invocation.getArguments()[0] == null) return true; - return ((String) invocation.getArguments()[0]).isEmpty(); - }); - } - - @Test - public void testEscape() { - assertEquals(DelimiterUtil.escape("MTV Music", ' '), "MTV\\ Music"); - assertEquals(DelimiterUtil.escape("MTV Music", ' '), "MTV\\ \\ Music"); - - assertEquals(DelimiterUtil.escape("MTV,Music", ','), "MTV\\,Music"); - assertEquals(DelimiterUtil.escape("MTV,,Music", ','), "MTV\\,\\,Music"); - - assertEquals(DelimiterUtil.escape("MTV Music", '+'), "MTV Music"); - } - - @Test - public void testSplit() { - String[] parts = DelimiterUtil.split("MTV\\ Music", ' '); - assertEquals(parts.length, 1); - assertEquals(parts[0], "MTV\\ Music"); - - parts = DelimiterUtil.split("MTV Music", ' '); - assertEquals(parts.length, 2); - assertEquals(parts[0], "MTV"); - assertEquals(parts[1], "Music"); - } - - @Test - public void testEscapeSplit() { - String input = "MTV Music"; - String intermediate = DelimiterUtil.escape(input, ' '); - String[] parts = DelimiterUtil.split(intermediate, ' '); - - assertEquals(parts.length, 1); - assertEquals(parts[0], "MTV\\ Music"); - assertEquals(DelimiterUtil.unescape(parts[0], ' '), "MTV Music"); - - input = "MTV\\ Music"; - intermediate = DelimiterUtil.escape(input, ' '); - parts = DelimiterUtil.split(intermediate, ' '); - - assertEquals(parts.length, 1); - assertEquals(parts[0], "MTV\\\\ Music"); - assertEquals(DelimiterUtil.unescape(parts[0], ' '), "MTV\\ Music"); - } - -} diff --git a/app/src/test/java/org/thoughtcrime/securesms/util/DelimiterUtilTest.kt b/app/src/test/java/org/thoughtcrime/securesms/util/DelimiterUtilTest.kt new file mode 100644 index 0000000000..aaae0f3eb5 --- /dev/null +++ b/app/src/test/java/org/thoughtcrime/securesms/util/DelimiterUtilTest.kt @@ -0,0 +1,66 @@ +package org.thoughtcrime.securesms.util + +import android.text.TextUtils +import io.mockk.every +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import org.junit.After +import org.junit.Assert.assertArrayEquals +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test + +class DelimiterUtilTest { + @Before + fun setup() { + mockkStatic(TextUtils::class) + every { TextUtils.isEmpty(any()) } answers { + (invocation.args.first() as? String)?.isEmpty() ?: true + } + } + + @After + fun cleanup() { + unmockkStatic(TextUtils::class) + } + + @Test + fun testEscape() { + assertEquals("MTV\\ Music", DelimiterUtil.escape("MTV Music", ' ')) + assertEquals("MTV\\ \\ Music", DelimiterUtil.escape("MTV Music", ' ')) + + assertEquals("MTV\\,Music", DelimiterUtil.escape("MTV,Music", ',')) + assertEquals("MTV\\,\\,Music", DelimiterUtil.escape("MTV,,Music", ',')) + + assertEquals("MTV Music", DelimiterUtil.escape("MTV Music", '+')) + } + + @Test + fun testSplit() { + assertArrayEquals( + arrayOf("MTV\\ Music"), + DelimiterUtil.split("MTV\\ Music", ' ') + ) + assertArrayEquals( + arrayOf("MTV", "Music"), + DelimiterUtil.split("MTV Music", ' ') + ) + } + + @Test + fun testEscapeSplit() { + "MTV Music".let { input -> + val intermediate = DelimiterUtil.escape(input, ' ') + val parts = DelimiterUtil.split(intermediate, ' ') + assertEquals("MTV\\ Music", parts.single()) + assertEquals("MTV Music", DelimiterUtil.unescape(parts.single(), ' ')) + } + + "MTV\\ Music".let { input -> + val intermediate = DelimiterUtil.escape(input, ' ') + val parts = DelimiterUtil.split(intermediate, ' ') + assertEquals("MTV\\\\ Music", parts.single()) + assertEquals("MTV\\ Music", DelimiterUtil.unescape(parts.single(), ' ')) + } + } +} diff --git a/core-util/src/test/java/org/signal/core/util/concurrent/LatestPrioritizedSerialExecutorTest.java b/core-util/src/test/java/org/signal/core/util/concurrent/LatestPrioritizedSerialExecutorTest.java deleted file mode 100644 index f1541594aa..0000000000 --- a/core-util/src/test/java/org/signal/core/util/concurrent/LatestPrioritizedSerialExecutorTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.signal.core.util.concurrent; - -import org.junit.Test; - -import java.util.LinkedList; -import java.util.Queue; -import java.util.concurrent.Executor; - -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -public final class LatestPrioritizedSerialExecutorTest { - - @Test - public void execute_sortsInPriorityOrder() { - TestExecutor executor = new TestExecutor(); - Runnable placeholder = new TestRunnable(); - - Runnable first = spy(new TestRunnable()); - Runnable second = spy(new TestRunnable()); - Runnable third = spy(new TestRunnable()); - - LatestPrioritizedSerialExecutor subject = new LatestPrioritizedSerialExecutor(executor); - subject.execute(0, placeholder); // The first thing we execute can't be sorted, so we put in this placeholder - subject.execute(1, third); - subject.execute(2, second); - subject.execute(3, first); - - executor.next(); // Clear the placeholder task - - executor.next(); - verify(first).run(); - - executor.next(); - verify(second).run(); - - executor.next(); - verify(third).run(); - } - - @Test - public void execute_replacesDupes() { - TestExecutor executor = new TestExecutor(); - Runnable placeholder = new TestRunnable(); - - Runnable firstReplaced = spy(new TestRunnable()); - Runnable first = spy(new TestRunnable()); - Runnable second = spy(new TestRunnable()); - Runnable thirdReplaced = spy(new TestRunnable()); - Runnable third = spy(new TestRunnable()); - - LatestPrioritizedSerialExecutor subject = new LatestPrioritizedSerialExecutor(executor); - subject.execute(0, placeholder); // The first thing we execute can't be sorted, so we put in this placeholder - subject.execute(1, thirdReplaced); - subject.execute(1, third); - subject.execute(2, second); - subject.execute(3, firstReplaced); - subject.execute(3, first); - - executor.next(); // Clear the placeholder task - - executor.next(); - verify(first).run(); - - executor.next(); - verify(second).run(); - - executor.next(); - verify(third).run(); - - verify(firstReplaced, never()).run(); - verify(thirdReplaced, never()).run(); - } - - private static final class TestExecutor implements Executor { - - private final Queue tasks = new LinkedList<>(); - - @Override - public void execute(Runnable command) { - tasks.add(command); - } - - public void next() { - tasks.remove().run(); - } - } - - public static class TestRunnable implements Runnable { - @Override - public void run() { } - } -} diff --git a/core-util/src/test/java/org/signal/core/util/concurrent/LatestPrioritizedSerialExecutorTest.kt b/core-util/src/test/java/org/signal/core/util/concurrent/LatestPrioritizedSerialExecutorTest.kt new file mode 100644 index 0000000000..9f53ebcbc3 --- /dev/null +++ b/core-util/src/test/java/org/signal/core/util/concurrent/LatestPrioritizedSerialExecutorTest.kt @@ -0,0 +1,90 @@ +package org.signal.core.util.concurrent + +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import java.util.concurrent.Executor + +class LatestPrioritizedSerialExecutorTest { + @Test + fun execute_sortsInPriorityOrder() { + val executor = TestExecutor() + val placeholder = TestRunnable() + + val first = TestRunnable() + val second = TestRunnable() + val third = TestRunnable() + + val subject = LatestPrioritizedSerialExecutor(executor) + subject.execute(0, placeholder) // The first thing we execute can't be sorted, so we put in this placeholder + subject.execute(1, third) + subject.execute(2, second) + subject.execute(3, first) + + executor.next() // Clear the placeholder task + + executor.next() + assertTrue(first.didRun) + + executor.next() + assertTrue(second.didRun) + + executor.next() + assertTrue(third.didRun) + } + + @Test + fun execute_replacesDupes() { + val executor = TestExecutor() + val placeholder = TestRunnable() + + val firstReplaced = TestRunnable() + val first = TestRunnable() + val second = TestRunnable() + val thirdReplaced = TestRunnable() + val third = TestRunnable() + + val subject = LatestPrioritizedSerialExecutor(executor) + subject.execute(0, placeholder) // The first thing we execute can't be sorted, so we put in this placeholder + subject.execute(1, thirdReplaced) + subject.execute(1, third) + subject.execute(2, second) + subject.execute(3, firstReplaced) + subject.execute(3, first) + + executor.next() // Clear the placeholder task + + executor.next() + assertTrue(first.didRun) + + executor.next() + assertTrue(second.didRun) + + executor.next() + assertTrue(third.didRun) + + assertFalse(firstReplaced.didRun) + assertFalse(thirdReplaced.didRun) + } + + private class TestExecutor : Executor { + private val tasks = ArrayDeque() + + override fun execute(command: Runnable) { + tasks.add(command) + } + + fun next() { + tasks.removeLast().run() + } + } + + class TestRunnable : Runnable { + private var _didRun = false + val didRun get() = _didRun + + override fun run() { + _didRun = true + } + } +} diff --git a/libsignal-service/src/test/java/org/whispersystems/signalservice/api/services/DonationsServiceTest.java b/libsignal-service/src/test/java/org/whispersystems/signalservice/api/services/DonationsServiceTest.java deleted file mode 100644 index 9f7a72a293..0000000000 --- a/libsignal-service/src/test/java/org/whispersystems/signalservice/api/services/DonationsServiceTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.whispersystems.signalservice.api.services; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.Mockito; -import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException; -import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription; -import org.whispersystems.signalservice.api.subscriptions.SubscriberId; -import org.whispersystems.signalservice.internal.ServiceResponse; -import org.whispersystems.signalservice.internal.push.PushServiceSocket; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@RunWith(JUnit4.class) -public class DonationsServiceTest { - - private final PushServiceSocket pushServiceSocket = Mockito.mock(PushServiceSocket.class); - private final DonationsService testSubject = new DonationsService(pushServiceSocket); - - @Test - public void givenASubscriberId_whenIGetASuccessfulResponse_thenItIsMappedWithTheCorrectStatusCodeAndNonEmptyObject() throws Exception { - // GIVEN - SubscriberId subscriberId = SubscriberId.generate(); - when(pushServiceSocket.getSubscription(subscriberId.serialize())) - .thenReturn(getActiveSubscription()); - - // WHEN - ServiceResponse response = testSubject.getSubscription(subscriberId); - - // THEN - verify(pushServiceSocket).getSubscription(subscriberId.serialize()); - assertEquals(200, response.getStatus()); - assertTrue(response.getResult().isPresent()); - } - - @Test - public void givenASubscriberId_whenIGetAnUnsuccessfulResponse_thenItIsMappedWithTheCorrectStatusCodeAndEmptyObject() throws Exception { - // GIVEN - SubscriberId subscriberId = SubscriberId.generate(); - when(pushServiceSocket.getSubscription(subscriberId.serialize())) - .thenThrow(new NonSuccessfulResponseCodeException(403)); - - // WHEN - ServiceResponse response = testSubject.getSubscription(subscriberId); - - // THEN - verify(pushServiceSocket).getSubscription(subscriberId.serialize()); - assertEquals(403, response.getStatus()); - assertFalse(response.getResult().isPresent()); - } - - private ActiveSubscription getActiveSubscription() { - return ActiveSubscription.EMPTY; - } -} diff --git a/libsignal-service/src/test/java/org/whispersystems/signalservice/api/services/DonationsServiceTest.kt b/libsignal-service/src/test/java/org/whispersystems/signalservice/api/services/DonationsServiceTest.kt new file mode 100644 index 0000000000..fa36648a79 --- /dev/null +++ b/libsignal-service/src/test/java/org/whispersystems/signalservice/api/services/DonationsServiceTest.kt @@ -0,0 +1,49 @@ +package org.whispersystems.signalservice.api.services + +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException +import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription +import org.whispersystems.signalservice.api.subscriptions.SubscriberId +import org.whispersystems.signalservice.internal.push.PushServiceSocket + +class DonationsServiceTest { + private val pushServiceSocket: PushServiceSocket = mockk() + private val testSubject = DonationsService(pushServiceSocket) + private val activeSubscription = ActiveSubscription.EMPTY + + @Test + fun givenASubscriberId_whenIGetASuccessfulResponse_thenItIsMappedWithTheCorrectStatusCodeAndNonEmptyObject() { + // GIVEN + val subscriberId = SubscriberId.generate() + every { pushServiceSocket.getSubscription(subscriberId.serialize()) } returns activeSubscription + + // WHEN + val response = testSubject.getSubscription(subscriberId) + + // THEN + verify { pushServiceSocket.getSubscription(subscriberId.serialize()) } + assertEquals(200, response.status) + assertTrue(response.result.isPresent) + } + + @Test + fun givenASubscriberId_whenIGetAnUnsuccessfulResponse_thenItIsMappedWithTheCorrectStatusCodeAndEmptyObject() { + // GIVEN + val subscriberId = SubscriberId.generate() + every { pushServiceSocket.getSubscription(subscriberId.serialize()) } throws NonSuccessfulResponseCodeException(403) + + // WHEN + val response = testSubject.getSubscription(subscriberId) + + // THEN + verify { pushServiceSocket.getSubscription(subscriberId.serialize()) } + assertEquals(403, response.status) + assertFalse(response.result.isPresent) + } +}