EntryEditScreenTest.kt

8.3 KB · raw

1package com.peachpasswords.ui.vault23import com.peachpasswords.vault.VaultEntry4import org.junit.Assert.assertEquals5import org.junit.Assert.assertFalse6import org.junit.Assert.assertTrue7import org.junit.Test89class EntryEditScreenTest {1011    // ── Top-bar label (cancel | <title> | save) ───────────────────────────────1213    @Test fun title_bar_label_is_type_specific_for_new_entries() {14        assertEquals("new entry", editTitleBarLabel(isNew = true, type = "login"))15        assertEquals("new note", editTitleBarLabel(isNew = true, type = "note"))16        assertEquals("new card", editTitleBarLabel(isNew = true, type = "card"))17    }1819    @Test fun title_bar_label_is_edit_for_existing_entries() {20        assertEquals("edit", editTitleBarLabel(isNew = false, type = "login"))21        assertEquals("edit", editTitleBarLabel(isNew = false, type = "note"))22    }2324    @Test fun primary_action_label_matches_browser_add_view() {25        assertEquals("create", entryEditPrimaryActionLabel(isNew = true, saving = false))26        assertEquals("save", entryEditPrimaryActionLabel(isNew = false, saving = false))27        assertEquals("saving...", entryEditPrimaryActionLabel(isNew = true, saving = true))28    }2930    @Test fun save_is_disabled_until_browser_minimum_fields_are_present() {31        assertFalse(canSaveEditForm(EditForm(type = "login", title = "")))32        assertTrue(canSaveEditForm(EditForm(type = "login", title = "GitHub")))33        assertFalse(canSaveEditForm(EditForm(type = "card", title = "Visa", cardholderName = "", cardNumber = "4242")))34        assertFalse(canSaveEditForm(EditForm(type = "card", title = "Visa", cardholderName = "June", cardNumber = "")))35        assertTrue(canSaveEditForm(EditForm(type = "card", title = "Visa", cardholderName = "June", cardNumber = "4242")))36    }3738    // ── New Entry creates logins/cards; Notes mode creates notes ─────────────3940    @Test fun entry_type_picker_excludes_notes_for_new_and_existing_entries() {41        assertEquals(listOf("login", "card"), entryEditTypeSegments().map { it.key })42    }4344    // ── Ghost watermark fades in as the title is typed ────────────────────────4546    @Test fun new_entry_ghost_watermark_appears_on_title_type() {47        assertEquals(0f, editGhostWatermarkTarget(""), 0f)48        assertEquals(0f, editGhostWatermarkTarget("   "), 0f)49        assertEquals(0.03f, editGhostWatermarkTarget("GitHub"), 0f)50    }5152    // ── Browser AddView optional login fields ────────────────────────────────5354    @Test fun new_login_hides_optional_totp_and_notes_until_requested() {55        assertFalse(shouldShowLoginTotp("login", revealed = false, totp = ""))56        assertFalse(shouldShowLoginNotes("login", revealed = false, notes = ""))57        assertTrue(shouldShowAddTotpLink("login", revealed = false, totp = ""))58        assertTrue(shouldShowAddNotesLink("login", revealed = false, notes = ""))59        assertFalse(shouldShowLoginNotesLink(isNew = true, type = "login", revealed = false, notes = ""))60        assertTrue(shouldShowLoginNotesLink(isNew = false, type = "login", revealed = false, notes = ""))61    }6263    @Test fun optional_login_fields_show_when_revealed_or_populated() {64        assertTrue(shouldShowLoginTotp("login", revealed = true, totp = ""))65        assertTrue(shouldShowLoginTotp("login", revealed = false, totp = "JBSWY3DPEHPK3PXP"))66        assertTrue(shouldShowLoginNotes("login", revealed = true, notes = ""))67        assertTrue(shouldShowLoginNotes("login", revealed = false, notes = "remember this"))68        assertFalse(shouldShowAddTotpLink("login", revealed = true, totp = ""))69        assertFalse(shouldShowAddNotesLink("login", revealed = false, notes = "remember this"))70    }7172    @Test fun identity_suggestions_split_username_and_email_like_browser() {73        val entries = listOf(74            identityEntry("a", username = "june", email = "[email protected]"),75            identityEntry("b", username = "june", email = null),76            identityEntry("c", username = "[email protected]", email = "[email protected]"),77            identityEntry("d", username = "[email protected]", email = null),78        )7980        assertEquals(listOf("june"), identitySuggestionsFor(entries, IdentityField.Username))81        assertEquals(82            listOf("[email protected]", "[email protected]", "[email protected]"),83            identitySuggestionsFor(entries, IdentityField.Email),84        )85    }8687    @Test fun generator_defaults_and_toggle_label_match_browser_add_view() {88        assertEquals(64, BROWSER_ADD_GENERATOR_LENGTH)89        assertEquals(GeneratorMode.Password, EditForm().genMode)90        assertEquals(5, EditForm().genWordCount)91        assertEquals("generate", generatorToggleLabel(open = false))92        assertEquals("hide generator", generatorToggleLabel(open = true))93    }9495    @Test fun edit_generator_uses_passphrase_word_count_and_separator() {96        val generated = generateEditCredential(97            EditForm(genMode = GeneratorMode.Passphrase, genWordCount = 12, genSeparator = "."),98        )99        assertEquals(12, generated.split(".").size)100    }101102    @Test fun tag_suggestions_match_browser_add_view_limit_and_filtering() {103        val all = listOf("banking", "billing", "books", "business", "backup", "travel")104        assertEquals(105            listOf("banking", "billing", "books", "business", "backup"),106            tagSuggestionsFor(input = "b", allTags = all, tags = emptyList()),107        )108        assertEquals(109            listOf("billing", "books", "business", "backup"),110            tagSuggestionsFor(input = "b", allTags = all, tags = listOf("banking")),111        )112    }113114    @Test fun tag_normalization_allows_spaces_and_caps_length_like_browser() {115        assertEquals("shared login", normalizeTag(" Shared Login "))116        assertEquals("a".repeat(MAX_TAG_LEN), normalizeTag("A".repeat(MAX_TAG_LEN + 8)))117    }118119    // ── Card field formatting (CardFieldUtils, used live by setCardNumber etc.) ─120121    @Test fun new_card_number_auto_formats() {122        assertEquals("4242 4242 4242 4242", CardFieldUtils.formatPan("4242424242424242"))123        // Amex groups 4-6-5.124        assertEquals("3782 822463 10005", CardFieldUtils.formatPan("378282246310005"))125    }126127    @Test fun card_network_detection_matches_browser_add_view_badges() {128        assertEquals("visa", CardFieldUtils.detectNetwork("4242424242424242"))129        assertEquals("mastercard", CardFieldUtils.detectNetwork("5555555555554444"))130        assertEquals("mastercard", CardFieldUtils.detectNetwork("2221000000000009"))131        assertEquals("amex", CardFieldUtils.detectNetwork("378282246310005"))132        assertEquals("discover", CardFieldUtils.detectNetwork("6011111111111117"))133        assertEquals("discover", CardFieldUtils.detectNetwork("6500000000000002"))134        assertEquals("unknown", CardFieldUtils.detectNetwork("6000000000000000"))135    }136137    @Test fun new_card_expiry_auto_formats_browser_mm_year() {138        assertEquals("12", CardFieldUtils.formatExpiry("12"))139        assertEquals("12/28", CardFieldUtils.formatExpiry("1228"))140        assertEquals("12/2899", CardFieldUtils.formatExpiry("122899")) // caps year at 4 digits141        assertEquals("12", CardFieldUtils.expiryMonth("12/2028"))142        assertEquals("2028", CardFieldUtils.expiryYear("12/2028"))143        assertEquals("12/2028", CardFieldUtils.combineExpiry("12", "2028"))144    }145146    @Test fun new_card_expiry_rejects_invalid_month() {147        // currentYear2 = 26, currentMonth = 6 (2026-06).148        assertFalse(CardFieldUtils.isExpiryValid("13/28", currentYear2 = 26, currentMonth = 6))149        assertFalse(CardFieldUtils.isExpiryValid("00/28", currentYear2 = 26, currentMonth = 6))150        assertTrue(CardFieldUtils.isExpiryValid("12/28", currentYear2 = 26, currentMonth = 6))151        assertTrue(CardFieldUtils.isExpiryValid("12/2028", currentYear2 = 26, currentMonth = 6))152        // Past year rejected.153        assertFalse(CardFieldUtils.isExpiryValid("12/24", currentYear2 = 26, currentMonth = 6))154    }155156    private fun identityEntry(id: String, username: String?, email: String?) = VaultEntry(157        id = id,158        title = id,159        type = "login",160        username = username,161        email = email,162        createdAt = 0,163        modifiedAt = 0,164    )165}