cheogram-android
created pr with
cheogram-android/onboarding-cancel.1
cmds
checkout latest patchset:
ssh pr.pico.sh pull cheogram-android:onboarding-cancel | git am -3checkout specific patchset revision:
ssh pr.pico.sh pull cheogram-android:onboarding-cancel [rev] | git am -3add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh cheogram-android:onboarding-canceladd comment to patch request:
ssh pr.pico.sh comment cheogram-android:onboarding-cancel "lgtm!"
Patchset
cheogram-android/onboarding-cancel.1
Refactor and improve onboarding cancel block
Stephen Paul Weber
2026-11-03T17:37:59ZDon't wait for server to reply to remember what the user chose. Once they've chosen something, we don't cancel out to non-cheogram onboarding. Disable back button during onboarding from the MagicCreateActivity so that they can't back out after they've already basically finished.
Semantic diff summary
0 added,
0 modified,
0 signature changed,
0 removed
across 0 analyzed files
(7 files skipped: unsupported file type)
+17
-0
src/cheogram/java/eu/siacs/conversations/ui/MagicCreateActivity.java
#
| ... | ... | @@ -38,7 +38,24 @@ public class MagicCreateActivity extends XmppActivity implements TextWatcher { | |
| 38 | 38 | ||
| 39 | 39 | @Override | |
| 40 | 40 | protected void onBackendConnected() { | |
| 41 | + | updateBackNavigation(); | |
| 42 | + | } | |
| 43 | + | ||
| 44 | + | private void updateBackNavigation() { | |
| 45 | + | if (xmppConnectionService == null) { | |
| 46 | + | return; | |
| 47 | + | } | |
| 48 | + | configureActionBar( | |
| 49 | + | getSupportActionBar(), | |
| 50 | + | this.domain == null && !xmppConnectionService.isOnboarding()); | |
| 51 | + | } | |
| 41 | 52 | ||
| 53 | + | @Override | |
| 54 | + | public void onBackPressed() { | |
| 55 | + | if (xmppConnectionService != null && xmppConnectionService.isOnboarding()) { | |
| 56 | + | return; | |
| 57 | + | } | |
| 58 | + | super.onBackPressed(); | |
| 42 | 59 | } | |
| 43 | 60 | ||
| 44 | 61 | @Override |
+41
-23
src/main/java/eu/siacs/conversations/entities/Conversation.java
#
| ... | ... | @@ -181,6 +181,7 @@ import eu.siacs.conversations.ui.util.SoftKeyboardUtils; | |
| 181 | 181 | import eu.siacs.conversations.utils.Emoticons; | |
| 182 | 182 | import eu.siacs.conversations.utils.JidHelper; | |
| 183 | 183 | import eu.siacs.conversations.utils.MessageUtils; | |
| 184 | + | import eu.siacs.conversations.utils.OnboardingUtils; | |
| 184 | 185 | import eu.siacs.conversations.utils.PhoneNumberUtilWrapper; | |
| 185 | 186 | import eu.siacs.conversations.utils.UIHelper; | |
| 186 | 187 | import eu.siacs.conversations.xml.Element; |
| ... | ... | @@ -2150,6 +2151,12 @@ public class Conversation extends AbstractEntity | |
| 2150 | 2151 | show(); | |
| 2151 | 2152 | CommandSession session = new CommandSession(command.getAttribute("name"), command.getAttribute("node"), xmppConnectionService); | |
| 2152 | 2153 | ||
| 2154 | + | if (xmppConnectionService.isOnboarding() | |
| 2155 | + | && "jabber:iq:register".equals(command.getAttribute("node")) | |
| 2156 | + | && OnboardingUtils.getSelectedGateway(xmppConnectionService.getPreferences()) != null) { | |
| 2157 | + | OnboardingUtils.markResume(xmppConnectionService.getPreferences()); | |
| 2158 | + | } | |
| 2159 | + | ||
| 2153 | 2160 | final var packet = new Iq(Iq.Type.SET); | |
| 2154 | 2161 | packet.setTo(command.getAttributeAsJid("jid")); | |
| 2155 | 2162 | final Element c = packet.addChild("command", Namespace.COMMANDS); |
| ... | ... | @@ -3430,6 +3437,7 @@ public class Conversation extends AbstractEntity | |
| 3430 | 3437 | protected Iq response = null; | |
| 3431 | 3438 | protected Element responseElement = null; | |
| 3432 | 3439 | protected boolean expectingRemoval = false; | |
| 3440 | + | private boolean resumed = false; | |
| 3433 | 3441 | protected List<Field> reported = null; | |
| 3434 | 3442 | protected SparseArray<Item> items = new SparseArray<>(); | |
| 3435 | 3443 | protected XmppConnectionService xmppConnectionService; |
| ... | ... | @@ -3487,15 +3495,13 @@ public class Conversation extends AbstractEntity | |
| 3487 | 3495 | xmppConnectionService.createContact(getAccount().getRoster().getContact(iq.getFrom())); | |
| 3488 | 3496 | } | |
| 3489 | 3497 | ||
| 3490 | - | if (xmppConnectionService.isOnboarding() && mNode.equals("jabber:iq:register") && !"canceled".equals(command.getAttribute("status")) && xmppConnectionService.getPreferences().contains("onboarding_action")) { | |
| 3491 | - | xmppConnectionService.getPreferences().edit().putBoolean("onboarding_continued", true).commit(); | |
| 3492 | - | } | |
| 3493 | - | ||
| 3498 | + | final boolean suppressCancel = isCancelSuppressed(); | |
| 3494 | 3499 | Element actions = command.findChild("actions", "http://jabber.org/protocol/commands"); | |
| 3495 | 3500 | if (actions != null) { | |
| 3496 | 3501 | for (Element action : actions.getChildren()) { | |
| 3497 | 3502 | if (!"http://jabber.org/protocol/commands".equals(action.getNamespace())) continue; | |
| 3498 | 3503 | if ("execute".equals(action.getName())) continue; | |
| 3504 | + | if (suppressCancel && "cancel".equals(action.getName())) continue; | |
| 3499 | 3505 | ||
| 3500 | 3506 | actionsAdapter.add(Pair.create(action.getName(), action.getName())); | |
| 3501 | 3507 | } |
| ... | ... | @@ -3521,6 +3527,7 @@ public class Conversation extends AbstractEntity | |
| 3521 | 3527 | actionsAdapter.clear(); | |
| 3522 | 3528 | ||
| 3523 | 3529 | for (Option action : actionList.getOptions()) { | |
| 3530 | + | if (suppressCancel && "cancel".equals(action.getValue())) continue; | |
| 3524 | 3531 | actionsAdapter.add(Pair.create(action.getValue(), action.toString())); | |
| 3525 | 3532 | } | |
| 3526 | 3533 | } |
| ... | ... | @@ -3571,17 +3578,17 @@ public class Conversation extends AbstractEntity | |
| 3571 | 3578 | if (responseElement == null && command.getAttribute("status") != null && (command.getAttribute("status").equals("completed") || command.getAttribute("status").equals("canceled"))) { | |
| 3572 | 3579 | if ("jabber:iq:register".equals(mNode) && "canceled".equals(command.getAttribute("status"))) { | |
| 3573 | 3580 | if (xmppConnectionService.isOnboarding()) { | |
| 3574 | - | if (xmppConnectionService.getPreferences().contains("onboarding_action")) { | |
| 3575 | - | xmppConnectionService.deleteAccount(getAccount()); | |
| 3576 | - | } else { | |
| 3577 | - | if (xmppConnectionService.getPreferences().getBoolean("onboarding_continued", false)) { | |
| 3578 | - | removeSession(this); | |
| 3579 | - | return; | |
| 3580 | - | } else { | |
| 3581 | - | xmppConnectionService.getPreferences().edit().putString("onboarding_action", "cancel").commit(); | |
| 3582 | - | xmppConnectionService.deleteAccount(getAccount()); | |
| 3583 | - | } | |
| 3581 | + | final boolean continued = OnboardingUtils.isContinued(xmppConnectionService.getPreferences()); | |
| 3582 | + | if (continued) { | |
| 3583 | + | // They already committed to this onboarding flow. Do not destroy | |
| 3584 | + | // their account just because a command session went away. | |
| 3585 | + | removeSession(this); | |
| 3586 | + | return; | |
| 3587 | + | } | |
| 3588 | + | if (!OnboardingUtils.isCanceled(xmppConnectionService.getPreferences())) { | |
| 3589 | + | OnboardingUtils.markCanceled(xmppConnectionService.getPreferences()); | |
| 3584 | 3590 | } | |
| 3591 | + | xmppConnectionService.deleteAccount(getAccount()); | |
| 3585 | 3592 | } | |
| 3586 | 3593 | xmppConnectionService.archiveConversation(Conversation.this); | |
| 3587 | 3594 | } |
| ... | ... | @@ -3620,15 +3627,19 @@ public class Conversation extends AbstractEntity | |
| 3620 | 3627 | ||
| 3621 | 3628 | Data dataForm = null; | |
| 3622 | 3629 | if (responseElement != null && responseElement.getName().equals("x") && responseElement.getNamespace().equals("jabber:x:data")) dataForm = Data.parse(responseElement); | |
| 3623 | - | if (mNode.equals("jabber:iq:register") && | |
| 3624 | - | xmppConnectionService.getPreferences().contains("onboarding_action") && | |
| 3630 | + | if (xmppConnectionService.isOnboarding() && | |
| 3631 | + | mNode.equals("jabber:iq:register") && | |
| 3625 | 3632 | dataForm != null && dataForm.getFieldByName("gateway-jid") != null) { | |
| 3626 | 3633 | ||
| 3627 | - | ||
| 3628 | - | dataForm.put("gateway-jid", xmppConnectionService.getPreferences().getString("onboarding_action", "")); | |
| 3629 | - | execute(); | |
| 3634 | + | final String gateway = OnboardingUtils.getSelectedGateway(xmppConnectionService.getPreferences()); | |
| 3635 | + | if (gateway != null) { | |
| 3636 | + | dataForm.put("gateway-jid", gateway); | |
| 3637 | + | if (!resumed && OnboardingUtils.isResumePending(xmppConnectionService.getPreferences())) { | |
| 3638 | + | resumed = true; | |
| 3639 | + | execute(); | |
| 3640 | + | } | |
| 3641 | + | } | |
| 3630 | 3642 | } | |
| 3631 | - | xmppConnectionService.getPreferences().edit().remove("onboarding_action").commit(); | |
| 3632 | 3643 | notifyDataSetChanged(); | |
| 3633 | 3644 | } | |
| 3634 | 3645 |
| ... | ... | @@ -3846,6 +3857,12 @@ public class Conversation extends AbstractEntity | |
| 3846 | 3857 | return execute(actionsAdapter.getItem(actionPosition).first); | |
| 3847 | 3858 | } | |
| 3848 | 3859 | ||
| 3860 | + | private boolean isCancelSuppressed() { | |
| 3861 | + | return mNode.equals("jabber:iq:register") | |
| 3862 | + | && xmppConnectionService.isOnboarding() | |
| 3863 | + | && OnboardingUtils.isContinued(xmppConnectionService.getPreferences()); | |
| 3864 | + | } | |
| 3865 | + | ||
| 3849 | 3866 | public synchronized boolean execute(String action) { | |
| 3850 | 3867 | if (!"cancel".equals(action) && executing) { | |
| 3851 | 3868 | loadingHasBeenLong = true; |
| ... | ... | @@ -3887,10 +3904,11 @@ public class Conversation extends AbstractEntity | |
| 3887 | 3904 | } | |
| 3888 | 3905 | ||
| 3889 | 3906 | if (mNode.equals("jabber:iq:register") && xmppConnectionService.isOnboarding() && form.getFieldByName("gateway-jid") != null) { | |
| 3890 | - | if (form.getValue("gateway-jid") == null) { | |
| 3891 | - | xmppConnectionService.getPreferences().edit().remove("onboarding_action").commit(); | |
| 3907 | + | final String gateway = form.getValue("gateway-jid"); | |
| 3908 | + | if (gateway == null || gateway.isEmpty()) { | |
| 3909 | + | OnboardingUtils.clearSelectedGateway(xmppConnectionService.getPreferences()); | |
| 3892 | 3910 | } else { | |
| 3893 | - | xmppConnectionService.getPreferences().edit().putString("onboarding_action", form.getValue("gateway-jid")).commit(); | |
| 3911 | + | OnboardingUtils.setSelectedGateway(xmppConnectionService.getPreferences(), gateway); | |
| 3894 | 3912 | } | |
| 3895 | 3913 | } | |
| 3896 | 3914 |
+2
-1
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
#
| ... | ... | @@ -164,6 +164,7 @@ import eu.siacs.conversations.utils.FileUtils; | |
| 164 | 164 | import eu.siacs.conversations.utils.MessageUtils; | |
| 165 | 165 | import eu.siacs.conversations.utils.Emoticons; | |
| 166 | 166 | import eu.siacs.conversations.utils.MimeUtils; | |
| 167 | + | import eu.siacs.conversations.utils.OnboardingUtils; | |
| 167 | 168 | import eu.siacs.conversations.utils.PhoneHelper; | |
| 168 | 169 | import eu.siacs.conversations.utils.QuickLoader; | |
| 169 | 170 | import eu.siacs.conversations.utils.ReplacingSerialSingleThreadExecutor; |
| ... | ... | @@ -3122,7 +3123,7 @@ public class XmppConnectionService extends Service { | |
| 3122 | 3123 | } | |
| 3123 | 3124 | ||
| 3124 | 3125 | public void deleteAccount(final Account account) { | |
| 3125 | - | getPreferences().edit().remove("onboarding_continued").commit(); | |
| 3126 | + | OnboardingUtils.clearProgress(getPreferences()); | |
| 3126 | 3127 | final boolean connected = account.getStatus() == Account.State.ONLINE; | |
| 3127 | 3128 | synchronized (this.conversations) { | |
| 3128 | 3129 | if (connected) { |
+3
-2
src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java
#
| ... | ... | @@ -88,6 +88,7 @@ import eu.siacs.conversations.ui.util.PendingItem; | |
| 88 | 88 | import eu.siacs.conversations.ui.util.SoftKeyboardUtils; | |
| 89 | 89 | import eu.siacs.conversations.ui.widget.SwipeRefreshListFragment; | |
| 90 | 90 | import eu.siacs.conversations.utils.AccountUtils; | |
| 91 | + | import eu.siacs.conversations.utils.OnboardingUtils; | |
| 91 | 92 | import eu.siacs.conversations.utils.UIHelper; | |
| 92 | 93 | import eu.siacs.conversations.utils.XmppUri; | |
| 93 | 94 | import eu.siacs.conversations.utils.XEP0392Helper; |
| ... | ... | @@ -1147,8 +1148,8 @@ public class StartConversationActivity extends XmppActivity | |
| 1147 | 1148 | break; | |
| 1148 | 1149 | } | |
| 1149 | 1150 | ||
| 1150 | - | final boolean onboardingCancel = xmppConnectionService.getPreferences().getString("onboarding_action", "").equals("cancel"); | |
| 1151 | - | if (onboardingCancel) xmppConnectionService.getPreferences().edit().remove("onboarding_action").commit(); | |
| 1151 | + | final boolean onboardingCancel = OnboardingUtils.isCanceled(xmppConnectionService.getPreferences()); | |
| 1152 | + | if (onboardingCancel) OnboardingUtils.clearCanceled(xmppConnectionService.getPreferences()); | |
| 1152 | 1153 | ||
| 1153 | 1154 | if ((xmppConnectionService.isOnboarding() || (intent != null && intent.getBooleanExtra("init", false))) && !onboardingCancel && !xmppConnectionService.getAccounts().isEmpty()) { | |
| 1154 | 1155 | Account selectedAccount = xmppConnectionService.getAccounts().get(0); |
+94
-0
src/main/java/eu/siacs/conversations/utils/OnboardingUtils.java
#
| ... | ... | @@ -0,0 +1,94 @@ | |
| 1 | + | package eu.siacs.conversations.utils; | |
| 2 | + | ||
| 3 | + | import android.content.SharedPreferences; | |
| 4 | + | ||
| 5 | + | public final class OnboardingUtils { | |
| 6 | + | ||
| 7 | + | private static final String PREF_CANCELED = "onboarding_action"; | |
| 8 | + | private static final String PREF_CONTINUED = "onboarding_continued"; | |
| 9 | + | private static final String PREF_RESUME = "onboarding_resume"; | |
| 10 | + | private static final String CANCELED = "cancel"; | |
| 11 | + | ||
| 12 | + | public static boolean isCanceled(final SharedPreferences preferences) { | |
| 13 | + | return CANCELED.equals(preferences.getString(PREF_CANCELED, null)); | |
| 14 | + | } | |
| 15 | + | ||
| 16 | + | public static void markCanceled(final SharedPreferences preferences) { | |
| 17 | + | preferences.edit().putString(PREF_CANCELED, CANCELED).commit(); | |
| 18 | + | } | |
| 19 | + | ||
| 20 | + | public static void clearCanceled(final SharedPreferences preferences) { | |
| 21 | + | preferences.edit().remove(PREF_CANCELED).commit(); | |
| 22 | + | } | |
| 23 | + | ||
| 24 | + | public static String getSelectedGateway(final SharedPreferences preferences) { | |
| 25 | + | // onboarding_continued used to be a boolean. Read it as an Object so | |
| 26 | + | // installations that still have the old value do not crash. | |
| 27 | + | final Object value = preferences.getAll().get(PREF_CONTINUED); | |
| 28 | + | if (value instanceof String) { | |
| 29 | + | final String gateway = (String) value; | |
| 30 | + | return gateway.isEmpty() ? null : gateway; | |
| 31 | + | } | |
| 32 | + | // Older versions temporarily stored the selected gateway here while a | |
| 33 | + | // request was in flight. Keep treating that as a committed selection. | |
| 34 | + | final Object legacy = preferences.getAll().get(PREF_CANCELED); | |
| 35 | + | if (legacy instanceof String && !CANCELED.equals(legacy)) { | |
| 36 | + | final String gateway = (String) legacy; | |
| 37 | + | return gateway.isEmpty() ? null : gateway; | |
| 38 | + | } | |
| 39 | + | return null; | |
| 40 | + | } | |
| 41 | + | ||
| 42 | + | public static boolean isContinued(final SharedPreferences preferences) { | |
| 43 | + | final Object value = preferences.getAll().get(PREF_CONTINUED); | |
| 44 | + | if (value instanceof Boolean && (Boolean) value) { | |
| 45 | + | return true; | |
| 46 | + | } | |
| 47 | + | return getSelectedGateway(preferences) != null; | |
| 48 | + | } | |
| 49 | + | ||
| 50 | + | public static void setSelectedGateway( | |
| 51 | + | final SharedPreferences preferences, final String gateway) { | |
| 52 | + | if (gateway == null || gateway.isEmpty()) { | |
| 53 | + | return; | |
| 54 | + | } | |
| 55 | + | preferences | |
| 56 | + | .edit() | |
| 57 | + | .putString(PREF_CONTINUED, gateway) | |
| 58 | + | .remove(PREF_CANCELED) | |
| 59 | + | .remove(PREF_RESUME) | |
| 60 | + | .commit(); | |
| 61 | + | } | |
| 62 | + | ||
| 63 | + | public static void clearSelectedGateway(final SharedPreferences preferences) { | |
| 64 | + | final SharedPreferences.Editor editor = | |
| 65 | + | preferences.edit().remove(PREF_CONTINUED).remove(PREF_RESUME); | |
| 66 | + | // Older versions temporarily stored the selected gateway in the cancel | |
| 67 | + | // preference. Drop that too, but leave the real cancel marker alone. | |
| 68 | + | final Object legacy = preferences.getAll().get(PREF_CANCELED); | |
| 69 | + | if (legacy instanceof String && !CANCELED.equals(legacy)) { | |
| 70 | + | editor.remove(PREF_CANCELED); | |
| 71 | + | } | |
| 72 | + | editor.commit(); | |
| 73 | + | } | |
| 74 | + | ||
| 75 | + | public static void markResume(final SharedPreferences preferences) { | |
| 76 | + | preferences.edit().putBoolean(PREF_RESUME, true).commit(); | |
| 77 | + | } | |
| 78 | + | ||
| 79 | + | public static boolean isResumePending(final SharedPreferences preferences) { | |
| 80 | + | return preferences.getBoolean(PREF_RESUME, false); | |
| 81 | + | } | |
| 82 | + | ||
| 83 | + | public static void clearProgress(final SharedPreferences preferences) { | |
| 84 | + | final SharedPreferences.Editor editor = | |
| 85 | + | preferences.edit().remove(PREF_CONTINUED).remove(PREF_RESUME); | |
| 86 | + | // Preserve the one-shot cancel marker so the next start-up does not | |
| 87 | + | // immediately offer cheogram onboarding again. Drop stale legacy values | |
| 88 | + | // that used to store the selected gateway here. | |
| 89 | + | if (!isCanceled(preferences)) { | |
| 90 | + | editor.remove(PREF_CANCELED); | |
| 91 | + | } | |
| 92 | + | editor.commit(); | |
| 93 | + | } | |
| 94 | + | } |
+1
-1
src/test/java/eu/siacs/conversations/entities/MessageTest.java
#
| ... | ... | @@ -24,7 +24,7 @@ public class MessageTest { | |
| 24 | 24 | public void extractLinksIgnoresInvalidUris() { | |
| 25 | 25 | final var conversation = mock(Conversational.class); | |
| 26 | 26 | when(conversation.getUuid()).thenReturn("test-uuid"); | |
| 27 | - | when(conversation.getJid()).thenReturn(Jid.ofLocalAndDomain("test", "example.com")); | |
| 27 | + | when(conversation.getAddress()).thenReturn(Jid.ofLocalAndDomain("test", "example.com")); | |
| 28 | 28 | ||
| 29 | 29 | final var message = new Message(conversation, "https://example.com?q=%s", Message.ENCRYPTION_NONE); | |
| 30 | 30 | Assert.assertEquals(0, message.getLinks().size()); |
+127
-0
src/test/java/eu/siacs/conversations/utils/OnboardingUtilsTest.java
#
| ... | ... | @@ -0,0 +1,127 @@ | |
| 1 | + | package eu.siacs.conversations.utils; | |
| 2 | + | ||
| 3 | + | import static org.junit.Assert.assertEquals; | |
| 4 | + | import static org.junit.Assert.assertFalse; | |
| 5 | + | import static org.junit.Assert.assertNull; | |
| 6 | + | import static org.junit.Assert.assertTrue; | |
| 7 | + | ||
| 8 | + | import android.content.Context; | |
| 9 | + | import android.content.SharedPreferences; | |
| 10 | + | import android.os.Build; | |
| 11 | + | ||
| 12 | + | import org.junit.Before; | |
| 13 | + | import org.junit.Test; | |
| 14 | + | import org.junit.runner.RunWith; | |
| 15 | + | import org.robolectric.RobolectricTestRunner; | |
| 16 | + | import org.robolectric.RuntimeEnvironment; | |
| 17 | + | import org.robolectric.annotation.Config; | |
| 18 | + | import org.robolectric.annotation.ConscryptMode; | |
| 19 | + | ||
| 20 | + | import eu.siacs.conversations.Conversations; | |
| 21 | + | ||
| 22 | + | @RunWith(RobolectricTestRunner.class) | |
| 23 | + | @Config(sdk = Build.VERSION_CODES.TIRAMISU, application = Conversations.class) | |
| 24 | + | @ConscryptMode(ConscryptMode.Mode.OFF) | |
| 25 | + | public class OnboardingUtilsTest { | |
| 26 | + | ||
| 27 | + | private static final String PREF_CANCELED = "onboarding_action"; | |
| 28 | + | private static final String PREF_CONTINUED = "onboarding_continued"; | |
| 29 | + | private static final String PREF_RESUME = "onboarding_resume"; | |
| 30 | + | ||
| 31 | + | private SharedPreferences preferences; | |
| 32 | + | ||
| 33 | + | @Before | |
| 34 | + | public void setUp() { | |
| 35 | + | preferences = | |
| 36 | + | RuntimeEnvironment.getApplication() | |
| 37 | + | .getSharedPreferences("onboarding-test", Context.MODE_PRIVATE); | |
| 38 | + | preferences.edit().clear().commit(); | |
| 39 | + | } | |
| 40 | + | ||
| 41 | + | @Test | |
| 42 | + | public void selectedGatewayMarksContinuedAndClearsCancel() { | |
| 43 | + | OnboardingUtils.markCanceled(preferences); | |
| 44 | + | OnboardingUtils.markResume(preferences); | |
| 45 | + | assertTrue(OnboardingUtils.isCanceled(preferences)); | |
| 46 | + | ||
| 47 | + | OnboardingUtils.setSelectedGateway(preferences, "snikket.example"); | |
| 48 | + | ||
| 49 | + | assertFalse(OnboardingUtils.isCanceled(preferences)); | |
| 50 | + | assertFalse(OnboardingUtils.isResumePending(preferences)); | |
| 51 | + | assertTrue(OnboardingUtils.isContinued(preferences)); | |
| 52 | + | assertEquals("snikket.example", OnboardingUtils.getSelectedGateway(preferences)); | |
| 53 | + | } | |
| 54 | + | ||
| 55 | + | @Test | |
| 56 | + | public void legacyBooleanIsTreatedAsContinuedWithoutGateway() { | |
| 57 | + | preferences.edit().putBoolean(PREF_CONTINUED, true).commit(); | |
| 58 | + | ||
| 59 | + | assertTrue(OnboardingUtils.isContinued(preferences)); | |
| 60 | + | assertNull(OnboardingUtils.getSelectedGateway(preferences)); | |
| 61 | + | } | |
| 62 | + | ||
| 63 | + | @Test | |
| 64 | + | public void legacyGatewayInCancelPreferenceIsTreatedAsContinued() { | |
| 65 | + | preferences.edit().putString(PREF_CANCELED, "snikket.example").commit(); | |
| 66 | + | ||
| 67 | + | assertTrue(OnboardingUtils.isContinued(preferences)); | |
| 68 | + | assertEquals("snikket.example", OnboardingUtils.getSelectedGateway(preferences)); | |
| 69 | + | } | |
| 70 | + | ||
| 71 | + | @Test | |
| 72 | + | public void clearingSelectionRemovesGatewayResumeAndLegacyValue() { | |
| 73 | + | OnboardingUtils.setSelectedGateway(preferences, "snikket.example"); | |
| 74 | + | OnboardingUtils.markResume(preferences); | |
| 75 | + | preferences.edit().putString(PREF_CANCELED, "legacy.example").commit(); | |
| 76 | + | ||
| 77 | + | OnboardingUtils.clearSelectedGateway(preferences); | |
| 78 | + | ||
| 79 | + | assertFalse(OnboardingUtils.isContinued(preferences)); | |
| 80 | + | assertNull(OnboardingUtils.getSelectedGateway(preferences)); | |
| 81 | + | assertFalse(OnboardingUtils.isResumePending(preferences)); | |
| 82 | + | assertNull(preferences.getString(PREF_CANCELED, null)); | |
| 83 | + | } | |
| 84 | + | ||
| 85 | + | @Test | |
| 86 | + | public void clearingSelectionKeepsCancelMarker() { | |
| 87 | + | OnboardingUtils.markCanceled(preferences); | |
| 88 | + | ||
| 89 | + | OnboardingUtils.clearSelectedGateway(preferences); | |
| 90 | + | ||
| 91 | + | assertTrue(OnboardingUtils.isCanceled(preferences)); | |
| 92 | + | } | |
| 93 | + | ||
| 94 | + | @Test | |
| 95 | + | public void resumeStaysPendingUntilProgressIsCleared() { | |
| 96 | + | OnboardingUtils.markResume(preferences); | |
| 97 | + | ||
| 98 | + | assertTrue(OnboardingUtils.isResumePending(preferences)); | |
| 99 | + | assertTrue(OnboardingUtils.isResumePending(preferences)); | |
| 100 | + | ||
| 101 | + | OnboardingUtils.clearProgress(preferences); | |
| 102 | + | ||
| 103 | + | assertFalse(OnboardingUtils.isResumePending(preferences)); | |
| 104 | + | } | |
| 105 | + | ||
| 106 | + | @Test | |
| 107 | + | public void clearProgressPreservesCancelButClearsGateway() { | |
| 108 | + | OnboardingUtils.setSelectedGateway(preferences, "snikket.example"); | |
| 109 | + | OnboardingUtils.markResume(preferences); | |
| 110 | + | OnboardingUtils.markCanceled(preferences); | |
| 111 | + | ||
| 112 | + | OnboardingUtils.clearProgress(preferences); | |
| 113 | + | ||
| 114 | + | assertNull(OnboardingUtils.getSelectedGateway(preferences)); | |
| 115 | + | assertFalse(OnboardingUtils.isResumePending(preferences)); | |
| 116 | + | assertTrue(OnboardingUtils.isCanceled(preferences)); | |
| 117 | + | } | |
| 118 | + | ||
| 119 | + | @Test | |
| 120 | + | public void clearProgressRemovesStaleLegacyGatewayFromCancelPreference() { | |
| 121 | + | preferences.edit().putString(PREF_CANCELED, "snikket.example").commit(); | |
| 122 | + | ||
| 123 | + | OnboardingUtils.clearProgress(preferences); | |
| 124 | + | ||
| 125 | + | assertNull(preferences.getString(PREF_CANCELED, null)); | |
| 126 | + | } | |
| 127 | + | } |