Skip to content

Commit e253591

Browse files
committed
fix: require private restore publish
1 parent 2d9645a commit e253591

4 files changed

Lines changed: 119 additions & 18 deletions

File tree

app/src/main/java/to/bitkit/ui/screens/profile/PayContactsViewModel.kt

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -154,18 +154,10 @@ class PayContactsViewModel @Inject constructor(
154154
}
155155
}
156156
privateCleanupError?.let { error ->
157-
runCatching {
158-
settingsStore.update { settings ->
159-
settings.copy(sharesPrivatePaykitEndpoints = previous.sharesPrivatePaykitEndpoints)
160-
}
161-
}.onFailure { rollbackError ->
162-
error.addSuppressed(rollbackError)
163-
}
164157
if (previous.sharesPrivatePaykitEndpoints) {
165-
privatePaykitRepo.setContactSharingCleanupPending(false)
166-
.onFailure(error::addSuppressed)
167-
privatePaykitRepo.prepareSavedContacts(contacts)
168-
.onFailure(error::addSuppressed)
158+
restorePrivateContactPayments(contacts, error)
159+
} else {
160+
updatePrivateContactsPreference(isEnabled = false, error = error)
169161
}
170162
}
171163

@@ -183,6 +175,36 @@ class PayContactsViewModel @Inject constructor(
183175
return Result.success(Unit)
184176
}
185177

