Files
MarketingTool/apps/api/tests/test_enrichment_api.py
T
2026-09-04 21:36:16 +02:00

67 lines
4.1 KiB
Python

"""Tests for the enrich business API endpoint."""
import json
import os
import sqlite3
import threading
import unittest
from http.client import HTTPConnection
from tempfile import TemporaryDirectory
from unittest.mock import patch
from app.main import create_server, hash_password
class EnrichmentApiTests(unittest.TestCase):
def setUp(self):
self.tmp = TemporaryDirectory()
os.environ["BOOTSTRAP_ADMIN_EMAIL"] = "enrich-owner@example.test"
os.environ["BOOTSTRAP_ADMIN_PASSWORD"] = "password"
self.server = create_server("127.0.0.1", 0, self.tmp.name + "/enrich.db")
self.thread = threading.Thread(target=self.server.serve_forever, daemon=True); self.thread.start()
self.conn = HTTPConnection("127.0.0.1", self.server.server_port, timeout=3); self.cookie = None
self.request("POST", "/api/v1/auth/login", {"email": "enrich-owner@example.test", "password": "password"})
def tearDown(self):
self.server.shutdown(); self.server.server_close(); self.thread.join(2); self.tmp.cleanup()
for key in ("BOOTSTRAP_ADMIN_EMAIL", "BOOTSTRAP_ADMIN_PASSWORD"):
os.environ.pop(key, None)
def request(self, method, path, payload=None):
headers = {"Content-Type": "application/json"}
if self.cookie: headers["Cookie"] = self.cookie
self.conn.request(method, path, json.dumps(payload).encode() if payload is not None else None, headers)
response = self.conn.getresponse(); cookie = response.getheader("Set-Cookie")
if cookie: self.cookie = cookie.split(";", 1)[0]
return response.status, json.loads(response.read() or b"{}")
def test_enrich_business_returns_website_domain_contacts(self):
status, business = self.request("POST", "/api/v1/businesses", {"name": "Enrich Co", "website": "https://enrich.example.test"})
self.assertEqual(status, 201)
scan = {"status": 200, "final_url": "https://enrich.example.test/", "redirect_chain": [], "body": b"<html><head><title>Enrich</title></head><body><h1>Enrich Co</h1><a href=\"mailto:hello@enrich.example.test\">hello@enrich.example.test</a></body></html>", "html": "<html><head><title>Enrich</title></head><body><h1>Enrich Co</h1><a href=\"mailto:hello@enrich.example.test\">hello@enrich.example.test</a></body></html>", "content_type": "text/html", "elapsed_ms": 15, "tls": True, "certificate_status": "valid"}
with patch("app.main.scan_website", return_value=scan), \
patch("app.enrichment.validate_url", side_effect=lambda url: url), \
patch("app.enrichment.normalize_registrable_domain", return_value="enrich.example.test"), \
patch("app.main.enrich_domain", return_value={"domain": "enrich.example.test", "status": "registered", "resolves": True}):
status, result = self.request("POST", f"/api/v1/businesses/{business['id']}/enrichment", {})
self.assertEqual(status, 200)
self.assertEqual(result["business_id"], business["id"])
self.assertEqual(result["website"]["status"], "working")
self.assertEqual(result["domain"]["status"], "registered")
self.assertTrue(any(c["value"] == "hello@enrich.example.test" for c in result["contacts"]))
def test_enrich_business_tenant_isolated(self):
status, business = self.request("POST", "/api/v1/businesses", {"name": "Tenant Co"})
self.assertEqual(status, 201)
other_hash, other_salt = hash_password("other-password")
db = sqlite3.connect(self.tmp.name + "/enrich.db")
db.execute("INSERT INTO organizations(id,name) VALUES(?,?)", ("other-tenant", "Other"))
db.execute("INSERT INTO users(organization_id,email,password_hash,password_salt,role) VALUES(?,?,?,?,?)", ("other-tenant", "other@example.test", other_hash, other_salt, "owner"))
db.commit(); db.close()
self.cookie = None
self.assertEqual(self.request("POST", "/api/v1/auth/login", {"email": "other@example.test", "password": "other-password"})[0], 200)
self.assertEqual(self.request("POST", f"/api/v1/businesses/{business['id']}/enrichment", {})[0], 404)
if __name__ == "__main__":
unittest.main()