summaryrefslogtreecommitdiff
path: root/protocols/Telegram/tdlib/td/test
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/tdlib/td/test')
-rw-r--r--protocols/Telegram/tdlib/td/test/CMakeLists.txt1
-rw-r--r--protocols/Telegram/tdlib/td/test/country_info.cpp59
-rw-r--r--protocols/Telegram/tdlib/td/test/crypto.cpp2
-rw-r--r--protocols/Telegram/tdlib/td/test/data.cpp2
-rw-r--r--protocols/Telegram/tdlib/td/test/data.h2
-rw-r--r--protocols/Telegram/tdlib/td/test/db.cpp112
-rw-r--r--protocols/Telegram/tdlib/td/test/fuzz_url.cpp2
-rw-r--r--protocols/Telegram/tdlib/td/test/http.cpp3
-rw-r--r--protocols/Telegram/tdlib/td/test/link.cpp681
-rw-r--r--protocols/Telegram/tdlib/td/test/main.cpp4
-rw-r--r--protocols/Telegram/tdlib/td/test/message_entities.cpp141
-rw-r--r--protocols/Telegram/tdlib/td/test/mtproto.cpp6
-rw-r--r--protocols/Telegram/tdlib/td/test/online.cpp28
-rw-r--r--protocols/Telegram/tdlib/td/test/poll.cpp2
-rw-r--r--protocols/Telegram/tdlib/td/test/query_merger.cpp102
-rw-r--r--protocols/Telegram/tdlib/td/test/secret.cpp40
-rw-r--r--protocols/Telegram/tdlib/td/test/secure_storage.cpp6
-rw-r--r--protocols/Telegram/tdlib/td/test/set_with_position.cpp2
-rw-r--r--protocols/Telegram/tdlib/td/test/string_cleaning.cpp3
-rw-r--r--protocols/Telegram/tdlib/td/test/tdclient.cpp29
-rw-r--r--protocols/Telegram/tdlib/td/test/tqueue.cpp16
21 files changed, 802 insertions, 441 deletions
diff --git a/protocols/Telegram/tdlib/td/test/CMakeLists.txt b/protocols/Telegram/tdlib/td/test/CMakeLists.txt
index 2ac9ad32d6..2a140a3af7 100644
--- a/protocols/Telegram/tdlib/td/test/CMakeLists.txt
+++ b/protocols/Telegram/tdlib/td/test/CMakeLists.txt
@@ -11,6 +11,7 @@ set(TD_TEST_SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/message_entities.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mtproto.cpp
${CMAKE_CURRENT_SOURCE_DIR}/poll.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/query_merger.cpp
${CMAKE_CURRENT_SOURCE_DIR}/secret.cpp
${CMAKE_CURRENT_SOURCE_DIR}/secure_storage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/set_with_position.cpp
diff --git a/protocols/Telegram/tdlib/td/test/country_info.cpp b/protocols/Telegram/tdlib/td/test/country_info.cpp
index bf88173915..0a9e3c26b6 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -7,11 +7,13 @@
#include "td/telegram/CountryInfoManager.h"
#include "td/utils/common.h"
+#include "td/utils/logging.h"
#include "td/utils/tests.h"
static void check_phone_number_info(td::string phone_number_prefix, const td::string &country_code,
- const td::string &calling_code, const td::string &formatted_phone_number) {
- auto result = td::CountryInfoManager::get_phone_number_info_sync(td::string(), std::move(phone_number_prefix));
+ const td::string &calling_code, const td::string &formatted_phone_number,
+ bool is_anonymous = false) {
+ auto result = td::CountryInfoManager::get_phone_number_info_sync(td::string(), phone_number_prefix);
CHECK(result != nullptr);
if (result->country_ == nullptr) {
CHECK(country_code.empty());
@@ -19,7 +21,11 @@ static void check_phone_number_info(td::string phone_number_prefix, const td::st
CHECK(result->country_->country_code_ == country_code);
}
CHECK(result->country_calling_code_ == calling_code);
- CHECK(result->formatted_phone_number_ == formatted_phone_number);
+ if (result->formatted_phone_number_ != formatted_phone_number) {
+ LOG(ERROR) << phone_number_prefix << ' ' << result->formatted_phone_number_ << ' ' << formatted_phone_number;
+ CHECK(result->formatted_phone_number_ == formatted_phone_number);
+ }
+ CHECK(result->is_anonymous_ == is_anonymous);
}
TEST(CountryInfo, phone_number_info) {
@@ -52,7 +58,7 @@ TEST(CountryInfo, phone_number_info) {
check_phone_number_info("77654321", "KZ", "7", "765 432 1- --");
check_phone_number_info("3", "", "3", "");
check_phone_number_info("37", "", "37", "");
- check_phone_number_info("372", "EE", "372", "---- ----");
+ check_phone_number_info("372", "EE", "372", "---- ---");
check_phone_number_info("42", "", "42", "");
check_phone_number_info("420", "CZ", "420", "--- --- ---");
check_phone_number_info("421", "SK", "421", "--- --- ---");
@@ -61,27 +67,36 @@ TEST(CountryInfo, phone_number_info) {
check_phone_number_info("424", "YL", "42", "4");
check_phone_number_info("4241234567890", "YL", "42", "41234567890");
check_phone_number_info("4", "", "4", "");
- check_phone_number_info("49", "DE", "49", "---- -------");
- check_phone_number_info("491", "DE", "49", "1--- -------");
- check_phone_number_info("492", "DE", "49", "2--- -------");
- check_phone_number_info("4915", "DE", "49", "15-- -------");
- check_phone_number_info("4916", "DE", "49", "16- -------");
- check_phone_number_info("4917", "DE", "49", "17- -------");
- check_phone_number_info("4918", "DE", "49", "18-- -------");
- check_phone_number_info("493", "DE", "49", "3--- -------");
- check_phone_number_info("4936", "DE", "49", "36-- -------");
- check_phone_number_info("49360", "DE", "49", "360- -------");
- check_phone_number_info("493601", "DE", "49", "3601 -------");
- check_phone_number_info("4936014", "DE", "49", "3601 4------");
- check_phone_number_info("4936015", "DE", "49", "3601 5------");
- check_phone_number_info("493601419", "DE", "49", "3601 419----");
- check_phone_number_info("4936014198", "DE", "49", "3601 4198--");
- check_phone_number_info("49360141980", "DE", "49", "3601 41980-");
+ check_phone_number_info("49", "DE", "49", "");
+ check_phone_number_info("491", "DE", "49", "1");
+ check_phone_number_info("492", "DE", "49", "2");
+ check_phone_number_info("4915", "DE", "49", "15");
+ check_phone_number_info("4916", "DE", "49", "16");
+ check_phone_number_info("4917", "DE", "49", "17");
+ check_phone_number_info("4918", "DE", "49", "18");
+ check_phone_number_info("493", "DE", "49", "3");
+ check_phone_number_info("4936", "DE", "49", "36");
+ check_phone_number_info("49360", "DE", "49", "360");
+ check_phone_number_info("493601", "DE", "49", "3601");
+ check_phone_number_info("4936014", "DE", "49", "36014");
+ check_phone_number_info("4936015", "DE", "49", "36015");
+ check_phone_number_info("493601419", "DE", "49", "3601419");
+ check_phone_number_info("4936014198", "DE", "49", "36014198");
+ check_phone_number_info("49360141980", "DE", "49", "360141980");
check_phone_number_info("841234567890", "VN", "84", "1234567890");
check_phone_number_info("31", "NL", "31", "- -- -- -- --");
check_phone_number_info("318", "NL", "31", "8 -- -- -- --");
check_phone_number_info("319", "NL", "31", "9 -- -- -- --");
check_phone_number_info("3196", "NL", "31", "9 6- -- -- --");
- check_phone_number_info("3197", "NL", "31", "97 ---- -----");
+ check_phone_number_info("3197", "NL", "31", "9 7- -- -- --");
check_phone_number_info("3198", "NL", "31", "9 8- -- -- --");
+ check_phone_number_info("88", "", "88", "");
+ check_phone_number_info("888", "FT", "888", "---- ----", true);
+ check_phone_number_info("8888", "FT", "888", "8 ---", true);
+ check_phone_number_info("88888", "FT", "888", "8 8--", true);
+ check_phone_number_info("888888", "FT", "888", "8 88-", true);
+ check_phone_number_info("8888888", "FT", "888", "8 888", true);
+ check_phone_number_info("88888888", "FT", "888", "8 8888", true);
+ check_phone_number_info("888888888", "FT", "888", "8 88888", true);
+ check_phone_number_info("8888888888", "FT", "888", "8 888888", true);
}
diff --git a/protocols/Telegram/tdlib/td/test/crypto.cpp b/protocols/Telegram/tdlib/td/test/crypto.cpp
index 1837cef631..f6657747f1 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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 34aff9b333..c53658d243 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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 07d863a894..79093e1996 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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 61757e9893..9e56e331f4 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -30,6 +30,7 @@
#include "td/utils/Random.h"
#include "td/utils/Slice.h"
#include "td/utils/Status.h"
+#include "td/utils/StringBuilder.h"
#include "td/utils/tests.h"
#include <limits>
@@ -62,6 +63,7 @@ TEST(DB, binlog_encryption_bug) {
binlog_name.str(), [&](const td::BinlogEvent &x) {}, cucumber)
.ensure();
}
+ td::Binlog::destroy(binlog_name).ignore();
}
TEST(DB, binlog_encryption) {
@@ -75,21 +77,22 @@ TEST(DB, binlog_encryption) {
{
td::Binlog binlog;
binlog.init(binlog_name.str(), [](const td::BinlogEvent &x) {}).ensure();
- binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_id(), 1, 0, td::create_storer("AAAA")),
+ binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_event_id(), 1, 0, td::create_storer("AAAA")),
td::BinlogDebugInfo{__FILE__, __LINE__});
- binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_id(), 1, 0, td::create_storer("BBBB")),
+ binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_event_id(), 1, 0, td::create_storer("BBBB")),
td::BinlogDebugInfo{__FILE__, __LINE__});
- binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_id(), 1, 0, td::create_storer(long_data)),
+ binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_event_id(), 1, 0, td::create_storer(long_data)),
td::BinlogDebugInfo{__FILE__, __LINE__});
LOG(INFO) << "SET PASSWORD";
binlog.change_key(cucumber);
binlog.change_key(hello);
LOG(INFO) << "OK";
- binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_id(), 1, 0, td::create_storer("CCCC")),
+ binlog.add_raw_event(td::BinlogEvent::create_raw(binlog.next_event_id(), 1, 0, td::create_storer("CCCC")),
td::BinlogDebugInfo{__FILE__, __LINE__});
binlog.close().ensure();
}
+ td::Binlog::destroy(binlog_name).ignore();
return;
auto add_suffix = [&] {
@@ -105,7 +108,7 @@ TEST(DB, binlog_encryption) {
td::Binlog binlog;
binlog
.init(
- binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.data_.str()); }, hello)
+ binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.get_data().str()); }, hello)
.ensure();
CHECK(v == td::vector<td::string>({"AAAA", "BBBB", long_data, "CCCC"}));
}
@@ -117,7 +120,7 @@ TEST(DB, binlog_encryption) {
LOG(INFO) << "RESTART";
td::Binlog binlog;
auto status = binlog.init(
- binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.data_.str()); }, cucumber);
+ binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.get_data().str()); }, cucumber);
CHECK(status.is_error());
}
@@ -128,9 +131,11 @@ TEST(DB, binlog_encryption) {
LOG(INFO) << "RESTART";
td::Binlog binlog;
auto status = binlog.init(
- binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.data_.str()); }, cucumber, hello);
+ binlog_name.str(), [&](const td::BinlogEvent &x) { v.push_back(x.get_data().str()); }, cucumber, hello);
CHECK(v == td::vector<td::string>({"AAAA", "BBBB", long_data, "CCCC"}));
}
+
+ td::Binlog::destroy(binlog_name).ignore();
}
TEST(DB, sqlite_lfs) {
@@ -264,13 +269,32 @@ TEST(DB, sqlite_encryption_migrate_v4) {
using SeqNo = td::uint64;
struct DbQuery {
- enum class Type { Get, Set, Erase } type = Type::Get;
+ enum class Type { Get, Set, Erase, EraseBatch } type = Type::Get;
SeqNo tid = 0;
- td::int32 id = 0;
td::string key;
td::string value;
+
+ // for EraseBatch
+ td::vector<td::string> erased_keys;
};
+static td::StringBuilder &operator<<(td::StringBuilder &string_builder, const DbQuery &query) {
+ string_builder << "seq_no = " << query.tid << ": ";
+ switch (query.type) {
+ case DbQuery::Type::Get:
+ return string_builder << "Get " << query.key << " = " << query.value;
+ case DbQuery::Type::Set:
+ return string_builder << "Set " << query.key << " = " << query.value;
+ case DbQuery::Type::Erase:
+ return string_builder << "Del " << query.key;
+ case DbQuery::Type::EraseBatch:
+ return string_builder << "Del " << query.erased_keys;
+ default:
+ UNREACHABLE();
+ return string_builder;
+ }
+}
+
template <class ImplT>
class QueryHandler {
public:
@@ -290,6 +314,10 @@ class QueryHandler {
impl_.erase(query.key);
query.tid = 1;
return;
+ case DbQuery::Type::EraseBatch:
+ impl_.erase_batch(query.erased_keys);
+ query.tid = 1;
+ return;
}
}
@@ -314,6 +342,9 @@ class SeqQueryHandler {
case DbQuery::Type::Erase:
query.tid = impl_.erase(query.key);
return;
+ case DbQuery::Type::EraseBatch:
+ query.tid = impl_.erase_batch(query.erased_keys);
+ return;
}
}
@@ -334,6 +365,12 @@ class SqliteKV {
kv_->get().erase(key);
return 0;
}
+ SeqNo erase_batch(td::vector<td::string> keys) {
+ for (auto &key : keys) {
+ kv_->get().erase(key);
+ }
+ return 0;
+ }
td::Status init(const td::string &name) {
auto sql_connection = std::make_shared<td::SqliteConnectionSafe>(name, td::DbKey::empty());
kv_ = std::make_shared<td::SqliteKeyValueSafe>("kv", sql_connection);
@@ -360,6 +397,14 @@ class BaselineKV {
map_.erase(key);
return ++current_tid_;
}
+ SeqNo erase_batch(td::vector<td::string> keys) {
+ for (auto &key : keys) {
+ map_.erase(key);
+ }
+ SeqNo result = current_tid_ + 1;
+ current_tid_ += map_.size();
+ return result;
+ }
private:
std::map<td::string, td::string> map_;
@@ -380,9 +425,8 @@ TEST(DB, key_value) {
int queries_n = 1000;
td::vector<DbQuery> queries(queries_n);
for (auto &q : queries) {
- int op = td::Random::fast(0, 2);
+ int op = td::Random::fast(0, 3);
const auto &key = rand_elem(keys);
- const auto &value = rand_elem(values);
if (op == 0) {
q.type = DbQuery::Type::Get;
q.key = key;
@@ -392,7 +436,13 @@ TEST(DB, key_value) {
} else if (op == 2) {
q.type = DbQuery::Type::Set;
q.key = key;
- q.value = value;
+ q.value = rand_elem(values);
+ } else if (op == 3) {
+ q.type = DbQuery::Type::EraseBatch;
+ q.erased_keys.resize(td::Random::fast(0, 3));
+ for (auto &erased_key : q.erased_keys) {
+ erased_key = rand_elem(keys);
+ }
}
}
@@ -494,17 +544,22 @@ TEST(DB, thread_key_value) {
for (auto &q : qs) {
int op = td::Random::fast(0, 10);
const auto &key = rand_elem(keys);
- const auto &value = rand_elem(values);
- if (op > 1) {
- q.type = DbQuery::Type::Get;
- q.key = key;
- } else if (op == 0) {
+ if (op == 0) {
q.type = DbQuery::Type::Erase;
q.key = key;
} else if (op == 1) {
+ q.type = DbQuery::Type::EraseBatch;
+ q.erased_keys.resize(td::Random::fast(0, 3));
+ for (auto &erased_key : q.erased_keys) {
+ erased_key = rand_elem(keys);
+ }
+ } else if (op <= 6) {
q.type = DbQuery::Type::Set;
q.key = key;
- q.value = value;
+ q.value = rand_elem(values);
+ } else {
+ q.type = DbQuery::Type::Get;
+ q.key = key;
}
}
}
@@ -606,17 +661,22 @@ TEST(DB, persistent_key_value) {
for (auto &q : qs) {
int op = td::Random::fast(0, 10);
const auto &key = rand_elem(keys);
- const auto &value = rand_elem(values);
- if (op > 1) {
- q.type = DbQuery::Type::Get;
- q.key = key;
- } else if (op == 0) {
+ if (op == 0) {
q.type = DbQuery::Type::Erase;
q.key = key;
} else if (op == 1) {
+ q.type = DbQuery::Type::EraseBatch;
+ q.erased_keys.resize(td::Random::fast(0, 3));
+ for (auto &erased_key : q.erased_keys) {
+ erased_key = rand_elem(keys);
+ }
+ } else if (op <= 6) {
q.type = DbQuery::Type::Set;
q.key = key;
- q.value = value;
+ q.value = rand_elem(values);
+ } else {
+ q.type = DbQuery::Type::Get;
+ q.key = key;
}
}
}
@@ -718,6 +778,7 @@ TEST(DB, persistent_key_value) {
if (was) {
continue;
}
+ LOG(DEBUG) << pos;
int best = -1;
SeqNo best_tid = 0;
@@ -728,6 +789,7 @@ TEST(DB, persistent_key_value) {
}
was = true;
auto &q = res[i][p];
+ LOG(DEBUG) << i << ' ' << p << ' ' << q;
if (q.tid != 0) {
if (best == -1 || q.tid < best_tid) {
best = i;
diff --git a/protocols/Telegram/tdlib/td/test/fuzz_url.cpp b/protocols/Telegram/tdlib/td/test/fuzz_url.cpp
index 0a1e880cbb..cd7af58a77 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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 2498c53e5c..e3d2301f6e 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -347,6 +347,7 @@ TEST(Http, aes_file_encryption) {
auto result = sink.result()->move_as_buffer_slice().as_slice().str();
ASSERT_EQ(str, result);
}
+ td::unlink(name).ignore();
}
TEST(Http, chunked_flow) {
diff --git a/protocols/Telegram/tdlib/td/test/link.cpp b/protocols/Telegram/tdlib/td/test/link.cpp
index 13c4613174..67b81c1354 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -81,14 +81,74 @@ TEST(Link, check_link) {
check_link("https://.", "");
}
+static td::td_api::object_ptr<td::td_api::InternalLinkType> get_internal_link_type_object(
+ const td::unique_ptr<td::LinkManager::InternalLink> &link) {
+ auto object = link->get_internal_link_type_object();
+ if (object->get_id() == td::td_api::internalLinkTypeMessageDraft::ID) {
+ static_cast<td::td_api::internalLinkTypeMessageDraft *>(object.get())->text_->entities_.clear();
+ }
+ return object;
+}
+
static void parse_internal_link(const td::string &url, td::td_api::object_ptr<td::td_api::InternalLinkType> expected) {
auto result = td::LinkManager::parse_internal_link(url);
if (result != nullptr) {
- auto object = result->get_internal_link_type_object();
- if (object->get_id() == td::td_api::internalLinkTypeMessageDraft::ID) {
- static_cast<td::td_api::internalLinkTypeMessageDraft *>(object.get())->text_->entities_.clear();
- }
+ auto object = get_internal_link_type_object(result);
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::internalLinkTypeMessage::ID) {
+ // external message links must be generated with getMessageLink
+ continue;
+ }
+ if (expected->get_id() == td::td_api::internalLinkTypeQrCodeAuthentication::ID) {
+ // QR code authentication links must never be generated manually
+ continue;
+ }
+ auto r_link = td::LinkManager::get_internal_link(expected, is_internal);
+ if (r_link.is_error()) {
+ if (r_link.error().message() == "HTTP link is unavailable for the link type") {
+ // some links are tg-only
+ continue;
+ }
+ if (r_link.error().message() == "Deep link is unavailable for the link type") {
+ // some links are HTTP-only
+ continue;
+ }
+ if (r_link.error().message() == "WALLPAPER_INVALID") {
+ continue;
+ }
+ LOG(ERROR) << url << ' ' << r_link.error() << ' ' << to_string(expected);
+ ASSERT_TRUE(r_link.is_ok());
+ }
+ auto new_result = td::LinkManager::parse_internal_link(r_link.ok());
+ ASSERT_TRUE(new_result != nullptr);
+ auto new_object = get_internal_link_type_object(new_result);
+
+ auto new_object_str = to_string(new_object);
+ auto expected_str = to_string(expected);
+ if (expected->get_id() == td::td_api::internalLinkTypeBackground::ID) {
+ for (auto &c : expected_str) {
+ if (c == '~') {
+ // getInternalLink always use '-'
+ c = '-';
+ }
+ }
+ if (new_object_str != expected_str && td::ends_with(expected_str, "\"\n}\n")) {
+ // getInternalLink always adds rotation parameter, because default value differs between apps
+ expected_str = expected_str.substr(0, expected_str.size() - 4) + "?rotation=0\"\n}\n";
+ }
+ }
+ ASSERT_EQ(new_object_str, expected_str);
+
+ r_link = td::LinkManager::get_internal_link(new_object, is_internal);
+ ASSERT_TRUE(r_link.is_ok());
+ new_result = td::LinkManager::parse_internal_link(r_link.ok());
+ ASSERT_TRUE(new_result != nullptr);
+
+ // the object must be the same after 2 round of conversion
+ ASSERT_STREQ(to_string(new_object), to_string(get_internal_link_type_object(new_result)));
+ }
} else {
LOG_IF(ERROR, expected != nullptr) << url;
ASSERT_TRUE(expected == nullptr);
@@ -97,159 +157,215 @@ static void parse_internal_link(const td::string &url, td::td_api::object_ptr<td
check_find_urls(url, result != nullptr);
}
-TEST(Link, parse_internal_link) {
- auto chat_administrator_rights = [](bool can_manage_chat, bool can_change_info, bool can_post_messages,
+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) {
- 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);
- };
- auto target_chat_chosen = [](bool allow_users, bool allow_bots, bool allow_groups, bool allow_channels) {
- return td::td_api::make_object<td::td_api::targetChatChosen>(allow_users, allow_bots, allow_groups, allow_channels);
- };
-
- auto active_sessions = [] {
- return td::td_api::make_object<td::td_api::internalLinkTypeActiveSessions>();
- };
- auto attachment_menu_bot = [](td::td_api::object_ptr<td::td_api::targetChatChosen> chat_types,
+ 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);
+}
+
+static auto target_chat_chosen(bool allow_users, bool allow_bots, bool allow_groups, bool allow_channels) {
+ return td::td_api::make_object<td::td_api::targetChatChosen>(allow_users, allow_bots, allow_groups, allow_channels);
+}
+
+static auto active_sessions() {
+ return td::td_api::make_object<td::td_api::internalLinkTypeActiveSessions>();
+}
+
+static auto attachment_menu_bot(td::td_api::object_ptr<td::td_api::targetChatChosen> chat_types,
td::td_api::object_ptr<td::td_api::InternalLinkType> chat_link,
const td::string &bot_username, const td::string &start_parameter) {
- td::td_api::object_ptr<td::td_api::TargetChat> target_chat;
- if (chat_link != nullptr) {
- target_chat = td::td_api::make_object<td::td_api::targetChatInternalLink>(std::move(chat_link));
- } else if (chat_types != nullptr) {
- target_chat = std::move(chat_types);
- } else {
- target_chat = td::td_api::make_object<td::td_api::targetChatCurrent>();
- }
- return td::td_api::make_object<td::td_api::internalLinkTypeAttachmentMenuBot>(
- std::move(target_chat), bot_username, start_parameter.empty() ? td::string() : "start://" + start_parameter);
- };
- auto authentication_code = [](const td::string &code) {
- return td::td_api::make_object<td::td_api::internalLinkTypeAuthenticationCode>(code);
- };
- auto background = [](const td::string &background_name) {
- return td::td_api::make_object<td::td_api::internalLinkTypeBackground>(background_name);
- };
- auto bot_add_to_channel = [](const td::string &bot_username,
+ td::td_api::object_ptr<td::td_api::TargetChat> target_chat;
+ if (chat_link != nullptr) {
+ target_chat = td::td_api::make_object<td::td_api::targetChatInternalLink>(std::move(chat_link));
+ } else if (chat_types != nullptr) {
+ target_chat = std::move(chat_types);
+ } else {
+ target_chat = td::td_api::make_object<td::td_api::targetChatCurrent>();
+ }
+ return td::td_api::make_object<td::td_api::internalLinkTypeAttachmentMenuBot>(
+ std::move(target_chat), bot_username, start_parameter.empty() ? td::string() : "start://" + start_parameter);
+}
+
+static auto authentication_code(const td::string &code) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeAuthenticationCode>(code);
+}
+
+static auto background(const td::string &background_name) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeBackground>(background_name);
+}
+
+static auto bot_add_to_channel(const td::string &bot_username,
td::td_api::object_ptr<td::td_api::chatAdministratorRights> &&administrator_rights) {
- return td::td_api::make_object<td::td_api::internalLinkTypeBotAddToChannel>(bot_username,
- std::move(administrator_rights));
- };
- auto bot_start = [](const td::string &bot_username, const td::string &start_parameter) {
- return td::td_api::make_object<td::td_api::internalLinkTypeBotStart>(bot_username, start_parameter, false);
- };
- auto bot_start_in_group = [](const td::string &bot_username, const td::string &start_parameter,
+ return td::td_api::make_object<td::td_api::internalLinkTypeBotAddToChannel>(bot_username,
+ std::move(administrator_rights));
+}
+
+static auto bot_start(const td::string &bot_username, const td::string &start_parameter) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeBotStart>(bot_username, start_parameter, false);
+}
+
+static auto bot_start_in_group(const td::string &bot_username, const td::string &start_parameter,
td::td_api::object_ptr<td::td_api::chatAdministratorRights> &&administrator_rights) {
- return td::td_api::make_object<td::td_api::internalLinkTypeBotStartInGroup>(bot_username, start_parameter,
- std::move(administrator_rights));
- };
- auto change_phone_number = [] {
- return td::td_api::make_object<td::td_api::internalLinkTypeChangePhoneNumber>();
- };
- auto chat_invite = [](const td::string &hash) {
- return td::td_api::make_object<td::td_api::internalLinkTypeChatInvite>("tg:join?invite=" + hash);
- };
- auto filter_settings = [] {
- return td::td_api::make_object<td::td_api::internalLinkTypeFilterSettings>();
- };
- auto game = [](const td::string &bot_username, const td::string &game_short_name) {
- return td::td_api::make_object<td::td_api::internalLinkTypeGame>(bot_username, game_short_name);
- };
- auto instant_view = [](const td::string &url, const td::string &fallback_url) {
- return td::td_api::make_object<td::td_api::internalLinkTypeInstantView>(url, fallback_url);
- };
- auto invoice = [](const td::string &invoice_name) {
- return td::td_api::make_object<td::td_api::internalLinkTypeInvoice>(invoice_name);
- };
- auto language_pack = [](const td::string &language_pack_name) {
- return td::td_api::make_object<td::td_api::internalLinkTypeLanguagePack>(language_pack_name);
- };
- auto language_settings = [] {
- return td::td_api::make_object<td::td_api::internalLinkTypeLanguageSettings>();
- };
- auto message = [](const td::string &url) {
- return td::td_api::make_object<td::td_api::internalLinkTypeMessage>(url);
- };
- auto message_draft = [](td::string text, bool contains_url) {
- auto formatted_text = td::td_api::make_object<td::td_api::formattedText>();
- formatted_text->text_ = std::move(text);
- return td::td_api::make_object<td::td_api::internalLinkTypeMessageDraft>(std::move(formatted_text), contains_url);
- };
- auto passport_data_request = [](td::int32 bot_user_id, const td::string &scope, const td::string &public_key,
+ return td::td_api::make_object<td::td_api::internalLinkTypeBotStartInGroup>(bot_username, start_parameter,
+ std::move(administrator_rights));
+}
+
+static auto change_phone_number() {
+ return td::td_api::make_object<td::td_api::internalLinkTypeChangePhoneNumber>();
+}
+
+static auto chat_folder_invite(const td::string &slug) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeChatFolderInvite>("tg:addlist?slug=" + slug);
+}
+
+static auto chat_folder_settings() {
+ return td::td_api::make_object<td::td_api::internalLinkTypeChatFolderSettings>();
+}
+
+static auto chat_invite(const td::string &hash) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeChatInvite>("tg:join?invite=" + hash);
+}
+
+static auto default_message_auto_delete_timer_settings() {
+ return td::td_api::make_object<td::td_api::internalLinkTypeDefaultMessageAutoDeleteTimerSettings>();
+}
+
+static auto edit_profile_settings() {
+ return td::td_api::make_object<td::td_api::internalLinkTypeEditProfileSettings>();
+}
+
+static auto game(const td::string &bot_username, const td::string &game_short_name) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeGame>(bot_username, game_short_name);
+}
+
+static auto instant_view(const td::string &url, const td::string &fallback_url) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeInstantView>(url, fallback_url);
+}
+
+static auto invoice(const td::string &invoice_name) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeInvoice>(invoice_name);
+}
+
+static auto language_pack(const td::string &language_pack_name) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeLanguagePack>(language_pack_name);
+}
+
+static auto language_settings() {
+ return td::td_api::make_object<td::td_api::internalLinkTypeLanguageSettings>();
+}
+
+static auto message(const td::string &url) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeMessage>(url);
+}
+
+static auto message_draft(td::string text, bool contains_url) {
+ auto formatted_text = td::td_api::make_object<td::td_api::formattedText>();
+ formatted_text->text_ = std::move(text);
+ return td::td_api::make_object<td::td_api::internalLinkTypeMessageDraft>(std::move(formatted_text), contains_url);
+}
+
+static auto passport_data_request(td::int32 bot_user_id, const td::string &scope, const td::string &public_key,
const td::string &nonce, const td::string &callback_url) {
- return td::td_api::make_object<td::td_api::internalLinkTypePassportDataRequest>(bot_user_id, scope, public_key,
- nonce, callback_url);
- };
- auto phone_number_confirmation = [](const td::string &hash, const td::string &phone_number) {
- return td::td_api::make_object<td::td_api::internalLinkTypePhoneNumberConfirmation>(hash, phone_number);
- };
- auto premium_features = [](const td::string &referrer) {
- return td::td_api::make_object<td::td_api::internalLinkTypePremiumFeatures>(referrer);
- };
- auto privacy_and_security_settings = [] {
- return td::td_api::make_object<td::td_api::internalLinkTypePrivacyAndSecuritySettings>();
- };
- auto proxy_mtproto = [](const td::string &server, td::int32 port, const td::string &secret) {
- return td::td_api::make_object<td::td_api::internalLinkTypeProxy>(
- server, port, td::td_api::make_object<td::td_api::proxyTypeMtproto>(secret));
- };
- auto proxy_socks = [](const td::string &server, td::int32 port, const td::string &username,
+ return td::td_api::make_object<td::td_api::internalLinkTypePassportDataRequest>(bot_user_id, scope, public_key, nonce,
+ callback_url);
+}
+
+static auto phone_number_confirmation(const td::string &hash, const td::string &phone_number) {
+ return td::td_api::make_object<td::td_api::internalLinkTypePhoneNumberConfirmation>(hash, phone_number);
+}
+
+static auto premium_features(const td::string &referrer) {
+ return td::td_api::make_object<td::td_api::internalLinkTypePremiumFeatures>(referrer);
+}
+
+static auto privacy_and_security_settings() {
+ return td::td_api::make_object<td::td_api::internalLinkTypePrivacyAndSecuritySettings>();
+}
+
+static auto proxy_mtproto(const td::string &server, td::int32 port, const td::string &secret) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeProxy>(
+ server, port, td::td_api::make_object<td::td_api::proxyTypeMtproto>(secret));
+}
+
+static auto proxy_socks(const td::string &server, td::int32 port, const td::string &username,
const td::string &password) {
- return td::td_api::make_object<td::td_api::internalLinkTypeProxy>(
- server, port, td::td_api::make_object<td::td_api::proxyTypeSocks5>(username, password));
- };
- auto public_chat = [](const td::string &chat_username) {
- return td::td_api::make_object<td::td_api::internalLinkTypePublicChat>(chat_username);
- };
- auto qr_code_authentication = [] {
- return td::td_api::make_object<td::td_api::internalLinkTypeQrCodeAuthentication>();
- };
- auto restore_purchases = [] {
- return td::td_api::make_object<td::td_api::internalLinkTypeRestorePurchases>();
- };
- auto settings = [] {
- return td::td_api::make_object<td::td_api::internalLinkTypeSettings>();
- };
- auto sticker_set = [](const td::string &sticker_set_name) {
- return td::td_api::make_object<td::td_api::internalLinkTypeStickerSet>(sticker_set_name);
- };
- auto theme = [](const td::string &theme_name) {
- return td::td_api::make_object<td::td_api::internalLinkTypeTheme>(theme_name);
- };
- auto theme_settings = [] {
- return td::td_api::make_object<td::td_api::internalLinkTypeThemeSettings>();
- };
- auto unknown_deep_link = [](const td::string &link) {
- return td::td_api::make_object<td::td_api::internalLinkTypeUnknownDeepLink>(link);
- };
- auto unsupported_proxy = [] {
- return td::td_api::make_object<td::td_api::internalLinkTypeUnsupportedProxy>();
- };
- auto user_phone_number = [](const td::string &phone_number) {
- return td::td_api::make_object<td::td_api::internalLinkTypeUserPhoneNumber>(phone_number);
- };
- auto video_chat = [](const td::string &chat_username, const td::string &invite_hash, bool is_live_stream) {
- return td::td_api::make_object<td::td_api::internalLinkTypeVideoChat>(chat_username, invite_hash, is_live_stream);
- };
-
- parse_internal_link("t.me/levlam/1", message("tg:resolve?domain=levlam&post=1"));
- parse_internal_link("telegram.me/levlam/1", message("tg:resolve?domain=levlam&post=1"));
- parse_internal_link("telegram.dog/levlam/1", message("tg:resolve?domain=levlam&post=1"));
- parse_internal_link("www.t.me/levlam/1", message("tg:resolve?domain=levlam&post=1"));
- parse_internal_link("www%2etelegram.me/levlam/1", message("tg:resolve?domain=levlam&post=1"));
- parse_internal_link("www%2Etelegram.dog/levlam/1", message("tg:resolve?domain=levlam&post=1"));
+ return td::td_api::make_object<td::td_api::internalLinkTypeProxy>(
+ 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 qr_code_authentication() {
+ return td::td_api::make_object<td::td_api::internalLinkTypeQrCodeAuthentication>();
+}
+
+static auto restore_purchases() {
+ return td::td_api::make_object<td::td_api::internalLinkTypeRestorePurchases>();
+}
+
+static auto settings() {
+ return td::td_api::make_object<td::td_api::internalLinkTypeSettings>();
+}
+
+static auto sticker_set(const td::string &sticker_set_name, bool expect_custom_emoji) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeStickerSet>(sticker_set_name, expect_custom_emoji);
+}
+
+static auto theme(const td::string &theme_name) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeTheme>(theme_name);
+}
+
+static auto theme_settings() {
+ return td::td_api::make_object<td::td_api::internalLinkTypeThemeSettings>();
+}
+
+static auto unknown_deep_link(const td::string &link) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeUnknownDeepLink>(link);
+}
+
+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_token(const td::string &token) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeUserToken>(token);
+}
+
+static auto video_chat(const td::string &chat_username, const td::string &invite_hash, bool is_live_stream) {
+ return td::td_api::make_object<td::td_api::internalLinkTypeVideoChat>(chat_username, invite_hash, is_live_stream);
+}
+
+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);
+}
+
+TEST(Link, parse_internal_link_part1) {
+ parse_internal_link("t.me/levlam/1", message("tg://resolve?domain=levlam&post=1"));
+ parse_internal_link("telegram.me/levlam/1", message("tg://resolve?domain=levlam&post=1"));
+ parse_internal_link("telegram.dog/levlam/1", message("tg://resolve?domain=levlam&post=1"));
+ parse_internal_link("www.t.me/levlam/1", message("tg://resolve?domain=levlam&post=1"));
+ parse_internal_link("www%2etelegram.me/levlam/1", message("tg://resolve?domain=levlam&post=1"));
+ parse_internal_link("www%2Etelegram.dog/levlam/1", message("tg://resolve?domain=levlam&post=1"));
parse_internal_link("www%252Etelegram.dog/levlam/1", nullptr);
- parse_internal_link("www.t.me/s/s/s/s/s/joinchat/1", chat_invite("1"));
- parse_internal_link("www.t.me/s/%73/%73/s/%73/joinchat/1", chat_invite("1"));
- parse_internal_link("http://t.me/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/joinchat/1", chat_invite("1"));
- parse_internal_link("http://t.me/levlam/1", message("tg:resolve?domain=levlam&post=1"));
- parse_internal_link("https://t.me/levlam/1", message("tg:resolve?domain=levlam&post=1"));
- parse_internal_link("hTtp://www.t.me:443/levlam/1", message("tg:resolve?domain=levlam&post=1"));
- parse_internal_link("httPs://t.me:80/levlam/1", message("tg:resolve?domain=levlam&post=1"));
+ parse_internal_link("www.t.me/s/s/s/s/s/joinchat/1", nullptr);
+ parse_internal_link("www.t.me/s/s/s/s/s/joinchat/a", chat_invite("a"));
+ parse_internal_link("www.t.me/s/%73/%73/s/%73/joinchat/a", chat_invite("a"));
+ parse_internal_link("http://t.me/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/s/joinchat/a", chat_invite("a"));
+ parse_internal_link("http://t.me/levlam/1", message("tg://resolve?domain=levlam&post=1"));
+ parse_internal_link("https://t.me/levlam/1", message("tg://resolve?domain=levlam&post=1"));
+ parse_internal_link("hTtp://www.t.me:443/levlam/1", message("tg://resolve?domain=levlam&post=1"));
+ parse_internal_link("httPs://t.me:80/levlam/1", message("tg://resolve?domain=levlam&post=1"));
parse_internal_link("https://t.me:200/levlam/1", nullptr);
parse_internal_link("http:t.me/levlam/1", nullptr);
parse_internal_link("t.dog/levlam/1", nullptr);
@@ -257,13 +373,13 @@ TEST(Link, parse_internal_link) {
parse_internal_link("t.men/levlam/1", nullptr);
parse_internal_link("tg:resolve?domain=username&post=12345&single",
- message("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",
- message("tg:resolve?domain=username&post=12345&single"));
+ message("tg://resolve?domain=username&post=12345&single"));
parse_internal_link("tg:resolve?domain=user%31name&post=%312345&single&comment=456&t=789&single&thread=123%20%31",
- message("tg:resolve?domain=user1name&post=12345&single&thread=123%201&comment=456&t=789"));
+ message("tg://resolve?domain=user1name&post=12345&single&thread=123%201&comment=456&t=789"));
parse_internal_link("TG://resolve?domain=username&post=12345&single&voicechat=aasd",
- message("tg:resolve?domain=username&post=12345&single"));
+ message("tg://resolve?domain=username&post=12345&single"));
parse_internal_link("TG://test@resolve?domain=username&post=12345&single", nullptr);
parse_internal_link("tg:resolve:80?domain=username&post=12345&single", nullptr);
parse_internal_link("tg:http://resolve?domain=username&post=12345&single", nullptr);
@@ -318,20 +434,33 @@ TEST(Link, parse_internal_link) {
parse_internal_link("tg:resolve?phone=+123", unknown_deep_link("tg://resolve?phone=+123"));
parse_internal_link("tg:resolve?phone=123456 ", unknown_deep_link("tg://resolve?phone=123456 "));
- parse_internal_link("t.me/username/12345?single", message("tg:resolve?domain=username&post=12345&single"));
- parse_internal_link("t.me/username/12345?asdasd", message("tg:resolve?domain=username&post=12345"));
- parse_internal_link("t.me/username/12345", message("tg:resolve?domain=username&post=12345"));
- parse_internal_link("t.me/username/12345/", message("tg:resolve?domain=username&post=12345"));
- parse_internal_link("t.me/username/12345#asdasd", message("tg:resolve?domain=username&post=12345"));
+ parse_internal_link("tg:contact?token=1", user_token("1"));
+ parse_internal_link("tg:contact?token=123456", user_token("123456"));
+ parse_internal_link("tg:contact?token=123456&startattach", user_token("123456"));
+ parse_internal_link("tg:contact?token=123456&startattach=123", user_token("123456"));
+ parse_internal_link("tg:contact?token=123456&attach=", user_token("123456"));
+ parse_internal_link("tg:contact?token=123456&attach=&startattach", user_token("123456"));
+ parse_internal_link("tg:contact?token=123456&attach=&startattach=123", user_token("123456"));
+ parse_internal_link("tg:contact?token=01234567890123456789012345678912",
+ user_token("01234567890123456789012345678912"));
+ parse_internal_link("tg:contact?token=012345678901234567890123456789123",
+ user_token("012345678901234567890123456789123"));
+ parse_internal_link("tg:contact?token=", unknown_deep_link("tg://contact?token="));
+ parse_internal_link("tg:contact?token=+123", user_token(" 123"));
+
+ parse_internal_link("t.me/username/12345?single", message("tg://resolve?domain=username&post=12345&single"));
+ parse_internal_link("t.me/username/12345?asdasd", message("tg://resolve?domain=username&post=12345"));
+ parse_internal_link("t.me/username/12345", message("tg://resolve?domain=username&post=12345"));
+ parse_internal_link("t.me/username/12345/", message("tg://resolve?domain=username&post=12345"));
+ parse_internal_link("t.me/username/12345#asdasd", message("tg://resolve?domain=username&post=12345"));
parse_internal_link("t.me/username/12345//?voicechat=&single",
- message("tg:resolve?domain=username&post=12345&single"));
+ message("tg://resolve?domain=username&post=12345&single"));
parse_internal_link("t.me/username/12345/asdasd//asd/asd/asd/?single",
- message("tg:resolve?domain=username&post=12345&single"));
+ message("tg://resolve?domain=username&post=12345&single"));
parse_internal_link("t.me/username/12345/67890/asdasd//asd/asd/asd/?single",
- message("tg:resolve?domain=username&post=67890&single&thread=12345"));
+ message("tg://resolve?domain=username&post=67890&single&thread=12345"));
parse_internal_link("t.me/username/1asdasdas/asdasd//asd/asd/asd/?single",
- message("tg:resolve?domain=username&post=1&single"));
- parse_internal_link("t.me/username/asd", public_chat("username"));
+ message("tg://resolve?domain=username&post=1&single"));
parse_internal_link("t.me/username/0", public_chat("username"));
parse_internal_link("t.me/username/-12345", public_chat("username"));
parse_internal_link("t.me//12345?single", nullptr);
@@ -364,19 +493,19 @@ TEST(Link, parse_internal_link) {
parse_internal_link("tg:privatepost?channel=username/12345&single",
unknown_deep_link("tg://privatepost?channel=username/12345&single"));
parse_internal_link("tg:privatepost?channel=username&post=12345",
- message("tg:privatepost?channel=username&post=12345"));
+ message("tg://privatepost?channel=username&post=12345"));
parse_internal_link("t.me/c/12345?single", nullptr);
parse_internal_link("t.me/c/1/c?single", nullptr);
parse_internal_link("t.me/c/c/1?single", nullptr);
parse_internal_link("t.me/c//1?single", nullptr);
- parse_internal_link("t.me/c/12345/123", message("tg:privatepost?channel=12345&post=123"));
- parse_internal_link("t.me/c/12345/123?single", message("tg:privatepost?channel=12345&post=123&single"));
- parse_internal_link("t.me/c/12345/123/asd/asd////?single", message("tg:privatepost?channel=12345&post=123&single"));
+ parse_internal_link("t.me/c/12345/123", message("tg://privatepost?channel=12345&post=123"));
+ parse_internal_link("t.me/c/12345/123?single", message("tg://privatepost?channel=12345&post=123&single"));
+ parse_internal_link("t.me/c/12345/123/asd/asd////?single", message("tg://privatepost?channel=12345&post=123&single"));
parse_internal_link("t.me/c/12345/123/456/asd/asd////?single",
- message("tg:privatepost?channel=12345&post=456&single&thread=123"));
+ message("tg://privatepost?channel=12345&post=456&single&thread=123"));
parse_internal_link("t.me/c/%312345/%3123?comment=456&t=789&single&thread=123%20%31",
- message("tg:privatepost?channel=12345&post=123&single&thread=123%201&comment=456&t=789"));
+ message("tg://privatepost?channel=12345&post=123&single&thread=123%201&comment=456&t=789"));
parse_internal_link("tg:bg?color=111111#asdasd", background("111111"));
parse_internal_link("tg:bg?color=11111%31", background("111111"));
@@ -386,16 +515,16 @@ TEST(Link, parse_internal_link) {
background("111111-222222%20?rotation=180%20"));
parse_internal_link("tg:bg?gradient=111111~222222", background("111111~222222"));
parse_internal_link("tg:bg?gradient=abacaba", background("abacaba"));
- parse_internal_link("tg:bg?slug=111111~222222#asdasd", background("111111~222222"));
- parse_internal_link("tg:bg?slug=111111~222222&mode=12", background("111111~222222?mode=12"));
- parse_internal_link("tg:bg?slug=111111~222222&mode=12&text=1", background("111111~222222?mode=12"));
- parse_internal_link("tg:bg?slug=111111~222222&mode=12&mode=1", background("111111~222222?mode=12"));
- parse_internal_link("tg:bg?slug=test&mode=12&rotation=4&intensity=2&bg_color=3",
- background("test?mode=12&intensity=2&bg_color=3&rotation=4"));
- parse_internal_link("tg:bg?mode=12&&slug=test&intensity=2&bg_color=3",
- background("test?mode=12&intensity=2&bg_color=3"));
- parse_internal_link("tg:bg?mode=12&intensity=2&bg_color=3",
- unknown_deep_link("tg://bg?mode=12&intensity=2&bg_color=3"));
+ parse_internal_link("tg:bg?slug=test#asdasd", background("test"));
+ parse_internal_link("tg:bg?slug=test&mode=blur", background("test?mode=blur"));
+ parse_internal_link("tg:bg?slug=test&mode=blur&text=1", background("test?mode=blur"));
+ parse_internal_link("tg:bg?slug=test&mode=blur&mode=1", background("test?mode=blur"));
+ parse_internal_link("tg:bg?slug=test&mode=blur&rotation=4&intensity=2&bg_color=3",
+ background("test?mode=blur&intensity=2&bg_color=3&rotation=4"));
+ parse_internal_link("tg:bg?mode=blur&&slug=test&intensity=2&bg_color=3",
+ background("test?mode=blur&intensity=2&bg_color=3"));
+ parse_internal_link("tg:bg?mode=blur&intensity=2&bg_color=3",
+ unknown_deep_link("tg://bg?mode=blur&intensity=2&bg_color=3"));
parse_internal_link("tg:bg?color=111111#asdasd", background("111111"));
parse_internal_link("tg:bg?color=11111%31", background("111111"));
@@ -403,18 +532,18 @@ TEST(Link, parse_internal_link) {
parse_internal_link("tg:bg?gradient=111111-222222", background("111111-222222"));
parse_internal_link("tg:bg?rotation=180%20&gradient=111111-222222%20",
background("111111-222222%20?rotation=180%20"));
- parse_internal_link("tg:bg?gradient=111111~222222", background("111111~222222"));
+ parse_internal_link("tg:bg?gradient=111111~222222&mode=blur", background("111111~222222"));
parse_internal_link("tg:bg?gradient=abacaba", background("abacaba"));
- parse_internal_link("tg:bg?slug=111111~222222#asdasd", background("111111~222222"));
- parse_internal_link("tg:bg?slug=111111~222222&mode=12", background("111111~222222?mode=12"));
- parse_internal_link("tg:bg?slug=111111~222222&mode=12&text=1", background("111111~222222?mode=12"));
- parse_internal_link("tg:bg?slug=111111~222222&mode=12&mode=1", background("111111~222222?mode=12"));
- parse_internal_link("tg:bg?slug=test&mode=12&rotation=4&intensity=2&bg_color=3",
- background("test?mode=12&intensity=2&bg_color=3&rotation=4"));
- parse_internal_link("tg:bg?mode=12&&slug=test&intensity=2&bg_color=3",
- background("test?mode=12&intensity=2&bg_color=3"));
- parse_internal_link("tg:bg?mode=12&intensity=2&bg_color=3",
- unknown_deep_link("tg://bg?mode=12&intensity=2&bg_color=3"));
+ parse_internal_link("tg:bg?slug=test#asdasd", background("test"));
+ parse_internal_link("tg:bg?slug=test&mode=blur", background("test?mode=blur"));
+ parse_internal_link("tg:bg?slug=test&mode=blur&text=1", background("test?mode=blur"));
+ parse_internal_link("tg:bg?slug=test&mode=blur&mode=1", background("test?mode=blur"));
+ parse_internal_link("tg:bg?slug=test&mode=blur&rotation=4&intensity=2&bg_color=3",
+ background("test?mode=blur&intensity=2&bg_color=3&rotation=4"));
+ parse_internal_link("tg:bg?mode=blur&&slug=test&intensity=2&bg_color=3",
+ background("test?mode=blur&intensity=2&bg_color=3"));
+ parse_internal_link("tg:bg?mode=blur&intensity=2&bg_color=3",
+ unknown_deep_link("tg://bg?mode=blur&intensity=2&bg_color=3"));
parse_internal_link("%54.me/bg/111111#asdasd", background("111111"));
parse_internal_link("t.me/bg/11111%31", background("111111"));
@@ -423,19 +552,21 @@ TEST(Link, parse_internal_link) {
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", public_chat("Bg"));
+ parse_internal_link("t.me/Bg/abacaba", web_app("Bg", "abacaba", ""));
parse_internal_link("t.me/bg/111111~222222#asdasd", background("111111~222222"));
- parse_internal_link("t.me/bg/111111~222222?mode=12", background("111111~222222?mode=12"));
- parse_internal_link("t.me/bg/111111~222222?mode=12&text=1", background("111111~222222?mode=12"));
- parse_internal_link("t.me/bg/111111~222222?mode=12&mode=1", background("111111~222222?mode=12"));
- parse_internal_link("t.me/bg/test?mode=12&rotation=4&intensity=2&bg_color=3",
- background("test?mode=12&intensity=2&bg_color=3&rotation=4"));
- parse_internal_link("t.me/%62g/test/?mode=12&&&intensity=2&bg_color=3",
- background("test?mode=12&intensity=2&bg_color=3"));
+ 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"));
+ parse_internal_link("t.me/bg/111111~222222?mode=blur&mode=1", background("111111~222222"));
+ parse_internal_link("t.me/bg/testteststststststststststststs?mode=blur&rotation=4&intensity=2&bg_color=3&mode=1",
+ background("testteststststststststststststs?mode=blur&intensity=2&bg_color=3&rotation=4"));
+ parse_internal_link("t.me/%62g/testteststststststststststststs/?mode=blur+motion&&&intensity=2&bg_color=3",
+ background("testteststststststststststststs?mode=blur%20motion&intensity=2&bg_color=3"));
parse_internal_link("t.me/bg//", nullptr);
parse_internal_link("t.me/bg/%20/", background("%20"));
parse_internal_link("t.me/bg/", nullptr);
+}
+TEST(Link, parse_internal_link_part2) {
parse_internal_link("t.me/invoice?slug=abcdef", nullptr);
parse_internal_link("t.me/invoice", nullptr);
parse_internal_link("t.me/invoice/", nullptr);
@@ -540,12 +671,15 @@ TEST(Link, parse_internal_link) {
parse_internal_link("t.me/joinchat/?abcdef", nullptr);
parse_internal_link("t.me/joinchat/#abcdef", nullptr);
parse_internal_link("t.me/joinchat/abacaba", chat_invite("abacaba"));
- parse_internal_link("t.me/joinchat/aba%20aba", chat_invite("aba%20aba"));
+ parse_internal_link("t.me/joinchat/aba%20aba", nullptr);
parse_internal_link("t.me/joinchat/aba%30aba", chat_invite("aba0aba"));
parse_internal_link("t.me/joinchat/123456a", chat_invite("123456a"));
- parse_internal_link("t.me/joinchat/12345678901", chat_invite("12345678901"));
- parse_internal_link("t.me/joinchat/123456", chat_invite("123456"));
- parse_internal_link("t.me/joinchat/123456/123123/12/31/a/s//21w/?asdas#test", chat_invite("123456"));
+ parse_internal_link("t.me/joinchat/12345678901", nullptr);
+ parse_internal_link("t.me/joinchat/123456", nullptr);
+ parse_internal_link("t.me/joinchat/123456/123123/12/31/a/s//21w/?asdas#test", nullptr);
+ parse_internal_link("t.me/joinchat/12345678901a", chat_invite("12345678901a"));
+ parse_internal_link("t.me/joinchat/123456a", chat_invite("123456a"));
+ parse_internal_link("t.me/joinchat/123456a/123123/12/31/a/s//21w/?asdas#test", chat_invite("123456a"));
parse_internal_link("t.me/+?invite=abcdef", nullptr);
parse_internal_link("t.me/+a", chat_invite("a"));
@@ -555,7 +689,7 @@ TEST(Link, parse_internal_link) {
parse_internal_link("t.me/+?abcdef", nullptr);
parse_internal_link("t.me/+#abcdef", nullptr);
parse_internal_link("t.me/ abacaba", chat_invite("abacaba"));
- parse_internal_link("t.me/+aba%20aba", chat_invite("aba%20aba"));
+ parse_internal_link("t.me/+aba%20aba", nullptr);
parse_internal_link("t.me/+aba%30aba", chat_invite("aba0aba"));
parse_internal_link("t.me/+123456a", chat_invite("123456a"));
parse_internal_link("t.me/%2012345678901", user_phone_number("12345678901"));
@@ -573,11 +707,40 @@ TEST(Link, parse_internal_link) {
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/addlist?invite=abcdef", nullptr);
+ parse_internal_link("t.me/addlist", nullptr);
+ parse_internal_link("t.me/addlist/", nullptr);
+ parse_internal_link("t.me/addlist//abcdef", nullptr);
+ parse_internal_link("t.me/addlist?/abcdef", nullptr);
+ parse_internal_link("t.me/addlist/?abcdef", nullptr);
+ parse_internal_link("t.me/addlist/#abcdef", nullptr);
+ parse_internal_link("t.me/addlist/abacaba", chat_folder_invite("abacaba"));
+ parse_internal_link("t.me/addlist/aba%20aba", nullptr);
+ parse_internal_link("t.me/addlist/aba%30aba", chat_folder_invite("aba0aba"));
+ parse_internal_link("t.me/addlist/123456a", chat_folder_invite("123456a"));
+ parse_internal_link("t.me/addlist/12345678901", chat_folder_invite("12345678901"));
+ parse_internal_link("t.me/addlist/123456", chat_folder_invite("123456"));
+ parse_internal_link("t.me/addlist/123456/123123/12/31/a/s//21w/?asdas#test", chat_folder_invite("123456"));
+ parse_internal_link("t.me/addlist/12345678901a", chat_folder_invite("12345678901a"));
+ parse_internal_link("t.me/addlist/123456a", chat_folder_invite("123456a"));
+ parse_internal_link("t.me/addlist/123456a/123123/12/31/a/s//21w/?asdas#test", chat_folder_invite("123456a"));
+
+ parse_internal_link("t.me/contact/startattach/adasd", user_token("startattach"));
+ parse_internal_link("t.me/contact/startattach", user_token("startattach"));
+ parse_internal_link("t.me/contact/startattach=1", user_token("startattach=1"));
+ parse_internal_link("t.me/contact/", nullptr);
+ parse_internal_link("t.me/contact/?attach=&startattach", nullptr);
+
parse_internal_link("tg:join?invite=abcdef", chat_invite("abcdef"));
- parse_internal_link("tg:join?invite=abc%20def", chat_invite("abc%20def"));
+ parse_internal_link("tg:join?invite=abc%20def", unknown_deep_link("tg://join?invite=abc%20def"));
parse_internal_link("tg://join?invite=abc%30def", chat_invite("abc0def"));
parse_internal_link("tg:join?invite=", unknown_deep_link("tg://join?invite="));
+ parse_internal_link("tg:addlist?slug=abcdef", chat_folder_invite("abcdef"));
+ parse_internal_link("tg:addlist?slug=abc%20def", unknown_deep_link("tg://addlist?slug=abc%20def"));
+ parse_internal_link("tg://addlist?slug=abc%30def", chat_folder_invite("abc0def"));
+ parse_internal_link("tg:addlist?slug=", unknown_deep_link("tg://addlist?slug="));
+
parse_internal_link("t.me/addstickers?set=abcdef", nullptr);
parse_internal_link("t.me/addstickers", nullptr);
parse_internal_link("t.me/addstickers/", nullptr);
@@ -585,15 +748,15 @@ TEST(Link, parse_internal_link) {
parse_internal_link("t.me/addstickers?/abcdef", nullptr);
parse_internal_link("t.me/addstickers/?abcdef", nullptr);
parse_internal_link("t.me/addstickers/#abcdef", nullptr);
- parse_internal_link("t.me/addstickers/abacaba", sticker_set("abacaba"));
- parse_internal_link("t.me/addstickers/aba%20aba", sticker_set("aba aba"));
- parse_internal_link("t.me/addstickers/123456a", sticker_set("123456a"));
- parse_internal_link("t.me/addstickers/12345678901", sticker_set("12345678901"));
- parse_internal_link("t.me/addstickers/123456", sticker_set("123456"));
- parse_internal_link("t.me/addstickers/123456/123123/12/31/a/s//21w/?asdas#test", sticker_set("123456"));
-
- parse_internal_link("tg:addstickers?set=abcdef", sticker_set("abcdef"));
- parse_internal_link("tg:addstickers?set=abc%30ef", sticker_set("abc0ef"));
+ parse_internal_link("t.me/addstickers/abacaba", sticker_set("abacaba", false));
+ parse_internal_link("t.me/addstickers/aba%20aba", sticker_set("aba aba", false));
+ parse_internal_link("t.me/addstickers/123456a", sticker_set("123456a", false));
+ parse_internal_link("t.me/addstickers/12345678901", sticker_set("12345678901", false));
+ parse_internal_link("t.me/addstickers/123456", sticker_set("123456", false));
+ parse_internal_link("t.me/addstickers/123456/123123/12/31/a/s//21w/?asdas#test", sticker_set("123456", false));
+
+ parse_internal_link("tg:addstickers?set=abcdef", sticker_set("abcdef", false));
+ parse_internal_link("tg:addstickers?set=abc%30ef", sticker_set("abc0ef", false));
parse_internal_link("tg://addstickers?set=", unknown_deep_link("tg://addstickers?set="));
parse_internal_link("t.me/addemoji?set=abcdef", nullptr);
@@ -603,17 +766,19 @@ TEST(Link, parse_internal_link) {
parse_internal_link("t.me/addemoji?/abcdef", nullptr);
parse_internal_link("t.me/addemoji/?abcdef", nullptr);
parse_internal_link("t.me/addemoji/#abcdef", nullptr);
- parse_internal_link("t.me/addemoji/abacaba", sticker_set("abacaba"));
- parse_internal_link("t.me/addemoji/aba%20aba", sticker_set("aba aba"));
- parse_internal_link("t.me/addemoji/123456a", sticker_set("123456a"));
- parse_internal_link("t.me/addemoji/12345678901", sticker_set("12345678901"));
- parse_internal_link("t.me/addemoji/123456", sticker_set("123456"));
- parse_internal_link("t.me/addemoji/123456/123123/12/31/a/s//21w/?asdas#test", sticker_set("123456"));
-
- parse_internal_link("tg:addemoji?set=abcdef", sticker_set("abcdef"));
- parse_internal_link("tg:addemoji?set=abc%30ef", sticker_set("abc0ef"));
+ parse_internal_link("t.me/addemoji/abacaba", sticker_set("abacaba", true));
+ parse_internal_link("t.me/addemoji/aba%20aba", sticker_set("aba aba", true));
+ parse_internal_link("t.me/addemoji/123456a", sticker_set("123456a", true));
+ parse_internal_link("t.me/addemoji/12345678901", sticker_set("12345678901", true));
+ parse_internal_link("t.me/addemoji/123456", sticker_set("123456", true));
+ parse_internal_link("t.me/addemoji/123456/123123/12/31/a/s//21w/?asdas#test", sticker_set("123456", true));
+
+ parse_internal_link("tg:addemoji?set=abcdef", sticker_set("abcdef", true));
+ parse_internal_link("tg:addemoji?set=abc%30ef", sticker_set("abc0ef", true));
parse_internal_link("tg://addemoji?set=", unknown_deep_link("tg://addemoji?set="));
+}
+TEST(Link, parse_internal_link_part3) {
parse_internal_link("t.me/confirmphone?hash=abc%30ef&phone=", nullptr);
parse_internal_link("t.me/confirmphone/123456/123123/12/31/a/s//21w/?hash=abc%30ef&phone=123456789",
phone_number_confirmation("abc0ef", "123456789"));
@@ -683,9 +848,9 @@ TEST(Link, parse_internal_link) {
parse_internal_link("tg://addtheme?slug=", unknown_deep_link("tg://addtheme?slug="));
parse_internal_link("t.me/proxy?server=1.2.3.4&port=80&secret=1234567890abcdef1234567890ABCDEF",
- proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF"));
+ proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890abcdef"));
parse_internal_link("t.me/proxy?server=1.2.3.4&port=80adasdas&secret=1234567890abcdef1234567890ABCDEF",
- proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF"));
+ proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890abcdef"));
parse_internal_link("t.me/proxy?server=1.2.3.4&port=adasdas&secret=1234567890abcdef1234567890ABCDEF",
unsupported_proxy());
parse_internal_link("t.me/proxy?server=1.2.3.4&port=65536&secret=1234567890abcdef1234567890ABCDEF",
@@ -693,9 +858,9 @@ TEST(Link, parse_internal_link) {
parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=", unsupported_proxy());
parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=12", unsupported_proxy());
parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=1234567890abcdef1234567890ABCDEF",
- proxy_mtproto("google.com", 80, "1234567890abcdef1234567890ABCDEF"));
+ proxy_mtproto("google.com", 80, "1234567890abcdef1234567890abcdef"));
parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=dd1234567890abcdef1234567890ABCDEF",
- proxy_mtproto("google.com", 80, "dd1234567890abcdef1234567890ABCDEF"));
+ proxy_mtproto("google.com", 80, "dd1234567890abcdef1234567890abcdef"));
parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=de1234567890abcdef1234567890ABCDEF",
unsupported_proxy());
parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF",
@@ -703,25 +868,25 @@ TEST(Link, parse_internal_link) {
parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF0",
unsupported_proxy());
parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF%30%30",
- proxy_mtproto("google.com", 80, "ee1234567890abcdef1234567890ABCDEF00"));
+ proxy_mtproto("google.com", 80, "7hI0VniQq83vEjRWeJCrze8A"));
parse_internal_link(
"t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF010101010101010101",
- proxy_mtproto("google.com", 80, "ee1234567890abcdef1234567890ABCDEF010101010101010101"));
+ proxy_mtproto("google.com", 80, "7hI0VniQq83vEjRWeJCrze8BAQEBAQEBAQE"));
parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=7tAAAAAAAAAAAAAAAAAAAAAAAAcuZ29vZ2xlLmNvbQ",
proxy_mtproto("google.com", 80, "7tAAAAAAAAAAAAAAAAAAAAAAAAcuZ29vZ2xlLmNvbQ"));
parse_internal_link("tg:proxy?server=1.2.3.4&port=80&secret=1234567890abcdef1234567890ABCDEF",
- proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF"));
+ proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890abcdef"));
parse_internal_link("tg:proxy?server=1.2.3.4&port=80adasdas&secret=1234567890abcdef1234567890ABCDEF",
- proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF"));
+ proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890abcdef"));
parse_internal_link("tg:proxy?server=1.2.3.4&port=adasdas&secret=1234567890abcdef1234567890ABCDEF",
unsupported_proxy());
parse_internal_link("tg:proxy?server=1.2.3.4&port=65536&secret=1234567890abcdef1234567890ABCDEF",
unsupported_proxy());
parse_internal_link("tg:proxy?server=google.com&port=8%30&secret=1234567890abcdef1234567890ABCDEF",
- proxy_mtproto("google.com", 80, "1234567890abcdef1234567890ABCDEF"));
+ proxy_mtproto("google.com", 80, "1234567890abcdef1234567890abcdef"));
parse_internal_link("tg:proxy?server=google.com&port=8%30&secret=dd1234567890abcdef1234567890ABCDEF",
- proxy_mtproto("google.com", 80, "dd1234567890abcdef1234567890ABCDEF"));
+ proxy_mtproto("google.com", 80, "dd1234567890abcdef1234567890abcdef"));
parse_internal_link("tg:proxy?server=google.com&port=8%30&secret=de1234567890abcdef1234567890ABCDEF",
unsupported_proxy());
@@ -757,7 +922,7 @@ TEST(Link, parse_internal_link) {
parse_internal_link("t.me/username/0/a//s/as?voicechat=", video_chat("username", "", false));
parse_internal_link("t.me/username/0/a//s/as?videochat=2", video_chat("username", "2", false));
parse_internal_link("t.me/username/0/a//s/as?livestream=3", video_chat("username", "3", true));
- parse_internal_link("t.me/username/aasdas?test=1&voicechat=#12312", video_chat("username", "", false));
+ parse_internal_link("t.me/username/aasdas/2?test=1&voicechat=#12312", video_chat("username", "", false));
parse_internal_link("t.me/username/0?voicechat=", video_chat("username", "", false));
parse_internal_link("t.me/username/-1?voicechat=asdasd", video_chat("username", "asdasd", false));
parse_internal_link("t.me/username?voicechat=", video_chat("username", "", false));
@@ -775,7 +940,7 @@ TEST(Link, parse_internal_link) {
parse_internal_link("tg:resolve?domain=telegram&&&&&&&start=%30", bot_start("telegram", "0"));
parse_internal_link("t.me/username/0/a//s/as?start=", bot_start("username", ""));
- parse_internal_link("t.me/username/aasdas?test=1&start=#12312", bot_start("username", ""));
+ parse_internal_link("t.me/username/aasdas/2?test=1&start=#12312", bot_start("username", ""));
parse_internal_link("t.me/username/0?start=", bot_start("username", ""));
parse_internal_link("t.me/username/-1?start=asdasd", bot_start("username", "asdasd"));
parse_internal_link("t.me/username?start=", bot_start("username", ""));
@@ -821,7 +986,7 @@ TEST(Link, parse_internal_link) {
true, true, 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?test=1&startgroup=#12312", bot_start_in_group("username", "", nullptr));
+ parse_internal_link("t.me/username/aasdas/2?test=1&startgroup=#12312", bot_start_in_group("username", "", nullptr));
parse_internal_link("t.me/username/0?startgroup=", bot_start_in_group("username", "", nullptr));
parse_internal_link("t.me/username/-1?startgroup=asdasd", bot_start_in_group("username", "asdasd", nullptr));
parse_internal_link("t.me/username?startgroup=", bot_start_in_group("username", "", nullptr));
@@ -857,7 +1022,9 @@ TEST(Link, parse_internal_link) {
"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)));
+}
+TEST(Link, parse_internal_link_part4) {
parse_internal_link("tg:resolve?domain=username&game=aasdasd", game("username", "aasdasd"));
parse_internal_link("TG://resolve?domain=username&game=", public_chat("username"));
parse_internal_link("TG://test@resolve?domain=username&game=asd", nullptr);
@@ -865,10 +1032,12 @@ TEST(Link, parse_internal_link) {
parse_internal_link("tg:http://resolve?domain=username&game=asd", nullptr);
parse_internal_link("tg:https://resolve?domain=username&game=asd", nullptr);
parse_internal_link("tg:resolve?domain=&game=asd", unknown_deep_link("tg://resolve?domain=&game=asd"));
- parse_internal_link("tg:resolve?domain=telegram&&&&&&&game=%30", game("telegram", "0"));
+ parse_internal_link("tg:resolve?domain=telegram&&&&&&&game=%30", public_chat("telegram"));
+ parse_internal_link("tg:resolve?domain=telegram&&&&&&&game=%30ab", public_chat("telegram"));
+ parse_internal_link("tg:resolve?domain=telegram&&&&&&&game=ab%30", game("telegram", "ab0"));
parse_internal_link("t.me/username/0/a//s/as?game=asd", game("username", "asd"));
- parse_internal_link("t.me/username/aasdas?test=1&game=asd#12312", game("username", "asd"));
+ parse_internal_link("t.me/username/aasdas/2?test=1&game=asd#12312", game("username", "asd"));
parse_internal_link("t.me/username/0?game=asd", game("username", "asd"));
parse_internal_link("t.me/username/-1?game=asdasd", game("username", "asdasd"));
parse_internal_link("t.me/username?game=asd", game("username", "asd"));
@@ -877,6 +1046,35 @@ TEST(Link, parse_internal_link) {
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&appname=aasdasd&startapp=123asd",
+ web_app("username", "aasdasd", "123asd"));
+ 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);
+ parse_internal_link("tg:http://resolve?domain=username&appname=asd", nullptr);
+ parse_internal_link("tg:https://resolve?domain=username&appname=asd", nullptr);
+ 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("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"));
+ parse_internal_link("t.me/username/0?appname=asd", public_chat("username"));
+ parse_internal_link("t.me/username/-1?appname=asdasd", public_chat("username"));
+ parse_internal_link("t.me/username?appname=asd", public_chat("username"));
+ parse_internal_link("t.me/username?appname=", public_chat("username"));
+ parse_internal_link("t.me/username#appname=asdas", public_chat("username"));
+ 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/", public_chat("username"));
+ parse_internal_link("https://telegram.dog/tele%63ram/t%63st", web_app("telecram", "tcst", ""));
+
parse_internal_link("tg:resolve?domain=username&Game=asd", public_chat("username"));
parse_internal_link("TG://test@resolve?domain=username", nullptr);
parse_internal_link("tg:resolve:80?domain=username", nullptr);
@@ -898,7 +1096,7 @@ TEST(Link, parse_internal_link) {
parse_internal_link("t.me/asdf0", public_chat("asdf0"));
parse_internal_link("t.me/asd__fg", nullptr);
parse_internal_link("t.me/username/0/a//s/as?gam=asd", public_chat("username"));
- parse_internal_link("t.me/username/aasdas?test=1", public_chat("username"));
+ parse_internal_link("t.me/username/aasdas/2?test=1", public_chat("username"));
parse_internal_link("t.me/username/0", public_chat("username"));
parse_internal_link("t.me//username", nullptr);
parse_internal_link("https://telegram.dog/tele%63ram", public_chat("telecram"));
@@ -943,9 +1141,11 @@ TEST(Link, parse_internal_link) {
parse_internal_link("tg://settings/themes/?as#rad", theme_settings());
parse_internal_link("tg://settings/themes/a", settings());
parse_internal_link("tg://settings/asdsathemesasdas/devices", settings());
+ parse_internal_link("tg://settings/auto_delete", default_message_auto_delete_timer_settings());
parse_internal_link("tg://settings/devices", active_sessions());
parse_internal_link("tg://settings/change_number", change_phone_number());
- parse_internal_link("tg://settings/folders", filter_settings());
+ parse_internal_link("tg://settings/edit_profile", edit_profile_settings());
+ parse_internal_link("tg://settings/folders", chat_folder_settings());
parse_internal_link("tg://settings/filters", settings());
parse_internal_link("tg://settings/language", language_settings());
parse_internal_link("tg://settings/privacy", privacy_and_security_settings());
@@ -953,8 +1153,8 @@ TEST(Link, parse_internal_link) {
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"));
- parse_internal_link("aAAb.t.me/12345?single", message("tg:resolve?domain=aaab&post=12345&single"));
- parse_internal_link("telegram.t.me/195", message("tg:resolve?domain=telegram&post=195"));
+ parse_internal_link("aAAb.t.me/12345?single", message("tg://resolve?domain=aaab&post=12345&single"));
+ parse_internal_link("telegram.t.me/195", message("tg://resolve?domain=telegram&post=195"));
parse_internal_link("shares.t.me", public_chat("shares"));
parse_internal_link("c.t.me/12345?single", nullptr);
@@ -963,6 +1163,7 @@ TEST(Link, parse_internal_link) {
parse_internal_link("0aaa.t.me/12345?single", nullptr);
parse_internal_link("_aaa.t.me/12345?single", 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);
diff --git a/protocols/Telegram/tdlib/td/test/main.cpp b/protocols/Telegram/tdlib/td/test/main.cpp
index 064871ae31..9a774b37db 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -32,6 +32,8 @@ int main(int argc, char **argv) {
td::OptionParser options;
options.add_option('f', "filter", "run only specified tests",
[&](td::Slice filter) { runner.add_substr_filter(filter.str()); });
+ options.add_option('o', "offset", "run tests from the specified test",
+ [&](td::Slice offset) { runner.set_offset(offset.str()); });
options.add_option('s', "stress", "run tests infinitely", [&] { runner.set_stress_flag(true); });
options.add_checked_option('v', "verbosity", "log verbosity level",
td::OptionParser::parse_integer(default_verbosity_level));
diff --git a/protocols/Telegram/tdlib/td/test/message_entities.cpp b/protocols/Telegram/tdlib/td/test/message_entities.cpp
index 9c62415579..378e76b23a 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -725,16 +725,16 @@ static void check_fix_formatted_text(td::string str, td::vector<td::MessageEntit
const td::string &expected_str,
const td::vector<td::MessageEntity> &expected_entities, bool allow_empty = true,
bool skip_new_entities = false, bool skip_bot_commands = false,
- bool for_draft = true) {
- ASSERT_TRUE(td::fix_formatted_text(str, entities, allow_empty, skip_new_entities, skip_bot_commands, true, for_draft)
+ bool skip_trim = true) {
+ ASSERT_TRUE(td::fix_formatted_text(str, entities, allow_empty, skip_new_entities, skip_bot_commands, true, skip_trim)
.is_ok());
ASSERT_STREQ(expected_str, str);
ASSERT_EQ(expected_entities, entities);
}
static void check_fix_formatted_text(td::string str, td::vector<td::MessageEntity> entities, bool allow_empty,
- bool skip_new_entities, bool skip_bot_commands, bool for_draft) {
- ASSERT_TRUE(td::fix_formatted_text(str, entities, allow_empty, skip_new_entities, skip_bot_commands, true, for_draft)
+ bool skip_new_entities, bool skip_bot_commands, bool skip_trim) {
+ ASSERT_TRUE(td::fix_formatted_text(str, entities, allow_empty, skip_new_entities, skip_bot_commands, true, skip_trim)
.is_error());
}
@@ -815,9 +815,9 @@ TEST(MessageEntities, fix_formatted_text) {
}
str = " /test @abaca #ORD $ABC telegram.org ";
- for (auto for_draft : {false, true}) {
- td::int32 shift = for_draft ? 2 : 0;
- td::string expected_str = for_draft ? str : str.substr(2, str.size() - 3);
+ for (auto skip_trim : {false, true}) {
+ td::int32 shift = skip_trim ? 2 : 0;
+ td::string expected_str = skip_trim ? str : str.substr(2, str.size() - 3);
for (auto skip_new_entities : {false, true}) {
for (auto skip_bot_commands : {false, true}) {
@@ -833,9 +833,9 @@ TEST(MessageEntities, fix_formatted_text) {
}
check_fix_formatted_text(str, {}, expected_str, entities, true, skip_new_entities, skip_bot_commands,
- for_draft);
+ skip_trim);
check_fix_formatted_text(str, {}, expected_str, entities, false, skip_new_entities, skip_bot_commands,
- for_draft);
+ skip_trim);
}
}
}
@@ -846,8 +846,8 @@ TEST(MessageEntities, fix_formatted_text) {
for (td::int32 offset = 0; static_cast<size_t>(offset + length) <= str.size(); offset++) {
for (auto type : {td::MessageEntity::Type::Bold, td::MessageEntity::Type::Url, td::MessageEntity::Type::TextUrl,
td::MessageEntity::Type::MentionName}) {
- for (auto for_draft : {false, true}) {
- fixed_str = for_draft ? "aba \n caba " : "aba \n caba";
+ for (auto skip_trim : {false, true}) {
+ 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()) {
@@ -885,7 +885,7 @@ TEST(MessageEntities, fix_formatted_text) {
}
}
}
- check_fix_formatted_text(str, entities, fixed_str, fixed_entities, true, false, false, for_draft);
+ check_fix_formatted_text(str, entities, fixed_str, fixed_entities, true, false, false, skip_trim);
}
}
}
@@ -1250,66 +1250,50 @@ TEST(MessageEntities, parse_html) {
check_parse_html("🏟 🏟&lt;</", "Unexpected end tag at byte offset 13");
check_parse_html("🏟 🏟&lt;<b></b></", "Unexpected end tag at byte offset 20");
check_parse_html("🏟 🏟&lt;<i>a</i ", "Unclosed end tag at byte offset 17");
- check_parse_html("🏟 🏟&lt;<i>a</em >",
- "Unmatched end tag at byte offset 17, expected \"</i>\", found \"</em>\"");
+ check_parse_html("🏟 🏟&lt;<i>a</em >", "Unmatched end tag at byte offset 17, expected \"</i>\", found \"</em>\"");
check_parse_html("", "", {});
check_parse_html("➡️ ➡️", "➡️ ➡️", {});
- check_parse_html("&lt;&gt;&amp;&quot;&laquo;&raquo;&#12345678;", "<>&\"&laquo;&raquo;&#12345678;", {});
- check_parse_html("➡️ ➡️<i>➡️ ➡️</i>", "➡️ ➡️➡️ ➡️",
- {{td::MessageEntity::Type::Italic, 5, 5}});
- check_parse_html("➡️ ➡️<em>➡️ ➡️</em>", "➡️ ➡️➡️ ➡️",
- {{td::MessageEntity::Type::Italic, 5, 5}});
- check_parse_html("➡️ ➡️<b>➡️ ➡️</b>", "➡️ ➡️➡️ ➡️",
- {{td::MessageEntity::Type::Bold, 5, 5}});
- check_parse_html("➡️ ➡️<strong>➡️ ➡️</strong>", "➡️ ➡️➡️ ➡️",
- {{td::MessageEntity::Type::Bold, 5, 5}});
- check_parse_html("➡️ ➡️<u>➡️ ➡️</u>", "➡️ ➡️➡️ ➡️",
- {{td::MessageEntity::Type::Underline, 5, 5}});
- check_parse_html("➡️ ➡️<ins>➡️ ➡️</ins>", "➡️ ➡️➡️ ➡️",
- {{td::MessageEntity::Type::Underline, 5, 5}});
- 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("&ge;&lt;&gt;&amp;&quot;&laquo;&raquo;&#12345678;", "&ge;<>&\"&laquo;&raquo;&#12345678;", {});
+ check_parse_html("&Or;", "&Or;", {});
+ check_parse_html("➡️ ➡️<i>➡️ ➡️</i>", "➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::Italic, 5, 5}});
+ check_parse_html("➡️ ➡️<em>➡️ ➡️</em>", "➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::Italic, 5, 5}});
+ check_parse_html("➡️ ➡️<b>➡️ ➡️</b>", "➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::Bold, 5, 5}});
+ check_parse_html("➡️ ➡️<strong>➡️ ➡️</strong>", "➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::Bold, 5, 5}});
+ check_parse_html("➡️ ➡️<u>➡️ ➡️</u>", "➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::Underline, 5, 5}});
+ check_parse_html("➡️ ➡️<ins>➡️ ➡️</ins>", "➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::Underline, 5, 5}});
+ 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("➡️ ➡️<i>➡️ ➡️</i><b>➡️ ➡️</b>", "➡️ ➡️➡️ ➡️➡️ ➡️",
{{td::MessageEntity::Type::Italic, 5, 5}, {td::MessageEntity::Type::Bold, 10, 5}});
check_parse_html("🏟 🏟<i>🏟 &lt🏟</i>", "🏟 🏟🏟 <🏟", {{td::MessageEntity::Type::Italic, 5, 6}});
check_parse_html("🏟 🏟<i>🏟 &gt;<b aba = caba>&lt🏟</b></i>", "🏟 🏟🏟 ><🏟",
{{td::MessageEntity::Type::Italic, 5, 7}, {td::MessageEntity::Type::Bold, 9, 3}});
- check_parse_html("🏟 🏟&lt;<i aba = 190azAz-. >a</i>", "🏟 🏟<a",
- {{td::MessageEntity::Type::Italic, 6, 1}});
- check_parse_html("🏟 🏟&lt;<i aba = 190azAz-.>a</i>", "🏟 🏟<a",
- {{td::MessageEntity::Type::Italic, 6, 1}});
+ check_parse_html("🏟 🏟&lt;<i aba = 190azAz-. >a</i>", "🏟 🏟<a", {{td::MessageEntity::Type::Italic, 6, 1}});
+ check_parse_html("🏟 🏟&lt;<i aba = 190azAz-.>a</i>", "🏟 🏟<a", {{td::MessageEntity::Type::Italic, 6, 1}});
check_parse_html("🏟 🏟&lt;<i aba = \"&lt;&gt;&quot;\">a</i>", "🏟 🏟<a",
{{td::MessageEntity::Type::Italic, 6, 1}});
check_parse_html("🏟 🏟&lt;<i aba = '&lt;&gt;&quot;'>a</i>", "🏟 🏟<a",
{{td::MessageEntity::Type::Italic, 6, 1}});
check_parse_html("🏟 🏟&lt;<i aba = '&lt;&gt;&quot;'>a</>", "🏟 🏟<a",
{{td::MessageEntity::Type::Italic, 6, 1}});
- check_parse_html("🏟 🏟&lt;<i>🏟 🏟&lt;</>", "🏟 🏟<🏟 🏟<",
- {{td::MessageEntity::Type::Italic, 6, 6}});
+ check_parse_html("🏟 🏟&lt;<i>🏟 🏟&lt;</>", "🏟 🏟<🏟 🏟<", {{td::MessageEntity::Type::Italic, 6, 6}});
check_parse_html("🏟 🏟&lt;<i>a</ >", "🏟 🏟<a", {{td::MessageEntity::Type::Italic, 6, 1}});
check_parse_html("🏟 🏟&lt;<i>a</i >", "🏟 🏟<a", {{td::MessageEntity::Type::Italic, 6, 1}});
check_parse_html("🏟 🏟&lt;<b></b>", "🏟 🏟<", {});
check_parse_html("<i>\t</i>", "\t", {{td::MessageEntity::Type::Italic, 0, 1}});
check_parse_html("<i>\r</i>", "\r", {{td::MessageEntity::Type::Italic, 0, 1}});
check_parse_html("<i>\n</i>", "\n", {{td::MessageEntity::Type::Italic, 0, 1}});
- check_parse_html("➡️ ➡️<span class = \"tg-spoiler\">➡️ ➡️</span><b>➡️ ➡️</b>",
- "➡️ ➡️➡️ ➡️➡️ ➡️",
+ check_parse_html("➡️ ➡️<span class = \"tg-spoiler\">➡️ ➡️</span><b>➡️ ➡️</b>", "➡️ ➡️➡️ ➡️➡️ ➡️",
{{td::MessageEntity::Type::Spoiler, 5, 5}, {td::MessageEntity::Type::Bold, 10, 5}});
check_parse_html("🏟 🏟<span class=\"tg-spoiler\">🏟 &lt🏟</span>", "🏟 🏟🏟 <🏟",
{{td::MessageEntity::Type::Spoiler, 5, 6}});
- check_parse_html("🏟 🏟<span class=\"tg-spoiler\">🏟 &gt;<b aba = caba>&lt🏟</b></span>",
- "🏟 🏟🏟 ><🏟",
+ check_parse_html("🏟 🏟<span class=\"tg-spoiler\">🏟 &gt;<b aba = caba>&lt🏟</b></span>", "🏟 🏟🏟 ><🏟",
{{td::MessageEntity::Type::Spoiler, 5, 7}, {td::MessageEntity::Type::Bold, 9, 3}});
- check_parse_html("➡️ ➡️<tg-spoiler>➡️ ➡️</tg-spoiler><b>➡️ ➡️</b>",
- "➡️ ➡️➡️ ➡️➡️ ➡️",
+ check_parse_html("➡️ ➡️<tg-spoiler>➡️ ➡️</tg-spoiler><b>➡️ ➡️</b>", "➡️ ➡️➡️ ➡️➡️ ➡️",
{{td::MessageEntity::Type::Spoiler, 5, 5}, {td::MessageEntity::Type::Bold, 10, 5}});
- check_parse_html("🏟 🏟<tg-spoiler>🏟 &lt🏟</tg-spoiler>", "🏟 🏟🏟 <🏟",
- {{td::MessageEntity::Type::Spoiler, 5, 6}});
+ check_parse_html("🏟 🏟<tg-spoiler>🏟 &lt🏟</tg-spoiler>", "🏟 🏟🏟 <🏟", {{td::MessageEntity::Type::Spoiler, 5, 6}});
check_parse_html("🏟 🏟<tg-spoiler>🏟 &gt;<b aba = caba>&lt🏟</b></tg-spoiler>", "🏟 🏟🏟 ><🏟",
{{td::MessageEntity::Type::Spoiler, 5, 7}, {td::MessageEntity::Type::Bold, 9, 3}});
check_parse_html("<a href=telegram.org>\t</a>", "\t",
@@ -1343,10 +1327,8 @@ TEST(MessageEntities, parse_html) {
{{td::MessageEntity::Type::TextUrl, 0, 12, "http://telegram.org/"}});
check_parse_html("<a>https://telegram.org/asdsa?asdasdwe#12e3we</a>", "https://telegram.org/asdsa?asdasdwe#12e3we",
{{td::MessageEntity::Type::TextUrl, 0, 42, "https://telegram.org/asdsa?asdasdwe#12e3we"}});
- check_parse_html("🏟 🏟&lt;<pre >🏟 🏟&lt;</>", "🏟 🏟<🏟 🏟<",
- {{td::MessageEntity::Type::Pre, 6, 6}});
- check_parse_html("🏟 🏟&lt;<code >🏟 🏟&lt;</>", "🏟 🏟<🏟 🏟<",
- {{td::MessageEntity::Type::Code, 6, 6}});
+ check_parse_html("🏟 🏟&lt;<pre >🏟 🏟&lt;</>", "🏟 🏟<🏟 🏟<", {{td::MessageEntity::Type::Pre, 6, 6}});
+ check_parse_html("🏟 🏟&lt;<code >🏟 🏟&lt;</>", "🏟 🏟<🏟 🏟<", {{td::MessageEntity::Type::Code, 6, 6}});
check_parse_html("🏟 🏟&lt;<pre><code>🏟 🏟&lt;</code></>", "🏟 🏟<🏟 🏟<",
{{td::MessageEntity::Type::Pre, 6, 6}, {td::MessageEntity::Type::Code, 6, 6}});
check_parse_html("🏟 🏟&lt;<pre><code class=\"language-\">🏟 🏟&lt;</code></>", "🏟 🏟<🏟 🏟<",
@@ -1359,8 +1341,7 @@ TEST(MessageEntities, parse_html) {
{{td::MessageEntity::Type::Pre, 6, 7}, {td::MessageEntity::Type::Code, 6, 6}});
check_parse_html("🏟 🏟&lt;<pre> <code class=\"language-fift\">🏟 🏟&lt;</></>", "🏟 🏟< 🏟 🏟<",
{{td::MessageEntity::Type::Pre, 6, 7}, {td::MessageEntity::Type::Code, 7, 6}});
- check_parse_html("➡️ ➡️<tg-emoji emoji-id = \"12345\">➡️ ➡️</tg-emoji><b>➡️ ➡️</b>",
- "➡️ ➡️➡️ ➡️➡️ ➡️",
+ check_parse_html("➡️ ➡️<tg-emoji emoji-id = \"12345\">➡️ ➡️</tg-emoji><b>➡️ ➡️</b>", "➡️ ➡️➡️ ➡️➡️ ➡️",
{{td::MessageEntity::Type::CustomEmoji, 5, 5, td::CustomEmojiId(static_cast<td::int64>(12345))},
{td::MessageEntity::Type::Bold, 10, 5}});
check_parse_html("🏟 🏟<tg-emoji emoji-id=\"54321\">🏟 &lt🏟</tg-emoji>", "🏟 🏟🏟 <🏟",
@@ -1443,8 +1424,7 @@ TEST(MessageEntities, parse_markdown) {
check_parse_markdown("🏟 🏟_abac \\* asd _", "🏟 🏟abac * asd ", {{td::MessageEntity::Type::Italic, 5, 11}});
check_parse_markdown("🏟 \\.🏟_🏟\\. 🏟_", "🏟 .🏟🏟. 🏟", {{td::MessageEntity::Type::Italic, 6, 6}});
check_parse_markdown("\\\\\\a\\b\\c\\d\\e\\f\\1\\2\\3\\4\\➡️\\", "\\abcdef1234\\➡️\\", {});
- check_parse_markdown("➡️ ➡️_➡️ ➡️_", "➡️ ➡️➡️ ➡️",
- {{td::MessageEntity::Type::Italic, 5, 5}});
+ check_parse_markdown("➡️ ➡️_➡️ ➡️_", "➡️ ➡️➡️ ➡️", {{td::MessageEntity::Type::Italic, 5, 5}});
check_parse_markdown("➡️ ➡️_➡️ ➡️_*➡️ ➡️*", "➡️ ➡️➡️ ➡️➡️ ➡️",
{{td::MessageEntity::Type::Italic, 5, 5}, {td::MessageEntity::Type::Bold, 10, 5}});
check_parse_markdown("🏟 🏟_🏟 \\.🏟_", "🏟 🏟🏟 .🏟", {{td::MessageEntity::Type::Italic, 5, 6}});
@@ -1457,22 +1437,14 @@ TEST(MessageEntities, parse_markdown) {
check_parse_markdown("🏟 🏟__🏟 _🏟_\\___", "🏟 🏟🏟 🏟_",
{{td::MessageEntity::Type::Underline, 5, 6}, {td::MessageEntity::Type::Italic, 8, 2}});
check_parse_markdown("🏟 🏟`🏟 🏟```", "🏟 🏟🏟 🏟", {{td::MessageEntity::Type::Code, 5, 5}});
- check_parse_markdown("🏟 🏟```🏟 🏟```", "🏟 🏟 🏟",
- {{td::MessageEntity::Type::PreCode, 5, 3, "🏟"}});
- check_parse_markdown("🏟 🏟```🏟\n🏟```", "🏟 🏟🏟",
- {{td::MessageEntity::Type::PreCode, 5, 2, "🏟"}});
- check_parse_markdown("🏟 🏟```🏟\r🏟```", "🏟 🏟🏟",
- {{td::MessageEntity::Type::PreCode, 5, 2, "🏟"}});
- check_parse_markdown("🏟 🏟```🏟\n\r🏟```", "🏟 🏟🏟",
- {{td::MessageEntity::Type::PreCode, 5, 2, "🏟"}});
- check_parse_markdown("🏟 🏟```🏟\r\n🏟```", "🏟 🏟🏟",
- {{td::MessageEntity::Type::PreCode, 5, 2, "🏟"}});
- check_parse_markdown("🏟 🏟```🏟\n\n🏟```", "🏟 🏟\n🏟",
- {{td::MessageEntity::Type::PreCode, 5, 3, "🏟"}});
- check_parse_markdown("🏟 🏟```🏟\r\r🏟```", "🏟 🏟\r🏟",
- {{td::MessageEntity::Type::PreCode, 5, 3, "🏟"}});
- check_parse_markdown("🏟 🏟```🏟 \\\\\\`🏟```", "🏟 🏟 \\`🏟",
- {{td::MessageEntity::Type::PreCode, 5, 5, "🏟"}});
+ check_parse_markdown("🏟 🏟```🏟 🏟```", "🏟 🏟 🏟", {{td::MessageEntity::Type::PreCode, 5, 3, "🏟"}});
+ check_parse_markdown("🏟 🏟```🏟\n🏟```", "🏟 🏟🏟", {{td::MessageEntity::Type::PreCode, 5, 2, "🏟"}});
+ check_parse_markdown("🏟 🏟```🏟\r🏟```", "🏟 🏟🏟", {{td::MessageEntity::Type::PreCode, 5, 2, "🏟"}});
+ check_parse_markdown("🏟 🏟```🏟\n\r🏟```", "🏟 🏟🏟", {{td::MessageEntity::Type::PreCode, 5, 2, "🏟"}});
+ check_parse_markdown("🏟 🏟```🏟\r\n🏟```", "🏟 🏟🏟", {{td::MessageEntity::Type::PreCode, 5, 2, "🏟"}});
+ check_parse_markdown("🏟 🏟```🏟\n\n🏟```", "🏟 🏟\n🏟", {{td::MessageEntity::Type::PreCode, 5, 3, "🏟"}});
+ check_parse_markdown("🏟 🏟```🏟\r\r🏟```", "🏟 🏟\r🏟", {{td::MessageEntity::Type::PreCode, 5, 3, "🏟"}});
+ check_parse_markdown("🏟 🏟```🏟 \\\\\\`🏟```", "🏟 🏟 \\`🏟", {{td::MessageEntity::Type::PreCode, 5, 5, "🏟"}});
check_parse_markdown("🏟 🏟**", "🏟 🏟", {});
check_parse_markdown("||test||", "test", {{td::MessageEntity::Type::Spoiler, 0, 4}});
check_parse_markdown("🏟 🏟``", "🏟 🏟", {});
@@ -1532,19 +1504,18 @@ TEST(MessageEntities, parse_markdown_v3) {
check_parse_markdown_v3("🏟````🏟``🏟`aba🏟```c🏟`aba🏟 daba🏟```c🏟`aba🏟```🏟 `🏟``🏟```",
"🏟````🏟``🏟aba🏟```c🏟aba🏟 daba🏟c🏟`aba🏟🏟 `🏟``🏟```",
{{td::MessageEntity::Type::Code, 12, 11}, {td::MessageEntity::Type::Pre, 35, 9}});
- check_parse_markdown_v3(
- "🏟````🏟``🏟`aba🏟```c🏟`aba🏟 daba🏟```c🏟`aba🏟🏟```🏟 `🏟``🏟```",
- {{td::MessageEntity::Type::Italic, 12, 1},
- {td::MessageEntity::Type::Italic, 44, 1},
- {td::MessageEntity::Type::Bold, 45, 1},
- {td::MessageEntity::Type::Bold, 49, 2}},
- "🏟````🏟``🏟`aba🏟c🏟`aba🏟 daba🏟c🏟`aba🏟🏟🏟 `🏟``🏟",
- {{td::MessageEntity::Type::Italic, 12, 1},
- {td::MessageEntity::Type::Pre, 18, 16},
- {td::MessageEntity::Type::Italic, 38, 1},
- {td::MessageEntity::Type::Bold, 39, 1},
- {td::MessageEntity::Type::Bold, 43, 2},
- {td::MessageEntity::Type::Pre, 45, 10}});
+ check_parse_markdown_v3("🏟````🏟``🏟`aba🏟```c🏟`aba🏟 daba🏟```c🏟`aba🏟🏟```🏟 `🏟``🏟```",
+ {{td::MessageEntity::Type::Italic, 12, 1},
+ {td::MessageEntity::Type::Italic, 44, 1},
+ {td::MessageEntity::Type::Bold, 45, 1},
+ {td::MessageEntity::Type::Bold, 49, 2}},
+ "🏟````🏟``🏟`aba🏟c🏟`aba🏟 daba🏟c🏟`aba🏟🏟🏟 `🏟``🏟",
+ {{td::MessageEntity::Type::Italic, 12, 1},
+ {td::MessageEntity::Type::Pre, 18, 16},
+ {td::MessageEntity::Type::Italic, 38, 1},
+ {td::MessageEntity::Type::Bold, 39, 1},
+ {td::MessageEntity::Type::Bold, 43, 2},
+ {td::MessageEntity::Type::Pre, 45, 10}});
check_parse_markdown_v3("` `", " ", {{td::MessageEntity::Type::Code, 0, 1}});
check_parse_markdown_v3("`\n`", "\n", {{td::MessageEntity::Type::Code, 0, 1}});
check_parse_markdown_v3("` `a", " a", {{td::MessageEntity::Type::Code, 0, 1}}, true);
diff --git a/protocols/Telegram/tdlib/td/test/mtproto.cpp b/protocols/Telegram/tdlib/td/test/mtproto.cpp
index 89f5441ab5..614e153e6f 100644
--- a/protocols/Telegram/tdlib/td/test/mtproto.cpp
+++ b/protocols/Telegram/tdlib/td/test/mtproto.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -241,7 +241,7 @@ class TestPingActor final : public td::Actor {
return stop();
}
if (ping_connection_->was_pong()) {
- LOG(INFO) << "GOT PONG";
+ LOG(INFO) << "Receive pong";
return stop();
}
}
@@ -604,7 +604,7 @@ class FastPingTestActor final : public td::Actor {
if (iteration_ % 2 == 0) {
auth_data = td::make_unique<td::mtproto::AuthData>();
auth_data->set_tmp_auth_key(handshake_->get_auth_key());
- auth_data->set_server_time_difference(handshake_->get_server_time_diff());
+ auth_data->reset_server_time_difference(handshake_->get_server_time_diff());
auth_data->set_server_salt(handshake_->get_server_salt(), td::Time::now());
auth_data->set_future_salts({td::mtproto::ServerSalt{0u, 1e20, 1e30}}, td::Time::now());
auth_data->set_use_pfs(true);
diff --git a/protocols/Telegram/tdlib/td/test/online.cpp b/protocols/Telegram/tdlib/td/test/online.cpp
index 6bcdcec833..de7afa8a66 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -23,6 +23,7 @@
#include "td/utils/port/signals.h"
#include "td/utils/Promise.h"
#include "td/utils/Random.h"
+#include "td/utils/tests.h"
#include <iostream>
#include <map>
@@ -220,14 +221,12 @@ class InitTask : public Task {
private:
Options options_;
td::Promise<> promise_;
- bool start_flag_{false};
void start_up() override {
- send_query(td::make_tl_object<td::td_api::getAuthorizationState>(),
- [this](auto res) { this->process_authorization_state(res.move_as_ok()); });
+ send_query(td::make_tl_object<td::td_api::getOption>("version"),
+ [](auto res) { LOG(INFO) << td::td_api::to_string(res.ok()); });
}
void process_authorization_state(td::tl_object_ptr<td::td_api::Object> authorization_state) {
- start_flag_ = true;
td::tl_object_ptr<td::td_api::Function> function;
switch (authorization_state->get_id()) {
case td::td_api::authorizationStateReady::ID:
@@ -266,9 +265,6 @@ class InitTask : public Task {
});
}
void process_update(std::shared_ptr<TestClient::Update> update) override {
- if (!start_flag_) {
- return;
- }
if (!update->object) {
return;
}
@@ -325,7 +321,7 @@ class UploadFile : public Task {
auto r_id = read_file(id_path_);
if (r_id.is_ok() && r_id.ok().size() > 10) {
auto id = r_id.move_as_ok();
- LOG(ERROR) << "Got file from cache";
+ LOG(ERROR) << "Receive file from cache";
Result res;
res.content = std::move(content_);
res.remote_id = id.as_slice().str();
@@ -437,16 +433,16 @@ class TestDownloadFile : public Task {
begin = end;
}
- random_shuffle(as_mutable_span(ranges_), rnd);
+ rand_shuffle(as_mutable_span(ranges_), rnd);
start_chunk();
}
- void got_chunk(const td_api::file &file) {
- LOG(ERROR) << "Got chunk";
+ void on_get_chunk(const td_api::file &file) {
+ LOG(ERROR) << "Receive chunk";
auto range = ranges_.back();
- std::string got_chunk(range.end - range.begin, '\0');
- FileFd::open(file.local_->path_, FileFd::Flags::Read).move_as_ok().pread(got_chunk, range.begin).ensure();
- CHECK(got_chunk == as_slice(content_).substr(range.begin, range.end - range.begin));
+ std::string received_chunk(range.end - range.begin, '\0');
+ FileFd::open(file.local_->path_, FileFd::Flags::Read).move_as_ok().pread(received_chunk, range.begin).ensure();
+ CHECK(received_chunk == as_slice(content_).substr(range.begin, range.end - range.begin));
ranges_.pop_back();
if (ranges_.empty()) {
promise_.set_value(Unit{});
@@ -459,7 +455,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) { got_chunk(*res.ok()); });
+ [this](auto 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 4c8012e441..3629c3c136 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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
new file mode 100644
index 0000000000..becac44e65
--- /dev/null
+++ b/protocols/Telegram/tdlib/td/test/query_merger.cpp
@@ -0,0 +1,102 @@
+//
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+//
+// 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/QueryMerger.h"
+
+#include "td/actor/actor.h"
+#include "td/actor/ConcurrentScheduler.h"
+#include "td/actor/SleepActor.h"
+
+#include "td/utils/common.h"
+#include "td/utils/FlatHashSet.h"
+#include "td/utils/logging.h"
+#include "td/utils/Promise.h"
+#include "td/utils/Random.h"
+#include "td/utils/Status.h"
+#include "td/utils/tests.h"
+
+#include <queue>
+
+class TestQueryMerger final : public td::Actor {
+ void start_up() final {
+ query_merger_.set_merge_function([this](td::vector<td::int64> query_ids, td::Promise<td::Unit> &&promise) {
+ ASSERT_TRUE(!query_ids.empty());
+ ASSERT_EQ(query_ids.size(), td::min(next_query_ids_.size(), MAX_MERGED_QUERY_COUNT));
+ for (auto query_id : query_ids) {
+ auto next_query_id = next_query_ids_.front();
+ next_query_ids_.pop();
+ ASSERT_EQ(query_id, next_query_id);
+ }
+ current_query_count_++;
+ ASSERT_TRUE(current_query_count_ <= MAX_CONCURRENT_QUERY_COUNT);
+ if (!next_query_ids_.empty()) {
+ ASSERT_EQ(current_query_count_, MAX_CONCURRENT_QUERY_COUNT);
+ }
+ td::create_actor<td::SleepActor>("CompleteMergeQuery", 0.02,
+ td::PromiseCreator::lambda([this, query_ids, promise = std::move(promise)](
+ td::Result<td::Unit> result) mutable {
+ for (auto query_id : query_ids) {
+ LOG(INFO) << "Complete " << query_id;
+ bool is_erased = pending_query_ids_.erase(query_id) > 0;
+ ASSERT_TRUE(is_erased);
+ }
+ current_query_count_--;
+ promise.set_result(std::move(result));
+ }))
+ .release();
+ yield();
+ });
+ loop();
+ }
+
+ void loop() final {
+ std::size_t query_count = 0;
+ std::size_t added_queries = td::Random::fast(1, 3);
+ while (query_count++ < added_queries && total_query_count_++ < MAX_QUERY_COUNT) {
+ td::int64 query_id = td::Random::fast(1, 20);
+ if (pending_query_ids_.insert(query_id).second) {
+ next_query_ids_.push(query_id);
+ }
+ query_merger_.add_query(query_id, td::PromiseCreator::lambda([this](td::Result<td::Unit> result) mutable {
+ completed_query_count_++;
+ if (completed_query_count_ == MAX_QUERY_COUNT) {
+ ASSERT_EQ(current_query_count_, 0u);
+ ASSERT_TRUE(next_query_ids_.empty());
+ ASSERT_TRUE(pending_query_ids_.empty());
+ td::Scheduler::instance()->finish();
+ } else {
+ yield();
+ }
+ }));
+ }
+ }
+
+ static constexpr std::size_t MAX_CONCURRENT_QUERY_COUNT = 5;
+ static constexpr std::size_t MAX_MERGED_QUERY_COUNT = 3;
+ static constexpr std::size_t MAX_QUERY_COUNT = 1000;
+
+ td::QueryMerger query_merger_{"QueryMerger", MAX_CONCURRENT_QUERY_COUNT, MAX_MERGED_QUERY_COUNT};
+ std::size_t current_query_count_ = 0;
+ std::size_t total_query_count_ = 0;
+ std::size_t completed_query_count_ = 0;
+
+ std::queue<td::int64> next_query_ids_;
+ td::FlatHashSet<td::int64> pending_query_ids_;
+};
+
+constexpr std::size_t TestQueryMerger::MAX_CONCURRENT_QUERY_COUNT;
+constexpr std::size_t TestQueryMerger::MAX_MERGED_QUERY_COUNT;
+constexpr std::size_t TestQueryMerger::MAX_QUERY_COUNT;
+
+TEST(QueryMerger, stress) {
+ td::ConcurrentScheduler sched(0, 0);
+ sched.create_actor_unsafe<TestQueryMerger>(0, "TestQueryMerger").release();
+ sched.start();
+ while (sched.run_main(10)) {
+ // empty
+ }
+ sched.finish();
+}
diff --git a/protocols/Telegram/tdlib/td/test/secret.cpp b/protocols/Telegram/tdlib/td/test/secret.cpp
index 2c79b7e2d8..bd54705695 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -382,14 +382,14 @@ class FakeBinlog final
void force_flush() final {
}
- uint64 next_id() final {
- auto res = last_id_;
- last_id_++;
+ uint64 next_event_id() final {
+ auto res = last_event_id_;
+ last_event_id_++;
return res;
}
- uint64 next_id(int32 shift) final {
- auto res = last_id_;
- last_id_ += shift;
+ uint64 next_event_id(int32 shift) final {
+ auto res = last_event_id_;
+ last_event_id_ += shift;
return res;
}
template <class F>
@@ -405,7 +405,7 @@ class FakeBinlog final
cancel_timeout();
for (auto &pending : pending_events_) {
auto &event = pending.event;
- if (!event.empty()) {
+ if (!event.is_empty()) {
// LOG(ERROR) << "FORGET EVENT: " << event.id_ << " " << event;
}
}
@@ -420,7 +420,7 @@ class FakeBinlog final
}
void close_and_destroy_impl(Promise<> promise) final {
}
- void add_raw_event_impl(uint64 id, BufferSlice &&raw_event, Promise<> promise, BinlogDebugInfo info) final {
+ void add_raw_event_impl(uint64 event_id, BufferSlice &&raw_event, Promise<> promise, BinlogDebugInfo info) final {
auto event = BinlogEvent(std::move(raw_event), info);
LOG(INFO) << "ADD EVENT: " << event.id_ << " " << event;
pending_events_.emplace_back();
@@ -439,7 +439,7 @@ class FakeBinlog final
for (size_t i = 0; i <= pos; i++) {
auto &pending = pending_events_[i];
auto event = std::move(pending.event);
- if (!event.empty()) {
+ if (!event.is_empty()) {
LOG(INFO) << "SAVE EVENT: " << event.id_ << " " << event;
events_processor_.add_event(std::move(event)).ensure();
}
@@ -464,7 +464,7 @@ class FakeBinlog final
}
}
bool has_request_sync = false;
- uint64 last_id_ = 1;
+ uint64 last_event_id_ = 1;
detail::BinlogEventsProcessor events_processor_;
struct PendingEvent {
@@ -764,11 +764,11 @@ class Master final : public Actor {
bob_ = create_actor<SecretChatProxy>("SecretChatProxy bob", "bob", actor_shared(this, 2));
send_closure(alice_.get_actor_unsafe()->actor_, &SecretChatActor::create_chat, UserId(static_cast<int64>(2)), 0,
123, PromiseCreator::lambda([actor_id = actor_id(this)](Result<SecretChatId> res) {
- send_closure(actor_id, &Master::got_secret_chat_id, std::move(res), false);
+ send_closure(actor_id, &Master::on_get_secret_chat_id, std::move(res), false);
}));
}
- void got_secret_chat_id(Result<SecretChatId> res, bool dummy) {
+ void on_get_secret_chat_id(Result<SecretChatId> res, bool dummy) {
CHECK(res.is_ok());
auto id = res.move_as_ok();
LOG(INFO) << "SecretChatId = " << id;
@@ -825,14 +825,14 @@ class Master final : public Actor {
}
void process_net_query(my_api::messages_getDhConfig &&get_dh_config, NetQueryPtr net_query,
ActorShared<NetQueryCallback> callback) {
- //LOG(INFO) << "Got query " << to_string(get_dh_config);
+ //LOG(INFO) << "Receive query " << to_string(get_dh_config);
my_api::messages_dhConfig config;
config.p_ = BufferSlice(base64url_decode(prime_base64).move_as_ok());
config.g_ = g;
config.version_ = 12;
auto storer = TLObjectStorer<my_api::messages_dhConfig>(config);
BufferSlice answer(storer.size());
- auto real_size = storer.store(answer.as_slice().ubegin());
+ auto real_size = storer.store(answer.as_mutable_slice().ubegin());
CHECK(real_size == answer.size());
net_query->set_ok(std::move(answer));
send_closure(std::move(callback), &NetQueryCallback::on_result, std::move(net_query));
@@ -857,7 +857,7 @@ class Master final : public Actor {
my_api::encryptedChat encrypted_chat(123, 321, 0, 1, 2, BufferSlice(), request_encryption.key_fingerprint_);
auto storer = TLObjectStorer<my_api::encryptedChat>(encrypted_chat);
BufferSlice answer(storer.size());
- auto real_size = storer.store(answer.as_slice().ubegin());
+ auto real_size = storer.store(answer.as_mutable_slice().ubegin());
CHECK(real_size == answer.size());
net_query->set_ok(std::move(answer));
send_closure(std::move(callback), &NetQueryCallback::on_result, std::move(net_query));
@@ -899,8 +899,8 @@ class Master final : public Actor {
void process_net_query_send_encrypted(BufferSlice data, NetQueryPtr net_query,
ActorShared<NetQueryCallback> callback) {
BufferSlice answer(8);
- answer.as_slice().fill(0);
- as<int32>(answer.as_slice().begin()) = static_cast<int32>(my_api::messages_sentEncryptedMessage::ID);
+ answer.as_mutable_slice().fill(0);
+ as<int32>(answer.as_mutable_slice().begin()) = static_cast<int32>(my_api::messages_sentEncryptedMessage::ID);
net_query->set_ok(std::move(answer));
send_closure(std::move(callback), &NetQueryCallback::on_result, std::move(net_query));
@@ -914,7 +914,7 @@ class Master final : public Actor {
int32 last_ping_ = std::numeric_limits<int32>::max();
void on_inbound_message(string message, Promise<> promise) {
promise.set_value(Unit());
- LOG(INFO) << "GOT INBOUND MESSAGE: " << message << " " << get_link_token();
+ LOG(INFO) << "Receive inbound message: " << message << " " << get_link_token();
int32 cnt;
int x = std::sscanf(message.c_str(), "PING: %d", &cnt);
if (x != 1) {
@@ -967,7 +967,7 @@ class Master final : public Actor {
std::map<int64, Message> sent_messages_;
void hangup_shared() final {
- LOG(INFO) << "GOT HANGUP: " << get_link_token();
+ LOG(INFO) << "Receive hang up: " << get_link_token();
send_closure(from(), &SecretChatProxy::on_closed);
}
};
diff --git a/protocols/Telegram/tdlib/td/test/secure_storage.cpp b/protocols/Telegram/tdlib/td/test/secure_storage.cpp
index 774dead5ac..714e92f77a 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -7,6 +7,7 @@
#include "td/telegram/SecureStorage.h"
#include "td/utils/buffer.h"
+#include "td/utils/common.h"
#include "td/utils/filesystem.h"
#include "td/utils/port/path.h"
#include "td/utils/SliceBuilder.h"
@@ -66,5 +67,8 @@ TEST(SecureStorage, simple) {
auto hash = td::secure_storage::encrypt_file(value_secret, value_path, encrypted_path).move_as_ok();
td::secure_storage::decrypt_file(value_secret, hash, encrypted_path, decrypted_path).ensure();
ASSERT_TRUE(td::read_file(decrypted_path).move_as_ok().as_slice() == file_value);
+ td::unlink(value_path).ignore();
+ td::unlink(encrypted_path).ignore();
+ td::unlink(decrypted_path).ignore();
}
}
diff --git a/protocols/Telegram/tdlib/td/test/set_with_position.cpp b/protocols/Telegram/tdlib/td/test/set_with_position.cpp
index c65b8bc362..f8494b392b 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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 442f82d913..c597d7616c 100644
--- a/protocols/Telegram/tdlib/td/test/string_cleaning.cpp
+++ b/protocols/Telegram/tdlib/td/test/string_cleaning.cpp
@@ -1,11 +1,12 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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/misc.h"
+#include "td/utils/common.h"
#include "td/utils/Slice.h"
#include "td/utils/tests.h"
diff --git a/protocols/Telegram/tdlib/td/test/tdclient.cpp b/protocols/Telegram/tdlib/td/test/tdclient.cpp
index 6ced39da30..a608c75593 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -146,7 +146,7 @@ class TestClient final : public td::Actor {
td::rmrf(name_).ignore();
auto old_context = set_context(std::make_shared<td::ActorContext>());
set_tag(name_);
- LOG(INFO) << "START UP!";
+ LOG(INFO) << "Start up!";
td_client_ = td::create_actor<td::ClientActor>("Td-proxy", make_td_callback());
}
@@ -204,11 +204,10 @@ class DoAuthentication final : public TestClinetTask {
: name_(std::move(name)), phone_(std::move(phone)), code_(std::move(code)), promise_(std::move(promise)) {
}
void start_up() final {
- send_query(td::make_tl_object<td::td_api::getAuthorizationState>(),
- [this](auto res) { this->process_authorization_state(std::move(res)); });
+ send_query(td::make_tl_object<td::td_api::getOption>("version"),
+ [](auto res) { LOG(INFO) << td::td_api::to_string(res); });
}
void process_authorization_state(td::tl_object_ptr<td::td_api::Object> authorization_state) {
- start_flag_ = true;
td::tl_object_ptr<td::td_api::Function> function;
switch (authorization_state->get_id()) {
case td::td_api::authorizationStateWaitPhoneNumber::ID:
@@ -252,7 +251,7 @@ class DoAuthentication final : public TestClinetTask {
send_query(std::move(function), [](auto res) { LOG_CHECK(res->get_id() == td::td_api::ok::ID) << to_string(res); });
}
void on_authorization_ready() {
- LOG(INFO) << "GOT AUTHORIZED";
+ LOG(INFO) << "Authorization is completed";
stop();
}
@@ -261,12 +260,8 @@ class DoAuthentication final : public TestClinetTask {
td::string phone_;
td::string code_;
td::Promise<> promise_;
- bool start_flag_{false};
void process_update(std::shared_ptr<TestClient::Update> update) final {
- if (!start_flag_) {
- return;
- }
if (!update->object) {
return;
}
@@ -299,7 +294,7 @@ class SetUsername final : public TestClinetTask {
self_id_ = user->id_;
auto current_username = user->usernames_ != nullptr ? user->usernames_->editable_username_ : td::string();
if (current_username != username_) {
- LOG(INFO) << "SET USERNAME: " << username_;
+ LOG(INFO) << "Set username: " << username_;
send_query(td::make_tl_object<td::td_api::setUsername>(username_), [this](auto res) {
CHECK(res->get_id() == td::td_api::ok::ID);
this->send_self_message();
@@ -335,7 +330,7 @@ class SetUsername final : public TestClinetTask {
auto messageText = td::move_tl_object_as<td::td_api::messageText>(message->content_);
auto text = messageText->text_->text_;
if (text.substr(0, tag_.size()) == tag_) {
- LOG(INFO) << "GOT SELF MESSAGE";
+ LOG(INFO) << "Receive self-message";
return stop();
}
}
@@ -365,7 +360,7 @@ class CheckTestA final : public TestClinetTask {
LOG_CHECK(text > previous_text_) << td::tag("now", text) << td::tag("previous", previous_text_);
previous_text_ = text;
cnt_--;
- LOG(INFO) << "GOT " << td::tag("text", text) << td::tag("left", cnt_);
+ LOG(INFO) << "Receive " << td::tag("text", text) << td::tag("left", cnt_);
if (cnt_ == 0) {
return stop();
}
@@ -432,7 +427,7 @@ class TestSecretChat final : public TestClinetTask {
update_secret_chat->secret_chat_->state_->get_id() != td::td_api::secretChatStateReady::ID) {
return;
}
- LOG(INFO) << "SEND ENCRYPTED MESSAGES";
+ LOG(INFO) << "Send encrypted messages";
for (int i = 0; i < 20; i++) {
send_query(
td::make_tl_object<td::td_api::sendMessage>(
@@ -487,7 +482,7 @@ class TestFileGenerated final : public TestClinetTask {
}
void one_file() {
- LOG(ERROR) << "Start ONE_FILE test";
+ LOG(ERROR) << "Start one_file test";
auto file_path = PSTRING() << "test_documents" << TD_DIR_SLASH << "a.txt";
td::mkpath(file_path).ensure();
auto raw_file =
@@ -559,7 +554,7 @@ class TestFileGenerated final : public TestClinetTask {
}
}
auto ready = std::ftell(to);
- LOG(ERROR) << "READY: " << ready;
+ LOG(ERROR) << "Ready: " << ready;
parent_->send_query(td::make_tl_object<td::td_api::setFileGenerationProgress>(
id_, 1039823 /*yeah, exact size of this file*/, td::narrow_cast<td::int32>(ready)),
[](auto result) { check_td_error(result); });
@@ -636,7 +631,7 @@ class CheckTestC final : public TestClinetTask {
auto text = messageDocument->caption_->text_;
if (text.substr(0, tag_.size()) == tag_) {
file_id_to_check_ = messageDocument->document_->document_->id_;
- LOG(ERROR) << "GOT FILE " << to_string(messageDocument->document_->document_);
+ LOG(ERROR) << "Receive file " << to_string(messageDocument->document_->document_);
send_query(td::make_tl_object<td::td_api::downloadFile>(file_id_to_check_, 1, 0, 0, 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 b1bf94a09e..9c3da0034c 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-2022
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// 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)
@@ -68,6 +68,15 @@ class TestTQueue {
binlog_->set_callback(std::move(tqueue_binlog));
}
+ TestTQueue(const TestTQueue &) = delete;
+ TestTQueue &operator=(const TestTQueue &) = delete;
+ TestTQueue(TestTQueue &&) = delete;
+ TestTQueue &operator=(TestTQueue &&) = delete;
+
+ ~TestTQueue() {
+ td::Binlog::destroy(binlog_path()).ensure();
+ }
+
void restart(td::Random::Xorshift128plus &rnd, td::int32 now) {
if (rnd.fast(0, 10) == 0) {
baseline_->run_gc(now);
@@ -234,17 +243,18 @@ TEST(TQueue, clear) {
td::int32 now = 0;
td::vector<td::TQueue::EventId> ids;
td::Random::Xorshift128plus rnd(123);
- for (size_t i = 0; i < 1000000; i++) {
+ for (size_t i = 0; i < 100000; i++) {
tqueue->push(1, td::string(td::Random::fast(100, 500), 'a'), now + 600000, 0, {}).ensure();
}
auto tail_id = tqueue->get_tail(1);
auto clear_start_time = td::Time::now();
size_t keep_count = td::Random::fast(0, 2);
- tqueue->clear(1, keep_count);
+ auto deleted_events = tqueue->clear(1, keep_count);
auto finish_time = td::Time::now();
LOG(INFO) << "Added TQueue events in " << clear_start_time - start_time << " seconds and cleared them in "
<< finish_time - clear_start_time << " seconds";
CHECK(tqueue->get_size(1) == keep_count);
CHECK(tqueue->get_head(1).advance(keep_count).ok() == tail_id);
CHECK(tqueue->get_tail(1) == tail_id);
+ CHECK(deleted_events.size() == 100000 - keep_count);
}