#include #include #include "search/search.h" // ── Config loading ────────────────────────────────────────────────────────── TEST_CASE("Config: loads SERPAPI_KEY from postgres.toml", "[search][config]") { auto cfg = search::load_config("config/postgres.toml"); REQUIRE(!cfg.serpapi_key.empty()); REQUIRE(cfg.serpapi_key.size() > 20); // SHA-like key } TEST_CASE("Config: loads GEO_CODER_KEY from postgres.toml", "[search][config]") { auto cfg = search::load_config("config/postgres.toml"); REQUIRE(!cfg.geocoder_key.empty()); } TEST_CASE("Config: loads BIG_DATA_KEY from postgres.toml", "[search][config]") { auto cfg = search::load_config("config/postgres.toml"); REQUIRE(!cfg.bigdata_key.empty()); } TEST_CASE("Config: loads postgres URL", "[search][config]") { auto cfg = search::load_config("config/postgres.toml"); REQUIRE(cfg.postgres_url.find("supabase.com") != std::string::npos); } TEST_CASE("Config: loads supabase URL and service key", "[search][config]") { auto cfg = search::load_config("config/postgres.toml"); REQUIRE(cfg.supabase_url.find("supabase.co") != std::string::npos); REQUIRE(!cfg.supabase_service_key.empty()); } TEST_CASE("Config: missing file returns empty config", "[search][config]") { auto cfg = search::load_config("nonexistent.toml"); REQUIRE(cfg.serpapi_key.empty()); REQUIRE(cfg.postgres_url.empty()); } // ── Search validation (no network) ────────────────────────────────────────── TEST_CASE("Search: empty key returns error", "[search][validate]") { search::Config cfg; // all empty search::SearchOptions opts; opts.query = "plumbers"; auto res = search::search_google_maps(cfg, opts); REQUIRE(!res.error.empty()); REQUIRE(res.error.find("key") != std::string::npos); } TEST_CASE("Search: empty query returns error", "[search][validate]") { search::Config cfg; cfg.serpapi_key = "test_key"; search::SearchOptions opts; // empty query auto res = search::search_google_maps(cfg, opts); REQUIRE(!res.error.empty()); REQUIRE(res.error.find("query") != std::string::npos); }