1package com.peachpasswords.autofill23import com.peachpasswords.autofill.AutofillResponseBuilder.FillMode4import com.peachpasswords.vault.VaultEntry5import org.junit.Assert.assertEquals6import org.junit.Assert.assertNotNull7import org.junit.Test89class AutofillPreviewLabelsTest {10 private fun entry(11 title: String = "GitHub",12 username: String? = "june",13 email: String? = null,14 url: String? = "https://github.com",15 ) = VaultEntry(16 id = title, title = title, username = username, email = email, url = url,17 createdAt = 0, modifiedAt = 0,18 )1920 @Test fun normal_mode_shows_entry_title_and_identity() {21 val labels = AutofillResponseBuilder.previewLabels(false, entry(), "github.com")22 assertEquals("GitHub", labels.title)23 assertEquals("june", labels.subtitle)24 assertEquals(FillMode.LOGIN, labels.fillMode)25 }2627 @Test fun normal_mode_falls_back_email_then_domain() {28 val emailOnly = entry(username = null, email = "[email protected]")29 assertEquals("[email protected]", AutofillResponseBuilder.previewLabels(false, emailOnly, null).subtitle)30 val bare = entry(username = null, email = null)31 assertEquals("github.com", AutofillResponseBuilder.previewLabels(false, bare, null).subtitle)32 }3334 @Test fun private_mode_hides_title_and_identity() {35 val labels = AutofillResponseBuilder.previewLabels(true, entry(), "github.com")36 assertEquals("Peach", labels.title)37 assertEquals("github.com", labels.subtitle)38 }3940 @Test fun private_mode_without_origin_has_blank_subtitle() {41 val labels = AutofillResponseBuilder.previewLabels(true, entry(), null)42 assertEquals("Peach", labels.title)43 assertEquals("", labels.subtitle)44 }4546 4748 @Test fun otpFill_mode_shows_chunked_code_as_title_and_entry_as_subtitle() {49 val labels = AutofillResponseBuilder.previewLabels(50 privatePreview = false,51 entry = entry(),52 originDomain = "github.com",53 fillMode = FillMode.OTP_FILL,54 otpCode = "482901",55 )56 assertEquals("482 901", labels.title)57 assertEquals("2FA", labels.subtitle)58 assertEquals("GitHub", labels.iconSource)59 assertEquals(FillMode.OTP_FILL, labels.fillMode)60 }6162 @Test fun otpFill_mode_passes_through_long_codes_unchunked() {63 val labels = AutofillResponseBuilder.previewLabels(64 privatePreview = false,65 entry = entry(),66 originDomain = null,67 fillMode = FillMode.OTP_FILL,68 otpCode = "JBSWY3DPEHPK3PXP",69 )70 71 assertEquals("JBSWY3DPEHPK3PXP", labels.title)72 assertEquals("2FA", labels.subtitle)73 }7475 @Test fun otpFill_mode_never_leaks_digits_in_private_preview() {76 val labels = AutofillResponseBuilder.previewLabels(77 privatePreview = true,78 entry = entry(),79 originDomain = "github.com",80 fillMode = FillMode.OTP_FILL,81 otpCode = "482901",82 )83 84 assertEquals("Peach", labels.title)85 assertEquals("github.com", labels.subtitle)86 }8788 @Test(expected = IllegalArgumentException::class)89 fun otpFill_mode_requires_otpCode() {90 AutofillResponseBuilder.previewLabels(91 privatePreview = false,92 entry = entry(),93 originDomain = "github.com",94 fillMode = FillMode.OTP_FILL,95 otpCode = null,96 )97 }9899 @Test fun chunkOtpForDisplay_groups_only_6digit_codes_with_space() {100 101 assertEquals("482 901", AutofillResponseBuilder.chunkOtpForDisplay("482901"))102 103 assertEquals("12345", AutofillResponseBuilder.chunkOtpForDisplay("12345"))104 assertEquals("1234567", AutofillResponseBuilder.chunkOtpForDisplay("1234567"))105 106 assertEquals("JBSWY3DPEHPK3PXP", AutofillResponseBuilder.chunkOtpForDisplay("JBSWY3DPEHPK3PXP"))107 }108}109110111112class AutofillPreviewLabelsCountdownTest {113 private fun entry(title: String = "GitHub") = VaultEntry(114 id = title, title = title, username = "june",115 createdAt = 0, modifiedAt = 0,116 )117118 @Test fun otpFill_chip_counts_down_seconds_remaining_in_subtitle() {119 val labels = AutofillResponseBuilder.previewLabels(120 privatePreview = false,121 entry = entry(),122 originDomain = "github.com",123 fillMode = FillMode.OTP_FILL,124 otpCode = "482901",125 secondsRemaining = 23,126 )127 assertEquals("482 901", labels.title)128 assertEquals("2FA · 23s", labels.subtitle)129 }130131 @Test fun otpFill_chip_amber_zone_at_five_to_nine_seconds() {132 val labels = AutofillResponseBuilder.previewLabels(133 false, entry(), null,134 fillMode = FillMode.OTP_FILL, otpCode = "123456", secondsRemaining = 7,135 )136 assertEquals("2FA · 7s", labels.subtitle)137 }138139 @Test fun otpFill_chip_red_zone_at_or_below_four_seconds() {140 val labels = AutofillResponseBuilder.previewLabels(141 false, entry(), null,142 fillMode = FillMode.OTP_FILL, otpCode = "123456", secondsRemaining = 3,143 )144 assertEquals("2FA · 3s", labels.subtitle)145 }146147 @Test fun otpFill_chip_at_zero_or_below_shows_expired() {148 val labels = AutofillResponseBuilder.previewLabels(149 false, entry(), null,150 fillMode = FillMode.OTP_FILL, otpCode = "123456", secondsRemaining = 0,151 )152 assertEquals("2FA · expired", labels.subtitle)153 }154155 @Test fun otpFill_chip_without_secondsRemaining_keeps_legacy_subtitle() {156 157 158 159 val labels = AutofillResponseBuilder.previewLabels(160 false, entry(), "github.com",161 fillMode = FillMode.OTP_FILL, otpCode = "482901",162 )163 assertEquals("2FA", labels.subtitle)164 assertEquals(null, labels.endIcon)165 }166167 @Test fun private_mode_still_hides_digits_even_with_countdown() {168 169 val labels = AutofillResponseBuilder.previewLabels(170 true, entry(), "github.com",171 fillMode = FillMode.OTP_FILL, otpCode = "482901", secondsRemaining = 7,172 )173 assertEquals("Peach", labels.title)174 assertEquals("github.com", labels.subtitle)175 }176}