From 3fc19112c9219b3fd6d4608757231573c41f6b66 Mon Sep 17 00:00:00 2001 From: "jabber.developer2" Date: Wed, 11 Feb 2026 15:19:58 +0300 Subject: [PATCH] test(disco): add comprehensive XEP-0030 functional tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add 7 new tests for /disco command: - disco_items_to_jid: query items to specific JID - disco_info_empty_result: handle empty disco#info response - disco_info_multiple_identities: multiple identity elements - disco_info_without_name: identity without optional name attr - disco_items_without_name: items without optional name attr - disco_info_service_unavailable: error handling for info - disco_items_error_handling: error handling for items (XEP-0030 ยง7) The disco_items_error_handling test documents a bug where disco#items errors are silently ignored (unlike disco#info which handles them). This violates XEP-0030 Section 7 which requires error feedback to user. --- tests/functionaltests/functionaltests.c | 7 + tests/functionaltests/test_disco.c | 195 ++++++++++++++++++++++++ tests/functionaltests/test_disco.h | 7 + 3 files changed, 209 insertions(+) diff --git a/tests/functionaltests/functionaltests.c b/tests/functionaltests/functionaltests.c index ad2f25eb..0227df82 100644 --- a/tests/functionaltests/functionaltests.c +++ b/tests/functionaltests/functionaltests.c @@ -187,6 +187,13 @@ main(int argc, char* argv[]) PROF_FUNC_TEST(disco_items_shows_items), PROF_FUNC_TEST(disco_items_empty_result), PROF_FUNC_TEST(disco_requires_connection), + PROF_FUNC_TEST(disco_items_to_jid), + PROF_FUNC_TEST(disco_info_empty_result), + PROF_FUNC_TEST(disco_info_multiple_identities), + PROF_FUNC_TEST(disco_info_without_name), + PROF_FUNC_TEST(disco_items_without_name), + PROF_FUNC_TEST(disco_info_service_unavailable), + PROF_FUNC_TEST(disco_items_error_handling), }; /* ============================================================ diff --git a/tests/functionaltests/test_disco.c b/tests/functionaltests/test_disco.c index dfafdc09..c73a3d43 100644 --- a/tests/functionaltests/test_disco.c +++ b/tests/functionaltests/test_disco.c @@ -248,3 +248,198 @@ disco_requires_connection(void **state) prof_input("/disco items"); assert_true(prof_output_exact("You are not currently connected.")); } + +void +disco_items_to_jid(void **state) +{ + /* + * Test that /disco items queries the specified JID. + */ + stbbr_for_query("http://jabber.org/protocol/disco#items", + "" + "" + "" + "" + "" + "" + ); + + prof_connect(); + + prof_input("/disco items conference.localhost"); + + prof_timeout(10); + /* Verify request was sent to specified JID */ + assert_true(stbbr_received( + "" + "" + "" + )); + + assert_true(prof_output_exact("Service discovery items for conference.localhost:")); + assert_true(prof_output_regex("room1@conference.localhost.*General Chat")); + prof_timeout_reset(); +} + +void +disco_info_empty_result(void **state) +{ + /* + * Test that /disco info handles empty result (no identities/features). + * This can happen with minimal server configurations. + */ + stbbr_for_query("http://jabber.org/protocol/disco#info", + "" + "" + "" + ); + + prof_connect(); + + prof_input("/disco info minimal.localhost"); + + prof_timeout(10); + /* Verify request was sent */ + assert_true(stbbr_received( + "" + "" + "" + )); + /* Empty result should not crash and should not show "Service discovery info" */ + prof_timeout_reset(); +} + +void +disco_info_multiple_identities(void **state) +{ + /* + * Test that /disco info displays multiple identities correctly. + * Entities can have multiple identities (e.g., server + gateway). + */ + stbbr_for_query("http://jabber.org/protocol/disco#info", + "" + "" + "" + "" + "" + "" + "" + ); + + prof_connect(); + + prof_input("/disco info gateway.localhost"); + + prof_timeout(10); + assert_true(prof_output_exact("Service discovery info for gateway.localhost")); + assert_true(prof_output_exact("Identities")); + assert_true(prof_output_regex("IRC Gateway.*irc.*gateway")); + assert_true(prof_output_regex("Room Directory.*chatroom.*directory")); + assert_true(prof_output_regex("Ad-Hoc Commands.*command-node.*automation")); + prof_timeout_reset(); +} + +void +disco_info_without_name(void **state) +{ + /* + * Test that /disco info handles identity without name attribute. + * Per XEP-0030: name is OPTIONAL, only category and type are REQUIRED. + */ + stbbr_for_query("http://jabber.org/protocol/disco#info", + "" + "" + "" + "" + "" + ); + + prof_connect(); + + prof_input("/disco info"); + + prof_timeout(10); + assert_true(prof_output_exact("Service discovery info for localhost")); + assert_true(prof_output_exact("Identities")); + /* Should show type and category even without name */ + assert_true(prof_output_regex("im.*server")); + prof_timeout_reset(); +} + +void +disco_items_without_name(void **state) +{ + /* + * Test that /disco items handles items without name attribute. + * Per XEP-0030: name is OPTIONAL for items, only jid is REQUIRED. + */ + stbbr_for_query("http://jabber.org/protocol/disco#items", + "" + "" + "" + "" + "" + "" + "" + ); + + prof_connect(); + + prof_input("/disco items"); + + prof_timeout(10); + assert_true(prof_output_exact("Service discovery items for localhost:")); + /* Items without name should still display their JID */ + assert_true(prof_output_exact("conference.localhost")); + assert_true(prof_output_regex("pubsub.localhost.*PubSub Service")); + assert_true(prof_output_exact("upload.localhost")); + prof_timeout_reset(); +} + +void +disco_info_service_unavailable(void **state) +{ + /* + * Test error handling when disco info returns service-unavailable. + */ + stbbr_for_query("http://jabber.org/protocol/disco#info", + "" + "" + "" + "" + "" + ); + + prof_connect(); + + prof_input("/disco info offline.localhost"); + + prof_timeout(10); + assert_true(prof_output_regex("Service discovery failed.*service-unavailable")); + prof_timeout_reset(); +} + +void +disco_items_error_handling(void **state) +{ + /* + * Test that /disco items displays error responses to user. + * Per XEP-0030 Section 7: errors like service-unavailable must be shown. + */ + stbbr_for_query("http://jabber.org/protocol/disco#items", + "" + "" + "" + "" + "" + ); + + prof_connect(); + + prof_input("/disco items broken.localhost"); + + prof_timeout(10); + /* Per XEP-0030, error should be displayed to user */ + assert_true(prof_output_regex("Service discovery failed.*service-unavailable")); + prof_timeout_reset(); +} diff --git a/tests/functionaltests/test_disco.h b/tests/functionaltests/test_disco.h index 4b98ed55..fbd7d0c2 100644 --- a/tests/functionaltests/test_disco.h +++ b/tests/functionaltests/test_disco.h @@ -11,3 +11,10 @@ void disco_info_not_found(void **state); void disco_items_shows_items(void **state); void disco_items_empty_result(void **state); void disco_requires_connection(void **state); +void disco_items_to_jid(void **state); +void disco_info_empty_result(void **state); +void disco_info_multiple_identities(void **state); +void disco_info_without_name(void **state); +void disco_items_without_name(void **state); +void disco_info_service_unavailable(void **state); +void disco_items_error_handling(void **state);