Skip to content

Commit

Permalink
Bump version to 7.29.0
Browse files Browse the repository at this point in the history
Fix derivation of RRP in RefreshAttributesJob.

Fix incorrect RRP bugs and reglock state with reregistering.

Update translations and other static files.

Bump version to 7.28.1

Fix large message size calculation to use bytes.

Update translations and other static files.

Bump version to 7.28.2

Fix bug with ellipsizing on media messages.

Bump version to 7.28.3

Translate missing recipients into unknown recipients.

Bump version to 7.28.4

Treat all groups updates as directionless for backupv2.

Remove Mockito dependency from project.

Resolves signalapp#13838

Fix gv1 updates in backupv2.

Fix empty profile names during backupv2 export.

Move from AssertJ to AssertK.

Resolves signalapp#13841

Fix dangling call ringers.

Isolated tests for RecurringInAppPaymentRepository.

Add verification metadata for windows.

Don't show linked device bottom sheets if you've seen them before.

Add internal UI for importing backup with different credentials.

Improve internal backup import UI tool.

Implement initial support for IAP data.

Upgrade to AGP 8.7.2

Upgrade to AGP 8.7.3

Isolated tests for OneTimeInAppPaymentRepository.

Move some things to lib.versions.toml

Add AAPT metadata for witness verification.

Use more plugin aliases.

Upgrade to kotlin 2.1.0

Update a bunch of libraries.

Update compileSdk to 35.

Add .kotlin to gitignore.

Update more libraries.

Ensure that the V262 database migration runs.

Update our base themes to avoid crashing MaterialAlertDialog.

Revert "Improve table display in Spinner."

This reverts commit df96b05.

Fix cutoff string in help section.

Fix typo in sql query.

Add trigger definitions to logs.

Capitalize log section title.

Fix small gap in call menu.

Update string translation comments.

Fix leaked refreshActiveSubscription disposable.

Fix ability to share text stories.

Fixes signalapp#13855
Resolves signalapp#13879

Initialize database error handler with application instance.

Fix text overflow length calculation.

Fix overflow handling in condensed mode.

Ensure filter is not retriggered when formatting.

Fixes signalapp#13876

Fix proximity sensor for voice notes.

Ensure new manifest is saved after rotation.

Inline and enable the SSRE2 config.

Exclude unregistered group members from invalid collisions check.

Fixes signalapp#13866

Stop in-chat notification sounds if notifications are disabled.

Fix bug showing null string on empty search.

Fixes signalapp#13854
Resolves signalapp#13878

Revert "Update our base themes to avoid crashing MaterialAlertDialog."

This reverts commit 446c7d6.

Add missing required material3 dialog theme attribute.

Disable the SSRE2 capability for now.

Fix benchmark build.

Add loading state to toggle switch and enforce when changing call link admin settings.

Update translations and other static files.

Update baseline profile.

Co-Authored-By: Greyson Parrelli <[email protected]>
  • Loading branch information
greyson-signal authored and AbandonedCart committed Jan 31, 2025
1 parent 43eba96 commit a90fdbc
Show file tree
Hide file tree
Showing 252 changed files with 18,290 additions and 12,783 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ dev.keystore
maps.key
/local/
kls_database.db
.kotlin
6 changes: 6 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 7 additions & 10 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import java.util.Date
import java.util.Properties

