deploy Nous v19 update
This commit is contained in:
@@ -9,6 +9,7 @@ from http.client import HTTPConnection
|
||||
from unittest.mock import patch
|
||||
|
||||
from api import server
|
||||
from api import browser_investigator
|
||||
|
||||
|
||||
class BrowserOnlyAppTests(unittest.TestCase):
|
||||
@@ -56,6 +57,8 @@ class BrowserOnlyAppTests(unittest.TestCase):
|
||||
self.assertEqual(status, 202)
|
||||
first = self.wait_for_run(first["id"])
|
||||
self.assertEqual(first["added"], 2)
|
||||
saved = self.request("GET", "/api/prospects")[1]["items"]
|
||||
self.assertTrue(all(item["search_category"] == "plumbers" for item in saved))
|
||||
status, second = self.request("POST", "/api/discover", {"category": "plumbers", "keywords": "plumbing", "location": "Cape Town", "max_results": 5})
|
||||
self.assertEqual(status, 202)
|
||||
second = self.wait_for_run(second["id"])
|
||||
@@ -153,6 +156,48 @@ class BrowserOnlyAppTests(unittest.TestCase):
|
||||
saved = server.db().execute("SELECT ai_probability,ai_recommendation,ai_reasoning FROM prospects WHERE id=1").fetchone()
|
||||
self.assertEqual(tuple(saved), (84.0, "contact", "Active business with a clear website opportunity."))
|
||||
|
||||
def test_browser_investigator_normalises_and_filters_candidates(self):
|
||||
raw = '{"candidates":[{"url":"https://www.acme.co.za/about","confidence":88,"evidence":["name match"]},{"url":"https://facebook.com/acme","confidence":99},{"domain":"other.co.za","confidence":"42","evidence":"not a list"}]}'
|
||||
candidates = browser_investigator._parse_agent_result(raw)
|
||||
self.assertEqual([item["domain"] for item in candidates], ["acme.co.za", "other.co.za"])
|
||||
self.assertEqual(candidates[0]["confidence"], 88)
|
||||
self.assertEqual(candidates[1]["evidence"], [])
|
||||
|
||||
def test_browser_website_candidates_can_be_found_and_accepted(self):
|
||||
conn = server.db()
|
||||
conn.execute("INSERT INTO prospects(name,domain,category,address,discovered_at) VALUES(?,?,?,?,?)", ("Acme Plumbing", "maps:abc", "plumber", "Cape Town", server.now()))
|
||||
conn.commit(); conn.close()
|
||||
found = [{"url": "https://acmeplumbing.co.za", "domain": "acmeplumbing.co.za", "confidence": 91, "evidence": ["name match", "location match"]}]
|
||||
with patch("api.server.investigate_websites", return_value=found):
|
||||
status, body = self.request("POST", "/api/prospects/1/website-candidates", {})
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual(body["count"], 1)
|
||||
candidate_id = body["items"][0]["id"]
|
||||
status, body = self.request("GET", "/api/prospects/1/website-candidates")
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual(body["items"][0]["domain"], "acmeplumbing.co.za")
|
||||
status, body = self.request("PATCH", f"/api/prospects/1/website-candidates/{candidate_id}", {"status": "accepted"})
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual(body["candidate"]["status"], "accepted")
|
||||
self.assertEqual(body["prospect"]["domain"], "acmeplumbing.co.za")
|
||||
self.assertEqual(body["prospect"]["website"], "https://acmeplumbing.co.za")
|
||||
|
||||
def test_email_draft_returns_structured_review_notes(self):
|
||||
conn = server.db()
|
||||
conn.execute("INSERT INTO prospects(name,domain,search_category,category,address,maps_url,website_status,emails,opportunity_score,score_reasons,discovered_at) VALUES(?,?,?,?,?,?,?,?,?,?,?)", ("Acme Plumbing", "maps:abc", "plumbers", "Plumber", "Cape Town", "https://maps.example/acme", "no_detected_website", "acme@gmail.com", 88, '["No detected website","Public email found"]', server.now()))
|
||||
for key, value in (("AI_PROVIDER", "custom"), ("AI_BASE_URL", "https://ai.example/v1"), ("AI_MODEL", "test-model"), ("AI_API_KEY", "test-key")):
|
||||
conn.execute("INSERT INTO settings(key,value,updated_at) VALUES(?,?,?)", (key, value, server.now()))
|
||||
conn.commit(); conn.close()
|
||||
content = json.dumps({"subject": "A website idea for Acme Plumbing", "message": "Good day Acme Plumbing,\n\nI noticed your public listing does not show a dedicated website. We can help with a professional online presence. Would you like me to send a few details?\n\nKind regards", "rationale": "Uses the missing-website signal and the supplied offer.", "recommended_offer": "Gold Plus hosting and a free one-page website", "unknowns": ["Confirm the preferred contact person"], "evidence_used": ["prospect_record", "public_maps_listing", "public_email_listing"], "follow_up": "Confirm the offer and recipient before sending."})
|
||||
with patch("api.server.http_json", return_value={"choices": [{"message": {"content": content}}]}):
|
||||
status, body = self.request("POST", "/api/prospects/1/message", {"offer": "Gold Plus hosting at R119/month with a free one-page website."})
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual(body["unknowns"], ["Confirm the preferred contact person"])
|
||||
self.assertEqual(body["evidence_used"], ["prospect_record", "public_maps_listing", "public_email_listing"])
|
||||
saved = server.db().execute("SELECT ai_unknowns,ai_evidence_ids,ai_follow_up FROM prospects WHERE id=1").fetchone()
|
||||
self.assertEqual(json.loads(saved[0]), body["unknowns"])
|
||||
self.assertEqual(json.loads(saved[1]), body["evidence_used"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user