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>
108 lines
3.9 KiB
Python
108 lines
3.9 KiB
Python
# app/modules/prospecting/tests/unit/test_campaign_service.py
|
|
"""
|
|
Unit tests for CampaignService.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from app.modules.prospecting.exceptions import CampaignTemplateNotFoundException
|
|
from app.modules.prospecting.services.campaign_service import CampaignService
|
|
|
|
|
|
@pytest.mark.unit
|
|
@pytest.mark.prospecting
|
|
class TestCampaignService:
|
|
"""Tests for CampaignService."""
|
|
|
|
def setup_method(self):
|
|
self.service = CampaignService()
|
|
|
|
def test_create_template(self, db):
|
|
"""Test creating a campaign template."""
|
|
template = self.service.create_template(db, {
|
|
"name": "Test Campaign",
|
|
"lead_type": "bad_website",
|
|
"channel": "email",
|
|
"language": "fr",
|
|
"subject_template": "Subject for {domain}",
|
|
"body_template": "Hello {business_name}, your site {domain} has issues.",
|
|
})
|
|
|
|
assert template.id is not None
|
|
assert template.name == "Test Campaign"
|
|
assert template.lead_type == "bad_website"
|
|
|
|
def test_get_templates(self, db, campaign_template):
|
|
"""Test listing campaign templates."""
|
|
templates = self.service.get_templates(db)
|
|
assert len(templates) >= 1
|
|
|
|
def test_get_templates_filter_lead_type(self, db, campaign_template):
|
|
"""Test filtering templates by lead type."""
|
|
templates = self.service.get_templates(db, lead_type="bad_website")
|
|
assert len(templates) >= 1
|
|
|
|
templates = self.service.get_templates(db, lead_type="no_website")
|
|
# campaign_template is bad_website, so this might be empty
|
|
assert isinstance(templates, list)
|
|
|
|
def test_get_template_by_id(self, db, campaign_template):
|
|
"""Test getting a template by ID."""
|
|
result = self.service.get_template_by_id(db, campaign_template.id)
|
|
assert result.id == campaign_template.id
|
|
|
|
def test_get_template_not_found(self, db):
|
|
"""Test getting non-existent template raises exception."""
|
|
with pytest.raises(CampaignTemplateNotFoundException):
|
|
self.service.get_template_by_id(db, 99999)
|
|
|
|
def test_update_template(self, db, campaign_template):
|
|
"""Test updating a template."""
|
|
updated = self.service.update_template(
|
|
db, campaign_template.id, {"name": "Updated Campaign"}
|
|
)
|
|
assert updated.name == "Updated Campaign"
|
|
|
|
def test_delete_template(self, db, campaign_template):
|
|
"""Test deleting a template."""
|
|
tid = campaign_template.id
|
|
self.service.delete_template(db, tid)
|
|
|
|
with pytest.raises(CampaignTemplateNotFoundException):
|
|
self.service.get_template_by_id(db, tid)
|
|
|
|
def test_render_campaign(self, db, campaign_template, prospect_with_score):
|
|
"""Test rendering a campaign with prospect data."""
|
|
result = self.service.render_campaign(
|
|
db, campaign_template.id, prospect_with_score.id
|
|
)
|
|
|
|
assert "subject" in result
|
|
assert "body" in result
|
|
assert prospect_with_score.domain_name in result["subject"]
|
|
|
|
def test_send_campaign(self, db, campaign_template, digital_prospect):
|
|
"""Test sending a campaign to prospects."""
|
|
sends = self.service.send_campaign(
|
|
db,
|
|
template_id=campaign_template.id,
|
|
prospect_ids=[digital_prospect.id],
|
|
sent_by_user_id=1,
|
|
)
|
|
|
|
assert len(sends) == 1
|
|
assert sends[0].prospect_id == digital_prospect.id
|
|
assert sends[0].status.value == "sent"
|
|
|
|
def test_get_sends(self, db, campaign_template, digital_prospect):
|
|
"""Test getting campaign sends."""
|
|
self.service.send_campaign(
|
|
db,
|
|
template_id=campaign_template.id,
|
|
prospect_ids=[digital_prospect.id],
|
|
sent_by_user_id=1,
|
|
)
|
|
|
|
sends = self.service.get_sends(db, prospect_id=digital_prospect.id)
|
|
assert len(sends) >= 1
|