# app/modules/prospecting/tests/unit/test_prospect_service.py """ Unit tests for ProspectService. """ import pytest from app.modules.prospecting.exceptions import ProspectNotFoundException from app.modules.prospecting.services.prospect_service import ProspectService @pytest.mark.unit @pytest.mark.prospecting class TestProspectService: """Tests for ProspectService.""" def setup_method(self): self.service = ProspectService() def test_create_digital_prospect(self, db): """Test creating a digital prospect.""" prospect = self.service.create( db, {"channel": "digital", "domain_name": "example.lu", "source": "domain_scan"}, ) assert prospect.id is not None assert prospect.channel.value == "digital" assert prospect.domain_name == "example.lu" assert prospect.status.value == "pending" def test_create_offline_prospect(self, db): """Test creating an offline prospect.""" prospect = self.service.create( db, { "channel": "offline", "business_name": "Test Café", "source": "street", "city": "Luxembourg", }, ) assert prospect.id is not None assert prospect.channel.value == "offline" assert prospect.business_name == "Test Café" assert prospect.city == "Luxembourg" def test_create_digital_prospect_with_contacts(self, db): """Test creating a digital prospect with inline contacts.""" prospect = self.service.create( db, { "channel": "digital", "domain_name": "with-contacts.lu", "contacts": [ {"contact_type": "email", "value": "info@with-contacts.lu"}, ], }, ) assert prospect.id is not None assert len(prospect.contacts) == 1 assert prospect.contacts[0].value == "info@with-contacts.lu" def test_get_by_id(self, db, digital_prospect): """Test getting a prospect by ID.""" result = self.service.get_by_id(db, digital_prospect.id) assert result.id == digital_prospect.id assert result.domain_name == digital_prospect.domain_name def test_get_by_id_not_found(self, db): """Test getting non-existent prospect raises exception.""" with pytest.raises(ProspectNotFoundException): self.service.get_by_id(db, 99999) def test_get_by_domain(self, db, digital_prospect): """Test getting a prospect by domain name.""" result = self.service.get_by_domain(db, digital_prospect.domain_name) assert result is not None assert result.id == digital_prospect.id def test_get_all_with_pagination(self, db, digital_prospect, offline_prospect): """Test listing prospects with pagination.""" prospects, total = self.service.get_all(db, page=1, per_page=10) assert total >= 2 assert len(prospects) >= 2 def test_get_all_filter_by_channel(self, db, digital_prospect, offline_prospect): """Test filtering prospects by channel.""" digital, count = self.service.get_all(db, channel="digital") assert count >= 1 assert all(p.channel.value == "digital" for p in digital) def test_get_all_filter_by_status(self, db, digital_prospect): """Test filtering prospects by status.""" active, count = self.service.get_all(db, status="active") assert count >= 1 assert all(p.status.value == "active" for p in active) def test_get_all_search(self, db, digital_prospect): """Test searching prospects by domain or business name.""" domain = digital_prospect.domain_name results, count = self.service.get_all(db, search=domain[:8]) assert count >= 1 def test_update_prospect(self, db, digital_prospect): """Test updating a prospect.""" updated = self.service.update( db, digital_prospect.id, {"notes": "Updated notes", "status": "contacted"} ) assert updated.notes == "Updated notes" status = updated.status.value if hasattr(updated.status, "value") else updated.status assert status == "contacted" def test_delete_prospect(self, db, digital_prospect): """Test deleting a prospect.""" pid = digital_prospect.id self.service.delete(db, pid) with pytest.raises(ProspectNotFoundException): self.service.get_by_id(db, pid) def test_create_bulk(self, db): """Test bulk creating prospects from domain list.""" domains = ["bulk1.lu", "bulk2.lu", "bulk3.lu"] created, skipped = self.service.create_bulk(db, domains, source="csv_import") assert created == 3 assert skipped == 0 def test_create_bulk_skips_duplicates(self, db, digital_prospect): """Test bulk create skips existing domains.""" domains = [digital_prospect.domain_name, "new-domain.lu"] created, skipped = self.service.create_bulk(db, domains, source="csv_import") assert created == 1 assert skipped == 1 def test_count_by_status(self, db, digital_prospect, offline_prospect): """Test counting prospects by status.""" counts = self.service.count_by_status(db) assert isinstance(counts, dict) assert counts.get("active", 0) >= 1 assert counts.get("pending", 0) >= 1 def test_count_by_channel(self, db, digital_prospect, offline_prospect): """Test counting prospects by channel.""" counts = self.service.count_by_channel(db) assert isinstance(counts, dict) assert counts.get("digital", 0) >= 1 assert counts.get("offline", 0) >= 1