package com.peachpasswords.ui.onboarding import com.peachpasswords.ui.PeachNav import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Test class OnboardingTest { // ── Launch guard ────────────────────────────────────────────────────────── @Test fun onboarding_shows_first_launch() { assertEquals(PeachNav.Onboarding, onboardingStartDestination(hasVault = false, onboarded = false)) } @Test fun onboarding_skipped_after_completion() { // Onboarded → Lock even with no vault yet (quit mid-create returns to Lock). assertEquals(PeachNav.Lock, onboardingStartDestination(hasVault = false, onboarded = true)) // Existing vault → always Lock, regardless of flag. assertEquals(PeachNav.Lock, onboardingStartDestination(hasVault = true, onboarded = false)) assertEquals(PeachNav.Lock, onboardingStartDestination(hasVault = true, onboarded = true)) } // ── Card copy (the spec is ONBOARDING_CARDS, ported from the browser) ────── @Test fun onboarding_has_three_cards() { assertEquals(3, ONBOARDING_CARDS.size) } @Test fun onboarding_card_copy_card1_matches_spec() { val c = ONBOARDING_CARDS[0] assertTrue(c.headline.contains("live here")) assertEquals(2, c.body.size) assertTrue(c.body[0].contains("No account. No server.")) assertTrue(c.body[1].contains("encrypted on your device")) } @Test fun onboarding_card_copy_card2_matches_spec() { val c = ONBOARDING_CARDS[1] assertEquals("two keys.", c.headline) assertEquals(2, c.body.size) assertTrue(c.body[0].contains("master password is yours alone")) assertTrue(c.body[1].contains("12 recovery words")) } @Test fun onboarding_card_copy_card3_matches_spec() { val c = ONBOARDING_CARDS[2] assertTrue(c.headline.contains("everything")) assertEquals(2, c.body.size) assertTrue(c.body[0].contains("Free includes")) assertTrue(c.body[1].contains("Pro adds")) } // Card 2 ("two keys.") carries the warning, not card 3 — verified against // the browser's BASE_CARDS (Onboarding.tsx); a prior pass had this on the // wrong card (ONBOARDING_ADDENDUM.md §1). @Test fun onboarding_card2_has_warning_row() { assertNotNull("card 2 carries the warning", ONBOARDING_CARDS[1].warning) assertTrue(ONBOARDING_CARDS[1].warning!!.contains("cannot be opened")) assertNull(ONBOARDING_CARDS[0].warning) assertNull(ONBOARDING_CARDS[2].warning) } // ── Nav row ─────────────────────────────────────────────────────────────── @Test fun back_is_hidden_on_first_card() { assertFalse(onboardingBackVisible(0)) } @Test fun back_is_visible_on_later_cards() { assertTrue(onboardingBackVisible(1)) assertTrue(onboardingBackVisible(2)) } @Test fun forward_label_is_next_until_last_card() { val count = ONBOARDING_CARDS.size assertEquals("next →", onboardingNextLabel(0, count)) assertEquals("next →", onboardingNextLabel(1, count)) } @Test fun forward_label_is_create_vault_on_last_card() { val count = ONBOARDING_CARDS.size assertEquals("create vault", onboardingNextLabel(count - 1, count)) } @Test fun existing_user_choices_put_pairing_first_and_name_restore_separately() { assertEquals("Create a new vault", ONBOARD_CREATE_LABEL) assertEquals("Pair with another device", ONBOARD_PAIR_LABEL) assertEquals("Restore a backup", ONBOARD_RESTORE_LABEL) } }