Renamed 'contacts_processor' to 'validate_and_format_contacts'

Moved Validate*Page functions to validate_and_format_contacts.hpp/.cpp

Moved validate_and_format_contacts tests to a separate CPP file

PR comments fixes

Fixed iOS build

Signed-off-by: S. Kozyr <s.trump@gmail.com>
This commit is contained in:
Sergiy Kozyr 2021-11-15 10:01:06 +02:00
parent 396f724e69
commit 9bb9ef073f
Signed by: strump
GPG key ID: C622E5563CAC205D
11 changed files with 322 additions and 279 deletions

View file

@ -7,6 +7,7 @@
#include "indexer/cuisines.hpp"
#include "indexer/editable_map_object.hpp"
#include "indexer/validate_and_format_contacts.hpp"
#include "coding/string_utf8_multilang.hpp"
@ -655,35 +656,35 @@ Java_com_mapswithme_maps_editor_Editor_nativeIsWebsiteValid(JNIEnv * env, jclass
JNIEXPORT jboolean JNICALL
Java_com_mapswithme_maps_editor_Editor_nativeIsFacebookPageValid(JNIEnv * env, jclass, jstring facebookPage)
{
return osm::EditableMapObject::ValidateFacebookPage(jni::ToNativeString(env, facebookPage));
return osm::ValidateFacebookPage(jni::ToNativeString(env, facebookPage));
}
// static boolean nativeIsInstagramPageValid(String instagramPage)
JNIEXPORT jboolean JNICALL
Java_com_mapswithme_maps_editor_Editor_nativeIsInstagramPageValid(JNIEnv * env, jclass, jstring instagramPage)
{
return osm::EditableMapObject::ValidateInstagramPage(jni::ToNativeString(env, instagramPage));
return osm::ValidateInstagramPage(jni::ToNativeString(env, instagramPage));
}
// static boolean nativeIsTwitterPageValid(String twitterPage)
JNIEXPORT jboolean JNICALL
Java_com_mapswithme_maps_editor_Editor_nativeIsTwitterPageValid(JNIEnv * env, jclass, jstring twitterPage)
{
return osm::EditableMapObject::ValidateTwitterPage(jni::ToNativeString(env, twitterPage));
return osm::ValidateTwitterPage(jni::ToNativeString(env, twitterPage));
}
// static boolean nativeIsVkPageValid(String vkPage)
JNIEXPORT jboolean JNICALL
Java_com_mapswithme_maps_editor_Editor_nativeIsVkPageValid(JNIEnv * env, jclass, jstring vkPage)
{
return osm::EditableMapObject::ValidateVkPage(jni::ToNativeString(env, vkPage));
return osm::ValidateVkPage(jni::ToNativeString(env, vkPage));
}
// static boolean nativeIsLinePageValid(String linePage)
JNIEXPORT jboolean JNICALL
Java_com_mapswithme_maps_editor_Editor_nativeIsLinePageValid(JNIEnv * env, jclass, jstring linePage)
{
return osm::EditableMapObject::ValidateLinePage(jni::ToNativeString(env, linePage));
return osm::ValidateLinePage(jni::ToNativeString(env, linePage));
}
// static boolean nativeIsEmailValid(String email)

View file

@ -1,7 +1,7 @@
#pragma once
#include "indexer/feature_data.hpp"
#include "indexer/contacts_processor.hpp"
#include "indexer/validate_and_format_contacts.hpp"
#include <string>

View file

@ -30,8 +30,6 @@ set(
complex/serdes.hpp
complex/serdes_utils.hpp
complex/tree_node.hpp
contacts_processor.cpp
contacts_processor.hpp
cuisines.cpp
cuisines.hpp
data_factory.cpp
@ -139,6 +137,8 @@ set(
unique_index.hpp
utils.cpp
utils.hpp
validate_and_format_contacts.cpp
validate_and_format_contacts.hpp
)
set(

View file

@ -1,9 +1,9 @@
#include "indexer/editable_map_object.hpp"
#include "indexer/classificator.hpp"
#include "indexer/contacts_processor.hpp"
#include "indexer/cuisines.hpp"
#include "indexer/postcodes_matcher.hpp"
#include "indexer/validate_and_format_contacts.hpp"
#include "platform/preferred_languages.hpp"
@ -495,27 +495,27 @@ void EditableMapObject::SetWebsite(string website)
m_metadata.Drop(feature::Metadata::FMD_URL);
}
void EditableMapObject::SetFacebookPage(string facebookPage)
void EditableMapObject::SetFacebookPage(string const & facebookPage)
{
m_metadata.Set(feature::Metadata::FMD_CONTACT_FACEBOOK, ValidateAndFormat_facebook(facebookPage));
}
void EditableMapObject::SetInstagramPage(string instagramPage)
void EditableMapObject::SetInstagramPage(string const & instagramPage)
{
m_metadata.Set(feature::Metadata::FMD_CONTACT_INSTAGRAM, ValidateAndFormat_instagram(instagramPage));
}
void EditableMapObject::SetTwitterPage(string twitterPage)
void EditableMapObject::SetTwitterPage(string const & twitterPage)
{
m_metadata.Set(feature::Metadata::FMD_CONTACT_TWITTER, ValidateAndFormat_twitter(twitterPage));
}
void EditableMapObject::SetVkPage(string vkPage)
void EditableMapObject::SetVkPage(string const & vkPage)
{
m_metadata.Set(feature::Metadata::FMD_CONTACT_VK, ValidateAndFormat_vk(vkPage));
}
void EditableMapObject::SetLinePage(string linePage)
void EditableMapObject::SetLinePage(string const & linePage)
{
m_metadata.Set(feature::Metadata::FMD_CONTACT_LINE, ValidateAndFormat_contactLine(linePage));
}
@ -772,146 +772,6 @@ bool EditableMapObject::ValidateWebsite(string const & site)
return true;
}
//static
bool EditableMapObject::ValidateFacebookPage(string const & page)
{
if (page.empty())
return true;
// See rules: https://www.facebook.com/help/105399436216001
static auto const s_fbRegex = regex(R"(^@?[a-zA-Z\d.\-]{5,}$)");
if (regex_match(page, s_fbRegex))
return true;
if (ValidateWebsite(page))
{
string const domain = strings::MakeLowerCase(url::Url::FromString(page).GetWebDomain());
return (strings::StartsWith(domain, "facebook.") || strings::StartsWith(domain, "fb.") ||
domain.find(".facebook.") != string::npos || domain.find(".fb.") != string::npos);
}
return false;
}
//static
bool EditableMapObject::ValidateInstagramPage(string const & page)
{
if (page.empty())
return true;
// Rules took here: https://blog.jstassen.com/2016/03/code-regex-for-instagram-username-and-hashtags/
static auto const s_instaRegex = regex(R"(^@?[A-Za-z0-9_][A-Za-z0-9_.]{0,28}[A-Za-z0-9_]$)");
if (regex_match(page, s_instaRegex))
return true;
if (ValidateWebsite(page))
{
string const domain = strings::MakeLowerCase(url::Url::FromString(page).GetWebDomain());
return domain == "instagram.com" || strings::EndsWith(domain, ".instagram.com");
}
return false;
}
//static
bool EditableMapObject::ValidateTwitterPage(string const & page)
{
if (page.empty())
return true;
if (ValidateWebsite(page))
{
string const domain = strings::MakeLowerCase(url::Url::FromString(page).GetWebDomain());
return domain == "twitter.com" || strings::EndsWith(domain, ".twitter.com");
}
else
{
// Rules took here: https://stackoverflow.com/q/11361044
static auto const s_twitterRegex = regex(R"(^@?[A-Za-z0-9_]{1,15}$)");
return regex_match(page, s_twitterRegex);
}
}
//static
bool EditableMapObject::ValidateVkPage(string const & page)
{
if (page.empty())
return true;
{
/* Check that page contains valid username. Rules took here: https://vk.com/faq18038
The page name must be between 5 and 32 characters.
Invalid format could be in cases:
* - begins with three or more numbers (one or two numbers are allowed).
* - begins and ends with "_".
* - contains a period with less than four symbols after it starting with a letter.
*/
if (page.size() < 5)
return false;
string vkLogin = page;
if (vkLogin.front() == '@')
vkLogin = vkLogin.substr(1);
if (vkLogin.front() == '_' && vkLogin.back() == '_')
return false;
static auto const s_badVkRegex = regex(R"(^\d\d\d.+$)");
if (regex_match(vkLogin, s_badVkRegex))
return false;
static auto const s_goodVkRegex = regex(R"(^[A-Za-z0-9_.]{5,32}$)");
if (regex_match(vkLogin, s_goodVkRegex))
return true;
}
if (ValidateWebsite(page))
{
string const domain = strings::MakeLowerCase(url::Url::FromString(page).GetWebDomain());
return domain == "vk.com" || strings::EndsWith(domain, ".vk.com")
|| domain == "vkontakte.ru" || strings::EndsWith(domain, ".vkontakte.ru");
}
return false;
}
//static
bool EditableMapObject::ValidateLinePage(string const & page)
{
if (page.empty())
return true;
{
// Check that linePage contains valid page name.
// Rules are defined here: https://help.line.me/line/?contentId=10009904
// The page name must be between 4 and 20 characters. Should contains alphanumeric characters
// and symbols '.', '-', and '_'
string linePageClean = page;
if (linePageClean.front() == '@')
linePageClean = linePageClean.substr(1);
if (regex_match(linePageClean, regex(R"(^[a-z0-9-_.]{4,20}$)")))
return true;
}
if (EditableMapObject::ValidateWebsite(page))
{
string linePageUrl = page;
// Check if HTTP protocol is present
if (!strings::StartsWith(page, "http://") && !strings::StartsWith(page, "https://"))
linePageUrl = "https://" + page;
const url::Url url = url::Url(linePageUrl);
const string &domain = strings::MakeLowerCase(url.GetWebDomain());
// Check Line domain name
if (domain == "line.me" || strings::EndsWith(domain, ".line.me"))
return true;
}
return false;
}
// static
bool EditableMapObject::ValidateEmail(string const & email)
{

View file

@ -137,11 +137,11 @@ public:
void SetEmail(std::string const & email);
void SetWebsite(std::string website);
void SetFacebookPage(std::string facebookPage);
void SetInstagramPage(std::string instagramPage);
void SetTwitterPage(std::string twitterPage);
void SetVkPage(std::string vkPage);
void SetLinePage(std::string linePage);
void SetFacebookPage(std::string const & facebookPage);
void SetInstagramPage(std::string const & instagramPage);
void SetTwitterPage(std::string const & twitterPage);
void SetVkPage(std::string const & vkPage);
void SetLinePage(std::string const & linePage);
void SetWikipedia(std::string const & wikipedia);
void SetInternet(Internet internet);
@ -173,11 +173,6 @@ public:
static bool ValidatePostCode(std::string const & postCode);
static bool ValidatePhoneList(std::string const & phone);
static bool ValidateWebsite(std::string const & site);
static bool ValidateFacebookPage(std::string const & facebookPage);
static bool ValidateInstagramPage(std::string const & page);
static bool ValidateTwitterPage(std::string const & page);
static bool ValidateVkPage(std::string const & page);
static bool ValidateLinePage(std::string const & page);
static bool ValidateEmail(std::string const & email);
static bool ValidateLevel(std::string const & level);
static bool ValidateName(std::string const & name);

View file

@ -38,6 +38,7 @@ set(
test_type.cpp
tree_node_tests.cpp
trie_test.cpp
validate_and_format_contacts_test.cpp
visibility_test.cpp
wheelchair_tests.cpp
)

View file

@ -193,103 +193,6 @@ UNIT_TEST(EditableMapObject_ValidateEmail)
TEST(!EditableMapObject::ValidateEmail("email@e#$%&'*+-/=?^`_{}|~.com"), ());
}
UNIT_TEST(EditableMapObject_ValidateFacebookPage)
{
TEST(EditableMapObject::ValidateFacebookPage(""), ());
TEST(EditableMapObject::ValidateFacebookPage("facebook.com/OpenStreetMap"), ());
TEST(EditableMapObject::ValidateFacebookPage("www.facebook.com/OpenStreetMap"), ());
TEST(EditableMapObject::ValidateFacebookPage("http://facebook.com/OpenStreetMap"), ());
TEST(EditableMapObject::ValidateFacebookPage("https://facebook.com/OpenStreetMap"), ());
TEST(EditableMapObject::ValidateFacebookPage("http://www.facebook.com/OpenStreetMap"), ());
TEST(EditableMapObject::ValidateFacebookPage("https://www.facebook.com/OpenStreetMap"), ());
TEST(EditableMapObject::ValidateFacebookPage("https://en-us.facebook.com/OpenStreetMap"), ());
TEST(EditableMapObject::ValidateFacebookPage("OpenStreetMap"), ());
TEST(EditableMapObject::ValidateFacebookPage("some.good.page"), ());
TEST(EditableMapObject::ValidateFacebookPage("Quaama-Volunteer-Bushfire-Brigade-526790054021506"), ());
TEST(EditableMapObject::ValidateFacebookPage("@tree-house-interiors"), ());
TEST(EditableMapObject::ValidateFacebookPage("alexander.net"), ());
TEST(!EditableMapObject::ValidateFacebookPage("instagram.com/openstreetmapus"), ());
TEST(!EditableMapObject::ValidateFacebookPage("https://instagram.com/openstreetmapus"), ());
TEST(!EditableMapObject::ValidateFacebookPage("osm"), ());
TEST(!EditableMapObject::ValidateFacebookPage("invalid_username"), ());
}
UNIT_TEST(EditableMapObject_ValidateInstagramPage)
{
TEST(EditableMapObject::ValidateInstagramPage(""), ());
TEST(EditableMapObject::ValidateInstagramPage("instagram.com/openstreetmapus"), ());
TEST(EditableMapObject::ValidateInstagramPage("www.instagram.com/openstreetmapus"), ());
TEST(EditableMapObject::ValidateInstagramPage("http://instagram.com/openstreetmapus"), ());
TEST(EditableMapObject::ValidateInstagramPage("https://instagram.com/openstreetmapus"), ());
TEST(EditableMapObject::ValidateInstagramPage("http://www.instagram.com/openstreetmapus"), ());
TEST(EditableMapObject::ValidateInstagramPage("https://www.instagram.com/openstreetmapus"), ());
TEST(EditableMapObject::ValidateInstagramPage("https://en-us.instagram.com/openstreetmapus"), ());
TEST(EditableMapObject::ValidateInstagramPage("openstreetmapus"), ());
TEST(EditableMapObject::ValidateInstagramPage("open.street.map.us"), ());
TEST(EditableMapObject::ValidateInstagramPage("open_street_map_us"), ());
TEST(EditableMapObject::ValidateInstagramPage("@open_street_map_us"), ());
TEST(EditableMapObject::ValidateInstagramPage("_osm_"), ());
TEST(!EditableMapObject::ValidateInstagramPage("facebook.com/osm_us"), ());
TEST(!EditableMapObject::ValidateInstagramPage("https://facebook.com/osm_us"), ());
TEST(!EditableMapObject::ValidateInstagramPage(".osm"), ());
TEST(!EditableMapObject::ValidateInstagramPage("osm."), ());
TEST(!EditableMapObject::ValidateInstagramPage(".dots_not_allowed."), ());
TEST(!EditableMapObject::ValidateInstagramPage("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), ());
}
UNIT_TEST(EditableMapObject_ValidateTwitterPage)
{
TEST(EditableMapObject::ValidateTwitterPage(""), ());
TEST(EditableMapObject::ValidateTwitterPage("twitter.com/osm_tech"), ());
TEST(EditableMapObject::ValidateTwitterPage("www.twitter.com/osm_tech"), ());
TEST(EditableMapObject::ValidateTwitterPage("http://twitter.com/osm_tech"), ());
TEST(EditableMapObject::ValidateTwitterPage("https://twitter.com/osm_tech"), ());
TEST(EditableMapObject::ValidateTwitterPage("http://www.twitter.com/osm_tech"), ());
TEST(EditableMapObject::ValidateTwitterPage("https://www.twitter.com/osm_tech"), ());
TEST(EditableMapObject::ValidateTwitterPage("osm_tech"), ());
TEST(EditableMapObject::ValidateTwitterPage("_osm_tech_"), ());
TEST(EditableMapObject::ValidateTwitterPage("@_osm_tech_"), ());
TEST(EditableMapObject::ValidateTwitterPage("1"), ());
TEST(!EditableMapObject::ValidateTwitterPage("instagram.com/osm_tech"), ());
TEST(!EditableMapObject::ValidateTwitterPage("https://instagram.com/osm_tech"), ());
TEST(!EditableMapObject::ValidateTwitterPage("dots.not.allowed"), ());
TEST(!EditableMapObject::ValidateTwitterPage("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), ());
}
UNIT_TEST(EditableMapObject_ValidateVkPage)
{
TEST(EditableMapObject::ValidateVkPage(""), ());
TEST(EditableMapObject::ValidateVkPage("vk.com/id404"), ());
TEST(EditableMapObject::ValidateVkPage("vkontakte.ru/id404"), ());
TEST(EditableMapObject::ValidateVkPage("www.vk.com/id404"), ());
TEST(EditableMapObject::ValidateVkPage("http://vk.com/id404"), ());
TEST(EditableMapObject::ValidateVkPage("https://vk.com/id404"), ());
TEST(EditableMapObject::ValidateVkPage("https://vkontakte.ru/id404"), ());
TEST(EditableMapObject::ValidateVkPage("http://www.vk.com/id404"), ());
TEST(EditableMapObject::ValidateVkPage("https://www.vk.com/id404"), ());
TEST(EditableMapObject::ValidateVkPage("id432160160"), ());
TEST(EditableMapObject::ValidateVkPage("hello_world"), ());
TEST(EditableMapObject::ValidateVkPage("osm63rus"), ());
TEST(EditableMapObject::ValidateVkPage("22ab.cdef"), ());
TEST(EditableMapObject::ValidateVkPage("@hello_world"), ());
TEST(EditableMapObject::ValidateVkPage("@osm63rus"), ());
TEST(EditableMapObject::ValidateVkPage("@22ab.cdef"), ());
TEST(!EditableMapObject::ValidateVkPage("333too_many_numbers"), ());
TEST(!EditableMapObject::ValidateVkPage("vk"), ());
TEST(!EditableMapObject::ValidateVkPage("@five"), ());
TEST(!EditableMapObject::ValidateVkPage("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), ());
TEST(!EditableMapObject::ValidateVkPage("_invalid_underscores_"), ());
TEST(!EditableMapObject::ValidateVkPage("invalid-dashes"), ());
//TEST(!EditableMapObject::ValidateVkPage("to.ma.ny.do.ts"), ()); //TODO: it's hard to test such cases. Skip for now
//TEST(!EditableMapObject::ValidateVkPage("dots.__.dots"), ()); //TODO: it's hard to test such cases. Skip for now
TEST(!EditableMapObject::ValidateVkPage("instagram.com/hello_world"), ());
TEST(!EditableMapObject::ValidateVkPage("https://instagram.com/hello_world"), ());
}
UNIT_TEST(EditableMapObject_ValidateName)
{
vector<string> correctNames = {"abc", "абв", "ᆺᆯㅕ", "꫞ꪺꫀꪸ", "a b?c", "a!b.c", "a(b)c", "a,b.c",

View file

@ -0,0 +1,137 @@
#include "testing/testing.hpp"
#include "indexer/validate_and_format_contacts.hpp"
#include <string>
UNIT_TEST(EditableMapObject_ValidateFacebookPage)
{
TEST(osm::ValidateFacebookPage(""), ());
TEST(osm::ValidateFacebookPage("facebook.com/OpenStreetMap"), ());
TEST(osm::ValidateFacebookPage("www.facebook.com/OpenStreetMap"), ());
TEST(osm::ValidateFacebookPage("http://facebook.com/OpenStreetMap"), ());
TEST(osm::ValidateFacebookPage("https://facebook.com/OpenStreetMap"), ());
TEST(osm::ValidateFacebookPage("http://www.facebook.com/OpenStreetMap"), ());
TEST(osm::ValidateFacebookPage("https://www.facebook.com/OpenStreetMap"), ());
TEST(osm::ValidateFacebookPage("https://en-us.facebook.com/OpenStreetMap"), ());
TEST(osm::ValidateFacebookPage("OpenStreetMap"), ());
TEST(osm::ValidateFacebookPage("some.good.page"), ());
TEST(osm::ValidateFacebookPage("Quaama-Volunteer-Bushfire-Brigade-526790054021506"), ());
TEST(osm::ValidateFacebookPage("@tree-house-interiors"), ());
TEST(osm::ValidateFacebookPage("alexander.net"), ());
TEST(!osm::ValidateFacebookPage("instagram.com/openstreetmapus"), ());
TEST(!osm::ValidateFacebookPage("https://instagram.com/openstreetmapus"), ());
TEST(!osm::ValidateFacebookPage("osm"), ());
TEST(!osm::ValidateFacebookPage("invalid_username"), ());
}
UNIT_TEST(EditableMapObject_ValidateInstagramPage)
{
TEST(osm::ValidateInstagramPage(""), ());
TEST(osm::ValidateInstagramPage("instagram.com/openstreetmapus"), ());
TEST(osm::ValidateInstagramPage("www.instagram.com/openstreetmapus"), ());
TEST(osm::ValidateInstagramPage("http://instagram.com/openstreetmapus"), ());
TEST(osm::ValidateInstagramPage("https://instagram.com/openstreetmapus"), ());
TEST(osm::ValidateInstagramPage("http://www.instagram.com/openstreetmapus"), ());
TEST(osm::ValidateInstagramPage("https://www.instagram.com/openstreetmapus"), ());
TEST(osm::ValidateInstagramPage("https://en-us.instagram.com/openstreetmapus"), ());
TEST(osm::ValidateInstagramPage("openstreetmapus"), ());
TEST(osm::ValidateInstagramPage("open.street.map.us"), ());
TEST(osm::ValidateInstagramPage("open_street_map_us"), ());
TEST(osm::ValidateInstagramPage("@open_street_map_us"), ());
TEST(osm::ValidateInstagramPage("_osm_"), ());
TEST(!osm::ValidateInstagramPage("facebook.com/osm_us"), ());
TEST(!osm::ValidateInstagramPage("https://facebook.com/osm_us"), ());
TEST(!osm::ValidateInstagramPage(".osm"), ());
TEST(!osm::ValidateInstagramPage("osm."), ());
TEST(!osm::ValidateInstagramPage(".dots_not_allowed."), ());
TEST(!osm::ValidateInstagramPage("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), ());
}
UNIT_TEST(EditableMapObject_ValidateTwitterPage)
{
TEST(osm::ValidateTwitterPage(""), ());
TEST(osm::ValidateTwitterPage("twitter.com/osm_tech"), ());
TEST(osm::ValidateTwitterPage("www.twitter.com/osm_tech"), ());
TEST(osm::ValidateTwitterPage("http://twitter.com/osm_tech"), ());
TEST(osm::ValidateTwitterPage("https://twitter.com/osm_tech"), ());
TEST(osm::ValidateTwitterPage("http://www.twitter.com/osm_tech"), ());
TEST(osm::ValidateTwitterPage("https://www.twitter.com/osm_tech"), ());
TEST(osm::ValidateTwitterPage("osm_tech"), ());
TEST(osm::ValidateTwitterPage("_osm_tech_"), ());
TEST(osm::ValidateTwitterPage("@_osm_tech_"), ());
TEST(osm::ValidateTwitterPage("1"), ());
TEST(!osm::ValidateTwitterPage("instagram.com/osm_tech"), ());
TEST(!osm::ValidateTwitterPage("https://instagram.com/osm_tech"), ());
TEST(!osm::ValidateTwitterPage("dots.not.allowed"), ());
TEST(!osm::ValidateTwitterPage("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), ());
}
UNIT_TEST(EditableMapObject_ValidateVkPage)
{
TEST(osm::ValidateVkPage(""), ());
TEST(osm::ValidateVkPage("vk.com/id404"), ());
TEST(osm::ValidateVkPage("vkontakte.ru/id404"), ());
TEST(osm::ValidateVkPage("www.vk.com/id404"), ());
TEST(osm::ValidateVkPage("http://vk.com/id404"), ());
TEST(osm::ValidateVkPage("https://vk.com/id404"), ());
TEST(osm::ValidateVkPage("https://vkontakte.ru/id404"), ());
TEST(osm::ValidateVkPage("http://www.vk.com/id404"), ());
TEST(osm::ValidateVkPage("https://www.vk.com/id404"), ());
TEST(osm::ValidateVkPage("id432160160"), ());
TEST(osm::ValidateVkPage("hello_world"), ());
TEST(osm::ValidateVkPage("osm63rus"), ());
TEST(osm::ValidateVkPage("22ab.cdef"), ());
TEST(osm::ValidateVkPage("@hello_world"), ());
TEST(osm::ValidateVkPage("@osm63rus"), ());
TEST(osm::ValidateVkPage("@22ab.cdef"), ());
TEST(!osm::ValidateVkPage("333too_many_numbers"), ());
TEST(!osm::ValidateVkPage("vk"), ());
TEST(!osm::ValidateVkPage("@five"), ());
TEST(!osm::ValidateVkPage("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), ());
TEST(!osm::ValidateVkPage("_invalid_underscores_"), ());
TEST(!osm::ValidateVkPage("invalid-dashes"), ());
//TEST(!osm::ValidateVkPage("to.ma.ny.do.ts"), ()); //TODO: it's hard to test such cases. Skip for now
//TEST(!osm::ValidateVkPage("dots.__.dots"), ()); //TODO: it's hard to test such cases. Skip for now
TEST(!osm::ValidateVkPage("instagram.com/hello_world"), ());
TEST(!osm::ValidateVkPage("https://instagram.com/hello_world"), ());
}
UNIT_TEST(EditableMapObject_ValidateLinePage)
{
TEST(osm::ValidateLinePage(""), ());
TEST(osm::ValidateLinePage("http://line.me/ti/p/mzog4fnz24"), ());
TEST(osm::ValidateLinePage("https://line.me/ti/p/xnv0g02rws"), ());
TEST(osm::ValidateLinePage("https://line.me/ti/p/@dgxs9r6wad"), ());
TEST(osm::ValidateLinePage("https://line.me/ti/p/%40vne5uwke17"), ());
TEST(osm::ValidateLinePage("http://line.me/R/ti/p/bfsg1a8x9u"), ());
TEST(osm::ValidateLinePage("https://line.me/R/ti/p/gdltt7s380"), ());
TEST(osm::ValidateLinePage("https://line.me/R/ti/p/@sdb2pb3lsg"), ());
TEST(osm::ValidateLinePage("https://line.me/R/ti/p/%40b30h5mdj11"), ());
TEST(osm::ValidateLinePage("http://line.me/R/home/public/main?id=hmczqsbav5"), ());
TEST(osm::ValidateLinePage("https://line.me/R/home/public/main?id=wa1gvx91jb"), ());
TEST(osm::ValidateLinePage("http://line.me/R/home/public/profile?id=5qll5dyqqu"), ());
TEST(osm::ValidateLinePage("https://line.me/R/home/public/profile?id=r90ck7n1rq"), ());
TEST(osm::ValidateLinePage("https://line.me/R/home/public/profile?id=r90ck7n1rq"), ());
TEST(osm::ValidateLinePage("https://page.line.me/fom5198h"), ());
TEST(osm::ValidateLinePage("https://page.line.me/qn58n8g?web=mobile"), ());
TEST(osm::ValidateLinePage("https://abc.line.me/en/some/page?id=xaladqv"), ());
TEST(osm::ValidateLinePage("@abcd"), ());
TEST(osm::ValidateLinePage("0000"), ());
TEST(osm::ValidateLinePage(".dots.are.allowed."), ());
TEST(osm::ValidateLinePage("@.dots.are.allowed."), ());
TEST(osm::ValidateLinePage("-hyphen-test-"), ());
TEST(osm::ValidateLinePage("@-hyphen-test-"), ());
TEST(osm::ValidateLinePage("under_score"), ());
TEST(osm::ValidateLinePage("@under_score"), ());
TEST(!osm::ValidateLinePage("no"), ());
TEST(!osm::ValidateLinePage("yes"), ());
TEST(!osm::ValidateLinePage("No-upper-case"), ());
TEST(!osm::ValidateLinePage("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), ());
TEST(!osm::ValidateLinePage("https://line.com/ti/p/invalid-domain"), ());
}

View file

@ -1,11 +1,10 @@
#include "indexer/contacts_processor.hpp"
#include "base/logging.hpp"
#include "base/string_utils.hpp"
#include "coding/url.hpp"
#include "indexer/editable_map_object.hpp"
#include "indexer/validate_and_format_contacts.hpp"
using namespace std;
@ -22,8 +21,7 @@ string ValidateAndFormat_facebook(string const & facebookPage)
{
if (facebookPage.front() == '@')
return facebookPage.substr(1);
else
return facebookPage;
return facebookPage;
}
if (EditableMapObject::ValidateWebsite(facebookPage))
{
@ -32,8 +30,8 @@ string ValidateAndFormat_facebook(string const & facebookPage)
if (!strings::StartsWith(facebookPage, "http://") && !strings::StartsWith(facebookPage, "https://"))
facebookPageUrl = "https://" + facebookPage;
const url::Url url = url::Url(facebookPageUrl);
const string & domain = strings::MakeLowerCase(url.GetWebDomain());
url::Url const url = url::Url(facebookPageUrl);
string const domain = strings::MakeLowerCase(url.GetWebDomain());
// Check Facebook domain name.
if (strings::EndsWith(domain, "facebook.com") || strings::EndsWith(domain, "fb.com")
|| strings::EndsWith(domain, "fb.me") || strings::EndsWith(domain, "facebook.de")
@ -61,8 +59,7 @@ string ValidateAndFormat_instagram(string const & instagramPage)
{
if (instagramPage.front() == '@')
return instagramPage.substr(1);
else
return instagramPage;
return instagramPage;
}
if (EditableMapObject::ValidateWebsite(instagramPage))
{
@ -80,8 +77,7 @@ string ValidateAndFormat_instagram(string const & instagramPage)
// Strip last '/' symbol.
if (webPath.back() == '/')
return webPath.substr(0, webPath.length()-1);
else
return webPath;
return webPath;
}
}
@ -98,8 +94,7 @@ string ValidateAndFormat_twitter(string const & twitterPage)
{
if (twitterPage.front() == '@')
return twitterPage.substr(1);
else
return twitterPage;
return twitterPage;
}
if (EditableMapObject::ValidateWebsite(twitterPage))
{
@ -146,9 +141,12 @@ string ValidateAndFormat_vk(string const & vkPage)
if (vkPageClean.front() == '@')
vkPageClean = vkPageClean.substr(1);
if (vkPageClean.front() == '_' && vkPageClean.back() == '_') return {};
if (regex_match(vkPageClean, regex(R"(^\d\d\d.+$)"))) return {};
if (regex_match(vkPageClean, regex(R"(^[A-Za-z0-9_.]{5,32}$)"))) return vkPageClean;
if (vkPageClean.front() == '_' && vkPageClean.back() == '_')
return {};
if (regex_match(vkPageClean, regex(R"(^\d\d\d.+$)")))
return {};
if (regex_match(vkPageClean, regex(R"(^[A-Za-z0-9_.]{5,32}$)")))
return vkPageClean;
}
if (EditableMapObject::ValidateWebsite(vkPage))
@ -168,8 +166,7 @@ string ValidateAndFormat_vk(string const & vkPage)
// Strip last '/' symbol.
if (webPath.back() == '/')
return webPath.substr(0, webPath.length()-1);
else
return webPath;
return webPath;
}
}
@ -263,4 +260,139 @@ string ValidateAndFormat_contactLine(string const & linePage)
return {};
}
bool ValidateFacebookPage(string const & page)
{
if (page.empty())
return true;
// See rules: https://www.facebook.com/help/105399436216001
static auto const s_fbRegex = regex(R"(^@?[a-zA-Z\d.\-]{5,}$)");
if (regex_match(page, s_fbRegex))
return true;
if (EditableMapObject::ValidateWebsite(page))
{
string const domain = strings::MakeLowerCase(url::Url::FromString(page).GetWebDomain());
return (strings::StartsWith(domain, "facebook.") || strings::StartsWith(domain, "fb.") ||
domain.find(".facebook.") != string::npos || domain.find(".fb.") != string::npos);
}
return false;
}
bool ValidateInstagramPage(string const & page)
{
if (page.empty())
return true;
// Rules took here: https://blog.jstassen.com/2016/03/code-regex-for-instagram-username-and-hashtags/
static auto const s_instaRegex = regex(R"(^@?[A-Za-z0-9_][A-Za-z0-9_.]{0,28}[A-Za-z0-9_]$)");
if (regex_match(page, s_instaRegex))
return true;
if (EditableMapObject::ValidateWebsite(page))
{
string const domain = strings::MakeLowerCase(url::Url::FromString(page).GetWebDomain());
return domain == "instagram.com" || strings::EndsWith(domain, ".instagram.com");
}
return false;
}
bool ValidateTwitterPage(string const & page)
{
if (page.empty())
return true;
if (EditableMapObject::ValidateWebsite(page))
{
string const domain = strings::MakeLowerCase(url::Url::FromString(page).GetWebDomain());
return domain == "twitter.com" || strings::EndsWith(domain, ".twitter.com");
}
else
{
// Rules took here: https://stackoverflow.com/q/11361044
static auto const s_twitterRegex = regex(R"(^@?[A-Za-z0-9_]{1,15}$)");
return regex_match(page, s_twitterRegex);
}
}
bool ValidateVkPage(string const & page)
{
if (page.empty())
return true;
{
/* Check that page contains valid username. Rules took here: https://vk.com/faq18038
The page name must be between 5 and 32 characters.
Invalid format could be in cases:
* - begins with three or more numbers (one or two numbers are allowed).
* - begins and ends with "_".
* - contains a period with less than four symbols after it starting with a letter.
*/
if (page.size() < 5)
return false;
string vkLogin = page;
if (vkLogin.front() == '@')
vkLogin = vkLogin.substr(1);
if (vkLogin.front() == '_' && vkLogin.back() == '_')
return false;
static auto const s_badVkRegex = regex(R"(^\d\d\d.+$)");
if (regex_match(vkLogin, s_badVkRegex))
return false;
static auto const s_goodVkRegex = regex(R"(^[A-Za-z0-9_.]{5,32}$)");
if (regex_match(vkLogin, s_goodVkRegex))
return true;
}
if (EditableMapObject::ValidateWebsite(page))
{
string const domain = strings::MakeLowerCase(url::Url::FromString(page).GetWebDomain());
return domain == "vk.com" || strings::EndsWith(domain, ".vk.com")
|| domain == "vkontakte.ru" || strings::EndsWith(domain, ".vkontakte.ru");
}
return false;
}
bool ValidateLinePage(string const & page)
{
if (page.empty())
return true;
{
// Check that linePage contains valid page name.
// Rules are defined here: https://help.line.me/line/?contentId=10009904
// The page name must be between 4 and 20 characters. Should contains alphanumeric characters
// and symbols '.', '-', and '_'
string linePageClean = page;
if (linePageClean.front() == '@')
linePageClean = linePageClean.substr(1);
if (regex_match(linePageClean, regex(R"(^[a-z0-9-_.]{4,20}$)")))
return true;
}
if (EditableMapObject::ValidateWebsite(page))
{
string linePageUrl = page;
// Check if HTTP protocol is present
if (!strings::StartsWith(page, "http://") && !strings::StartsWith(page, "https://"))
linePageUrl = "https://" + page;
const url::Url url = url::Url(linePageUrl);
const string &domain = strings::MakeLowerCase(url.GetWebDomain());
// Check Line domain name
if (domain == "line.me" || strings::EndsWith(domain, ".line.me"))
return true;
}
return false;
}
}

View file

@ -8,4 +8,10 @@ namespace osm {
std::string ValidateAndFormat_twitter(std::string const & v);
std::string ValidateAndFormat_vk(std::string const & v);
std::string ValidateAndFormat_contactLine(std::string const & v);
}
bool ValidateFacebookPage(std::string const & v);
bool ValidateInstagramPage(std::string const & v);
bool ValidateTwitterPage(std::string const & v);
bool ValidateVkPage(std::string const & v);
bool ValidateLinePage(std::string const & v);
}

View file

@ -184,6 +184,8 @@
FA67C84626BB356800B33DCA /* categories_cuisines.txt in Resources */ = {isa = PBXBuildFile; fileRef = 4052928E21496D2B00D821F1 /* categories_cuisines.txt */; };
FA67C84926BB35A400B33DCA /* bounds.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 40C3C090205BF9F400CED188 /* bounds.hpp */; };
FA67C84F26BB36D700B33DCA /* categories_brands.txt in Resources */ = {isa = PBXBuildFile; fileRef = FA67C84E26BB36D600B33DCA /* categories_brands.txt */; };
FA7F9B84273F32680093EA08 /* validate_and_format_contacts.hpp in Headers */ = {isa = PBXBuildFile; fileRef = FA7F9B82273F32680093EA08 /* validate_and_format_contacts.hpp */; };
FA7F9B85273F32680093EA08 /* validate_and_format_contacts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7F9B83273F32680093EA08 /* validate_and_format_contacts.cpp */; };
FACB7C0B26B9176500810C9C /* brands_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 406970A121AEF2F10024DDB2 /* brands_tests.cpp */; };
FACB7C0C26B9176A00810C9C /* centers_table_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D452AF91EE6D9F5009EAB9B /* centers_table_test.cpp */; };
FACB7C0D26B9176F00810C9C /* classificator_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 40DF582C2174979200E4E0FC /* classificator_tests.cpp */; };
@ -416,6 +418,8 @@
F6DF5F301CD0FD9A00A87154 /* categories_index.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = categories_index.hpp; sourceTree = "<group>"; };
F6F1DABD1F13D8B4006A69B7 /* ftraits.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ftraits.hpp; sourceTree = "<group>"; };
FA67C84E26BB36D600B33DCA /* categories_brands.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = categories_brands.txt; path = ../../data/categories_brands.txt; sourceTree = "<group>"; };
FA7F9B82273F32680093EA08 /* validate_and_format_contacts.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = validate_and_format_contacts.hpp; sourceTree = "<group>"; };
FA7F9B83273F32680093EA08 /* validate_and_format_contacts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = validate_and_format_contacts.cpp; sourceTree = "<group>"; };
FACB7C1A26B919AD00810C9C /* libbase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libbase.a; sourceTree = BUILT_PRODUCTS_DIR; };
FACB7C1B26B919AD00810C9C /* libcoding.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libcoding.a; sourceTree = BUILT_PRODUCTS_DIR; };
FACB7C1C26B919AD00810C9C /* libgeometry.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libgeometry.a; sourceTree = BUILT_PRODUCTS_DIR; };
@ -622,6 +626,8 @@
675340AD1A3F540F00A0A8C3 /* classificator_loader.hpp */,
675340AE1A3F540F00A0A8C3 /* classificator.cpp */,
675340AF1A3F540F00A0A8C3 /* classificator.hpp */,
FA7F9B83273F32680093EA08 /* validate_and_format_contacts.cpp */,
FA7F9B82273F32680093EA08 /* validate_and_format_contacts.hpp */,
34583BC11C88552100F94664 /* cuisines.cpp */,
34583BC21C88552100F94664 /* cuisines.hpp */,
40D62CEE23F2E8BE009A20F5 /* dat_section_header.hpp */,
@ -797,6 +803,7 @@
6758AED21BB4413000C26E27 /* drules_selector_parser.hpp in Headers */,
6753413F1A3F540F00A0A8C3 /* scale_index.hpp in Headers */,
6753410E1A3F540F00A0A8C3 /* drawing_rules.hpp in Headers */,
FA7F9B84273F32680093EA08 /* validate_and_format_contacts.hpp in Headers */,
409EE3E3237E9AA700EA31A4 /* postcodes.hpp in Headers */,
670C615C1AB0691900C38A8C /* features_offsets_table.hpp in Headers */,
6758AED41BB4413000C26E27 /* drules_selector.hpp in Headers */,
@ -998,6 +1005,7 @@
675341121A3F540F00A0A8C3 /* feature_algo.cpp in Sources */,
675341211A3F540F00A0A8C3 /* feature_utils.cpp in Sources */,
4099F6491FC7142A002A7B05 /* fake_feature_ids.cpp in Sources */,
FA7F9B85273F32680093EA08 /* validate_and_format_contacts.cpp in Sources */,
675341231A3F540F00A0A8C3 /* feature_visibility.cpp in Sources */,
56C74C221C749E4700B71B9F /* search_delimiters.cpp in Sources */,
347F337B1C454242009758CC /* rank_table.cpp in Sources */,