""" Basic tests for Govbot functionality. These tests demonstrate the core features without requiring Mastodon. """ import pytest from pathlib import Path import sys import tempfile import shutil # Add src to path sys.path.insert(0, str(Path(__file__).parent.parent)) from src.govbot.db.models import init_db, get_session from src.govbot.agent import GovernanceAgent from src.govbot.governance.constitution import ConstitutionalReasoner from src.govbot.governance.primitives import GovernancePrimitives @pytest.fixture def test_db(): """Create a temporary test database""" temp_dir = tempfile.mkdtemp() db_path = Path(temp_dir) / "test.db" engine = init_db(str(db_path)) session = get_session(engine) yield session session.close() shutil.rmtree(temp_dir) @pytest.fixture def constitution_path(): """Get path to test constitution""" return str(Path(__file__).parent.parent / "constitution.md") def test_constitution_loading(constitution_path): """Test that constitution loads and parses correctly""" reasoner = ConstitutionalReasoner(constitution_path) assert reasoner.constitution_text assert len(reasoner.sections) > 0 # Test section listing sections = reasoner.list_sections() assert any("Proposal" in s for s in sections) def test_constitutional_query(constitution_path): """Test querying the constitution""" reasoner = ConstitutionalReasoner(constitution_path) result = reasoner.query("What are the rules for standard proposals?") assert "answer" in result assert "citations" in result assert len(result["citations"]) > 0 def test_primitives_store_and_query(test_db): """Test basic primitive operations""" primitives = GovernancePrimitives(test_db) # Store a record record_id = primitives.store_record( record_type="test_record", data={"foo": "bar", "count": 42}, actor="test_user", reasoning="Testing storage", ) assert record_id > 0 # Query it back records = primitives.query_records(record_type="store_test_record") assert len(records) > 0 def test_create_process(test_db): """Test creating a governance process""" primitives = GovernancePrimitives(test_db) process_id = primitives.create_process( process_type="test_proposal", creator="test_user", deadline_days=6, constitutional_basis="Article 3, Section 1", initial_state={"proposal_text": "Test proposal"}, ) assert process_id > 0 # Verify it was created from src.govbot.db import queries process = queries.get_process(test_db, process_id) assert process is not None assert process.process_type == "test_proposal" assert process.creator == "test_user" def test_vote_counting(test_db): """Test vote counting and threshold checking""" primitives = GovernancePrimitives(test_db) # Create a process process_id = primitives.create_process( process_type="test_proposal", creator="alice", deadline_days=6, constitutional_basis="Article 3", initial_state={"votes": {}}, ) # Cast some votes primitives.update_process_state( process_id, { "votes.alice": {"vote": "agree"}, "votes.bob": {"vote": "agree"}, "votes.charlie": {"vote": "disagree"}, }, ) # Count votes counts = primitives.count_votes(process_id) assert counts["agree"] == 2 assert counts["disagree"] == 1 # Check threshold passed = primitives.check_threshold(counts, "simple_majority") assert passed is True def test_agent_proposal_creation(test_db, constitution_path): """Test agent creating a proposal from natural language""" agent = GovernanceAgent(test_db, constitution_path, model=None) result = agent.process_request( request="I propose we have weekly meetings", actor="test_user", ) assert result["success"] is True assert result["process_id"] is not None assert "proposal" in result["response"].lower() def test_proposal_interpretation(constitution_path): """Test interpreting different proposal types""" reasoner = ConstitutionalReasoner(constitution_path) # Standard proposal info = reasoner.interpret_proposal("We should update the guidelines") assert "proposal_type" in info assert info["discussion_period_days"] >= 2 # Urgent proposal info = reasoner.interpret_proposal("URGENT: We need to address this spam attack") # Should recognize urgency (though AI interpretation may vary) assert "proposal_type" in info if __name__ == "__main__": # Run tests pytest.main([__file__, "-v"])