diff --git a/tests/unittests/test_ai_client.c b/tests/unittests/test_ai_client.c index 4a40b0d4..516fcb7f 100644 --- a/tests/unittests/test_ai_client.c +++ b/tests/unittests/test_ai_client.c @@ -614,6 +614,24 @@ test_ai_set_provider_setting(void** state) assert_null(ai_get_provider_setting("p_set_settings", "nonexistent_setting")); } +void +test_ai_set_provider_setting_reserved_key(void** state) +{ + ai_add_provider("p_reserved_keys", "https://example.test/rk/"); + + /* Reserved payload keys are rejected (would duplicate fixed fields) */ + assert_false(ai_set_provider_setting("p_reserved_keys", "model", "x")); + assert_false(ai_set_provider_setting("p_reserved_keys", "messages", "[]")); + assert_false(ai_set_provider_setting("p_reserved_keys", "stream", "true")); + assert_null(ai_get_provider_setting("p_reserved_keys", "model")); + + /* Ordinary keys still work */ + assert_true(ai_set_provider_setting("p_reserved_keys", "temperature", "0.7")); + auto_gchar gchar* temp = ai_get_provider_setting("p_reserved_keys", "temperature"); + assert_non_null(temp); + assert_string_equal("0.7", temp); +} + void test_ai_get_provider_setting(void** state) { @@ -919,22 +937,22 @@ test_ai_parse_response_openai_content(void** state) } void -test_ai_parse_response_perplexity_text(void** state) +test_ai_parse_response_legacy_text_format_unsupported(void** state) { + /* Legacy Perplexity /v1/agent format: "content" is an array, not a string. + * Dropped with the chat-completions alignment, so parsing yields NULL. */ const gchar* json = "{\"output\":[{\"content\":[{\"text\":\"Search result\",\"type\":\"output_text\"}]}]}"; - auto_gchar gchar* out = ai_parse_response(json); - assert_non_null(out); - assert_string_equal("Search result", out); + assert_null(ai_parse_response(json)); } void -test_ai_parse_response_text_preferred_over_content(void** state) +test_ai_parse_response_content_preferred_over_text(void** state) { - /* When both formats are present, "text" wins (Perplexity path tried first). */ + /* Chat-completions "content" is extracted; a stray "text" field is ignored. */ const gchar* json = "{\"text\":\"from text field\",\"content\":\"from content field\"}"; auto_gchar gchar* out = ai_parse_response(json); assert_non_null(out); - assert_string_equal("from text field", out); + assert_string_equal("from content field", out); } void diff --git a/tests/unittests/test_ai_client.h b/tests/unittests/test_ai_client.h index e99c355d..6bf2062e 100644 --- a/tests/unittests/test_ai_client.h +++ b/tests/unittests/test_ai_client.h @@ -43,6 +43,7 @@ void test_ai_providers_find_case_insensitive(void** state); void test_ai_set_provider_default_model(void** state); void test_ai_get_provider_default_model(void** state); void test_ai_set_provider_setting(void** state); +void test_ai_set_provider_setting_reserved_key(void** state); void test_ai_get_provider_setting(void** state); /* Model caching tests */ void test_ai_models_are_fresh_initial(void** state); @@ -64,8 +65,8 @@ int ai_client_teardown_with_prefs(void** state); /* Chat response parser tests (ai_parse_response) */ void test_ai_parse_response_openai_content(void** state); -void test_ai_parse_response_perplexity_text(void** state); -void test_ai_parse_response_text_preferred_over_content(void** state); +void test_ai_parse_response_legacy_text_format_unsupported(void** state); +void test_ai_parse_response_content_preferred_over_text(void** state); void test_ai_parse_response_escaped_quote(void** state); void test_ai_parse_response_newline_escape(void** state); void test_ai_parse_response_empty_content(void** state); diff --git a/tests/unittests/unittests.c b/tests/unittests/unittests.c index ca1a7d1e..cf01788e 100644 --- a/tests/unittests/unittests.c +++ b/tests/unittests/unittests.c @@ -752,6 +752,7 @@ main(int argc, char* argv[]) cmocka_unit_test_setup_teardown(test_ai_set_provider_default_model, ai_client_setup, ai_client_teardown), cmocka_unit_test_setup_teardown(test_ai_get_provider_default_model, ai_client_setup, ai_client_teardown), cmocka_unit_test_setup_teardown(test_ai_set_provider_setting, ai_client_setup, ai_client_teardown), + cmocka_unit_test_setup_teardown(test_ai_set_provider_setting_reserved_key, ai_client_setup, ai_client_teardown), cmocka_unit_test_setup_teardown(test_ai_get_provider_setting, ai_client_setup, ai_client_teardown), /* Model caching tests */ cmocka_unit_test_setup_teardown(test_ai_models_are_fresh_initial, ai_client_setup, ai_client_teardown), @@ -774,8 +775,8 @@ main(int argc, char* argv[]) cmocka_unit_test(test_ai_json_escape_backslash_quote), /* Chat response parser */ cmocka_unit_test(test_ai_parse_response_openai_content), - cmocka_unit_test(test_ai_parse_response_perplexity_text), - cmocka_unit_test(test_ai_parse_response_text_preferred_over_content), + cmocka_unit_test(test_ai_parse_response_legacy_text_format_unsupported), + cmocka_unit_test(test_ai_parse_response_content_preferred_over_text), cmocka_unit_test(test_ai_parse_response_escaped_quote), cmocka_unit_test(test_ai_parse_response_newline_escape), cmocka_unit_test(test_ai_parse_response_empty_content),