178+
private suspend fun restorePrivateContactPayments(
179+
contacts: List<String>,
180+
error: Throwable,
181+
) {
182+
val preferenceRestored = updatePrivateContactsPreference(isEnabled = true, error = error)
183+
if (!preferenceRestored) return
184+
185+
privatePaykitRepo.prepareSavedContacts(
186+
publicKeys = contacts,
187+
requireImmediatePublication = true,
188+
).onFailure {
189+
error.addSuppressed(it)
190+
updatePrivateContactsPreference(isEnabled = false, error = error)
191+
return
192+
}
193+
194+
privatePaykitRepo.setContactSharingCleanupPending(false)
195+
.onFailure {
196+
error.addSuppressed(it)
197+
updatePrivateContactsPreference(isEnabled = false, error = error)
198+
}
199+
}
200+
201+
private suspend fun updatePrivateContactsPreference(
202+
isEnabled: Boolean,
203+
error: Throwable,
204+
): Boolean = runCatching {
205+
settingsStore.update { it.copy(sharesPrivatePaykitEndpoints = isEnabled) }
206+
}.onFailure(error::addSuppressed).isSuccess
207+
186208
private fun syncErrorMessage(error: Throwable): String = when (error) {
187209
PublicPaykitError.InvalidPayload -> context.getString(R.string.profile__pay_contacts_error_invalid_payload)
188210
PublicPaykitError.NoSupportedEndpoint -> context.getString(R.string.profile__pay_contacts_error_no_endpoint)

app/src/main/java/to/bitkit/ui/settings/paymentPreference/PaymentPreferenceViewModel.kt

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@ class PaymentPreferenceViewModel @Inject constructor(
208208
error: Throwable,
209209
) {
210210
val contacts = contactPublicKeys()
211+
if (!requestedEnabled && previous.sharesPrivatePaykitEndpoints) {
212+
restorePrivateContactsPreference(contacts, error)
213+
return
214+
}
215+
211216
runCatching {
212217
settingsStore.update { it.copy(sharesPrivatePaykitEndpoints = previous.sharesPrivatePaykitEndpoints) }
213218
}.onFailure(error::addSuppressed)
@@ -216,14 +221,38 @@ class PaymentPreferenceViewModel @Inject constructor(
216221
privatePaykitRepo.disableSharingAndPruneUnsavedContactState(contacts)
217222
.onFailure(error::addSuppressed)
218223
}
219-
if (!requestedEnabled && previous.sharesPrivatePaykitEndpoints) {
220-
privatePaykitRepo.setContactSharingCleanupPending(false)
221-
.onFailure(error::addSuppressed)
222-
privatePaykitRepo.prepareSavedContacts(contacts)
223-
.onFailure(error::addSuppressed)
224+
}
225+
226+
private suspend fun restorePrivateContactsPreference(
227+
contacts: List<String>,
228+
error: Throwable,
229+
) {
230+
val preferenceRestored = updatePrivateContactsPreference(isEnabled = true, error = error)
231+
if (!preferenceRestored) return
232+
233+
privatePaykitRepo.prepareSavedContacts(
234+
publicKeys = contacts,
235+
requireImmediatePublication = true,
236+
).onFailure {
237+
error.addSuppressed(it)
238+
updatePrivateContactsPreference(isEnabled = false, error = error)
239+
return
224240
}
241+
242+
privatePaykitRepo.setContactSharingCleanupPending(false)
243+
.onFailure {
244+
error.addSuppressed(it)
245+
updatePrivateContactsPreference(isEnabled = false, error = error)
246+
}
225247
}
226248

249+
private suspend fun updatePrivateContactsPreference(
250+
isEnabled: Boolean,
251+
error: Throwable,
252+
): Boolean = runCatching {
253+
settingsStore.update { it.copy(sharesPrivatePaykitEndpoints = isEnabled) }
254+
}.onFailure(error::addSuppressed).isSuccess
255+
227256
private suspend fun showSyncError(error: Throwable) {
228257
ToastEventBus.send(
229258
type = Toast.ToastType.ERROR,

app/src/test/java/to/bitkit/ui/screens/profile/PayContactsViewModelTest.kt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import kotlinx.coroutines.test.advanceUntilIdle
99
import org.junit.Before
1010
import org.junit.Test
1111
import org.mockito.kotlin.any
12+
import org.mockito.kotlin.eq
1213
import org.mockito.kotlin.mock
1314
import org.mockito.kotlin.never
1415
import org.mockito.kotlin.verify
@@ -225,7 +226,36 @@ class PayContactsViewModelTest : BaseUnitTest() {
225226
assertFalse(sut.uiState.value.isLoading)
226227
assertTrue(sut.uiState.value.isPaymentSharingEnabled)
227228
verify(privatePaykitRepo).setContactSharingCleanupPending(false)
228-
verify(privatePaykitRepo).prepareSavedContacts(listOf(CONTACT_KEY), false)
229+
verify(privatePaykitRepo).prepareSavedContacts(listOf(CONTACT_KEY), true)
230+
}
231+
232+
@Test
233+
fun `continueToProfile keeps private sharing disabled when private restore fails`() = test {
234+
settingsFlow.value = SettingsData(
235+
hasConfirmedPublicPaykitEndpoints = true,
236+
sharesPrivatePaykitEndpoints = true,
237+
)
238+
whenever { privatePaykitRepo.disableSharingAndPruneUnsavedContactState(any<Collection<String>>()) }
239+
.thenReturn(Result.failure(PayContactsTestAppError("cleanup failed")))
240+
whenever { privatePaykitRepo.prepareSavedContacts(any<Collection<String>>(), eq(true)) }
241+
.thenReturn(Result.failure(PayContactsTestAppError("restore failed")))
242+
val sut = createSut()
243+
advanceUntilIdle()
244+
245+
sut.effects.test {
246+
sut.setPaymentSharingEnabled(false)
247+
sut.continueToProfile()
248+
advanceUntilIdle()
249+
250+
expectNoEvents()
251+
}
252+
253+
assertTrue(settingsFlow.value.hasConfirmedPublicPaykitEndpoints)
254+
assertFalse(settingsFlow.value.sharesPrivatePaykitEndpoints)
255+
assertFalse(sut.uiState.value.isLoading)
256+
assertFalse(sut.uiState.value.isPaymentSharingEnabled)
257+
verify(privatePaykitRepo).prepareSavedContacts(listOf(CONTACT_KEY), true)
258+
verify(privatePaykitRepo, never()).setContactSharingCleanupPending(false)
229259
}
230260

231261
@Test

app/src/test/java/to/bitkit/ui/settings/paymentPreference/PaymentPreferenceViewModelTest.kt

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,27 @@ class PaymentPreferenceViewModelTest : BaseUnitTest() {
152152
assertTrue(sut.uiState.value.privateContactsEnabled)
153153
assertFalse(sut.uiState.value.isUpdatingPrivateContacts)
154154
verify(privatePaykitRepo).setContactSharingCleanupPending(false)
155-
verify(privatePaykitRepo).prepareSavedContacts(listOf(CONTACT_KEY), false)
155+
verify(privatePaykitRepo).prepareSavedContacts(listOf(CONTACT_KEY), true)
156+
}
157+
158+
@Test
159+
fun `setPrivateContactsEnabled keeps disabled when private disable rollback publish fails`() = test {
160+
settingsFlow.value = SettingsData(sharesPrivatePaykitEndpoints = true)
161+
whenever { privatePaykitRepo.disableSharingAndPruneUnsavedContactState(any<Collection<String>>()) }
162+
.thenReturn(Result.failure(PublicPaykitError.WalletNotReady))
163+
whenever { privatePaykitRepo.prepareSavedContacts(any<Collection<String>>(), eq(true)) }
164+
.thenReturn(Result.failure(PublicPaykitError.WalletNotReady))
165+
val sut = createSut()
166+
advanceUntilIdle()
167+
168+
sut.setPrivateContactsEnabled(false)
169+
advanceUntilIdle()
170+
171+
assertFalse(settingsFlow.value.sharesPrivatePaykitEndpoints)
172+
assertFalse(sut.uiState.value.privateContactsEnabled)
173+
assertFalse(sut.uiState.value.isUpdatingPrivateContacts)
174+
verify(privatePaykitRepo).prepareSavedContacts(listOf(CONTACT_KEY), true)
175+
verify(privatePaykitRepo, never()).setContactSharingCleanupPending(false)
156176
}
157177

158178
@Test

0 commit comments

Comments
 (0)