diff options
Diffstat (limited to 'protocols/Telegram/tdlib/td/test')
21 files changed, 596 insertions, 190 deletions
diff --git a/protocols/Telegram/tdlib/td/test/CMakeLists.txt b/protocols/Telegram/tdlib/td/test/CMakeLists.txt index 2a140a3af7..da7d45c3f2 100644 --- a/protocols/Telegram/tdlib/td/test/CMakeLists.txt +++ b/protocols/Telegram/tdlib/td/test/CMakeLists.txt @@ -2,7 +2,6 @@ if ((CMAKE_MAJOR_VERSION LESS 3) OR (CMAKE_VERSION VERSION_LESS "3.0.2")) message(FATAL_ERROR "CMake >= 3.0.2 is required") endif() -#SOURCE SETS set(TD_TEST_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/country_info.cpp ${CMAKE_CURRENT_SOURCE_DIR}/db.cpp @@ -36,11 +35,10 @@ set(TESTS_MAIN #target_link_libraries(all_tests PRIVATE tdcore tdclient) if (NOT CMAKE_CROSSCOMPILING OR EMSCRIPTEN) - #Tests if (OPENSSL_FOUND) add_executable(test-crypto EXCLUDE_FROM_ALL crypto.cpp) target_include_directories(test-crypto SYSTEM PRIVATE ${OPENSSL_INCLUDE_DIR}) - target_link_libraries(test-crypto PRIVATE ${OPENSSL_CRYPTO_LIBRARY} ${CMAKE_DL_LIBS} ${ZLIB_LIBRARIES} tdutils tdcore) + target_link_libraries(test-crypto PRIVATE ${OPENSSL_CRYPTO_LIBRARY} ${CMAKE_DL_LIBS} ${ZLIB_LIBRARIES} tdutils tdmtproto) if (WIN32) if (MINGW) diff --git a/protocols/Telegram/tdlib/td/test/country_info.cpp b/protocols/Telegram/tdlib/td/test/country_info.cpp index 0a9e3c26b6..2fe59de245 100644 --- a/protocols/Telegram/tdlib/td/test/country_info.cpp +++ b/protocols/Telegram/tdlib/td/test/country_info.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/protocols/Telegram/tdlib/td/test/crypto.cpp b/protocols/Telegram/tdlib/td/test/crypto.cpp index f6657747f1..0de3d464c3 100644 --- a/protocols/Telegram/tdlib/td/test/crypto.cpp +++ b/protocols/Telegram/tdlib/td/test/crypto.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/protocols/Telegram/tdlib/td/test/data.cpp b/protocols/Telegram/tdlib/td/test/data.cpp index c53658d243..e0516dd16d 100644 --- a/protocols/Telegram/tdlib/td/test/data.cpp +++ b/protocols/Telegram/tdlib/td/test/data.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/protocols/Telegram/tdlib/td/test/data.h b/protocols/Telegram/tdlib/td/test/data.h index 79093e1996..99e1936227 100644 --- a/protocols/Telegram/tdlib/td/test/data.h +++ b/protocols/Telegram/tdlib/td/test/data.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/protocols/Telegram/tdlib/td/test/db.cpp b/protocols/Telegram/tdlib/td/test/db.cpp index 9e56e331f4..4fe75c15f8 100644 --- a/protocols/Telegram/tdlib/td/test/db.cpp +++ b/protocols/Telegram/tdlib/td/test/db.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/protocols/Telegram/tdlib/td/test/fuzz_url.cpp b/protocols/Telegram/tdlib/td/test/fuzz_url.cpp index cd7af58a77..f29e7c1295 100644 --- a/protocols/Telegram/tdlib/td/test/fuzz_url.cpp +++ b/protocols/Telegram/tdlib/td/test/fuzz_url.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/protocols/Telegram/tdlib/td/test/http.cpp b/protocols/Telegram/tdlib/td/test/http.cpp index e3d2301f6e..5deca6d0c9 100644 --- a/protocols/Telegram/tdlib/td/test/http.cpp +++ b/protocols/Telegram/tdlib/td/test/http.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -71,13 +71,13 @@ static td::string gen_http_content() { return td::rand_string(std::numeric_limits<char>::min(), std::numeric_limits<char>::max(), len); } -static td::string make_http_query(td::string content, bool is_json, bool is_chunked, bool is_gzip, double gzip_k = 5, - td::string zip_override = td::string()) { +static td::string make_http_query(td::string content, td::string content_type, bool is_chunked, bool is_gzip, + double gzip_k = 5, td::string zip_override = td::string()) { td::HttpHeaderCreator hc; hc.init_post("/"); hc.add_header("jfkdlsahhjk", td::rand_string('a', 'z', td::Random::fast(1, 2000))); - if (is_json) { - hc.add_header("content-type", "application/json"); + if (!content_type.empty()) { + hc.add_header("content-type", content_type); } if (is_gzip) { td::BufferSlice zip; @@ -105,7 +105,7 @@ static td::string make_http_query(td::string content, bool is_json, bool is_chun static td::string rand_http_query(td::string content) { bool is_chunked = td::Random::fast_bool(); bool is_gzip = td::Random::fast_bool(); - return make_http_query(std::move(content), false, is_chunked, is_gzip); + return make_http_query(std::move(content), td::string(), is_chunked, is_gzip); } static td::string join(const td::vector<td::string> &v) { @@ -145,8 +145,16 @@ TEST(Http, reader) { #pragma clang diagnostic ignored "-Wunknown-warning-option" #pragma clang diagnostic ignored "-Wself-move" #endif +#if TD_GCC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Wself-move" +#endif a = std::move(a); b = std::move(b); +#if TD_GCC +#pragma GCC diagnostic pop +#endif #if TD_CLANG #pragma clang diagnostic pop #endif @@ -220,7 +228,7 @@ TEST(Http, gzip_bomb) { .as_slice() .str(); - auto query = make_http_query("", false, false, true, 0.01, gzip_bomb_str); + auto query = make_http_query(td::string(), td::string(), false, true, 0.01, gzip_bomb_str); auto parts = td::rand_split(query); td::ChainBufferWriter input_writer; auto input = input_writer.extract_reader(); @@ -248,7 +256,7 @@ TEST(Http, gzip) { td::HttpReader reader; reader.init(&input, 0, 0); - auto query = make_http_query("", true, false, true, 0.01, gzip_str); + auto query = make_http_query(td::string(), "application/json", false, true, 0.01, gzip_str); input_writer.append(query); input.sync_with_writer(); @@ -442,7 +450,7 @@ TEST(Http, gzip_bomb_with_limit) { gzip_bomb_str = sink.result()->move_as_buffer_slice().as_slice().str(); } - auto query = make_http_query("", false, false, true, 0.01, gzip_bomb_str); + auto query = make_http_query(td::string(), td::string(), false, true, 0.01, gzip_bomb_str); auto parts = td::rand_split(query); td::ChainBufferWriter input_writer; auto input = input_writer.extract_reader(); @@ -464,6 +472,67 @@ TEST(Http, gzip_bomb_with_limit) { ASSERT_TRUE(ok); } +TEST(Http, partial_form_data) { + td::ChainBufferWriter input_writer; + auto input = input_writer.extract_reader(); + + td::HttpReader reader; + reader.init(&input, 0, 0); + + auto query = + make_http_query("------abcd\r\nCo", "Content-Type: multipart/form-data; boundary=----abcd", false, false); + input_writer.append(query); + input.sync_with_writer(); + + td::HttpQuery q; + auto r_state = reader.read_next(&q); + ASSERT_TRUE(r_state.is_error()); + ASSERT_EQ(400, r_state.error().code()); +} + +TEST(Http, form_data) { + td::ChainBufferWriter input_writer; + auto input = input_writer.extract_reader(); + + td::HttpReader reader; + reader.init(&input, 0, 1); + + auto query = make_http_query( + "------abcd\r\n" + "Content-Disposition: form-data; name=\"text\"\r\n" + "\r\n" + "some text\r\n" + "------abcd\r\n" + "Content-Disposition: form-data; name=\"text2\"\r\n" + "\r\n" + "some text\r\n" + "more text\r\n" + "------abcd\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"file.txt\"\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "File content\r\n" + "------abcd--", + "Content-Type: multipart/form-data; boundary=----abcd", false, false); + input_writer.append(query); + input.sync_with_writer(); + + td::HttpQuery q; + auto r_state = reader.read_next(&q); + ASSERT_TRUE(r_state.is_ok()); + ASSERT_EQ(2u, q.args_.size()); + ASSERT_EQ("text", q.args_[0].first); + ASSERT_EQ("some text", q.args_[0].second); + ASSERT_EQ("text2", q.args_[1].first); + ASSERT_EQ("some text\r\nmore text", q.args_[1].second); + ASSERT_EQ(1u, q.files_.size()); + ASSERT_EQ("file.txt", q.files_[0].name); + ASSERT_EQ("file", q.files_[0].field_name); + ASSERT_EQ("text/plain", q.files_[0].content_type); + ASSERT_EQ(12, q.files_[0].size); + ASSERT_TRUE(!q.files_[0].temp_file_name.empty()); +} + #if TD_DARWIN_WATCH_OS struct Baton { std::mutex mutex; diff --git a/protocols/Telegram/tdlib/td/test/link.cpp b/protocols/Telegram/tdlib/td/test/link.cpp index 67b81c1354..6403b98962 100644 --- a/protocols/Telegram/tdlib/td/test/link.cpp +++ b/protocols/Telegram/tdlib/td/test/link.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -79,6 +79,8 @@ TEST(Link, check_link) { check_link("http://..", "http://../"); check_link("..", "http://../"); check_link("https://.", ""); + check_link("tOnSiTe://google", "tonsite://google/"); + check_link("tOnSiTe://google.ton?t=1#we", "tonsite://google.ton?t=1#we"); } static td::td_api::object_ptr<td::td_api::InternalLinkType> get_internal_link_type_object( @@ -97,6 +99,10 @@ static void parse_internal_link(const td::string &url, td::td_api::object_ptr<td ASSERT_STREQ(url + ' ' + to_string(expected), url + ' ' + to_string(object)); for (auto is_internal : {true, false}) { + if (!is_internal && expected->get_id() == td::td_api::internalLinkTypeChatBoost::ID) { + // external chat boost links must be generated with getChatBoostLink + continue; + } if (!is_internal && expected->get_id() == td::td_api::internalLinkTypeMessage::ID) { // external message links must be generated with getMessageLink continue; @@ -160,11 +166,12 @@ static void parse_internal_link(const td::string &url, td::td_api::object_ptr<td static auto chat_administrator_rights(bool can_manage_chat, bool can_change_info, bool can_post_messages, bool can_edit_messages, bool can_delete_messages, bool can_invite_users, bool can_restrict_members, bool can_pin_messages, bool can_manage_topics, - bool can_promote_members, bool can_manage_video_chats, bool is_anonymous) { + bool can_promote_members, bool can_manage_video_chats, bool can_post_stories, + bool can_edit_stories, bool can_delete_stories, bool is_anonymous) { return td::td_api::make_object<td::td_api::chatAdministratorRights>( can_manage_chat, can_change_info, can_post_messages, can_edit_messages, can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages, can_manage_topics, can_promote_members, can_manage_video_chats, - is_anonymous); + can_post_stories, can_edit_stories, can_delete_stories, is_anonymous); } static auto target_chat_chosen(bool allow_users, bool allow_bots, bool allow_groups, bool allow_channels) { @@ -214,10 +221,22 @@ static auto bot_start_in_group(const td::string &bot_username, const td::string std::move(administrator_rights)); } +static auto business_chat(const td::string &link_name) { + return td::td_api::make_object<td::td_api::internalLinkTypeBusinessChat>(link_name); +} + +static auto buy_stars(td::int64 star_count, const td::string &purpose) { + return td::td_api::make_object<td::td_api::internalLinkTypeBuyStars>(star_count, purpose); +} + static auto change_phone_number() { return td::td_api::make_object<td::td_api::internalLinkTypeChangePhoneNumber>(); } +static auto chat_boost(const td::string &url) { + return td::td_api::make_object<td::td_api::internalLinkTypeChatBoost>(url); +} + static auto chat_folder_invite(const td::string &slug) { return td::td_api::make_object<td::td_api::internalLinkTypeChatFolderInvite>("tg:addlist?slug=" + slug); } @@ -258,6 +277,10 @@ static auto language_settings() { return td::td_api::make_object<td::td_api::internalLinkTypeLanguageSettings>(); } +static auto main_web_app(const td::string &bot_username, const td::string &start_parameter, bool is_compact) { + return td::td_api::make_object<td::td_api::internalLinkTypeMainWebApp>(bot_username, start_parameter, is_compact); +} + static auto message(const td::string &url) { return td::td_api::make_object<td::td_api::internalLinkTypeMessage>(url); } @@ -282,6 +305,14 @@ static auto premium_features(const td::string &referrer) { return td::td_api::make_object<td::td_api::internalLinkTypePremiumFeatures>(referrer); } +static auto premium_gift(const td::string &referrer) { + return td::td_api::make_object<td::td_api::internalLinkTypePremiumGift>(referrer); +} + +static auto premium_gift_code(const td::string &code) { + return td::td_api::make_object<td::td_api::internalLinkTypePremiumGiftCode>(code); +} + static auto privacy_and_security_settings() { return td::td_api::make_object<td::td_api::internalLinkTypePrivacyAndSecuritySettings>(); } @@ -297,8 +328,9 @@ static auto proxy_socks(const td::string &server, td::int32 port, const td::stri server, port, td::td_api::make_object<td::td_api::proxyTypeSocks5>(username, password)); } -static auto public_chat(const td::string &chat_username) { - return td::td_api::make_object<td::td_api::internalLinkTypePublicChat>(chat_username); +static auto public_chat(const td::string &chat_username, const td::string &draft_text = td::string(), + bool open_profile = false) { + return td::td_api::make_object<td::td_api::internalLinkTypePublicChat>(chat_username, draft_text, open_profile); } static auto qr_code_authentication() { @@ -317,6 +349,10 @@ static auto sticker_set(const td::string &sticker_set_name, bool expect_custom_e return td::td_api::make_object<td::td_api::internalLinkTypeStickerSet>(sticker_set_name, expect_custom_emoji); } +static auto story(const td::string &sender_username, td::int32 story_id) { + return td::td_api::make_object<td::td_api::internalLinkTypeStory>(sender_username, story_id); +} + static auto theme(const td::string &theme_name) { return td::td_api::make_object<td::td_api::internalLinkTypeTheme>(theme_name); } @@ -333,8 +369,10 @@ static auto unsupported_proxy() { return td::td_api::make_object<td::td_api::internalLinkTypeUnsupportedProxy>(); } -static auto user_phone_number(const td::string &phone_number) { - return td::td_api::make_object<td::td_api::internalLinkTypeUserPhoneNumber>(phone_number); +static auto user_phone_number(const td::string &phone_number, const td::string &draft_text = td::string(), + bool open_profile = false) { + return td::td_api::make_object<td::td_api::internalLinkTypeUserPhoneNumber>('+' + phone_number, draft_text, + open_profile); } static auto user_token(const td::string &token) { @@ -346,8 +384,9 @@ static auto video_chat(const td::string &chat_username, const td::string &invite } static auto web_app(const td::string &bot_username, const td::string &web_app_short_name, - const td::string &start_parameter) { - return td::td_api::make_object<td::td_api::internalLinkTypeWebApp>(bot_username, web_app_short_name, start_parameter); + const td::string &start_parameter, bool is_compact) { + return td::td_api::make_object<td::td_api::internalLinkTypeWebApp>(bot_username, web_app_short_name, start_parameter, + is_compact); } TEST(Link, parse_internal_link_part1) { @@ -372,6 +411,29 @@ TEST(Link, parse_internal_link_part1) { parse_internal_link("t.m/levlam/1", nullptr); parse_internal_link("t.men/levlam/1", nullptr); + parse_internal_link("t.me/levlam?boos", public_chat("levlam")); + parse_internal_link("telegram.me/levlam?booster", public_chat("levlam")); + parse_internal_link("telegram.dog/levlam?boost", chat_boost("tg://boost?domain=levlam")); + parse_internal_link("www.t.me/levlam?boost", chat_boost("tg://boost?domain=levlam")); + parse_internal_link("t.me/c/l12345?boost", nullptr); + parse_internal_link("t.me/c/12345l5431?boost", chat_boost("tg://boost?channel=12345")); + parse_internal_link("t.me/c/12345?boost", chat_boost("tg://boost?channel=12345")); + parse_internal_link("t.me/c/123456789012?boost", chat_boost("tg://boost?channel=123456789012")); + parse_internal_link("t.me/c/123456789012?boost=12312&domain=123", chat_boost("tg://boost?channel=123456789012")); + + parse_internal_link("t.me/boost/s/12345", story("boost", 12345)); + parse_internal_link("t.me/boost/s", chat_boost("tg://boost?domain=s")); + parse_internal_link("t.me/boost/12", message("tg://resolve?domain=boost&post=12")); + parse_internal_link("t.me/boost?cc=1#c=1", public_chat("boost")); + parse_internal_link("t.me/boost?c=-1", public_chat("boost")); + parse_internal_link("t.me/boost?c=12telegram", chat_boost("tg://boost?channel=12")); + parse_internal_link("t.me/bOoSt?c=12telegram", chat_boost("tg://boost?channel=12")); + + parse_internal_link("tg:boost?domain=username/12345&single", chat_boost("tg://boost?domain=username%2F12345")); + parse_internal_link("tg:boost?domain=username&channel=12345", chat_boost("tg://boost?domain=username")); + parse_internal_link("tg:boost?channel=12345&domain=username", chat_boost("tg://boost?domain=username")); + parse_internal_link("tg:boost?channel=12345", chat_boost("tg://boost?channel=12345")); + parse_internal_link("tg:resolve?domain=username&post=12345&single", message("tg://resolve?domain=username&post=12345&single")); parse_internal_link("tg:resolve?domain=username&post=12345&single&startattach=1&attach=test", @@ -412,8 +474,11 @@ TEST(Link, parse_internal_link_part1) { attachment_menu_bot(nullptr, public_chat("telegram"), "test", "")); parse_internal_link("tg:resolve?domain=telegram&attach=test&startattach=1", attachment_menu_bot(nullptr, public_chat("telegram"), "test", "1")); + parse_internal_link("tg:resolve?domain=username&profile=12&asd", public_chat("username", "", true)); + parse_internal_link("tg:resolve?domain=username&profile&text=@asd", public_chat("username", " @asd", true)); parse_internal_link("tg:resolve?phone=1", user_phone_number("1")); + parse_internal_link("tg:resolve?phone=+1", user_phone_number("1")); parse_internal_link("tg:resolve?phone=123456", user_phone_number("123456")); parse_internal_link("tg:resolve?phone=123456&startattach", user_phone_number("123456")); parse_internal_link("tg:resolve?phone=123456&startattach=123", user_phone_number("123456")); @@ -422,6 +487,10 @@ TEST(Link, parse_internal_link_part1) { parse_internal_link("tg:resolve?phone=123456&attach=&startattach=123", user_phone_number("123456")); parse_internal_link("tg:resolve?phone=123456&attach=test", attachment_menu_bot(nullptr, user_phone_number("123456"), "test", "")); + parse_internal_link("tg:resolve?phone=+123456&attach=test", + attachment_menu_bot(nullptr, user_phone_number("123456"), "test", "")); + parse_internal_link("tg:resolve?phone=++123456&attach=test", + unknown_deep_link("tg://resolve?phone=++123456&attach=test")); parse_internal_link("tg:resolve?phone=123456&attach=test&startattach&choose=users", attachment_menu_bot(nullptr, user_phone_number("123456"), "test", "")); parse_internal_link("tg:resolve?phone=123456&attach=test&startattach=123", @@ -431,8 +500,16 @@ TEST(Link, parse_internal_link_part1) { parse_internal_link("tg:resolve?phone=012345678901234567890123456789123", unknown_deep_link("tg://resolve?phone=012345678901234567890123456789123")); parse_internal_link("tg:resolve?phone=", unknown_deep_link("tg://resolve?phone=")); - parse_internal_link("tg:resolve?phone=+123", unknown_deep_link("tg://resolve?phone=+123")); + parse_internal_link("tg:resolve?phone=+123", user_phone_number("123")); parse_internal_link("tg:resolve?phone=123456 ", unknown_deep_link("tg://resolve?phone=123456 ")); + parse_internal_link("tg:resolve?domain=telegram&text=asd", public_chat("telegram", "asd")); + parse_internal_link("tg:resolve?phone=12345678901&text=asd", user_phone_number("12345678901", "asd")); + parse_internal_link("tg:resolve?domain=telegram&text=@asd", public_chat("telegram", " @asd")); + parse_internal_link("tg:resolve?phone=12345678901&text=@asd", user_phone_number("12345678901", " @asd")); + parse_internal_link("tg:resolve?domain=telegram&text=1%A02", public_chat("telegram")); + parse_internal_link("tg:resolve?phone=12345678901&text=1%A02", user_phone_number("12345678901")); + parse_internal_link("tg:resolve?phone=123456&profile", user_phone_number("123456", "", true)); + parse_internal_link("tg:resolve?phone=123456&profile&text=@asd", user_phone_number("123456", " @asd", true)); parse_internal_link("tg:contact?token=1", user_token("1")); parse_internal_link("tg:contact?token=123456", user_token("123456")); @@ -487,6 +564,8 @@ TEST(Link, parse_internal_link_part1) { attachment_menu_bot(nullptr, public_chat("username"), "bot", "")); parse_internal_link("t.me/username?attach=bot&startattach=1&choose=users", attachment_menu_bot(nullptr, public_chat("username"), "bot", "1")); + parse_internal_link("t.me/username?asd&profile=12", public_chat("username", "", true)); + parse_internal_link("t.me/username?profile&text=@asd", public_chat("username", " @asd", true)); parse_internal_link("tg:privatepost?domain=username/12345&single", unknown_deep_link("tg://privatepost?domain=username/12345&single")); @@ -552,7 +631,7 @@ TEST(Link, parse_internal_link_part1) { parse_internal_link("t.me/bg/111111-222222%20?rotation=180%20", background("111111-222222%20?rotation=180%20")); parse_internal_link("t.me/bg/111111~222222", background("111111~222222")); parse_internal_link("t.me/bg/abacaba", background("abacaba")); - parse_internal_link("t.me/Bg/abacaba", web_app("Bg", "abacaba", "")); + parse_internal_link("t.me/Bg/abacaba", web_app("Bg", "abacaba", "", false)); parse_internal_link("t.me/bg/111111~222222#asdasd", background("111111~222222")); parse_internal_link("t.me/bg/111111~222222?mode=blur", background("111111~222222")); parse_internal_link("t.me/bg/111111~222222?mode=blur&text=1", background("111111~222222")); @@ -599,6 +678,42 @@ TEST(Link, parse_internal_link_part2) { parse_internal_link("tg:invoice?slug=abc%30ef", invoice("abc0ef")); parse_internal_link("tg://invoice?slug=", unknown_deep_link("tg://invoice?slug=")); + parse_internal_link("t.me/giftcode?slug=abcdef", nullptr); + parse_internal_link("t.me/giftcode", nullptr); + parse_internal_link("t.me/giftcode/", nullptr); + parse_internal_link("t.me/giftcode//abcdef", nullptr); + parse_internal_link("t.me/giftcode?/abcdef", nullptr); + parse_internal_link("t.me/giftcode/?abcdef", nullptr); + parse_internal_link("t.me/giftcode/#abcdef", nullptr); + parse_internal_link("t.me/giftcode/abacaba", premium_gift_code("abacaba")); + parse_internal_link("t.me/giftcode/aba%20aba", premium_gift_code("aba aba")); + parse_internal_link("t.me/giftcode/123456a", premium_gift_code("123456a")); + parse_internal_link("t.me/giftcode/12345678901", premium_gift_code("12345678901")); + parse_internal_link("t.me/giftcode/123456", premium_gift_code("123456")); + parse_internal_link("t.me/giftcode/123456/123123/12/31/a/s//21w/?asdas#test", premium_gift_code("123456")); + + parse_internal_link("tg:giftcode?slug=abcdef", premium_gift_code("abcdef")); + parse_internal_link("tg:giftcode?slug=abc%30ef", premium_gift_code("abc0ef")); + parse_internal_link("tg://giftcode?slug=", unknown_deep_link("tg://giftcode?slug=")); + + parse_internal_link("t.me/m?slug=abcdef", nullptr); + parse_internal_link("t.me/m", nullptr); + parse_internal_link("t.me/m/", nullptr); + parse_internal_link("t.me/m//abcdef", nullptr); + parse_internal_link("t.me/m?/abcdef", nullptr); + parse_internal_link("t.me/m/?abcdef", nullptr); + parse_internal_link("t.me/m/#abcdef", nullptr); + parse_internal_link("t.me/m/abacaba", business_chat("abacaba")); + parse_internal_link("t.me/m/aba%20aba", business_chat("aba aba")); + parse_internal_link("t.me/m/123456a", business_chat("123456a")); + parse_internal_link("t.me/m/12345678901", business_chat("12345678901")); + parse_internal_link("t.me/m/123456", business_chat("123456")); + parse_internal_link("t.me/m/123456/123123/12/31/a/s//21w/?asdas#test", business_chat("123456")); + + parse_internal_link("tg:message?slug=abcdef", business_chat("abcdef")); + parse_internal_link("tg:message?slug=abc%30ef", business_chat("abc0ef")); + parse_internal_link("tg://message?slug=", unknown_deep_link("tg://message?slug=")); + parse_internal_link("tg:share?url=google.com&text=text#asdasd", message_draft("google.com\ntext", true)); parse_internal_link("tg:share?url=google.com&text=", message_draft("google.com", false)); parse_internal_link("tg:share?url=&text=google.com", message_draft("google.com", false)); @@ -702,10 +817,19 @@ TEST(Link, parse_internal_link_part2) { parse_internal_link("t.me/+123456?attach=&startattach", user_phone_number("123456")); parse_internal_link("t.me/+123456?attach=&startattach=1", user_phone_number("123456")); parse_internal_link("t.me/+123456?attach=bot", attachment_menu_bot(nullptr, user_phone_number("123456"), "bot", "")); - parse_internal_link("t.me/+123456?attach=bot&startattach", + parse_internal_link("t.me/+123456?attach=bot&startattach&profile", attachment_menu_bot(nullptr, user_phone_number("123456"), "bot", "")); parse_internal_link("t.me/+123456?attach=bot&startattach=1", attachment_menu_bot(nullptr, user_phone_number("123456"), "bot", "1")); + parse_internal_link("t.me/+123456?profile", user_phone_number("123456", "", true)); + parse_internal_link("t.me/+123456?profile&text=@asd", user_phone_number("123456", " @asd", true)); + + parse_internal_link("telegram.t.me?text=asd", public_chat("telegram", "asd")); + parse_internal_link("t.me/%2012345678901?text=asd", user_phone_number("12345678901", "asd")); + parse_internal_link("t.me/telegram?text=@asd", public_chat("telegram", " @asd")); + parse_internal_link("t.me/%2012345678901?text=@asd", user_phone_number("12345678901", " @asd")); + parse_internal_link("t.me/telegram?text=1%A02", public_chat("telegram")); + parse_internal_link("t.me/%2012345678901?text=1%A02", user_phone_number("12345678901")); parse_internal_link("t.me/addlist?invite=abcdef", nullptr); parse_internal_link("t.me/addlist", nullptr); @@ -965,25 +1089,26 @@ TEST(Link, parse_internal_link_part3) { parse_internal_link("tg:resolve?domain=username&startgroup=1&admin=delete_messages+anonymous", bot_start_in_group("username", "1", chat_administrator_rights(true, false, false, false, true, false, false, false, - false, false, false, true))); + false, false, false, false, false, false, true))); parse_internal_link( "tg:resolve?domain=username&startgroup&admin=manage_chat+change_info+post_messages+edit_messages+delete_messages+" - "invite_users+restrict_members+pin_messages+manage_topics+promote_members+manage_video_chats+anonymous", - bot_start_in_group( - "username", "", - chat_administrator_rights(true, true, false, false, true, true, true, true, true, true, true, true))); + "invite_users+restrict_members+pin_messages+manage_topics+promote_members+manage_video_chats+post_stories+edit_" + "stories+delete_stories+anonymous", + bot_start_in_group("username", "", + chat_administrator_rights(true, true, false, false, true, true, true, true, true, true, true, + true, true, true, true))); parse_internal_link("tg:resolve?domain=username&startchannel", public_chat("username")); parse_internal_link("tg:resolve?domain=username&startchannel&admin=", public_chat("username")); parse_internal_link( "tg:resolve?domain=username&startchannel&admin=post_messages", bot_add_to_channel("username", chat_administrator_rights(true, false, true, false, false, false, true, false, - false, false, false, false))); + false, false, false, false, false, false, false))); parse_internal_link( "tg:resolve?domain=username&startchannel&admin=manage_chat+change_info+post_messages+edit_messages+delete_" "messages+invite_users+restrict_members+pin_messages+manage_topics+promote_members+manage_video_chats+anonymous", bot_add_to_channel("username", chat_administrator_rights(true, true, true, true, true, true, true, false, false, - true, true, false))); + true, true, false, false, false, false))); parse_internal_link("t.me/username/0/a//s/as?startgroup=", bot_start_in_group("username", "", nullptr)); parse_internal_link("t.me/username/aasdas/2?test=1&startgroup=#12312", bot_start_in_group("username", "", nullptr)); @@ -1001,27 +1126,29 @@ TEST(Link, parse_internal_link_part3) { parse_internal_link("t.me/username?startgroup=1&admin=delete_messages+anonymous", bot_start_in_group("username", "1", chat_administrator_rights(true, false, false, false, true, false, false, false, - false, false, false, true))); + false, false, false, false, false, false, true))); parse_internal_link( "t.me/" "username?startgroup&admin=manage_chat+change_info+post_messages+edit_messages+delete_messages+invite_users+" - "restrict_members+pin_messages+manage_topics+promote_members+manage_video_chats+anonymous", - bot_start_in_group( - "username", "", - chat_administrator_rights(true, true, false, false, true, true, true, true, true, true, true, true))); + "restrict_members+pin_messages+manage_topics+promote_members+manage_video_chats+post_stories+edit_stories+delete_" + "stories+anonymous", + bot_start_in_group("username", "", + chat_administrator_rights(true, true, false, false, true, true, true, true, true, true, true, + true, true, true, true))); parse_internal_link("t.me/username?startchannel", public_chat("username")); parse_internal_link("t.me/username?startchannel&admin=", public_chat("username")); parse_internal_link( "t.me/username?startchannel&admin=post_messages", bot_add_to_channel("username", chat_administrator_rights(true, false, true, false, false, false, true, false, - false, false, false, false))); + false, false, false, false, false, false, false))); parse_internal_link( "t.me/" "username?startchannel&admin=manage_chat+change_info+post_messages+edit_messages+delete_messages+invite_users+" - "restrict_members+pin_messages+manage_topics+promote_members+manage_video_chats+anonymous", + "restrict_members+pin_messages+manage_topics+promote_members+manage_video_chats+post_stories+edit_stories+delete_" + "stories+anonymous", bot_add_to_channel("username", chat_administrator_rights(true, true, true, true, true, true, true, false, false, - true, true, false))); + true, true, true, true, true, false))); } TEST(Link, parse_internal_link_part4) { @@ -1046,8 +1173,33 @@ TEST(Link, parse_internal_link_part4) { parse_internal_link("t.me//username?game=asd", nullptr); parse_internal_link("https://telegram.dog/tele%63ram?game=t%63st", game("telecram", "tcst")); + parse_internal_link("tg:resolve?domain=username&story=123", story("username", 123)); + parse_internal_link("TG://resolve?domain=username&story=", public_chat("username")); + parse_internal_link("TG://resolve?domain=username&story=0", public_chat("username")); + parse_internal_link("TG://resolve?domain=username&story=-1", public_chat("username")); + parse_internal_link("TG://test@resolve?domain=username&story=1", nullptr); + parse_internal_link("tg:resolve:80?domain=username&story=1", nullptr); + parse_internal_link("tg:http://resolve?domain=username&story=1", nullptr); + parse_internal_link("tg:https://resolve?domain=username&story=1", nullptr); + parse_internal_link("tg:resolve?domain=&story=1", unknown_deep_link("tg://resolve?domain=&story=1")); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&story=%30", public_chat("telegram")); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&story=%31", story("telegram", 1)); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&story=%31ab", public_chat("telegram")); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&story=%31%39", story("telegram", 19)); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&story=2222222222", public_chat("telegram")); + + parse_internal_link("t.me/username/s/1234", story("username", 1234)); + parse_internal_link("t.me/username/s/3?qwe=12312#12312", story("username", 3)); + parse_internal_link("t.me/username/s/1", story("username", 1)); + parse_internal_link("t.me/username/s/2", story("username", 2)); + parse_internal_link("t.me/username/s/5", story("username", 5)); + parse_internal_link("t.me/username/s/", public_chat("username")); + parse_internal_link("t.me/username#/s/123", public_chat("username")); + parse_internal_link("t.me/username?story=123", public_chat("username")); + parse_internal_link("https://telegram.dog/tele%63ram/s/%31%39", story("telecram", 19)); + parse_internal_link("tg:resolve?domain=username&appname=aasdasd&startapp=123asd", - web_app("username", "aasdasd", "123asd")); + web_app("username", "aasdasd", "123asd", false)); parse_internal_link("TG://resolve?domain=username&appname=&startapp=123asd", public_chat("username")); parse_internal_link("TG://test@resolve?domain=username&appname=asd", nullptr); parse_internal_link("tg:resolve:80?domain=username&appname=asd", nullptr); @@ -1056,7 +1208,10 @@ TEST(Link, parse_internal_link_part4) { parse_internal_link("tg:resolve?domain=&appname=asd", unknown_deep_link("tg://resolve?domain=&appname=asd")); parse_internal_link("tg:resolve?domain=telegram&&&&&&&appname=%41&startapp=", public_chat("telegram")); parse_internal_link("tg:resolve?domain=telegram&&&&&&&appname=%41b&startapp=", public_chat("telegram")); - parse_internal_link("tg:resolve?domain=telegram&&&&&&&appname=%41bc&startapp=", web_app("telegram", "Abc", "")); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&appname=%41bc&startapp=", + web_app("telegram", "Abc", "", false)); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&appname=%41bc&startapp=&mode=compact", + web_app("telegram", "Abc", "", true)); parse_internal_link("t.me/username/0/a//s/as?appname=asd", public_chat("username")); parse_internal_link("t.me/username/aasdas/2?test=1&appname=asd#12312", public_chat("username")); @@ -1068,12 +1223,35 @@ TEST(Link, parse_internal_link_part4) { parse_internal_link("t.me//username?appname=asd", nullptr); parse_internal_link("https://telegram.dog/tele%63ram?appname=t%63st", public_chat("telecram")); parse_internal_link("t.me/username/def/asd", public_chat("username")); - parse_internal_link("t.me/username/asd#12312&startapp=qwe", web_app("username", "asd", "")); - parse_internal_link("t.me/username/asd?12312&startapp=qwe", web_app("username", "asd", "qwe")); - parse_internal_link("t.me/username/asdasd?startapp=0", web_app("username", "asdasd", "0")); - parse_internal_link("t.me/username/asd", web_app("username", "asd", "")); + parse_internal_link("t.me/username/asd#12312&startapp=qwe", web_app("username", "asd", "", false)); + parse_internal_link("t.me/username/asd?12312&startapp=qwe&mode=compac", web_app("username", "asd", "qwe", false)); + parse_internal_link("t.me/username/asd?12312&startapp=qwe&mode=compact", web_app("username", "asd", "qwe", true)); + parse_internal_link("t.me/username/asdasd?startapp=0", web_app("username", "asdasd", "0", false)); + parse_internal_link("t.me/username/asd", web_app("username", "asd", "", false)); parse_internal_link("t.me/username/", public_chat("username")); - parse_internal_link("https://telegram.dog/tele%63ram/t%63st", web_app("telecram", "tcst", "")); + parse_internal_link("https://telegram.dog/tele%63ram/t%63st", web_app("telecram", "tcst", "", false)); + parse_internal_link("https://telegram.dog/tele%63ram/t%63st?mode=compact", web_app("telecram", "tcst", "", true)); + + parse_internal_link("tg:resolve?domain=username&startapp=aasdasd", main_web_app("username", "aasdasd", false)); + parse_internal_link("TG://resolve?domain=username&startapp=&startapp=123asd", main_web_app("username", "", false)); + parse_internal_link("TG://test@resolve?domain=username&startapp=asd", nullptr); + parse_internal_link("tg:resolve:80?domain=username&startapp=asd", nullptr); + parse_internal_link("tg:http://resolve?domain=username&startapp=asd", nullptr); + parse_internal_link("tg:https://resolve?domain=username&startapp=asd", nullptr); + parse_internal_link("tg:resolve?domain=&startapp=asd", unknown_deep_link("tg://resolve?domain=&startapp=asd")); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&startapp=%41", main_web_app("telegram", "A", false)); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&startapp=%41b", main_web_app("telegram", "Ab", false)); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&startapp=%41bc", main_web_app("telegram", "Abc", false)); + parse_internal_link("tg:resolve?domain=telegram&&mode=compact&&&&&&startapp=%41bc", + main_web_app("telegram", "Abc", true)); + + parse_internal_link("t.me/username?startapp=qwe", main_web_app("username", "qwe", false)); + parse_internal_link("t.me/username?12312&startapp=qwe", main_web_app("username", "qwe", false)); + parse_internal_link("t.me/username?startapp=0", main_web_app("username", "0", false)); + parse_internal_link("https://telegram.dog/tele%63ram?startapp=t%63st", main_web_app("telecram", "tcst", false)); + parse_internal_link("https://telegram.dog/tele%63ram?startapp=t%63st&mode=%63ompact", + main_web_app("telecram", "tcst", true)); + parse_internal_link("https://telegram.dog?startapp=t%63st", nullptr); parse_internal_link("tg:resolve?domain=username&Game=asd", public_chat("username")); parse_internal_link("TG://test@resolve?domain=username", nullptr); @@ -1129,6 +1307,10 @@ TEST(Link, parse_internal_link_part4) { parse_internal_link("tg:premium_offer?ref=abc%30ef", premium_features("abc0ef")); parse_internal_link("tg://premium_offer?ref=", premium_features("")); + parse_internal_link("tg:premium_multigift?ref=abcdef", premium_gift("abcdef")); + parse_internal_link("tg:premium_multigift?ref=abc%30ef", premium_gift("abc0ef")); + parse_internal_link("tg://premium_multigift?ref=", premium_gift("")); + parse_internal_link("tg://settings", settings()); parse_internal_link("tg://setting", unknown_deep_link("tg://setting")); parse_internal_link("tg://settings?asdsa?D?SADasD?asD", settings()); @@ -1150,6 +1332,12 @@ TEST(Link, parse_internal_link_part4) { parse_internal_link("tg://settings/language", language_settings()); parse_internal_link("tg://settings/privacy", privacy_and_security_settings()); + parse_internal_link("tg://stars_topup", unknown_deep_link("tg://stars_topup")); + parse_internal_link("tg://stars_topup?balance=", unknown_deep_link("tg://stars_topup?balance=")); + parse_internal_link("tg://stars_topup?balance=test", buy_stars(1, "")); + parse_internal_link("tg://stars_topup?balance=10&purpose=%30test", buy_stars(10, "0test")); + parse_internal_link("tg://stars_topup?balance=100000000000&purpose=subs", buy_stars(100000000000, "subs")); + parse_internal_link("username.t.me////0/a//s/as?start=", bot_start("username", "")); parse_internal_link("username.t.me?start=as", bot_start("username", "as")); parse_internal_link("username.t.me", public_chat("username")); @@ -1162,15 +1350,24 @@ TEST(Link, parse_internal_link_part4) { parse_internal_link("aaa_.t.me/12345?single", nullptr); parse_internal_link("0aaa.t.me/12345?single", nullptr); parse_internal_link("_aaa.t.me/12345?single", nullptr); + parse_internal_link("a.t.me", nullptr); + parse_internal_link("b.t.me", nullptr); + parse_internal_link("k.t.me", nullptr); + parse_internal_link("z.t.me", nullptr); + parse_internal_link("web.t.me", nullptr); parse_internal_link("addemoji.t.me", nullptr); parse_internal_link("addlist.t.me", nullptr); parse_internal_link("addstickers.t.me", nullptr); parse_internal_link("addtheme.t.me", nullptr); parse_internal_link("auth.t.me", nullptr); + parse_internal_link("boost.t.me", nullptr); parse_internal_link("confirmphone.t.me", nullptr); + parse_internal_link("contact.t.me", nullptr); + parse_internal_link("giftcode.t.me", nullptr); parse_internal_link("invoice.t.me", nullptr); parse_internal_link("joinchat.t.me", nullptr); parse_internal_link("login.t.me", nullptr); + parse_internal_link("m.t.me", nullptr); parse_internal_link("proxy.t.me", nullptr); parse_internal_link("setlanguage.t.me", nullptr); parse_internal_link("share.t.me", nullptr); diff --git a/protocols/Telegram/tdlib/td/test/main.cpp b/protocols/Telegram/tdlib/td/test/main.cpp index 9a774b37db..6cd81fd421 100644 --- a/protocols/Telegram/tdlib/td/test/main.cpp +++ b/protocols/Telegram/tdlib/td/test/main.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/protocols/Telegram/tdlib/td/test/message_entities.cpp b/protocols/Telegram/tdlib/td/test/message_entities.cpp index 378e76b23a..64cd7dcca9 100644 --- a/protocols/Telegram/tdlib/td/test/message_entities.cpp +++ b/protocols/Telegram/tdlib/td/test/message_entities.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -29,7 +29,7 @@ static void check_mention(const td::string &str, const td::vector<td::string> &e result.push_back(it.str()); } if (result != expected) { - LOG(FATAL) << td::tag("text", str) << td::tag("got", td::format::as_array(result)) + LOG(FATAL) << td::tag("text", str) << td::tag("receive", td::format::as_array(result)) << td::tag("expected", td::format::as_array(expected)); } } @@ -60,7 +60,7 @@ static void check_bot_command(const td::string &str, const td::vector<td::string result.push_back(it.str()); } if (result != expected) { - LOG(FATAL) << td::tag("text", str) << td::tag("got", td::format::as_array(result)) + LOG(FATAL) << td::tag("text", str) << td::tag("receive", td::format::as_array(result)) << td::tag("expected", td::format::as_array(expected)); } } @@ -84,7 +84,7 @@ static void check_hashtag(const td::string &str, const td::vector<td::string> &e result.push_back(it.str()); } if (result != expected) { - LOG(FATAL) << td::tag("text", str) << td::tag("got", td::format::as_array(result)) + LOG(FATAL) << td::tag("text", str) << td::tag("receive", td::format::as_array(result)) << td::tag("expected", td::format::as_array(expected)); } } @@ -128,7 +128,7 @@ static void check_cashtag(const td::string &str, const td::vector<td::string> &e result.push_back(it.str()); } if (result != expected) { - LOG(FATAL) << td::tag("text", str) << td::tag("got", td::format::as_array(result)) + LOG(FATAL) << td::tag("text", str) << td::tag("receive", td::format::as_array(result)) << td::tag("expected", td::format::as_array(expected)); } } @@ -190,7 +190,7 @@ static void check_media_timestamp(const td::string &str, const td::vector<std::p auto result = td::transform(td::find_media_timestamps(str), [](auto &&entity) { return std::make_pair(entity.first.str(), entity.second); }); if (result != expected) { - LOG(FATAL) << td::tag("text", str) << td::tag("got", td::format::as_array(result)) + LOG(FATAL) << td::tag("text", str) << td::tag("receive", td::format::as_array(result)) << td::tag("expected", td::format::as_array(expected)); } } @@ -235,7 +235,7 @@ static void check_bank_card_number(const td::string &str, const td::vector<td::s result.push_back(it.str()); } if (result != expected) { - LOG(FATAL) << td::tag("text", str) << td::tag("got", td::format::as_array(result)) + LOG(FATAL) << td::tag("text", str) << td::tag("receive", td::format::as_array(result)) << td::tag("expected", td::format::as_array(expected)); } } @@ -284,7 +284,7 @@ static void check_tg_url(const td::string &str, const td::vector<td::string> &ex result.push_back(it.str()); } if (result != expected) { - LOG(FATAL) << td::tag("text", str) << td::tag("got", td::format::as_array(result)) + LOG(FATAL) << td::tag("text", str) << td::tag("receive", td::format::as_array(result)) << td::tag("expected", td::format::as_array(expected)); } } @@ -464,11 +464,11 @@ static void check_url(const td::string &str, const td::vector<td::string> &expec } } if (result_urls != expected_urls) { - LOG(FATAL) << td::tag("text", str) << td::tag("got", td::format::as_array(result_urls)) + LOG(FATAL) << td::tag("text", str) << td::tag("receive", td::format::as_array(result_urls)) << td::tag("expected", td::format::as_array(expected_urls)); } if (result_email_addresses != expected_email_addresses) { - LOG(FATAL) << td::tag("text", str) << td::tag("got", td::format::as_array(result_email_addresses)) + LOG(FATAL) << td::tag("text", str) << td::tag("receive", td::format::as_array(result_email_addresses)) << td::tag("expected", td::format::as_array(expected_email_addresses)); } } @@ -501,6 +501,10 @@ TEST(MessageEntities, url) { check_url("ftp://telegram.org", {"ftp://telegram.org"}); check_url("ftps://telegram.org", {}); check_url("sftp://telegram.org", {}); + check_url("tonsite://telegram.ton", {"tonsite://telegram.ton"}); + check_url("telegram.ton", {"telegram.ton"}); + check_url("telegram.onion", {"telegram.onion"}); + check_url("telegram.tonsite", {}); check_url("hTtPs://telegram.org", {"hTtPs://telegram.org"}); check_url("HTTP://telegram.org", {"HTTP://telegram.org"}); check_url("аHTTP://telegram.org", {"HTTP://telegram.org"}); @@ -787,17 +791,13 @@ TEST(MessageEntities, fix_formatted_text) { entities.emplace_back(td::MessageEntity::Type::Bold, 0, i); td::vector<td::MessageEntity> fixed_entities; - if (i != 33) { - fixed_entities.emplace_back(td::MessageEntity::Type::Bold, 32, i - 33); - } + fixed_entities.emplace_back(td::MessageEntity::Type::Bold, 0, i - 1 /* deleted \r */); check_fix_formatted_text(str, entities, fixed_str, fixed_entities, true, false, false, true); - td::string expected_str; + td::string expected_str = fixed_str.substr(0, 33); if (i != 33) { - fixed_entities.back().offset = 0; - fixed_entities.back().length = 1; + fixed_entities.back().length = 33; } - expected_str = "a"; check_fix_formatted_text(str, entities, expected_str, fixed_entities, false, false, false, false); } @@ -809,8 +809,13 @@ TEST(MessageEntities, fix_formatted_text) { check_fix_formatted_text(str, entities, true, true, true, true); check_fix_formatted_text(str, entities, false, false, false, false); } else { - check_fix_formatted_text(str, entities, str, {}, true, true, true, true); - check_fix_formatted_text(str, entities, str.substr(0, str.size() - 2), {}, false, false, false, false); + check_fix_formatted_text(str, entities, str, {{td::MessageEntity::Type::Bold, i, 1}}, true, true, true, true); + if (i == 2) { + check_fix_formatted_text(str, entities, str.substr(0, str.size() - 2), {{td::MessageEntity::Type::Bold, i, 1}}, + false, false, false, false); + } else { + check_fix_formatted_text(str, entities, str.substr(0, str.size() - 2), {}, false, false, false, false); + } } } @@ -850,18 +855,9 @@ TEST(MessageEntities, fix_formatted_text) { fixed_str = skip_trim ? "aba \n caba " : "aba \n caba"; auto fixed_length = offset <= 4 && offset + length >= 5 ? length - 1 : length; auto fixed_offset = offset >= 5 ? offset - 1 : offset; - if (static_cast<size_t>(fixed_offset) >= fixed_str.size()) { - fixed_length = 0; - } while (static_cast<size_t>(fixed_offset + fixed_length) > fixed_str.size()) { fixed_length--; } - if (type == td::MessageEntity::Type::Bold || type == td::MessageEntity::Type::Url) { - while (fixed_length > 0 && (fixed_str[fixed_offset] == ' ' || fixed_str[fixed_offset] == '\n')) { - fixed_offset++; - fixed_length--; - } - } td::vector<td::MessageEntity> entities; entities.emplace_back(type, offset, length); @@ -872,17 +868,11 @@ TEST(MessageEntities, fix_formatted_text) { } td::vector<td::MessageEntity> fixed_entities; if (fixed_length > 0) { - for (auto i = 0; i < length; i++) { - if (!td::is_space(str[offset + i]) || type == td::MessageEntity::Type::TextUrl || - type == td::MessageEntity::Type::MentionName) { - fixed_entities.emplace_back(type, fixed_offset, fixed_length); - if (type == td::MessageEntity::Type::TextUrl) { - fixed_entities.back().argument = "t.me"; - } else if (type == td::MessageEntity::Type::MentionName) { - fixed_entities.back().user_id = user_id; - } - break; - } + fixed_entities.emplace_back(type, fixed_offset, fixed_length); + if (type == td::MessageEntity::Type::TextUrl) { + fixed_entities.back().argument = "t.me"; + } else if (type == td::MessageEntity::Type::MentionName) { + fixed_entities.back().user_id = user_id; } } check_fix_formatted_text(str, entities, fixed_str, fixed_entities, true, false, false, skip_trim); @@ -904,13 +894,7 @@ TEST(MessageEntities, fix_formatted_text) { td::vector<td::MessageEntity> fixed_entities; if (length > 0) { - if (offset == 3) { - if (length >= 2) { - fixed_entities.emplace_back(td::MessageEntity::Type::Bold, offset + 1, length - 1); - } - } else { - fixed_entities.emplace_back(td::MessageEntity::Type::Bold, offset, length); - } + fixed_entities.emplace_back(td::MessageEntity::Type::Bold, offset, length); } check_fix_formatted_text(str, entities, str, fixed_entities, true, false, false, false); @@ -958,6 +942,9 @@ TEST(MessageEntities, fix_formatted_text) { if (i < 4) { fixed_entities.emplace_back(td::MessageEntity::Type::Bold, i * 3, 2); } + if (i < 3) { + fixed_entities.emplace_back(td::MessageEntity::Type::Italic, i * 3 + 2, 1); + } } check_fix_formatted_text(str, entities, td::utf8_utf16_substr(str, 3, 11).str(), fixed_entities, false, false, @@ -974,10 +961,10 @@ TEST(MessageEntities, fix_formatted_text) { check_fix_formatted_text("a \r", {{td::MessageEntity::Type::Bold, 0, 3}, {td::MessageEntity::Type::Underline, 2, 1}}, "a ", {{td::MessageEntity::Type::Bold, 0, 2}}, true, false, false, true); check_fix_formatted_text("a \r ", {{td::MessageEntity::Type::Bold, 0, 4}, {td::MessageEntity::Type::Underline, 2, 1}}, - "a ", {{td::MessageEntity::Type::Bold, 0, 2}}, true, false, false, true); - check_fix_formatted_text( - "a \r b", {{td::MessageEntity::Type::Bold, 0, 5}, {td::MessageEntity::Type::Underline, 2, 1}}, "a b", - {{td::MessageEntity::Type::Bold, 0, 2}, {td::MessageEntity::Type::Bold, 3, 1}}, true, false, false, true); + "a ", {{td::MessageEntity::Type::Bold, 0, 3}}, true, false, false, true); + check_fix_formatted_text("a \r b", + {{td::MessageEntity::Type::Bold, 0, 5}, {td::MessageEntity::Type::Underline, 2, 1}}, "a b", + {{td::MessageEntity::Type::Bold, 0, 4}}, true, false, false, true); check_fix_formatted_text("a\rbc\r", {{td::MessageEntity::Type::Italic, 0, 1}, @@ -1014,6 +1001,7 @@ TEST(MessageEntities, fix_formatted_text) { check_fix_formatted_text("@tests @tests", {{td::MessageEntity::Type::Italic, 0, 13}}, "@tests @tests", {{td::MessageEntity::Type::Mention, 0, 6}, {td::MessageEntity::Type::Italic, 0, 6}, + {td::MessageEntity::Type::Italic, 6, 1}, {td::MessageEntity::Type::Mention, 7, 6}, {td::MessageEntity::Type::Italic, 7, 6}}); @@ -1113,7 +1101,7 @@ TEST(MessageEntities, fix_formatted_text) { check_fix_formatted_text("example.com a", {{td::MessageEntity::Type::Italic, 0, 13}}, "example.com a", {{td::MessageEntity::Type::Url, 0, 11}, {td::MessageEntity::Type::Italic, 0, 11}, - {td::MessageEntity::Type::Italic, 12, 1}}); + {td::MessageEntity::Type::Italic, 11, 2}}); check_fix_formatted_text("a example.com", {{td::MessageEntity::Type::Italic, 0, 13}}, "a example.com", {{td::MessageEntity::Type::Italic, 0, 2}, {td::MessageEntity::Type::Url, 2, 11}, @@ -1134,7 +1122,7 @@ TEST(MessageEntities, fix_formatted_text) { auto n = td::Random::fast(1, 20); td::vector<td::MessageEntity> entities; for (int j = 0; j < n; j++) { - td::int32 type = td::Random::fast(4, 16); + td::int32 type = td::Random::fast(4, static_cast<int>(td::MessageEntity::Type::Size) - 1); td::int32 offset = td::Random::fast(0, static_cast<int>(str.size()) - 1); auto max_length = static_cast<int>(str.size() - offset); if ((test_n & 1) != 0 && max_length > 4) { @@ -1156,7 +1144,7 @@ TEST(MessageEntities, fix_formatted_text) { auto old_type_mask = get_type_mask(str.size(), entities); ASSERT_TRUE(td::fix_formatted_text(str, entities, false, false, true, true, false).is_ok()); auto new_type_mask = get_type_mask(str.size(), entities); - auto splittable_mask = (1 << 5) | (1 << 6) | (1 << 14) | (1 << 15); + auto splittable_mask = (1 << 5) | (1 << 6) | (1 << 14) | (1 << 15) | (1 << 19); auto pre_mask = (1 << 7) | (1 << 8) | (1 << 9); for (std::size_t pos = 0; pos < str.size(); pos++) { if ((new_type_mask[pos] & pre_mask) != 0) { @@ -1176,7 +1164,9 @@ TEST(MessageEntities, fix_formatted_text) { if (keep_url && ((1 << static_cast<td::int32>(entity.type)) & splittable_mask) == 0 && !(end <= url_offset || url_end <= offset)) { - keep_url = (entity.type == td::MessageEntity::Type::BlockQuote && offset <= url_offset && url_end <= end); + keep_url = ((entity.type == td::MessageEntity::Type::BlockQuote || + entity.type == td::MessageEntity::Type::ExpandableBlockQuote) && + offset <= url_offset && url_end <= end); } } ASSERT_EQ(keep_url, std::count(entities.begin(), entities.end(), url_entity) == 1); @@ -1199,7 +1189,8 @@ TEST(MessageEntities, fix_formatted_text) { // pre can't contain other entities ASSERT_TRUE((type_mask & pre_mask) == 0); - if ((type_mask & splittable_mask) == 0 && entities[i].type != td::MessageEntity::Type::BlockQuote) { + if ((type_mask & splittable_mask) == 0 && entities[i].type != td::MessageEntity::Type::BlockQuote && + entities[i].type != td::MessageEntity::Type::ExpandableBlockQuote) { // continuous entities can contain only splittable entities ASSERT_TRUE(((1 << static_cast<td::int32>(entities[j].type)) & splittable_mask) != 0); } @@ -1217,6 +1208,24 @@ TEST(MessageEntities, fix_formatted_text) { {}); } +TEST(MessageEntities, is_visible_url) { + td::string str = "a telegram.org telegran.org telegrao.org telegram.orc telegrap.org c"; + td::vector<td::MessageEntity> entities; + entities.emplace_back(td::MessageEntity::Type::TextUrl, 0, 1, "telegrab.org"); + entities.emplace_back(td::MessageEntity::Type::TextUrl, static_cast<td::int32>(str.size()) - 1, 1, "telegrax.org"); + td::fix_formatted_text(str, entities, false, false, false, false, true).ensure(); + td::FormattedText text{std::move(str), std::move(entities)}; + ASSERT_EQ(td::get_first_url(text), "telegrab.org"); + ASSERT_TRUE(!td::is_visible_url(text, "telegrab.org")); + ASSERT_TRUE(td::is_visible_url(text, "telegram.org")); + ASSERT_TRUE(td::is_visible_url(text, "telegran.org")); + ASSERT_TRUE(td::is_visible_url(text, "telegrao.org")); + ASSERT_TRUE(!td::is_visible_url(text, "telegram.orc")); + ASSERT_TRUE(td::is_visible_url(text, "telegrap.org")); + ASSERT_TRUE(!td::is_visible_url(text, "telegraf.org")); + ASSERT_TRUE(!td::is_visible_url(text, "telegrax.org")); +} + static void check_parse_html(td::string text, const td::string &result, const td::vector<td::MessageEntity> &entities) { auto r_entities = td::parse_html(text); ASSERT_TRUE(r_entities.is_ok()); @@ -1241,8 +1250,7 @@ TEST(MessageEntities, parse_html) { check_parse_html("🏟 🏟<<abac aba>", "Unsupported start tag \"abac\" at byte offset 13"); check_parse_html("🏟 🏟<<abac>", "Unsupported start tag \"abac\" at byte offset 13"); check_parse_html("🏟 🏟<<i =aba>", "Empty attribute name in the tag \"i\" at byte offset 13"); - check_parse_html("🏟 🏟<<i aba>", - "Expected equal sign in declaration of an attribute of the tag \"i\" at byte offset 13"); + check_parse_html("🏟 🏟<<i aba>", "Can't find end tag corresponding to start tag \"i\""); check_parse_html("🏟 🏟<<i aba = ", "Unclosed start tag \"i\" at byte offset 13"); check_parse_html("🏟 🏟<<i aba = 190azAz-.,", "Unexpected end of name token at byte offset 27"); check_parse_html("🏟 🏟<<i aba = \"<>">", "Unclosed start tag at byte offset 13"); @@ -1265,6 +1273,7 @@ TEST(MessageEntities, parse_html) { check_parse_html("➡️ ➡️<s>➡️ ➡️</s>", "➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::Strikethrough, 5, 5}}); check_parse_html("➡️ ➡️<strike>➡️ ➡️</strike>", "➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::Strikethrough, 5, 5}}); check_parse_html("➡️ ➡️<del>➡️ ➡️</del>", "➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::Strikethrough, 5, 5}}); + check_parse_html("➡️ ➡️<blockquote>➡️ ➡️</blockquote>", "➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::BlockQuote, 5, 5}}); check_parse_html("➡️ ➡️<i>➡️ ➡️</i><b>➡️ ➡️</b>", "➡️ ➡️➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::Italic, 5, 5}, {td::MessageEntity::Type::Bold, 10, 5}}); check_parse_html("🏟 🏟<i>🏟 <🏟</i>", "🏟 🏟🏟 <🏟", {{td::MessageEntity::Type::Italic, 5, 6}}); @@ -1349,11 +1358,22 @@ TEST(MessageEntities, parse_html) { check_parse_html("🏟 🏟<b aba = caba><tg-emoji emoji-id=\"1\">🏟</tg-emoji>1</b>", "🏟 🏟🏟1", {{td::MessageEntity::Type::Bold, 5, 3}, {td::MessageEntity::Type::CustomEmoji, 5, 2, td::CustomEmojiId(static_cast<td::int64>(1))}}); + check_parse_html("<blockquote cite=\"\" askdlbas nasjdbaj nj12b3>a<<pre >b;</></>", "a<b;", + {{td::MessageEntity::Type::BlockQuote, 0, 4}, {td::MessageEntity::Type::Pre, 2, 2}}); + check_parse_html("<blockquote expandable>a<<pre >b;</></>", "a<b;", + {{td::MessageEntity::Type::ExpandableBlockQuote, 0, 4}, {td::MessageEntity::Type::Pre, 2, 2}}); + check_parse_html("<blockquote expandable asd>a<<pre >b;</></>", "a<b;", + {{td::MessageEntity::Type::ExpandableBlockQuote, 0, 4}, {td::MessageEntity::Type::Pre, 2, 2}}); + check_parse_html("<blockquote expandable=false>a<<pre >b;</></>", "a<b;", + {{td::MessageEntity::Type::ExpandableBlockQuote, 0, 4}, {td::MessageEntity::Type::Pre, 2, 2}}); } static void check_parse_markdown(td::string text, const td::string &result, const td::vector<td::MessageEntity> &entities) { auto r_entities = td::parse_markdown_v2(text); + if (r_entities.is_error()) { + LOG(ERROR) << r_entities.error(); + } ASSERT_TRUE(r_entities.is_ok()); ASSERT_EQ(entities, r_entities.ok()); ASSERT_STREQ(result, text); @@ -1368,7 +1388,7 @@ static void check_parse_markdown(td::string text, td::Slice error_message) { TEST(MessageEntities, parse_markdown) { td::Slice reserved_characters("]()>#+-=|{}.!"); - td::Slice begin_characters("_*[~`"); + td::Slice begin_characters("_*[~`>"); for (char c = 1; c < 126; c++) { if (begin_characters.find(c) != td::Slice::npos) { continue; @@ -1405,6 +1425,7 @@ TEST(MessageEntities, parse_markdown) { check_parse_markdown("🏟 🏟__", "Can't find end of Underline entity at byte offset 9"); check_parse_markdown("🏟 🏟||test\\|", "Can't find end of Spoiler entity at byte offset 9"); check_parse_markdown("🏟 🏟!", "Character '!' is reserved and must be escaped with the preceding '\\'"); + check_parse_markdown("🏟 🏟>", "Character '>' is reserved and must be escaped with the preceding '\\'"); check_parse_markdown("🏟 🏟![", "Can't find end of CustomEmoji entity at byte offset 9"); check_parse_markdown("🏟 🏟![👍", "Can't find end of CustomEmoji entity at byte offset 9"); check_parse_markdown("🏟 🏟![👍]", "Custom emoji entity must contain a tg://emoji URL"); @@ -1414,6 +1435,12 @@ TEST(MessageEntities, parse_markdown) { check_parse_markdown("🏟 🏟![👍](tg://emoji#test)", "Custom emoji URL must have an emoji identifier"); check_parse_markdown("🏟 🏟![👍](tg://emoji?test=1#&id=25)", "Custom emoji URL must have an emoji identifier"); check_parse_markdown("🏟 🏟![👍](tg://emoji?test=1231&id=025)", "Invalid custom emoji identifier specified"); + check_parse_markdown(">*b\n>ld \n>bo\nld*\nasd\ndef", "Can't find end of Bold entity at byte offset 1"); + check_parse_markdown(">\n*a*>2", "Character '>' is reserved and must be escaped with the preceding '\\'"); + check_parse_markdown(">asd\n>q||e||w||\n||asdad", "Can't find end of Spoiler entity at byte offset 16"); + check_parse_markdown(">asd\n>q||ew\n||asdad", "Can't find end of Spoiler entity at byte offset 7"); + check_parse_markdown(">asd\n>q||e||w__\n||asdad", "Can't find end of Underline entity at byte offset 13"); + check_parse_markdown(">asd\n>q||e||w||a\n||asdad", "Can't find end of Spoiler entity at byte offset 13"); check_parse_markdown("", "", {}); check_parse_markdown("\\\\", "\\", {}); @@ -1478,6 +1505,71 @@ TEST(MessageEntities, parse_markdown) { {{0, 12, td::UserId(static_cast<td::int64>(123456))}}); check_parse_markdown("🏟 🏟![👍](TG://EMoJI/?test=1231&id=25#id=32)a", "🏟 🏟👍a", {{td::MessageEntity::Type::CustomEmoji, 5, 2, td::CustomEmojiId(static_cast<td::int64>(25))}}); + check_parse_markdown("> \n> \n>", " \n \n", {{td::MessageEntity::Type::BlockQuote, 0, 4}}); + check_parse_markdown("> \\>\n \\> \n>", " >\n > \n", {{td::MessageEntity::Type::BlockQuote, 0, 3}}); + check_parse_markdown("abc\n> \n> \n>\ndef", "abc\n \n \n\ndef", {{td::MessageEntity::Type::BlockQuote, 4, 5}}); + check_parse_markdown(">", "", {}); + check_parse_markdown(">a", "a", {{td::MessageEntity::Type::BlockQuote, 0, 1}}); + check_parse_markdown("\r>a", "\ra", {{td::MessageEntity::Type::BlockQuote, 1, 1}}); + check_parse_markdown("\r\r>\r\ra\r\n\r", "\r\r\r\ra\r\n\r", {{td::MessageEntity::Type::BlockQuote, 2, 5}}); + check_parse_markdown( + ">*bold _italic bold ~italic bold strikethrough ||italic bold strikethrough spoiler||~ __underline italic " + "bold___ bold*", + "bold italic bold italic bold strikethrough italic bold strikethrough spoiler underline italic bold bold", + {{td::MessageEntity::Type::BlockQuote, 0, 103}, + {td::MessageEntity::Type::Bold, 0, 103}, + {td::MessageEntity::Type::Italic, 5, 93}, + {td::MessageEntity::Type::Strikethrough, 17, 59}, + {td::MessageEntity::Type::Spoiler, 43, 33}, + {td::MessageEntity::Type::Underline, 77, 21}}); + check_parse_markdown(">*b\n>ld \n>bo\n>ld*\nasd\ndef", "b\nld \nbo\nld\nasd\ndef", + {{td::MessageEntity::Type::BlockQuote, 0, 12}, {td::MessageEntity::Type::Bold, 0, 11}}); + check_parse_markdown("*a\n>b\n>ld \n>bo\n>ld\nasd*\ndef", "a\nb\nld \nbo\nld\nasd\ndef", + {{td::MessageEntity::Type::Bold, 0, 17}, {td::MessageEntity::Type::BlockQuote, 2, 12}}); + check_parse_markdown(">`b\n>ld \n>bo\nld`\n>asd\ndef", "b\n>ld \n>bo\nld\nasd\ndef", + {{td::MessageEntity::Type::BlockQuote, 0, 18}, {td::MessageEntity::Type::Code, 0, 13}}); + check_parse_markdown("`>b\n>ld \n>bo\nld`\n>asd\ndef", ">b\n>ld \n>bo\nld\nasd\ndef", + {{td::MessageEntity::Type::Code, 0, 14}, {td::MessageEntity::Type::BlockQuote, 15, 4}}); + check_parse_markdown(">1", "1", {{td::MessageEntity::Type::BlockQuote, 0, 1}}); + check_parse_markdown(">\n1", "\n1", {{td::MessageEntity::Type::BlockQuote, 0, 1}}); + check_parse_markdown(">\n\r>2", "\n\r2", + {{td::MessageEntity::Type::BlockQuote, 0, 1}, {td::MessageEntity::Type::BlockQuote, 2, 1}}); + check_parse_markdown(">\n**>2", "\n2", + {{td::MessageEntity::Type::BlockQuote, 0, 1}, {td::MessageEntity::Type::BlockQuote, 1, 1}}); + check_parse_markdown(">**\n>2", "\n2", {{td::MessageEntity::Type::BlockQuote, 0, 2}}); + // check_parse_markdown("*>abcd*", "abcd", + // {{td::MessageEntity::Type::BlockQuote, 0, 4}, {td::MessageEntity::Type::Bold, 0, 4}}); + check_parse_markdown(">*abcd*", "abcd", + {{td::MessageEntity::Type::BlockQuote, 0, 4}, {td::MessageEntity::Type::Bold, 0, 4}}); + // check_parse_markdown(">*abcd\n*", "abcd\n", + // {{td::MessageEntity::Type::BlockQuote, 0, 5}, {td::MessageEntity::Type::Bold, 0, 5}}); + check_parse_markdown(">*abcd*\n", "abcd\n", + {{td::MessageEntity::Type::BlockQuote, 0, 5}, {td::MessageEntity::Type::Bold, 0, 4}}); + check_parse_markdown("*>abcd\n*", "abcd\n", + {{td::MessageEntity::Type::BlockQuote, 0, 5}, {td::MessageEntity::Type::Bold, 0, 5}}); + check_parse_markdown("abc\n>def\n>def\n\r>ghi2\njkl", "abc\ndef\ndef\n\rghi2\njkl", + {{td::MessageEntity::Type::BlockQuote, 4, 8}, {td::MessageEntity::Type::BlockQuote, 13, 5}}); + check_parse_markdown( + ">asd\n>q||e||w||\nasdad", "asd\nqew\nasdad", + {{td::MessageEntity::Type::ExpandableBlockQuote, 0, 8}, {td::MessageEntity::Type::Spoiler, 5, 1}}); + check_parse_markdown(">asd\n>q||ew||\nasdad", "asd\nqew\nasdad", + {{td::MessageEntity::Type::BlockQuote, 0, 8}, {td::MessageEntity::Type::Spoiler, 5, 2}}); + check_parse_markdown( + ">asd\r\n>q||e||w||\r\nasdad", "asd\r\nqew\r\nasdad", + {{td::MessageEntity::Type::ExpandableBlockQuote, 0, 10}, {td::MessageEntity::Type::Spoiler, 6, 1}}); + check_parse_markdown(">asd\r\n>q||ew||\r\nasdad", "asd\r\nqew\r\nasdad", + {{td::MessageEntity::Type::BlockQuote, 0, 10}, {td::MessageEntity::Type::Spoiler, 6, 2}}); + check_parse_markdown( + ">asd\r\n>q||e||w||\r\n", "asd\r\nqew\r\n", + {{td::MessageEntity::Type::ExpandableBlockQuote, 0, 10}, {td::MessageEntity::Type::Spoiler, 6, 1}}); + check_parse_markdown(">asd\r\n>q||ew||\r\n", "asd\r\nqew\r\n", + {{td::MessageEntity::Type::BlockQuote, 0, 10}, {td::MessageEntity::Type::Spoiler, 6, 2}}); + check_parse_markdown( + ">asd\r\n>q||e||w||", "asd\r\nqew", + {{td::MessageEntity::Type::ExpandableBlockQuote, 0, 8}, {td::MessageEntity::Type::Spoiler, 6, 1}}); + check_parse_markdown(">asd\r\n>q||ew||", "asd\r\nqew", + {{td::MessageEntity::Type::BlockQuote, 0, 8}, {td::MessageEntity::Type::Spoiler, 6, 2}}); + check_parse_markdown(">||", "", {}); } static void check_parse_markdown_v3(td::string text, td::vector<td::MessageEntity> entities, @@ -1628,8 +1720,8 @@ TEST(MessageEntities, parse_markdown_v3) { check_parse_markdown_v3("__ __", " ", {{td::MessageEntity::Type::Italic, 0, 1}}); check_parse_markdown_v3("__\n__", "\n", {{td::MessageEntity::Type::Italic, 0, 1}}); - check_parse_markdown_v3("__ __a", " a", {}, true); - check_parse_markdown_v3("__\n__a", "\na", {}, true); + check_parse_markdown_v3("__ __a", " a", {{td::MessageEntity::Type::Italic, 0, 1}}, true); + check_parse_markdown_v3("__\n__a", "\na", {{td::MessageEntity::Type::Italic, 0, 1}}, true); check_parse_markdown_v3("**** __a__ **b** ~~c~~ ||d||", "**** a b c d", {{td::MessageEntity::Type::Italic, 5, 1}, {td::MessageEntity::Type::Bold, 7, 1}, @@ -1764,9 +1856,10 @@ TEST(MessageEntities, parse_markdown_v3) { check_parse_markdown_v3( "__italic__ ~~strikethrough~~ **bold** `code` ```pre``` __[italic__ text_url](telegram.org) __italic**bold " "italic__bold**__italic__ ~~strikethrough~~ **bold** `code` ```pre``` __[italic__ text_url](telegram.org) " - "__italic**bold italic__bold** ||spoiler||", + "__italic**bold italic__bold** ||spoiler|| ```pre\nprecode``` init", + {{td::MessageEntity::Type::Italic, 271, 4}}, "italic strikethrough bold code pre italic text_url italicbold italicbolditalic strikethrough bold code pre " - "italic text_url italicbold italicbold spoiler", + "italic text_url italicbold italicbold spoiler precode init", {{td::MessageEntity::Type::Italic, 0, 6}, {td::MessageEntity::Type::Strikethrough, 7, 13}, {td::MessageEntity::Type::Bold, 21, 4}, @@ -1785,14 +1878,31 @@ TEST(MessageEntities, parse_markdown_v3) { {td::MessageEntity::Type::Italic, 107, 6}, {td::MessageEntity::Type::Italic, 123, 17}, {td::MessageEntity::Type::Bold, 129, 15}, - {td::MessageEntity::Type::Spoiler, 145, 7}}); + {td::MessageEntity::Type::Spoiler, 145, 7}, + {td::MessageEntity::Type::PreCode, 153, 7, "pre"}, + {td::MessageEntity::Type::Italic, 161, 4}}); + check_parse_markdown_v3("```\nsome code\n```", "some code\n", {{td::MessageEntity::Type::Pre, 0, 10}}); + check_parse_markdown_v3("asd\n```\nsome code\n```cabab", "asd\nsome code\ncabab", + {{td::MessageEntity::Type::Pre, 4, 10}}); + check_parse_markdown_v3("asd\naba```\nsome code\n```cabab", "asd\nabasome code\ncabab", + {{td::MessageEntity::Type::Pre, 7, 10}}); + check_parse_markdown_v3("asd\naba```\nsome code\n```\ncabab", "asd\nabasome code\n\ncabab", + {{td::MessageEntity::Type::Pre, 7, 10}}); + check_parse_markdown_v3("asd\naba```a b\nsome code\n```\ncabab", "asd\nabaa b\nsome code\n\ncabab", + {{td::MessageEntity::Type::Pre, 7, 14}}); + check_parse_markdown_v3("asd\naba```a!@#$%^&*(b\nsome code\n```\ncabab", "asd\nabasome code\n\ncabab", + {{td::MessageEntity::Type::PreCode, 7, 10, "a!@#$%^&*(b"}}); + check_parse_markdown_v3("```aba\n```", "aba\n", {{td::MessageEntity::Type::Pre, 0, 4}}); + check_parse_markdown_v3("```\n```", "\n", {{td::MessageEntity::Type::Pre, 0, 1}}); + check_parse_markdown_v3("```\n```", {{td::MessageEntity::Type::BlockQuote, 0, 7}}, "\n", + {{td::MessageEntity::Type::BlockQuote, 0, 1}, {td::MessageEntity::Type::Pre, 0, 1}}); td::vector<td::string> parts{"a", " #test__a", "__", "**", "~~", "||", "[", "](t.me)", "`"}; td::vector<td::MessageEntity::Type> types{ td::MessageEntity::Type::Bold, td::MessageEntity::Type::Italic, td::MessageEntity::Type::Underline, td::MessageEntity::Type::Strikethrough, td::MessageEntity::Type::Spoiler, td::MessageEntity::Type::Code, td::MessageEntity::Type::Pre, td::MessageEntity::Type::PreCode, td::MessageEntity::Type::TextUrl, - td::MessageEntity::Type::MentionName, td::MessageEntity::Type::Cashtag}; + td::MessageEntity::Type::MentionName, td::MessageEntity::Type::Cashtag, td::MessageEntity::Type::BlockQuote}; for (size_t test_n = 0; test_n < 1000; test_n++) { td::string str; int part_n = td::Random::fast(1, 200); @@ -1836,7 +1946,7 @@ static void check_get_markdown_v3(const td::string &result_text, const td::vecto } TEST(MessageEntities, get_markdown_v3) { - check_get_markdown_v3("``` ```", {}, " ", {{td::MessageEntity::Type::Pre, 0, 1}}); + check_get_markdown_v3("```\n ```", {}, " ", {{td::MessageEntity::Type::Pre, 0, 1}}); check_get_markdown_v3("` `", {}, " ", {{td::MessageEntity::Type::Code, 0, 1}}); check_get_markdown_v3("`\n`", {}, "\n", {{td::MessageEntity::Type::Code, 0, 1}}); check_get_markdown_v3("ab", {{td::MessageEntity::Type::Code, 0, 1}, {td::MessageEntity::Type::Pre, 1, 1}}, "ab", @@ -1851,16 +1961,18 @@ TEST(MessageEntities, get_markdown_v3) { check_get_markdown_v3("** **", {}, " ", {{td::MessageEntity::Type::Bold, 0, 1}}); check_get_markdown_v3("~~ ~~", {}, " ", {{td::MessageEntity::Type::Strikethrough, 0, 1}}); check_get_markdown_v3("|| ||", {}, " ", {{td::MessageEntity::Type::Spoiler, 0, 1}}); - check_get_markdown_v3("__a__ **b** ~~c~~ ||d|| e", {{td::MessageEntity::Type::PreCode, 24, 1, "C++"}}, "a b c d e", + check_get_markdown_v3("__a__ **b** ~~c~~ ||d|| e", {{td::MessageEntity::Type::PreCode, 24, 1, " C++"}}, "a b c d e", {{td::MessageEntity::Type::Italic, 0, 1}, {td::MessageEntity::Type::Bold, 2, 1}, {td::MessageEntity::Type::Strikethrough, 4, 1}, {td::MessageEntity::Type::Spoiler, 6, 1}, - {td::MessageEntity::Type::PreCode, 8, 1, "C++"}}); - check_get_markdown_v3("`ab` ```cd``` ef", {{td::MessageEntity::Type::PreCode, 14, 2, "C++"}}, "ab cd ef", - {{td::MessageEntity::Type::Code, 0, 2}, - {td::MessageEntity::Type::Pre, 3, 2}, - {td::MessageEntity::Type::PreCode, 6, 2, "C++"}}); + {td::MessageEntity::Type::PreCode, 8, 1, " C++"}}); + check_get_markdown_v3("```cpp\ngh```\n`ab`\n```\ncd```\nef", {{td::MessageEntity::Type::PreCode, 28, 2, " C++"}}, + "gh\nab\ncd\nef", + {{td::MessageEntity::Type::PreCode, 0, 2, "cpp"}, + {td::MessageEntity::Type::Code, 3, 2}, + {td::MessageEntity::Type::Pre, 6, 2}, + {td::MessageEntity::Type::PreCode, 9, 2, " C++"}}); check_get_markdown_v3("__asd__[__ab__cd](http://t.me/)", {}, "asdabcd", {{td::MessageEntity::Type::Italic, 0, 3}, {td::MessageEntity::Type::TextUrl, 3, 4, "http://t.me/"}, @@ -1879,4 +1991,19 @@ TEST(MessageEntities, get_markdown_v3) { {{td::MessageEntity::Type::TextUrl, 0, 16, "http://example.com/"}, {td::MessageEntity::Type::Bold, 0, 16}, {td::MessageEntity::Type::Italic, 0, 16}}); + check_get_markdown_v3("```\nsome code\n```", {}, "some code\n", {{td::MessageEntity::Type::Pre, 0, 10}}); + check_get_markdown_v3("asd\n```\nsome code\n```cabab", {}, "asd\nsome code\ncabab", + {{td::MessageEntity::Type::Pre, 4, 10}}); + check_get_markdown_v3("asd\naba```\nsome code\n```cabab", {}, "asd\nabasome code\ncabab", + {{td::MessageEntity::Type::Pre, 7, 10}}); + check_get_markdown_v3("asd\naba```\nsome code\n```\ncabab", {}, "asd\nabasome code\n\ncabab", + {{td::MessageEntity::Type::Pre, 7, 10}}); + check_get_markdown_v3("asd\naba```\na b\nsome code\n```\ncabab", {}, "asd\nabaa b\nsome code\n\ncabab", + {{td::MessageEntity::Type::Pre, 7, 14}}); + check_get_markdown_v3("asd\n```\na b\nsome code\n```\ncabab", {}, "asd\na b\nsome code\n\ncabab", + {{td::MessageEntity::Type::Pre, 4, 14}}); + check_get_markdown_v3("asd\naba```a!@#$%^&*(b\nsome code\n```\ncabab", {}, "asd\nabasome code\n\ncabab", + {{td::MessageEntity::Type::PreCode, 7, 10, "a!@#$%^&*(b"}}); + check_get_markdown_v3("```\naba\n```", {}, "aba\n", {{td::MessageEntity::Type::Pre, 0, 4}}); + check_get_markdown_v3("```\n```", {}, "\n", {{td::MessageEntity::Type::Pre, 0, 1}}); } diff --git a/protocols/Telegram/tdlib/td/test/mtproto.cpp b/protocols/Telegram/tdlib/td/test/mtproto.cpp index 614e153e6f..72d1af5d73 100644 --- a/protocols/Telegram/tdlib/td/test/mtproto.cpp +++ b/protocols/Telegram/tdlib/td/test/mtproto.cpp @@ -1,14 +1,13 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/ConfigManager.h" -#include "td/telegram/net/DcId.h" -#include "td/telegram/net/PublicRsaKeyShared.h" -#include "td/telegram/net/Session.h" +#include "td/telegram/net/PublicRsaKeySharedMain.h" #include "td/telegram/NotificationManager.h" +#include "td/telegram/telegram_api.h" #include "td/mtproto/AuthData.h" #include "td/mtproto/DhCallback.h" @@ -34,6 +33,7 @@ #include "td/utils/BufferedFd.h" #include "td/utils/common.h" #include "td/utils/crypto.h" +#include "td/utils/HttpDate.h" #include "td/utils/logging.h" #include "td/utils/port/Clocks.h" #include "td/utils/port/IPAddress.h" @@ -46,6 +46,8 @@ #include "td/utils/tests.h" #include "td/utils/Time.h" +#include <memory> + TEST(Mtproto, GetHostByNameActor) { int threads_n = 1; td::ConcurrentScheduler sched(threads_n, 0); @@ -194,7 +196,7 @@ TEST(Mtproto, encrypted_config) { "FnWWdEV+BPJeOTk+ARHcNkuJBt0CqnfcVCoDOpKqGyq0U31s2MOpQvHgAG+Tlpg02syuH0E4dCGRw5CbJPARiynteb9y5fT5x/" "kmdp6BMR5tWQSQF0liH16zLh8BDSIdiMsikdcwnAvBwdNhRqQBqGx9MTh62MDmlebjtczE9Gz0z5cscUO2yhzGdphgIy6SP+" "bwaqLWYF0XdPGjKLMUEJW+rou6fbL1t/EUXPtU0XmQAnO0Fh86h+AqDMOe30N4qKrPQ== "; - auto config = td::decode_config(data).move_as_ok(); + td::telegram_api::object_ptr<td::telegram_api::help_configSimple> config = td::decode_config(data).move_as_ok(); } class TestPingActor final : public td::Actor { @@ -300,11 +302,11 @@ class HandshakeContext final : public td::mtproto::AuthKeyHandshakeContext { return nullptr; } td::mtproto::PublicRsaKeyInterface *get_public_rsa_key_interface() final { - return &public_rsa_key; + return public_rsa_key_.get(); } private: - td::PublicRsaKeyShared public_rsa_key{td::DcId::empty(), true}; + std::shared_ptr<td::mtproto::PublicRsaKeyInterface> public_rsa_key_ = td::PublicRsaKeySharedMain::create(true); }; class HandshakeTestActor final : public td::Actor { @@ -365,11 +367,11 @@ class HandshakeTestActor final : public td::Actor { 10.0, td::PromiseCreator::lambda( [actor_id = actor_id(this)](td::Result<td::unique_ptr<td::mtproto::RawConnection>> raw_connection) { - td::send_closure(actor_id, &HandshakeTestActor::got_connection, std::move(raw_connection), 1); + td::send_closure(actor_id, &HandshakeTestActor::on_connection, std::move(raw_connection), 1); }), td::PromiseCreator::lambda( [actor_id = actor_id(this)](td::Result<td::unique_ptr<td::mtproto::AuthKeyHandshake>> handshake) { - td::send_closure(actor_id, &HandshakeTestActor::got_handshake, std::move(handshake), 1); + td::send_closure(actor_id, &HandshakeTestActor::on_handshake, std::move(handshake), 1); })) .release(); wait_for_raw_connection_ = true; @@ -377,7 +379,7 @@ class HandshakeTestActor final : public td::Actor { } } - void got_connection(td::Result<td::unique_ptr<td::mtproto::RawConnection>> r_raw_connection, bool dummy) { + void on_connection(td::Result<td::unique_ptr<td::mtproto::RawConnection>> r_raw_connection, bool dummy) { CHECK(wait_for_raw_connection_); wait_for_raw_connection_ = false; if (r_raw_connection.is_ok()) { @@ -390,7 +392,7 @@ class HandshakeTestActor final : public td::Actor { loop(); } - void got_handshake(td::Result<td::unique_ptr<td::mtproto::AuthKeyHandshake>> r_handshake, bool dummy) { + void on_handshake(td::Result<td::unique_ptr<td::mtproto::AuthKeyHandshake>> r_handshake, bool dummy) { CHECK(wait_for_handshake_); wait_for_handshake_ = false; CHECK(r_handshake.is_ok()); @@ -553,16 +555,16 @@ class FastPingTestActor final : public td::Actor { "HandshakeActor", std::move(handshake), std::move(raw_connection), td::make_unique<HandshakeContext>(), 10.0, td::PromiseCreator::lambda( [actor_id = actor_id(this)](td::Result<td::unique_ptr<td::mtproto::RawConnection>> raw_connection) { - td::send_closure(actor_id, &FastPingTestActor::got_connection, std::move(raw_connection), 1); + td::send_closure(actor_id, &FastPingTestActor::on_connection, std::move(raw_connection), 1); }), td::PromiseCreator::lambda( [actor_id = actor_id(this)](td::Result<td::unique_ptr<td::mtproto::AuthKeyHandshake>> handshake) { - td::send_closure(actor_id, &FastPingTestActor::got_handshake, std::move(handshake), 1); + td::send_closure(actor_id, &FastPingTestActor::on_handshake, std::move(handshake), 1); })) .release(); } - void got_connection(td::Result<td::unique_ptr<td::mtproto::RawConnection>> r_raw_connection, bool dummy) { + void on_connection(td::Result<td::unique_ptr<td::mtproto::RawConnection>> r_raw_connection, bool dummy) { if (r_raw_connection.is_error()) { *result_ = r_raw_connection.move_as_error(); LOG(INFO) << "Receive " << *result_ << " instead of a connection"; @@ -572,7 +574,7 @@ class FastPingTestActor final : public td::Actor { loop(); } - void got_handshake(td::Result<td::unique_ptr<td::mtproto::AuthKeyHandshake>> r_handshake, bool dummy) { + void on_handshake(td::Result<td::unique_ptr<td::mtproto::AuthKeyHandshake>> r_handshake, bool dummy) { if (r_handshake.is_error()) { *result_ = r_handshake.move_as_error(); LOG(INFO) << "Receive " << *result_ << " instead of a handshake"; @@ -582,7 +584,7 @@ class FastPingTestActor final : public td::Actor { loop(); } - void got_raw_connection(td::Result<td::unique_ptr<td::mtproto::RawConnection>> r_connection) { + void on_raw_connection(td::Result<td::unique_ptr<td::mtproto::RawConnection>> r_connection) { if (r_connection.is_error()) { *result_ = r_connection.move_as_error(); LOG(INFO) << "Receive " << *result_ << " instead of a handshake"; @@ -619,7 +621,7 @@ class FastPingTestActor final : public td::Actor { td::Slice(), std::move(connection_), std::move(auth_data), td::PromiseCreator::lambda( [actor_id = actor_id(this)](td::Result<td::unique_ptr<td::mtproto::RawConnection>> r_raw_connection) { - td::send_closure(actor_id, &FastPingTestActor::got_raw_connection, std::move(r_raw_connection)); + td::send_closure(actor_id, &FastPingTestActor::on_raw_connection, std::move(r_raw_connection)); }), td::ActorShared<>()); } diff --git a/protocols/Telegram/tdlib/td/test/online.cpp b/protocols/Telegram/tdlib/td/test/online.cpp index de7afa8a66..db5faa8771 100644 --- a/protocols/Telegram/tdlib/td/test/online.cpp +++ b/protocols/Telegram/tdlib/td/test/online.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -224,7 +224,9 @@ class InitTask : public Task { void start_up() override { send_query(td::make_tl_object<td::td_api::getOption>("version"), - [](auto res) { LOG(INFO) << td::td_api::to_string(res.ok()); }); + [](td::Result<td::td_api::object_ptr<td::td_api::OptionValue>> res) { + LOG(INFO) << td::td_api::to_string(res.ok()); + }); } void process_authorization_state(td::tl_object_ptr<td::td_api::Object> authorization_state) { td::tl_object_ptr<td::td_api::Function> function; @@ -244,7 +246,6 @@ class InitTask : public Task { request->system_language_code_ = "en"; request->device_model_ = "Desktop"; request->application_version_ = "tdclient-test"; - request->enable_storage_optimizer_ = true; send(std::move(request)); break; } @@ -258,7 +259,7 @@ class InitTask : public Task { } template <class T> void send(T &&query) { - send_query(std::move(query), [this](auto res) { + send_query(std::move(query), [this](td::Result<typename T::element_type::ReturnType> res) { if (is_alive()) { res.ensure(); } @@ -284,7 +285,9 @@ class GetMe : public Task { explicit GetMe(Promise<Result> promise) : promise_(std::move(promise)) { } void start_up() override { - send_query(td::make_tl_object<td::td_api::getMe>(), [this](auto res) { with_user_id(res.move_as_ok()->id_); }); + send_query( + td::make_tl_object<td::td_api::getMe>(), + [this](td::Result<td::td_api::object_ptr<td::td_api::user>> res) { with_user_id(res.move_as_ok()->id_); }); } private: @@ -293,8 +296,9 @@ class GetMe : public Task { void with_user_id(int64 user_id) { result_.user_id = user_id; - send_query(td::make_tl_object<td::td_api::createPrivateChat>(user_id, false), - [this](auto res) { with_chat_id(res.move_as_ok()->id_); }); + send_query( + td::make_tl_object<td::td_api::createPrivateChat>(user_id, false), + [this](td::Result<td::td_api::object_ptr<td::td_api::chat>> res) { with_chat_id(res.move_as_ok()->id_); }); } void with_chat_id(int64 chat_id) { @@ -333,11 +337,11 @@ class UploadFile : public Task { write_file(content_path_, content_).ensure(); send_query(td::make_tl_object<td::td_api::sendMessage>( - chat_id_, 0, 0, nullptr, nullptr, + chat_id_, 0, nullptr, nullptr, nullptr, td::make_tl_object<td::td_api::inputMessageDocument>( td::make_tl_object<td::td_api::inputFileLocal>(content_path_), nullptr, true, td::make_tl_object<td::td_api::formattedText>("tag", td::Auto()))), - [this](auto res) { with_message(res.move_as_ok()); }); + [this](td::Result<td::td_api::object_ptr<td::td_api::message>> res) { with_message(res.move_as_ok()); }); } private: @@ -393,7 +397,7 @@ class TestDownloadFile : public Task { } void start_up() override { send_query(td::make_tl_object<td::td_api::getRemoteFile>(remote_id_, nullptr), - [this](auto res) { start_file(*res.ok()); }); + [this](td::Result<td::td_api::object_ptr<td::td_api::file>> res) { start_file(*res.ok()); }); } private: @@ -455,7 +459,7 @@ class TestDownloadFile : public Task { send_query(td::make_tl_object<td::td_api::downloadFile>( file_id_, 1, static_cast<int64>(ranges_.back().begin), static_cast<int64>(ranges_.back().end - ranges_.back().begin), true), - [this](auto res) { on_get_chunk(*res.ok()); }); + [this](td::Result<td::td_api::object_ptr<td::td_api::file>> res) { on_get_chunk(*res.ok()); }); } }; diff --git a/protocols/Telegram/tdlib/td/test/poll.cpp b/protocols/Telegram/tdlib/td/test/poll.cpp index 3629c3c136..757d9c0eda 100644 --- a/protocols/Telegram/tdlib/td/test/poll.cpp +++ b/protocols/Telegram/tdlib/td/test/poll.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/protocols/Telegram/tdlib/td/test/query_merger.cpp b/protocols/Telegram/tdlib/td/test/query_merger.cpp index becac44e65..1211407082 100644 --- a/protocols/Telegram/tdlib/td/test/query_merger.cpp +++ b/protocols/Telegram/tdlib/td/test/query_merger.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -70,7 +70,8 @@ class TestQueryMerger final : public td::Actor { } else { yield(); } - })); + }), + "TestQueryMerger::loop"); } } diff --git a/protocols/Telegram/tdlib/td/test/secret.cpp b/protocols/Telegram/tdlib/td/test/secret.cpp index bd54705695..48523ec27b 100644 --- a/protocols/Telegram/tdlib/td/test/secret.cpp +++ b/protocols/Telegram/tdlib/td/test/secret.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,8 +9,11 @@ #include "td/telegram/Global.h" #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/MessageId.h" +#include "td/telegram/net/NetQuery.h" +#include "td/telegram/net/NetQueryCreator.h" #include "td/telegram/secret_api.h" #include "td/telegram/SecretChatActor.h" +#include "td/telegram/SecretChatDb.h" #include "td/telegram/SecretChatId.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" @@ -66,7 +69,7 @@ class messages_getDhConfig { messages_getDhConfig() = default; - messages_getDhConfig(int32 version_, int32 random_length_); + messages_getDhConfig(int32 version, int32 random_length); static const int32 ID = 651135312; @@ -225,8 +228,8 @@ class messages_dhConfig final { messages_dhConfig() = default; - messages_dhConfig(int32 g_, BufferSlice &&p_, int32 version_, BufferSlice &&random_) - : g_(g_), p_(std::move(p_)), version_(version_), random_(std::move(random_)) { + messages_dhConfig(int32 g, BufferSlice &&p, int32 version, BufferSlice &&random) + : g_(g), p_(std::move(p)), version_(version), random_(std::move(random)) { } static const int32 ID = 740433629; @@ -249,6 +252,7 @@ class messages_dhConfig final { TlStoreString::store(random_, s); } }; +const int32 messages_dhConfig::ID; class encryptedChat final { public: @@ -262,15 +266,15 @@ class encryptedChat final { encryptedChat() = default; - encryptedChat(int32 id_, int64 access_hash_, int32 date_, int64 admin_id_, int64 participant_id_, - BufferSlice &&g_a_or_b_, int64 key_fingerprint_) - : id_(id_) - , access_hash_(access_hash_) - , date_(date_) - , admin_id_(admin_id_) - , participant_id_(participant_id_) - , g_a_or_b_(std::move(g_a_or_b_)) - , key_fingerprint_(key_fingerprint_) { + encryptedChat(int32 id, int64 access_hash, int32 date, int64 admin_id, int64 participant_id, BufferSlice &&g_a_or_b, + int64 key_fingerprint) + : id_(id) + , access_hash_(access_hash) + , date_(date) + , admin_id_(admin_id) + , participant_id_(participant_id) + , g_a_or_b_(std::move(g_a_or_b)) + , key_fingerprint_(key_fingerprint) { } static const int32 ID = -94974410; @@ -300,6 +304,7 @@ class encryptedChat final { TlStoreBinary::store(key_fingerprint_, s); } }; +const int32 encryptedChat::ID; class messages_sentEncryptedMessage final { public: @@ -307,7 +312,7 @@ class messages_sentEncryptedMessage final { messages_sentEncryptedMessage() = default; - explicit messages_sentEncryptedMessage(int32 date_) : date_(date_) { + explicit messages_sentEncryptedMessage(int32 date) : date_(date) { } static const int32 ID = 1443858741; @@ -361,7 +366,7 @@ class FakeBinlog final FakeBinlog() { register_actor("FakeBinlog", this).release(); } - void force_sync(Promise<> promise) final { + void force_sync(Promise<> promise, const char *source) final { if (pending_events_.empty()) { pending_events_.emplace_back(); } @@ -527,7 +532,7 @@ class FakeSecretChatContext final : public SecretChatActor::Context { return false; } - // We don't want to expose the whole NetQueryDispatcher, MessagesManager and ContactsManager. + // We don't want to expose the whole NetQueryDispatcher, MessagesManager and UserManager. // So it is more clear which parts of MessagesManager is really used. And it is much easier to create tests. void send_net_query(NetQueryPtr query, ActorShared<NetQueryCallback> callback, bool ordered) final; @@ -636,7 +641,7 @@ class Master final : public Actor { if (binlog_generation != binlog_generation_) { return promise.set_error(Status::Error("Binlog generation mismatch")); } - binlog_->force_sync(std::move(promise)); + binlog_->force_sync(std::move(promise), "sync_binlog"); } void on_closed() { LOG(INFO) << "CLOSED"; diff --git a/protocols/Telegram/tdlib/td/test/secure_storage.cpp b/protocols/Telegram/tdlib/td/test/secure_storage.cpp index 714e92f77a..e115e751b8 100644 --- a/protocols/Telegram/tdlib/td/test/secure_storage.cpp +++ b/protocols/Telegram/tdlib/td/test/secure_storage.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/protocols/Telegram/tdlib/td/test/set_with_position.cpp b/protocols/Telegram/tdlib/td/test/set_with_position.cpp index f8494b392b..ca2742f8ce 100644 --- a/protocols/Telegram/tdlib/td/test/set_with_position.cpp +++ b/protocols/Telegram/tdlib/td/test/set_with_position.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/protocols/Telegram/tdlib/td/test/string_cleaning.cpp b/protocols/Telegram/tdlib/td/test/string_cleaning.cpp index c597d7616c..a1bb9e989b 100644 --- a/protocols/Telegram/tdlib/td/test/string_cleaning.cpp +++ b/protocols/Telegram/tdlib/td/test/string_cleaning.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -112,4 +112,8 @@ TEST(StringCleaning, strip_empty_characters) { check_strip_empty_characters( "\xe2\x80\xa7\xe2\x80\xa8\xe2\x80\xa9\xe2\x80\xaa\xe2\x80\xab\xe2\x80\xac\xe2\x80\xad\xe2\x80\xae", 3, "\xe2\x80\xa7\xe2\x80\xa8\xe2\x80\xa9"); + check_strip_empty_characters( + "\xF3\x9F\xBF\xBF\xF3\xA0\x80\x80\xF3\xA0\x80\x81\xF3\xA0\x80\xBF\xF3\xA0\x81\x80\xF3\xA0\x81\x81\xF3\xA0\x81\xBF" + "\xF3\xA0\x82\x80", + 9, "\xF3\x9F\xBF\xBF \xF3\xA0\x82\x80"); } diff --git a/protocols/Telegram/tdlib/td/test/tdclient.cpp b/protocols/Telegram/tdlib/td/test/tdclient.cpp index a608c75593..66f0ae6154 100644 --- a/protocols/Telegram/tdlib/td/test/tdclient.cpp +++ b/protocols/Telegram/tdlib/td/test/tdclient.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -224,7 +224,7 @@ class DoAuthentication final : public TestClinetTask { function = td::make_tl_object<td::td_api::checkAuthenticationCode>(code_); break; case td::td_api::authorizationStateWaitRegistration::ID: - function = td::make_tl_object<td::td_api::registerUser>(name_, ""); + function = td::make_tl_object<td::td_api::registerUser>(name_, "", false); break; case td::td_api::authorizationStateWaitTdlibParameters::ID: { auto request = td::td_api::make_object<td::td_api::setTdlibParameters>(); @@ -237,7 +237,6 @@ class DoAuthentication final : public TestClinetTask { request->system_language_code_ = "en"; request->device_model_ = "Desktop"; request->application_version_ = "tdclient-test"; - request->enable_storage_optimizer_ = true; function = std::move(request); break; } @@ -311,10 +310,10 @@ class SetUsername final : public TestClinetTask { CHECK(res->get_id() == td::td_api::chat::ID); auto chat = td::move_tl_object_as<td::td_api::chat>(res); this->send_query(td::make_tl_object<td::td_api::sendMessage>( - chat->id_, 0, 0, nullptr, nullptr, + chat->id_, 0, nullptr, nullptr, nullptr, td::make_tl_object<td::td_api::inputMessageText>( td::make_tl_object<td::td_api::formattedText>(PSTRING() << tag_ << " INIT", td::Auto()), - false, false)), + nullptr, false)), [](auto res) {}); }); } @@ -382,10 +381,10 @@ class TestA final : public TestClinetTask { for (int i = 0; i < 20; i++) { this->send_query( td::make_tl_object<td::td_api::sendMessage>( - chat->id_, 0, 0, nullptr, nullptr, + chat->id_, 0, nullptr, nullptr, nullptr, td::make_tl_object<td::td_api::inputMessageText>( td::make_tl_object<td::td_api::formattedText>(PSTRING() << tag_ << " " << (1000 + i), td::Auto()), - false, false)), + nullptr, false)), [&](auto res) { this->stop(); }); } }); @@ -431,10 +430,10 @@ class TestSecretChat final : public TestClinetTask { for (int i = 0; i < 20; i++) { send_query( td::make_tl_object<td::td_api::sendMessage>( - chat_id_, 0, 0, nullptr, nullptr, + chat_id_, 0, nullptr, nullptr, nullptr, td::make_tl_object<td::td_api::inputMessageText>( td::make_tl_object<td::td_api::formattedText>(PSTRING() << tag_ << " " << (1000 + i), td::Auto()), - false, false)), + nullptr, false)), [](auto res) {}); } } @@ -495,7 +494,7 @@ class TestFileGenerated final : public TestClinetTask { file.flush_write().ensure(); // important file.close(); send_query(td::make_tl_object<td::td_api::sendMessage>( - chat_id_, 0, 0, nullptr, nullptr, + chat_id_, 0, nullptr, nullptr, nullptr, td::make_tl_object<td::td_api::inputMessageDocument>( td::make_tl_object<td::td_api::inputFileGenerated>(file_path, "square", 0), td::make_tl_object<td::td_api::inputThumbnail>( @@ -504,7 +503,7 @@ class TestFileGenerated final : public TestClinetTask { [](auto res) { check_td_error(res); }); send_query(td::make_tl_object<td::td_api::sendMessage>( - chat_id_, 0, 0, nullptr, nullptr, + chat_id_, 0, nullptr, nullptr, nullptr, td::make_tl_object<td::td_api::inputMessageDocument>( td::make_tl_object<td::td_api::inputFileGenerated>(file_path, "square", 0), nullptr, true, td::make_tl_object<td::td_api::formattedText>(tag_, td::Auto()))), @@ -612,10 +611,10 @@ class CheckTestC final : public TestClinetTask { void one_file() { send_query(td::make_tl_object<td::td_api::sendMessage>( - chat_id_, 0, 0, nullptr, nullptr, + chat_id_, 0, nullptr, nullptr, nullptr, td::make_tl_object<td::td_api::inputMessageText>( td::make_tl_object<td::td_api::formattedText>(PSTRING() << tag_ << " ONE_FILE", td::Auto()), - false, false)), + nullptr, false)), [](auto res) { check_td_error(res); }); } diff --git a/protocols/Telegram/tdlib/td/test/tqueue.cpp b/protocols/Telegram/tdlib/td/test/tqueue.cpp index 9c3da0034c..50f58e4dbe 100644 --- a/protocols/Telegram/tdlib/td/test/tqueue.cpp +++ b/protocols/Telegram/tdlib/td/test/tqueue.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -31,7 +31,7 @@ TEST(TQueue, hands) { auto qid = 12; ASSERT_EQ(true, tqueue->get_head(qid).empty()); ASSERT_EQ(true, tqueue->get_tail(qid).empty()); - tqueue->push(qid, "hello", 1, 0, td::TQueue::EventId()); + tqueue->push(qid, "hello", 1, 0, td::TQueue::EventId()).ignore(); auto head = tqueue->get_head(qid); auto tail = tqueue->get_tail(qid); ASSERT_EQ(head.next().ok(), tail); |