package com.peachpasswords.vault import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test import java.security.MessageDigest class PasswordGeneratorTest { @Test fun respects_length() { repeat(20) { assertEquals(24, PasswordGenerator.generate(PasswordGenerator.Options(length = 24)).length) } } @Test fun numbers_only_yields_only_digits() { val pw = PasswordGenerator.generate( PasswordGenerator.Options(length = 60, includeLowercase = false, includeUppercase = false, includeNumbers = true, includeSymbols = false), ) assertTrue(pw.all { it.isDigit() }) } @Test fun forbidden_chars_are_excluded() { val pw = PasswordGenerator.generate( PasswordGenerator.Options(length = 200, forbiddenChars = "0O1lI"), ) assertFalse(pw.any { it in "0O1lI" }) } @Test fun empty_charset_falls_back_to_lowercase() { val pw = PasswordGenerator.generate( PasswordGenerator.Options(length = 30, includeLowercase = false, includeUppercase = false, includeNumbers = false, includeSymbols = false), ) assertEquals(30, pw.length) assertTrue(pw.all { it in 'a'..'z' }) } @Test fun passphrase_defaults_to_five_words() { assertEquals(5, PasswordGenerator.generatePassphrase().split("-").size) } @Test fun passphrase_supports_four_through_twelve_words() { assertEquals(4, PasswordGenerator.generatePassphrase(wordCount = 4).split("-").size) assertEquals(12, PasswordGenerator.generatePassphrase(wordCount = 12).split("-").size) } @Test fun passphrase_uses_the_selected_separator() { assertEquals(8, PasswordGenerator.generatePassphrase(wordCount = 8, separator = ".").split(".").size) } @Test fun eff_short_word_list_matches_the_published_source() { val normalized = EffShortWordList.words.joinToString(separator = "\n", postfix = "\n") val digest = MessageDigest.getInstance("SHA-256") .digest(normalized.toByteArray()) .joinToString("") { "%02x".format(it) } assertEquals(1296, EffShortWordList.words.size) assertEquals("36ecca49e4fa20ca84b176c32f2e9c82f98f446585190e75f9879a95c08247bf", digest) } }