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 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 3940 @Test fun new_entry_type_picker_excludes_notes() {41 assertEquals(listOf("login", "card"), entryEditTypeSegments(isNew = true).map { it.key })42 assertEquals(listOf("login", "note", "card"), entryEditTypeSegments(isNew = false).map { it.key })43 }4445 4647 @Test fun new_entry_ghost_watermark_appears_on_title_type() {48 assertEquals(0f, editGhostWatermarkTarget(""), 0f)49 assertEquals(0f, editGhostWatermarkTarget(" "), 0f)50 assertEquals(0.03f, editGhostWatermarkTarget("GitHub"), 0f)51 }5253 5455 @Test fun new_login_hides_optional_totp_and_notes_until_requested() {56 assertFalse(shouldShowLoginTotp("login", revealed = false, totp = ""))57 assertFalse(shouldShowLoginNotes("login", revealed = false, notes = ""))58 assertTrue(shouldShowAddTotpLink("login", revealed = false, totp = ""))59 assertTrue(shouldShowAddNotesLink("login", revealed = false, notes = ""))60 assertFalse(shouldShowLoginNotesLink(isNew = true, type = "login", revealed = false, notes = ""))61 assertTrue(shouldShowLoginNotesLink(isNew = false, type = "login", revealed = false, notes = ""))62 }6364 @Test fun optional_login_fields_show_when_revealed_or_populated() {65 assertTrue(shouldShowLoginTotp("login", revealed = true, totp = ""))66 assertTrue(shouldShowLoginTotp("login", revealed = false, totp = "JBSWY3DPEHPK3PXP"))67 assertTrue(shouldShowLoginNotes("login", revealed = true, notes = ""))68 assertTrue(shouldShowLoginNotes("login", revealed = false, notes = "remember this"))69 assertFalse(shouldShowAddTotpLink("login", revealed = true, totp = ""))70 assertFalse(shouldShowAddNotesLink("login", revealed = false, notes = "remember this"))71 }7273 @Test fun identity_suggestions_split_username_and_email_like_browser() {74 val entries = listOf(75 identityEntry("a", username = "june", email = "[email protected]"),76 identityEntry("b", username = "june", email = null),77 identityEntry("c", username = "[email protected]", email = "[email protected]"),78 identityEntry("d", username = "[email protected]", email = null),79 )8081 assertEquals(listOf("june"), identitySuggestionsFor(entries, IdentityField.Username))82 assertEquals(83 listOf("[email protected]", "[email protected]", "[email protected]"),84 identitySuggestionsFor(entries, IdentityField.Email),85 )86 }8788 @Test fun generator_defaults_and_toggle_label_match_browser_add_view() {89 assertEquals(64, BROWSER_ADD_GENERATOR_LENGTH)90 assertEquals("generate", generatorToggleLabel(open = false))91 assertEquals("hide generator", generatorToggleLabel(open = true))92 }9394 @Test fun tag_suggestions_match_browser_add_view_limit_and_filtering() {95 val all = listOf("banking", "billing", "books", "business", "backup", "travel")96 assertEquals(97 listOf("banking", "billing", "books", "business", "backup"),98 tagSuggestionsFor(input = "b", allTags = all, tags = emptyList()),99 )100 assertEquals(101 listOf("billing", "books", "business", "backup"),102 tagSuggestionsFor(input = "b", allTags = all, tags = listOf("banking")),103 )104 }105106 @Test fun tag_normalization_allows_spaces_and_caps_length_like_browser() {107 assertEquals("shared login", normalizeTag(" Shared Login "))108 assertEquals("a".repeat(MAX_TAG_LEN), normalizeTag("A".repeat(MAX_TAG_LEN + 8)))109 }110111 112113 @Test fun new_card_number_auto_formats() {114 assertEquals("4242 4242 4242 4242", CardFieldUtils.formatPan("4242424242424242"))115 116 assertEquals("3782 822463 10005", CardFieldUtils.formatPan("378282246310005"))117 }118119 @Test fun card_network_detection_matches_browser_add_view_badges() {120 assertEquals("visa", CardFieldUtils.detectNetwork("4242424242424242"))121 assertEquals("mastercard", CardFieldUtils.detectNetwork("5555555555554444"))122 assertEquals("mastercard", CardFieldUtils.detectNetwork("2221000000000009"))123 assertEquals("amex", CardFieldUtils.detectNetwork("378282246310005"))124 assertEquals("discover", CardFieldUtils.detectNetwork("6011111111111117"))125 assertEquals("discover", CardFieldUtils.detectNetwork("6500000000000002"))126 assertEquals("unknown", CardFieldUtils.detectNetwork("6000000000000000"))127 }128129 @Test fun new_card_expiry_auto_formats_browser_mm_year() {130 assertEquals("12", CardFieldUtils.formatExpiry("12"))131 assertEquals("12/28", CardFieldUtils.formatExpiry("1228"))132 assertEquals("12/2899", CardFieldUtils.formatExpiry("122899")) 133 assertEquals("12", CardFieldUtils.expiryMonth("12/2028"))134 assertEquals("2028", CardFieldUtils.expiryYear("12/2028"))135 assertEquals("12/2028", CardFieldUtils.combineExpiry("12", "2028"))136 }137138 @Test fun new_card_expiry_rejects_invalid_month() {139 140 assertFalse(CardFieldUtils.isExpiryValid("13/28", currentYear2 = 26, currentMonth = 6))141 assertFalse(CardFieldUtils.isExpiryValid("00/28", currentYear2 = 26, currentMonth = 6))142 assertTrue(CardFieldUtils.isExpiryValid("12/28", currentYear2 = 26, currentMonth = 6))143 assertTrue(CardFieldUtils.isExpiryValid("12/2028", currentYear2 = 26, currentMonth = 6))144 145 assertFalse(CardFieldUtils.isExpiryValid("12/24", currentYear2 = 26, currentMonth = 6))146 }147148 private fun identityEntry(id: String, username: String?, email: String?) = VaultEntry(149 id = id,150 title = id,151 type = "login",152 username = username,153 email = email,154 createdAt = 0,155 modifiedAt = 0,156 )157}