Skip to content

Commit f94c91c

Browse files
committed
Ensure terminal errors in the manual code flow also quits the pairing session
1 parent f0ff4aa commit f94c91c

6 files changed

Lines changed: 63 additions & 17 deletions

File tree

sync/sync-impl/src/main/java/com/duckduckgo/sync/impl/ui/EnterCodeActivity.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ class EnterCodeActivity : DuckDuckGoActivity() {
153153
is Command.AskJoinerConfirmation -> askJoinerConfirmation(command.peerName, command.peerKind)
154154
is Command.AskHostConfirmation -> askHostConfirmation(command.peerName, command.peerKind)
155155
Command.FinishWithError -> {
156-
setResult(RESULT_CANCELED)
156+
val resultIntent = Intent().putExtra(EXTRA_FINISHED_WITH_ERROR, true)
157+
setResult(RESULT_CANCELED, resultIntent)
157158
finish()
158159
}
159160
}
@@ -228,6 +229,7 @@ class EnterCodeActivity : DuckDuckGoActivity() {
228229
private const val EXTRA_CODE_TYPE = "codeType"
229230

230231
const val EXTRA_USER_SWITCHED_ACCOUNT = "userSwitchedAccount"
232+
const val EXTRA_FINISHED_WITH_ERROR = "finishedWithError"
231233

232234
internal fun intent(context: Context, codeType: Code): Intent {
233235
return Intent(context, EnterCodeActivity::class.java).apply {

sync/sync-impl/src/main/java/com/duckduckgo/sync/impl/ui/SyncConnectActivity.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,15 @@ class SyncConnectActivity : DuckDuckGoActivity() {
8282
private val enterCodeLauncher = registerForActivityResult(
8383
EnterCodeContract(),
8484
) { result ->
85-
if (result != EnterCodeContractOutput.Error) {
86-
viewModel.onLoginSuccess()
85+
when (result) {
86+
EnterCodeContractOutput.LoginSuccess,
87+
EnterCodeContractOutput.SwitchAccountSuccess,
88+
-> viewModel.onLoginSuccess()
89+
EnterCodeContractOutput.Error -> {
90+
setResult(RESULT_CANCELED)
91+
finish()
92+
}
93+
EnterCodeContractOutput.Cancelled -> {}
8794
}
8895
}
8996

sync/sync-impl/src/main/java/com/duckduckgo/sync/impl/ui/SyncLoginActivity.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,15 @@ class SyncLoginActivity : DuckDuckGoActivity() {
5959
private val enterCodeLauncher = registerForActivityResult(
6060
EnterCodeContract(),
6161
) { result ->
62-
if (result != EnterCodeContractOutput.Error) {
63-
viewModel.onLoginSuccess()
62+
when (result) {
63+
EnterCodeContractOutput.LoginSuccess,
64+
EnterCodeContractOutput.SwitchAccountSuccess,
65+
-> viewModel.onLoginSuccess()
66+
EnterCodeContractOutput.Error -> {
67+
setResult(RESULT_CANCELED)
68+
finish()
69+
}
70+
EnterCodeContractOutput.Cancelled -> {}
6471
}
6572
}
6673

sync/sync-impl/src/main/java/com/duckduckgo/sync/impl/ui/SyncWithAnotherActivityViewModel.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,8 @@ class SyncWithAnotherActivityViewModel @Inject constructor(
443443
fun onEnterCodeResult(result: EnterCodeContractOutput) {
444444
viewModelScope.launch {
445445
when (result) {
446-
EnterCodeContractOutput.Error -> {}
446+
EnterCodeContractOutput.Error -> command.send(FinishWithError)
447+
EnterCodeContractOutput.Cancelled -> {}
447448
EnterCodeContractOutput.LoginSuccess -> {
448449
// Manual entry: EnterCodeViewModel fires "Setup success"; only fire login pixel here.
449450
syncPixels.fireLoginPixel()

sync/sync-impl/src/main/java/com/duckduckgo/sync/impl/ui/setup/EnterCodeContract.kt

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import android.content.Intent
2222
import androidx.activity.result.contract.ActivityResultContract
2323
import com.duckduckgo.sync.impl.ui.EnterCodeActivity
2424
import com.duckduckgo.sync.impl.ui.EnterCodeActivity.Companion.Code
25+
import com.duckduckgo.sync.impl.ui.EnterCodeActivity.Companion.EXTRA_FINISHED_WITH_ERROR
2526
import com.duckduckgo.sync.impl.ui.EnterCodeActivity.Companion.EXTRA_USER_SWITCHED_ACCOUNT
2627
import com.duckduckgo.sync.impl.ui.setup.EnterCodeContract.EnterCodeContractOutput
2728

@@ -37,23 +38,18 @@ class EnterCodeContract : ActivityResultContract<Code, EnterCodeContractOutput>(
3738
resultCode: Int,
3839
intent: Intent?,
3940
): EnterCodeContractOutput {
40-
when {
41-
resultCode == Activity.RESULT_OK -> {
42-
val userSwitchedAccount = intent?.getBooleanExtra(EXTRA_USER_SWITCHED_ACCOUNT, false) ?: false
43-
return if (userSwitchedAccount) {
44-
EnterCodeContractOutput.SwitchAccountSuccess
45-
} else {
46-
EnterCodeContractOutput.LoginSuccess
47-
}
48-
}
49-
50-
else -> return EnterCodeContractOutput.Error
41+
if (resultCode == Activity.RESULT_OK) {
42+
val userSwitchedAccount = intent?.getBooleanExtra(EXTRA_USER_SWITCHED_ACCOUNT, false) ?: false
43+
return if (userSwitchedAccount) EnterCodeContractOutput.SwitchAccountSuccess else EnterCodeContractOutput.LoginSuccess
5144
}
45+
val finishedWithError = intent?.getBooleanExtra(EXTRA_FINISHED_WITH_ERROR, false) ?: false
46+
return if (finishedWithError) EnterCodeContractOutput.Error else EnterCodeContractOutput.Cancelled
5247
}
5348

5449
sealed class EnterCodeContractOutput {
5550
data object LoginSuccess : EnterCodeContractOutput()
5651
data object SwitchAccountSuccess : EnterCodeContractOutput()
5752
data object Error : EnterCodeContractOutput()
53+
data object Cancelled : EnterCodeContractOutput()
5854
}
5955
}

sync/sync-impl/src/test/java/com/duckduckgo/sync/impl/ui/SyncWithAnotherDeviceViewModelTest.kt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ import com.duckduckgo.sync.impl.ui.SyncWithAnotherActivityViewModel.Command.Logi
7474
import com.duckduckgo.sync.impl.ui.SyncWithAnotherActivityViewModel.Command.ShowError
7575
import com.duckduckgo.sync.impl.ui.SyncWithAnotherActivityViewModel.Command.ShowV2Error
7676
import com.duckduckgo.sync.impl.ui.SyncWithAnotherActivityViewModel.Command.SwitchAccountSuccess
77+
import com.duckduckgo.sync.impl.ui.setup.EnterCodeContract.EnterCodeContractOutput
7778
import kotlinx.coroutines.flow.filter
7879
import kotlinx.coroutines.flow.flowOf
7980
import kotlinx.coroutines.test.runTest
@@ -795,6 +796,38 @@ class SyncWithAnotherDeviceViewModelTest {
795796
}
796797
}
797798

799+
@Test
800+
fun whenEnterCodeReturnsErrorThenFinishWithError() = runTest {
801+
testee.onEnterCodeResult(EnterCodeContractOutput.Error)
802+
803+
testee.commands().test {
804+
val command = awaitItem()
805+
assertTrue("expected FinishWithError, got $command", command is Command.FinishWithError)
806+
cancelAndIgnoreRemainingEvents()
807+
}
808+
}
809+
810+
@Test
811+
fun whenEnterCodeReturnsCancelledThenNoCommand() = runTest {
812+
testee.onEnterCodeResult(EnterCodeContractOutput.Cancelled)
813+
814+
testee.commands().test {
815+
expectNoEvents()
816+
cancelAndIgnoreRemainingEvents()
817+
}
818+
}
819+
820+
@Test
821+
fun whenEnterCodeReturnsLoginSuccessThenLoginSuccessCommand() = runTest {
822+
testee.onEnterCodeResult(EnterCodeContractOutput.LoginSuccess)
823+
824+
testee.commands().test {
825+
val command = awaitItem()
826+
assertTrue("expected LoginSuccess, got $command", command is LoginSuccess)
827+
cancelAndIgnoreRemainingEvents()
828+
}
829+
}
830+
798831
@Test
799832
fun whenV2UpgradeRequiredThenShowUpdateError() = runTest {
800833
syncFeature.canUseV2ConnectFlow().setRawStoredState(State(true))

0 commit comments

Comments
 (0)