feat(prospecting): add complete prospecting module for lead discovery and scoring
Some checks failed
Some checks failed
Migrates scanning pipeline from marketing-.lu-domains app into Orion module. Supports digital (domain scan) and offline (manual capture) lead channels with enrichment, scoring, campaign management, and interaction tracking. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# app/modules/prospecting/tests/unit/test_enrichment_service.py
|
||||
"""
|
||||
Unit tests for EnrichmentService.
|
||||
|
||||
Note: These tests mock external HTTP calls to avoid real network requests.
|
||||
"""
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from app.modules.prospecting.services.enrichment_service import EnrichmentService
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.prospecting
|
||||
class TestEnrichmentService:
|
||||
"""Tests for EnrichmentService."""
|
||||
|
||||
def setup_method(self):
|
||||
self.service = EnrichmentService()
|
||||
|
||||
def test_check_http_success(self, db, digital_prospect):
|
||||
"""Test HTTP check with mocked successful response."""
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.url = f"https://{digital_prospect.domain_name}"
|
||||
mock_response.headers = {}
|
||||
|
||||
with patch("app.modules.prospecting.services.enrichment_service.requests.get", return_value=mock_response):
|
||||
result = self.service.check_http(db, digital_prospect)
|
||||
|
||||
assert result["has_website"] is True
|
||||
assert result["uses_https"] is True
|
||||
|
||||
def test_check_http_no_website(self, db, digital_prospect):
|
||||
"""Test HTTP check when website doesn't respond."""
|
||||
import requests as req
|
||||
|
||||
with patch(
|
||||
"app.modules.prospecting.services.enrichment_service.requests.get",
|
||||
side_effect=req.exceptions.ConnectionError("Connection refused"),
|
||||
):
|
||||
result = self.service.check_http(db, digital_prospect)
|
||||
|
||||
assert result["has_website"] is False
|
||||
|
||||
def test_check_http_no_domain(self, db, offline_prospect):
|
||||
"""Test HTTP check with no domain name."""
|
||||
result = self.service.check_http(db, offline_prospect)
|
||||
assert result["has_website"] is False
|
||||
assert result["error"] == "No domain name"
|
||||
|
||||
def test_detect_cms_wordpress(self):
|
||||
"""Test CMS detection for WordPress."""
|
||||
html = '<link rel="stylesheet" href="/wp-content/themes/test/style.css">'
|
||||
assert self.service._detect_cms(html) == "wordpress"
|
||||
|
||||
def test_detect_cms_drupal(self):
|
||||
"""Test CMS detection for Drupal."""
|
||||
html = '<meta name="generator" content="drupal 7">'
|
||||
assert self.service._detect_cms(html) == "drupal"
|
||||
|
||||
def test_detect_cms_none(self):
|
||||
"""Test CMS detection when no CMS detected."""
|
||||
html = "<html><body>Hello world</body></html>"
|
||||
assert self.service._detect_cms(html) is None
|
||||
|
||||
def test_detect_js_framework_jquery(self):
|
||||
"""Test JS framework detection for jQuery."""
|
||||
html = '<script src="/js/jquery.min.js"></script>'
|
||||
assert self.service._detect_js_framework(html) == "jquery"
|
||||
|
||||
def test_detect_js_framework_react(self):
|
||||
"""Test JS framework detection for React."""
|
||||
html = '<script id="__NEXT_DATA__" type="application/json">{}</script>'
|
||||
assert self.service._detect_js_framework(html) == "react"
|
||||
|
||||
def test_detect_analytics_google(self):
|
||||
"""Test analytics detection for Google Analytics."""
|
||||
html = '<script async src="https://www.googletagmanager.com/gtag/js?id=G-123"></script>'
|
||||
result = self.service._detect_analytics(html)
|
||||
assert result is not None
|
||||
assert "google" in result
|
||||
|
||||
def test_detect_analytics_none(self):
|
||||
"""Test analytics detection when no analytics detected."""
|
||||
html = "<html><body>No analytics here</body></html>"
|
||||
assert self.service._detect_analytics(html) is None
|
||||
|
||||
def test_service_instance_exists(self):
|
||||
"""Test that service singleton is importable."""
|
||||
from app.modules.prospecting.services.enrichment_service import (
|
||||
enrichment_service,
|
||||
)
|
||||
|
||||
assert enrichment_service is not None
|
||||
assert isinstance(enrichment_service, EnrichmentService)
|
||||
Reference in New Issue
Block a user