Files

125 lines
3.6 KiB
Python

# -*- coding: utf-8 -*-
"""Tests for agent ID generation, sanitization, and validation."""
import pytest
from pineagents.config.config import (
generate_short_agent_id,
sanitize_agent_id,
validate_agent_id,
)
def test_generate_short_agent_id_length():
"""Test that generated agent ID has correct length."""
agent_id = generate_short_agent_id()
assert len(agent_id) == 6
assert isinstance(agent_id, str)
def test_generate_short_agent_id_unique():
"""Test that generated agent IDs are unique."""
ids = {generate_short_agent_id() for _ in range(100)}
# With 100 generations, we should get at least 95 unique IDs
# (allowing for some collisions in the random space)
assert len(ids) >= 95
def test_generate_short_agent_id_alphanumeric():
"""Test that generated agent ID contains only alphanumeric chars."""
agent_id = generate_short_agent_id()
# shortuuid uses base57 alphabet by default
# (0-9, A-Z, a-z minus ambiguous chars like I, l, O, 0, etc.)
assert agent_id.isalnum()
# --- sanitize_agent_id ---
def test_sanitize_strips_whitespace():
"""Test sanitize_agent_id strips whitespace."""
assert sanitize_agent_id(" Browse-Agent ") == "Browse-Agent"
assert sanitize_agent_id("MY_BOT") == "MY_BOT"
assert sanitize_agent_id("hello") == "hello"
def test_sanitize_empty_string():
"""Test sanitize_agent_id with empty / whitespace-only input."""
assert sanitize_agent_id("") == ""
assert sanitize_agent_id(" ") == ""
# --- validate_agent_id ---
@pytest.mark.parametrize(
"agent_id",
[
"browse-agent",
"my_bot_v2",
"a1",
"agent123",
"Browse-Agent",
"MY_BOT",
],
)
def test_validate_valid_ids(agent_id):
"""Test that well-formed IDs pass validation."""
validate_agent_id(agent_id, set())
@pytest.mark.parametrize(
"agent_id,expected_msg",
[
("a", "at least 2 characters"),
("", "at least 2 characters"),
],
)
def test_validate_too_short(agent_id, expected_msg):
"""Test that IDs shorter than 2 chars are rejected."""
with pytest.raises(ValueError, match=expected_msg):
validate_agent_id(agent_id, set())
def test_validate_too_long():
"""Test that IDs longer than 64 chars are rejected."""
long_id = "a" * 65
with pytest.raises(ValueError, match="at most 64 characters"):
validate_agent_id(long_id, set())
@pytest.mark.parametrize(
"agent_id",
[
"Browse Agent", # space
"中文名", # non-ASCII
"special!chars", # special chars
"-starts-dash", # starts with dash
"_starts-under", # starts with underscore
"ends-dash-", # ends with dash
"ends_under_", # ends with underscore
],
)
def test_validate_invalid_pattern(agent_id):
"""Test that IDs with invalid characters are rejected."""
with pytest.raises(ValueError, match="invalid characters"):
validate_agent_id(agent_id, set())
def test_validate_reserved_id():
"""Test that reserved IDs are rejected."""
with pytest.raises(ValueError, match="reserved"):
validate_agent_id("default", set())
def test_validate_duplicate_id():
"""Test that duplicate IDs are rejected."""
existing = {"browse-agent", "my-bot"}
with pytest.raises(ValueError, match="already exists"):
validate_agent_id("browse-agent", existing)
def test_validate_ok_when_no_conflict():
"""Test that a valid ID passes when there is no conflict."""
existing = {"other-agent"}
validate_agent_id("browse-agent", existing) # should not raise