package com.peachpasswords.vault import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Test class TOTPGeneratorTest { // RFC 6238 test secret "12345678901234567890" (ASCII) in base32. private val SECRET = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ" @Test fun rfc6238_vector_sha1_6digits() { // T = 59s -> counter 1 -> 8-digit 94287082 -> 6-digit 287082. assertEquals("287082", TOTPGenerator.generateCode(SECRET, nowMillis = 59_000L)) // T = 1111111109s -> 8-digit 07081804 -> 6-digit 081804. assertEquals("081804", TOTPGenerator.generateCode(SECRET, nowMillis = 1_111_111_109_000L)) } @Test fun parses_otpauth_uri() { val uri = "otpauth://totp/Example:alice@example.com?secret=$SECRET&issuer=Example&period=30" assertEquals("287082", TOTPGenerator.generateCode(uri, nowMillis = 59_000L)) } @Test fun remaining_and_progress_track_period() { // 10s into a period: 20s remaining, 1/3 elapsed. assertEquals(20, TOTPGenerator.remainingSeconds(10_000L)) assertEquals(10f / 30f, TOTPGenerator.periodProgress(10_000L), 0.001f) } @Test fun invalid_secret_returns_null() { assertNull(TOTPGenerator.generateCode("not!base32!")) assertNull(TOTPGenerator.generateCode("")) } }