plugins {
id("com.android.application")
id("kotlin-android")
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
alias(libs.plugins.ktlint)
alias(libs.plugins.compose.compiler)
id("androidx.navigation.safeargs")
id("org.jlleitschuh.gradle.ktlint")
id("org.jetbrains.kotlin.android")
id("app.cash.exhaustive")
id("kotlin-parcelize")
id("com.squareup.wire")
id("translations")
Expand All @@ -21,8 +20,8 @@ plugins {

apply(from = "static-ips.gradle.kts")

val canonicalVersionCode = 1492
val canonicalVersionName = "7.28.0"
val canonicalVersionCode = 1497
val canonicalVersionName = "7.29.0"
val currentHotfixVersion = 0
val maxHotfixVersions = 100

Expand Down Expand Up @@ -590,9 +589,7 @@ dependencies {
}

testImplementation(testLibs.junit.junit)
testImplementation(testLibs.assertj.core)
testImplementation(testLibs.mockito.core)
testImplementation(testLibs.mockito.kotlin)
testImplementation(testLibs.assertk)
testImplementation(testLibs.androidx.test.core)
testImplementation(testLibs.robolectric.robolectric) {
exclude(group = "com.google.protobuf", module = "protobuf-java")
Expand Down
5 changes: 2 additions & 3 deletions app/proguard/proguard-automation.pro
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
-dontwarn com.android.support.test.**
-dontwarn sun.reflect.**
-dontwarn sun.misc.**
-dontwarn org.assertj.**
-dontwarn assertk.**
-dontwarn org.hamcrest.**
-dontwarn org.mockito.**
-dontwarn com.squareup.**

-dontobfuscate
-dontobfuscate
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ class ArchiveImportExportTests {
length = importData.size.toLong(),
inputStreamFactory = { ByteArrayInputStream(importData) },
selfData = BackupRepository.SelfData(SELF_ACI, SELF_PNI, SELF_E164, ProfileKey(SELF_PROFILE_KEY)),
plaintext = true
backupKey = null
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,12 @@ class CheckoutFlowActivityTest__RecurringDonations {
currency = currency,
type = InAppPaymentSubscriberRecord.Type.DONATION,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.CARD
paymentMethodType = InAppPaymentData.PaymentMethodType.CARD,
iapSubscriptionId = null
)

InAppPaymentsRepository.setSubscriber(subscriber)
SignalStore.inAppPayments.setSubscriberCurrency(currency, subscriber.type)
SignalStore.inAppPayments.setRecurringDonationCurrency(currency)

InstrumentationApplicationDependencyProvider.addMockWebRequestHandlers(
Get("/v1/subscription/${subscriber.subscriberId.serialize()}") {
Expand Down Expand Up @@ -149,11 +150,12 @@ class CheckoutFlowActivityTest__RecurringDonations {
currency = currency,
type = InAppPaymentSubscriberRecord.Type.DONATION,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.CARD
paymentMethodType = InAppPaymentData.PaymentMethodType.CARD,
iapSubscriptionId = null
)

InAppPaymentsRepository.setSubscriber(subscriber)
SignalStore.inAppPayments.setSubscriberCurrency(currency, subscriber.type)
SignalStore.inAppPayments.setRecurringDonationCurrency(currency)

InstrumentationApplicationDependencyProvider.addMockWebRequestHandlers(
Get("/v1/subscription/${subscriber.subscriberId.serialize()}") {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
package org.thoughtcrime.securesms.database

import android.database.sqlite.SQLiteConstraintException
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.signal.core.util.count
import org.signal.core.util.deleteAll
import org.signal.core.util.readToSingleInt
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository
import org.thoughtcrime.securesms.database.model.InAppPaymentSubscriberRecord
import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData
import org.thoughtcrime.securesms.testing.SignalActivityRule
import org.thoughtcrime.securesms.testing.assertIs
import org.whispersystems.signalservice.api.storage.IAPSubscriptionId
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
import java.util.Currency

class InAppPaymentSubscriberTableTest {
@get:Rule
val harness = SignalActivityRule()

@Before
fun setUp() {
SignalDatabase.inAppPaymentSubscribers.writableDatabase.deleteAll(InAppPaymentTable.TABLE_NAME)
}

@Test(expected = SQLiteConstraintException::class)
fun givenASubscriberWithCurrencyAndIAPData_whenITryToInsert_thenIExpectException() {
val subscriber = InAppPaymentSubscriberRecord(
subscriberId = SubscriberId.generate(),
currency = Currency.getInstance("USD"),
type = InAppPaymentSubscriberRecord.Type.DONATION,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.CARD,
iapSubscriptionId = IAPSubscriptionId.GooglePlayBillingPurchaseToken("testToken")
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(subscriber)

fail("Expected a thrown exception.")
}

@Test(expected = SQLiteConstraintException::class)
fun givenADonorSubscriberWithGoogleIAPData_whenITryToInsert_thenIExpectException() {
val subscriber = InAppPaymentSubscriberRecord(
subscriberId = SubscriberId.generate(),
currency = null,
type = InAppPaymentSubscriberRecord.Type.DONATION,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.CARD,
iapSubscriptionId = IAPSubscriptionId.GooglePlayBillingPurchaseToken("testToken")
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(subscriber)

fail("Expected a thrown exception.")
}

@Test(expected = SQLiteConstraintException::class)
fun givenADonorSubscriberWithAppleIAPData_whenITryToInsert_thenIExpectException() {
val subscriber = InAppPaymentSubscriberRecord(
subscriberId = SubscriberId.generate(),
currency = null,
type = InAppPaymentSubscriberRecord.Type.DONATION,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.CARD,
iapSubscriptionId = IAPSubscriptionId.AppleIAPOriginalTransactionId(1000L)
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(subscriber)

fail("Expected a thrown exception.")
}

@Test(expected = SQLiteConstraintException::class)
fun givenADonorSubscriberWithoutCurrency_whenITryToInsert_thenIExpectException() {
val subscriber = InAppPaymentSubscriberRecord(
subscriberId = SubscriberId.generate(),
currency = null,
type = InAppPaymentSubscriberRecord.Type.DONATION,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.CARD,
iapSubscriptionId = null
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(subscriber)

fail("Expected a thrown exception.")
}

@Test
fun givenADonorSubscriberWithCurrency_whenITryToInsert_thenIExpectSuccess() {
val subscriber = InAppPaymentSubscriberRecord(
subscriberId = SubscriberId.generate(),
currency = Currency.getInstance("USD"),
type = InAppPaymentSubscriberRecord.Type.DONATION,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.CARD,
iapSubscriptionId = null
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(subscriber)
}

@Test(expected = SQLiteConstraintException::class)
fun givenABackupSubscriberWithCurrency_whenITryToInsert_thenIExpectException() {
val subscriber = InAppPaymentSubscriberRecord(
subscriberId = SubscriberId.generate(),
currency = Currency.getInstance("USD"),
type = InAppPaymentSubscriberRecord.Type.BACKUP,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.GOOGLE_PLAY_BILLING,
iapSubscriptionId = null
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(subscriber)

fail("Expected a thrown exception.")
}

@Test(expected = SQLiteConstraintException::class)
fun givenABackupSubscriberWithoutIAPData_whenITryToInsert_thenIExpectException() {
val subscriber = InAppPaymentSubscriberRecord(
subscriberId = SubscriberId.generate(),
currency = null,
type = InAppPaymentSubscriberRecord.Type.BACKUP,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.GOOGLE_PLAY_BILLING,
iapSubscriptionId = null
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(subscriber)
}

@Test
fun givenABackupSubscriberWithGoogleIAPData_whenITryToInsert_thenIExpectSuccess() {
val subscriber = InAppPaymentSubscriberRecord(
subscriberId = SubscriberId.generate(),
currency = null,
type = InAppPaymentSubscriberRecord.Type.BACKUP,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.GOOGLE_PLAY_BILLING,
iapSubscriptionId = IAPSubscriptionId.GooglePlayBillingPurchaseToken("testToken")
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(subscriber)
}

@Test
fun givenABackupSubscriberWithAppleIAPData_whenITryToInsert_thenIExpectSuccess() {
val subscriber = InAppPaymentSubscriberRecord(
subscriberId = SubscriberId.generate(),
currency = null,
type = InAppPaymentSubscriberRecord.Type.BACKUP,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.GOOGLE_PLAY_BILLING,
iapSubscriptionId = IAPSubscriptionId.AppleIAPOriginalTransactionId(1000L)
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(subscriber)
}

@Test
fun givenABackupSubscriberWithAppleIAPData_whenITryToInsertAGoogleSubscriber_thenIExpectSuccess() {
val appleSubscriber = InAppPaymentSubscriberRecord(
subscriberId = SubscriberId.generate(),
currency = null,
type = InAppPaymentSubscriberRecord.Type.BACKUP,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.GOOGLE_PLAY_BILLING,
iapSubscriptionId = IAPSubscriptionId.AppleIAPOriginalTransactionId(1000L)
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(appleSubscriber)

val googleSubscriber = InAppPaymentSubscriberRecord(
subscriberId = SubscriberId.generate(),
currency = null,
type = InAppPaymentSubscriberRecord.Type.BACKUP,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.GOOGLE_PLAY_BILLING,
iapSubscriptionId = IAPSubscriptionId.GooglePlayBillingPurchaseToken("testToken")
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(googleSubscriber)

val subscriberCount = SignalDatabase.inAppPaymentSubscribers.readableDatabase.count()
.from(InAppPaymentSubscriberTable.TABLE_NAME)
.run()
.readToSingleInt()

subscriberCount assertIs 1

val subscriber = InAppPaymentsRepository.requireSubscriber(InAppPaymentSubscriberRecord.Type.BACKUP)
subscriber.iapSubscriptionId?.originalTransactionId assertIs null
subscriber.iapSubscriptionId?.purchaseToken assertIs "testToken"
subscriber.subscriberId assertIs googleSubscriber.subscriberId
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ class FixInAppCurrencyIfAbleTest {
currency = Currency.getInstance(currencyCode),
type = InAppPaymentSubscriberRecord.Type.DONATION,
requiresCancel = false,
paymentMethodType = InAppPaymentData.PaymentMethodType.PAYPAL
paymentMethodType = InAppPaymentData.PaymentMethodType.PAYPAL,
iapSubscriptionId = null
)

SignalDatabase.inAppPaymentSubscribers.insertOrReplace(record)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import okhttp3.mockwebserver.MockWebServer
import okhttp3.mockwebserver.RecordedRequest
import okio.ByteString
import org.signal.core.util.Base64
import org.signal.core.util.billing.BillingApi
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.BuildConfig
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess
Expand Down Expand Up @@ -49,6 +50,7 @@ class InstrumentationApplicationDependencyProvider(val application: Application,
private val serviceNetworkAccessMock: SignalServiceNetworkAccess
private val recipientCache: LiveRecipientCache
private var signalServiceMessageSender: SignalServiceMessageSender? = null
private var billingApi: BillingApi = mockk()

init {
runSync {
Expand Down Expand Up @@ -108,6 +110,8 @@ class InstrumentationApplicationDependencyProvider(val application: Application,
recipientCache = LiveRecipientCache(application) { r -> r.run() }
}

override fun provideBillingApi(): BillingApi = billingApi

override fun provideSignalServiceNetworkAccess(): SignalServiceNetworkAccess {
return serviceNetworkAccessMock
}
Expand Down
Loading

0 comments on commit a90fdbc

Please sign in to comment.