Skip to main content
Glama
test_pan_verification.py10.5 kB
"""Unit tests for PAN verification tool.""" import pytest from unittest.mock import AsyncMock from pydantic import ValidationError from src.tools.pan_verification import PANVerificationTool class TestPANVerificationTool: """Test suite for PAN verification tool.""" @pytest.mark.asyncio async def test_successful_verification_all_match( self, pan_verification_tool, valid_pan_request, mock_pan_verification_response ): """Test successful PAN verification with all fields matching.""" # Setup mock pan_verification_tool.api_client.post = AsyncMock( return_value=mock_pan_verification_response ) # Execute result = await pan_verification_tool.execute(valid_pan_request) # Assert assert result["pan"] == "ABCDE1234F" assert result["status"] == "valid" assert result["name_match"] is True assert result["dob_match"] is True assert result["aadhaar_seeding_status"] == "y" assert "verified_at" in result # Verify API was called correctly pan_verification_tool.api_client.post.assert_called_once() call_args = pan_verification_tool.api_client.post.call_args assert call_args[1]["endpoint"] == "/kyc/pan/verify" assert call_args[1]["data"]["pan"] == "ABCDE1234F" @pytest.mark.asyncio async def test_verification_name_mismatch( self, pan_verification_tool, valid_pan_request, mock_responses ): """Test PAN verification with name mismatch.""" # Setup mock with name mismatch response response = mock_responses["pan_verification"]["success_name_mismatch"] pan_verification_tool.api_client.post = AsyncMock(return_value=response) # Execute result = await pan_verification_tool.execute(valid_pan_request) # Assert assert result["name_match"] is False assert result["dob_match"] is True assert result["status"] == "valid" @pytest.mark.asyncio async def test_verification_dob_mismatch( self, pan_verification_tool, valid_pan_request, mock_responses ): """Test PAN verification with DOB mismatch.""" # Setup mock with DOB mismatch response response = mock_responses["pan_verification"]["success_dob_mismatch"] pan_verification_tool.api_client.post = AsyncMock(return_value=response) # Execute result = await pan_verification_tool.execute(valid_pan_request) # Assert assert result["name_match"] is True assert result["dob_match"] is False assert result["aadhaar_seeding_status"] == "n" @pytest.mark.asyncio async def test_verification_deceased_holder( self, pan_verification_tool, valid_pan_request, mock_responses ): """Test PAN verification for deceased holder.""" # Setup mock with deceased holder response response = mock_responses["pan_verification"]["success_deceased"] pan_verification_tool.api_client.post = AsyncMock(return_value=response) # Execute result = await pan_verification_tool.execute(valid_pan_request) # Assert assert result["remarks"] == "Holder is Deceased" assert result["aadhaar_seeding_status"] == "na" @pytest.mark.asyncio async def test_invalid_pan_format(self, pan_verification_tool): """Test validation error for invalid PAN format.""" invalid_request = { "pan": "INVALID", "name_as_per_pan": "John Doe", "date_of_birth": "01/01/1990", "consent": "Y", "reason": "Test" } # Execute and assert with pytest.raises(ValueError, match="Invalid input parameters"): await pan_verification_tool.execute(invalid_request) @pytest.mark.asyncio async def test_lowercase_pan(self, pan_verification_tool): """Test validation error for lowercase PAN.""" invalid_request = { "pan": "abcde1234f", "name_as_per_pan": "John Doe", "date_of_birth": "01/01/1990", "consent": "Y", "reason": "Test" } with pytest.raises(ValueError): await pan_verification_tool.execute(invalid_request) @pytest.mark.asyncio async def test_invalid_date_format(self, pan_verification_tool): """Test validation error for invalid date format.""" invalid_request = { "pan": "ABCDE1234F", "name_as_per_pan": "John Doe", "date_of_birth": "1990-01-01", # Wrong format "consent": "Y", "reason": "Test" } with pytest.raises(ValueError): await pan_verification_tool.execute(invalid_request) @pytest.mark.asyncio async def test_missing_consent(self, pan_verification_tool): """Test validation error for missing consent.""" invalid_request = { "pan": "ABCDE1234F", "name_as_per_pan": "John Doe", "date_of_birth": "01/01/1990", "consent": "N", # Invalid consent "reason": "Test" } with pytest.raises(ValueError): await pan_verification_tool.execute(invalid_request) @pytest.mark.asyncio async def test_missing_required_field(self, pan_verification_tool): """Test validation error for missing required field.""" invalid_request = { "pan": "ABCDE1234F", "name_as_per_pan": "John Doe", # Missing date_of_birth "consent": "Y", "reason": "Test" } with pytest.raises(ValueError): await pan_verification_tool.execute(invalid_request) @pytest.mark.asyncio async def test_api_error_handling(self, pan_verification_tool, valid_pan_request): """Test handling of API errors.""" # Setup mock to raise exception pan_verification_tool.api_client.post = AsyncMock( side_effect=Exception("API Error") ) # Execute and assert with pytest.raises(Exception, match="API Error"): await pan_verification_tool.execute(valid_pan_request) def test_get_name(self, pan_verification_tool): """Test tool name.""" assert pan_verification_tool.get_name() == "verify_pan" def test_cache_key_generation(self, pan_verification_tool, valid_pan_request): """Test cache key generation.""" cache_key = pan_verification_tool.get_cache_key(valid_pan_request) assert cache_key.startswith("pan_verify:") assert len(cache_key) > len("pan_verify:") # Same input should generate same key cache_key2 = pan_verification_tool.get_cache_key(valid_pan_request) assert cache_key == cache_key2 def test_cache_key_different_for_different_inputs(self, pan_verification_tool): """Test that different inputs generate different cache keys.""" request1 = { "pan": "ABCDE1234F", "name_as_per_pan": "John Doe", "date_of_birth": "01/01/1990", "consent": "Y", "reason": "Test" } request2 = { "pan": "XYZPQ5678R", "name_as_per_pan": "Jane Smith", "date_of_birth": "15/06/1985", "consent": "Y", "reason": "Test" } key1 = pan_verification_tool.get_cache_key(request1) key2 = pan_verification_tool.get_cache_key(request2) assert key1 != key2 def test_cache_ttl(self, pan_verification_tool): """Test cache TTL value.""" ttl = pan_verification_tool.get_cache_ttl() assert ttl == 3600 # 1 hour @pytest.mark.asyncio async def test_empty_name(self, pan_verification_tool): """Test validation error for empty name.""" invalid_request = { "pan": "ABCDE1234F", "name_as_per_pan": "", "date_of_birth": "01/01/1990", "consent": "Y", "reason": "Test" } with pytest.raises(ValueError): await pan_verification_tool.execute(invalid_request) @pytest.mark.asyncio async def test_empty_reason(self, pan_verification_tool): """Test validation error for empty reason.""" invalid_request = { "pan": "ABCDE1234F", "name_as_per_pan": "John Doe", "date_of_birth": "01/01/1990", "consent": "Y", "reason": "" } with pytest.raises(ValueError): await pan_verification_tool.execute(invalid_request) @pytest.mark.asyncio async def test_company_pan_verification( self, pan_verification_tool, mock_responses ): """Test PAN verification for company PAN.""" request = { "pan": "ABCCC1234F", "name_as_per_pan": "ABC Company Ltd", "date_of_birth": "01/01/2000", "consent": "Y", "reason": "Company verification" } response = mock_responses["pan_verification"]["success_company"] pan_verification_tool.api_client.post = AsyncMock(return_value=response) result = await pan_verification_tool.execute(request) assert result["category"] == "company" assert result["aadhaar_seeding_status"] == "na" @pytest.mark.asyncio async def test_lowercase_consent_accepted( self, pan_verification_tool, valid_pan_request, mock_pan_verification_response ): """Test that lowercase 'y' is accepted for consent.""" valid_pan_request["consent"] = "y" pan_verification_tool.api_client.post = AsyncMock( return_value=mock_pan_verification_response ) result = await pan_verification_tool.execute(valid_pan_request) assert result["status"] == "valid" @pytest.mark.asyncio async def test_special_characters_in_name( self, pan_verification_tool, valid_pan_request, mock_pan_verification_response ): """Test handling of special characters in name.""" valid_pan_request["name_as_per_pan"] = "O'Brien-Smith Jr." pan_verification_tool.api_client.post = AsyncMock( return_value=mock_pan_verification_response ) result = await pan_verification_tool.execute(valid_pan_request) assert result["status"] == "valid"

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/CTD-Techs/CTD-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server