"""Tests for profile field validation.""" from validation import ( validate_contact_email, validate_nostr_npub, validate_profile_fields, validate_signal, validate_telegram, ) class TestValidateContactEmail: """Tests for contact email validation.""" def test_none_is_valid(self): assert validate_contact_email(None) is None def test_empty_string_is_valid(self): assert validate_contact_email("") is None def test_valid_email(self): assert validate_contact_email("user@example.com") is None def test_valid_email_with_plus(self): assert validate_contact_email("user+tag@example.com") is None def test_valid_email_subdomain(self): assert validate_contact_email("user@mail.example.com") is None def test_invalid_email_no_at(self): result = validate_contact_email("userexample.com") assert result is not None assert "not valid" in result.lower() or "@" in result def test_invalid_email_no_domain(self): result = validate_contact_email("user@") assert result is not None def test_invalid_email_spaces(self): result = validate_contact_email("user @example.com") assert result is not None class TestValidateTelegram: """Tests for Telegram handle validation.""" def test_none_is_valid(self): assert validate_telegram(None) is None def test_empty_string_is_valid(self): assert validate_telegram("") is None def test_valid_handle(self): assert validate_telegram("@alice") is None def test_valid_handle_with_numbers(self): assert validate_telegram("@alice123") is None def test_valid_handle_with_underscore(self): assert validate_telegram("@alice_bob") is None def test_valid_handle_min_length(self): # 1 character after @ assert validate_telegram("@a") is None def test_valid_handle_max_length(self): # 32 characters after @ assert validate_telegram("@" + "a" * 32) is None def test_missing_at_prefix(self): result = validate_telegram("alice") assert result is not None assert "@" in result def test_just_at_sign(self): result = validate_telegram("@") assert result is not None def test_too_long(self): # More than 32 characters after @ result = validate_telegram("@" + "a" * 33) assert result is not None assert "32" in result def test_starts_with_number_is_valid(self): # Now allowed - any character is valid assert validate_telegram("@1alice") is None def test_special_characters_are_valid(self): # Now allowed - any character is valid assert validate_telegram("@alice-bob") is None assert validate_telegram("@test.user") is None class TestValidateSignal: """Tests for Signal username validation.""" def test_none_is_valid(self): assert validate_signal(None) is None def test_empty_string_is_valid(self): assert validate_signal("") is None def test_valid_username(self): assert validate_signal("alice.42") is None def test_valid_simple_username(self): assert validate_signal("alice") is None def test_valid_with_numbers(self): assert validate_signal("alice123") is None def test_whitespace_only_invalid(self): result = validate_signal(" ") assert result is not None assert "empty" in result.lower() def test_too_long(self): result = validate_signal("a" * 65) assert result is not None assert "64" in result class TestValidateNostrNpub: """Tests for Nostr npub validation.""" # Valid npub for testing (32 zero bytes encoded as bech32) VALID_NPUB = "npub1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzqujme" def test_none_is_valid(self): assert validate_nostr_npub(None) is None def test_empty_string_is_valid(self): assert validate_nostr_npub("") is None def test_valid_npub(self): # Generate a valid npub for testing # This is the npub for 32 zero bytes assert validate_nostr_npub(self.VALID_NPUB) is None def test_wrong_prefix(self): result = validate_nostr_npub( "nsec1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqwcv5dz" ) assert result is not None assert "npub" in result.lower() def test_invalid_checksum(self): # Change last character to break checksum result = validate_nostr_npub( "npub1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsutgpd" ) assert result is not None assert "checksum" in result.lower() def test_too_short(self): result = validate_nostr_npub("npub1short") assert result is not None def test_not_starting_with_npub1(self): result = validate_nostr_npub( "npub2qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsutgpc" ) assert result is not None assert "npub1" in result def test_random_string(self): result = validate_nostr_npub("not_a_valid_npub_at_all") assert result is not None class TestValidateProfileFields: """Tests for validating all profile fields together.""" def test_all_none_is_valid(self): errors = validate_profile_fields() assert errors == {} def test_all_valid(self): errors = validate_profile_fields( contact_email="user@example.com", telegram="@alice", signal="alice.42", nostr_npub="npub1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzqujme", ) assert errors == {} def test_single_invalid_field(self): errors = validate_profile_fields( contact_email="user@example.com", telegram="alice", # Missing @ signal="alice.42", ) assert "telegram" in errors assert len(errors) == 1 def test_multiple_invalid_fields(self): errors = validate_profile_fields( contact_email="not-an-email", telegram="alice", # Missing @ ) assert "contact_email" in errors assert "telegram" in errors assert len(errors) == 2 def test_empty_values_are_valid(self): errors = validate_profile_fields( contact_email="", telegram="", signal="", nostr_npub="", ) assert errors == {}