deploy ProspectOS workspace v5 final
This commit is contained in:
+89
-1
@@ -201,6 +201,92 @@ class BrowserOnlyAppTests(unittest.TestCase):
|
||||
self.assertIn("Services", body)
|
||||
self.assertIn("images.unsplash.com", body)
|
||||
self.assertIn("https://images.unsplash.com", response.getheader("Content-Security-Policy"))
|
||||
self.assertIn("frame-ancestors 'none'", response.getheader("Content-Security-Policy"))
|
||||
|
||||
def test_mockup_editor_creates_a_new_version_and_keeps_original(self):
|
||||
conn = server.db()
|
||||
conn.execute("INSERT INTO prospects(name,domain,category,discovered_at) VALUES(?,?,?,?)", ("Brightspark Electrical", "maps:bright-editor", "electrician", server.now()))
|
||||
conn.commit(); conn.close()
|
||||
status, original = self.request("POST", "/api/prospects/1/mockup", {"mode": "multipage"})
|
||||
self.assertEqual(status, 201)
|
||||
self.assertEqual(original.get("version"), None) # v1 rows remain backwards-compatible
|
||||
conn = server.db()
|
||||
for key, value in (("AI_PROVIDER", "nous"), ("AI_MODEL", "meituan/longcat-2.0:free"), ("AI_API_KEY", "test-key")):
|
||||
conn.execute("INSERT INTO settings(key,value,updated_at) VALUES(?,?,?)", (key, value, server.now()))
|
||||
conn.commit(); conn.close()
|
||||
ai_response = {"choices": [{"message": {"content": json.dumps({
|
||||
"tagline": "Powerful work. Presented with confidence.",
|
||||
"intro": "A sharper digital home for Brightspark Electrical.",
|
||||
"services": [{"name": "Electrical services", "description": "A clear way to understand the work available."}],
|
||||
"about": "A refined concept based on the public business listing.",
|
||||
"cta": "Let’s make the next step easy.",
|
||||
"hero_image": server.STOCK_IMAGE_LIBRARY["electric"][0],
|
||||
"gallery_image": server.STOCK_IMAGE_LIBRARY["electric"][1],
|
||||
})}}]}
|
||||
with patch("api.server.http_json", return_value=ai_response) as request:
|
||||
status, edited = self.request("POST", f"/api/mockups/{original['id']}/edit", {"instruction": "Make the whole site darker and put more emphasis on services.", "page": "all"})
|
||||
self.assertEqual(status, 201)
|
||||
self.assertEqual(edited["version"], 2)
|
||||
self.assertEqual(edited["parent_id"], original["id"])
|
||||
self.assertEqual(edited["mode"], "multipage")
|
||||
self.assertIn("Applied your request", edited["change_summary"])
|
||||
self.assertIn("max_tokens", request.call_args.args[2])
|
||||
self.assertEqual(request.call_args.args[2]["max_tokens"], 1800)
|
||||
self.conn.request("GET", "/mockups/" + edited["token"] + "/services?embed=1")
|
||||
response = self.conn.getresponse(); body = response.read().decode("utf-8")
|
||||
self.assertEqual(response.status, 200)
|
||||
self.assertIn("frame-ancestors 'self'", response.getheader("Content-Security-Policy"))
|
||||
self.assertIn("--paper:#091321", body)
|
||||
self.assertIn("Electrical services", body)
|
||||
self.conn.request("GET", "/mockups/" + edited["token"])
|
||||
response = self.conn.getresponse(); edited_home = response.read().decode("utf-8")
|
||||
self.assertEqual(response.status, 200)
|
||||
self.assertIn("Powerful work", edited_home)
|
||||
self.conn.request("GET", "/mockups/" + original["token"] + "/services")
|
||||
response = self.conn.getresponse(); original_body = response.read().decode("utf-8")
|
||||
self.assertEqual(response.status, 200)
|
||||
self.assertIn("Brightspark Electrical", original_body)
|
||||
status, metadata = self.request("GET", f"/api/mockups/{edited['id']}")
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual(metadata["version"], 2)
|
||||
status, listed = self.request("GET", "/api/prospects/1/mockups")
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual([item["version"] for item in listed["items"]], [2, 1])
|
||||
|
||||
def test_multipage_ai_uses_compact_content_and_renders_all_pages(self):
|
||||
conn = server.db()
|
||||
conn.execute("INSERT INTO prospects(name,domain,category,discovered_at) VALUES(?,?,?,?)", ("Brightspark Electrical", "maps:bright-ai", "electrician", server.now()))
|
||||
for key, value in (("AI_PROVIDER", "nous"), ("AI_MODEL", "meituan/longcat-2.0:free"), ("AI_API_KEY", "test-key")):
|
||||
conn.execute("INSERT INTO settings(key,value,updated_at) VALUES(?,?,?)", (key, value, server.now()))
|
||||
conn.commit(); conn.close()
|
||||
response = {"choices": [{"message": {"content": json.dumps({
|
||||
"tagline": "Powerful work. Presented with clarity.",
|
||||
"intro": "A considered digital home for Brightspark Electrical.",
|
||||
"services": [{"name": "Electrical services", "description": "A clear way to understand the work available."}],
|
||||
"about": "A refined concept grounded in the public business listing.",
|
||||
"cta": "Let’s make the next step easy.",
|
||||
"hero_image": server.STOCK_IMAGE_LIBRARY["electric"][0],
|
||||
"gallery_image": server.STOCK_IMAGE_LIBRARY["electric"][1],
|
||||
})}}]}
|
||||
with patch("api.server.http_json", return_value=response) as request:
|
||||
status, created = self.request("POST", "/api/prospects/1/mockup", {"mode": "multipage"})
|
||||
self.assertEqual(status, 201)
|
||||
self.assertEqual(created["generation_source"], "ai")
|
||||
self.assertEqual({item["slug"] for item in created["pages"]}, {"home", "services", "about", "contact"})
|
||||
payload = request.call_args.args[2]
|
||||
self.assertEqual(payload["max_tokens"], 1800)
|
||||
self.assertNotIn("pages", json.dumps(payload["messages"]))
|
||||
stored = server.db().execute("SELECT pages_json FROM mockups WHERE id=?", (created["id"],)).fetchone()
|
||||
pages = json.loads(stored[0])
|
||||
self.assertIn("Powerful work", pages["home"])
|
||||
self.assertTrue(all("Brightspark Electrical" in html and "@keyframes" in html and "<footer" in html for html in pages.values()))
|
||||
|
||||
def test_onepage_mockup_uses_in_page_navigation(self):
|
||||
html = server.premium_render_pages({"name": "Acme", "category": "plumber"}, mode="onepage")["home"]
|
||||
self.assertIn('href="#services"', html)
|
||||
self.assertIn('id="services"', html)
|
||||
self.assertIn('id="about"', html)
|
||||
self.assertIn('id="contact"', html)
|
||||
|
||||
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"}]}'
|
||||
@@ -314,18 +400,20 @@ class BrowserOnlyAppTests(unittest.TestCase):
|
||||
status, body = self.request("POST", "/api/settings", {
|
||||
"browser_use": {"enabled": True, "max_steps": 22, "timeout_seconds": 900, "llm_timeout_seconds": 120},
|
||||
"maps": {"request_timeout_seconds": 1800, "poll_seconds": 4, "max_depth": 3},
|
||||
"limits": {"website_scan_timeout_seconds": 15},
|
||||
"limits": {"website_scan_timeout_seconds": 15, "ai_mockup_timeout_seconds": 75},
|
||||
})
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual(body["browser_use"]["timeout_seconds"], 900)
|
||||
self.assertEqual(body["maps"]["request_timeout_seconds"], 1800)
|
||||
self.assertEqual(body["limits"]["website_scan_timeout_seconds"], 15)
|
||||
self.assertEqual(body["limits"]["ai_mockup_timeout_seconds"], 75)
|
||||
status, settings = self.request("GET", "/api/settings")
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual(settings["browser_use"]["max_steps"], 22)
|
||||
self.assertEqual(settings["browser_use"]["llm_timeout_seconds"], 120)
|
||||
self.assertEqual(settings["maps"]["poll_seconds"], 4.0)
|
||||
self.assertEqual(settings["maps"]["max_depth"], 3)
|
||||
self.assertEqual(settings["limits"]["ai_mockup_timeout_seconds"], 75)
|
||||
self.assertEqual(server.browser_use_limits(), (22, 900))
|
||||
self.assertEqual(server.website_scan_timeout_seconds(), 15)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user