From c6cb6e0065a4c170d4f080b51f0a0596817dbe45 Mon Sep 17 00:00:00 2001 From: VladiMihaylenko Date: Wed, 7 Mar 2018 14:27:01 +0300 Subject: [PATCH] Lightweight framework --- map/CMakeLists.txt | 1 + map/framework_light.hpp | 87 +++++++++++++++++++++++++ map/map_tests/CMakeLists.txt | 1 + map/map_tests/framework_light_tests.cpp | 36 ++++++++++ map/user.cpp | 12 ++++ map/user.hpp | 5 ++ ugc/storage.cpp | 34 +++++++++- ugc/storage.hpp | 5 ++ ugc/ugc_tests/storage_tests.cpp | 31 +++++++++ xcode/map/map.xcodeproj/project.pbxproj | 4 ++ 10 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 map/framework_light.hpp create mode 100644 map/map_tests/framework_light_tests.cpp diff --git a/map/CMakeLists.txt b/map/CMakeLists.txt index 604220e840..7a92f33180 100644 --- a/map/CMakeLists.txt +++ b/map/CMakeLists.txt @@ -42,6 +42,7 @@ set( feature_vec_model.hpp framework.cpp framework.hpp + framework_light.hpp ge0_parser.cpp ge0_parser.hpp geourl_process.cpp diff --git a/map/framework_light.hpp b/map/framework_light.hpp new file mode 100644 index 0000000000..ef2d5bb314 --- /dev/null +++ b/map/framework_light.hpp @@ -0,0 +1,87 @@ +#pragma once + +#include "map/user.hpp" + +#include "ugc/storage.hpp" + +#include "base/assert.hpp" + +namespace lightweight +{ +struct LightFrameworkTest; + +enum RequestType +{ + REQUEST_TYPE_EMPTY = 0u, + REQUEST_TYPE_NUMBER_OF_UNSENT_UGC = 1u << 0, + REQUEST_TYPE_USER_AUTH_STATUS = 1u << 1, + REQUEST_TYPE_NUMBER_OF_UNSENT_EDITS = 1u << 2, +}; + +using RequestTypeMask = unsigned; + +// A class which allows you to acquire data in a synchronous way. +// The common use case is to create an instance of Framework +// with specified mask, acquire data according to the mask and destroy the instance. + +class Framework +{ +public: + friend struct LightFrameworkTest; + + explicit Framework(RequestTypeMask request) : m_request(request) + { + CHECK_NOT_EQUAL(request, REQUEST_TYPE_EMPTY, ("Mask is empty")); + + if (request & REQUEST_TYPE_NUMBER_OF_UNSENT_UGC) + { + m_numberOfUnsentUGC = GetNumberOfUnsentUGC(); + request ^= REQUEST_TYPE_NUMBER_OF_UNSENT_UGC; + } + + if (request & REQUEST_TYPE_USER_AUTH_STATUS) + { + m_userAuthStatus = IsUserAuthenticated(); + request ^= REQUEST_TYPE_USER_AUTH_STATUS; + } + + if (request & REQUEST_TYPE_NUMBER_OF_UNSENT_EDITS) + { + // TODO: Hasn't implemented yet. + request ^= REQUEST_TYPE_NUMBER_OF_UNSENT_EDITS; + } + + CHECK_EQUAL(request, REQUEST_TYPE_EMPTY, ("Incorrect mask type:", request)); + } + + template + auto Get() const; + +private: + RequestTypeMask m_request; + bool m_userAuthStatus = false; + size_t m_numberOfUnsentUGC = 0; + size_t m_numberOfUnsentEdits = 0; +}; + +template<> +auto Framework::Get() const +{ + ASSERT(m_request & REQUEST_TYPE_USER_AUTH_STATUS, (m_request)); + return m_userAuthStatus; +} + +template<> +auto Framework::Get() const +{ + ASSERT(m_request & REQUEST_TYPE_NUMBER_OF_UNSENT_UGC, (m_request)); + return m_numberOfUnsentUGC; +} + +template<> +auto Framework::Get() const +{ + ASSERT(m_request & REQUEST_TYPE_NUMBER_OF_UNSENT_EDITS, (m_request)); + return m_numberOfUnsentEdits; +} +} // namespace lightweight diff --git a/map/map_tests/CMakeLists.txt b/map/map_tests/CMakeLists.txt index c609dd6368..400d67ab88 100644 --- a/map/map_tests/CMakeLists.txt +++ b/map/map_tests/CMakeLists.txt @@ -11,6 +11,7 @@ set( chart_generator_tests.cpp cloud_tests.cpp feature_getters_tests.cpp + framework_light_tests.cpp ge0_parser_tests.cpp geourl_test.cpp gps_track_collection_test.cpp diff --git a/map/map_tests/framework_light_tests.cpp b/map/map_tests/framework_light_tests.cpp new file mode 100644 index 0000000000..b625ad468b --- /dev/null +++ b/map/map_tests/framework_light_tests.cpp @@ -0,0 +1,36 @@ +#include "testing/testing.hpp" + +#include "map/framework_light.hpp" + +namespace lightweight +{ +struct LightFrameworkTest +{ + static void SmokeTest() + { + { + Framework f(REQUEST_TYPE_NUMBER_OF_UNSENT_UGC | REQUEST_TYPE_USER_AUTH_STATUS); + f.m_userAuthStatus = true; + f.m_numberOfUnsentUGC = 30; + TEST_EQUAL(f.Get(), 30, ()); + TEST(f.Get(), ()); + } + + { + Framework f(REQUEST_TYPE_USER_AUTH_STATUS | + REQUEST_TYPE_NUMBER_OF_UNSENT_EDITS | + REQUEST_TYPE_NUMBER_OF_UNSENT_UGC); + + f.m_numberOfUnsentEdits = 10; + TEST_EQUAL(f.Get(), 10, ()); + TEST_EQUAL(f.Get(), 0, ()); + TEST(!f.Get(), ()); + } + } +}; +} // namespace lightweight + +UNIT_TEST(LightFramework_Smoke) +{ + lightweight::LightFrameworkTest::SmokeTest(); +} diff --git a/map/user.cpp b/map/user.cpp index 1c3dbed1c2..545f8dd608 100644 --- a/map/user.cpp +++ b/map/user.cpp @@ -422,3 +422,15 @@ void User::RequestImpl(std::string const & url, BuildRequestHandler const & onBu }); } } + +namespace lightweight +{ +bool IsUserAuthenticated() +{ + std::string token; + if (GetPlatform().GetSecureStorage().Load(kMapsMeTokenKey, token)) + return !token.empty(); + + return false; +} +} // namespace lightweight diff --git a/map/user.hpp b/map/user.hpp index 7781d3680d..3d71fad871 100644 --- a/map/user.hpp +++ b/map/user.hpp @@ -86,3 +86,8 @@ private: Details m_details; std::vector> m_subscribers; }; + +namespace lightweight +{ +bool IsUserAuthenticated(); +} //namespace lightweight diff --git a/ugc/storage.cpp b/ugc/storage.cpp index cffc49af28..c12f83c61c 100644 --- a/ugc/storage.cpp +++ b/ugc/storage.cpp @@ -411,5 +411,37 @@ Storage::SettingResult Storage::SetUGCUpdateForTesting(FeatureID const & id, return SetGenericUGCUpdate(m_UGCIndexes, m_numberOfDeleted, id, ugc, *feature, Version::V0); } - } // namespace ugc + +namespace lightweight +{ +size_t GetNumberOfUnsentUGC() +{ + auto const indexFilePath = ugc::GetIndexFilePath(); + if (!Platform::IsFileExistsByFullPath(indexFilePath)) + return 0; + + string data; + try + { + FileReader r(indexFilePath); + r.ReadAsString(data); + } + catch (FileReader::Exception const & exception) + { + LOG(LWARNING, ("Exception while reading file:", indexFilePath, "reason:", exception.what())); + return 0; + } + + vector index; + ugc::DeserializeUGCIndex(data, index); + size_t number = 0; + for (auto const & i : index) + { + if (!i.m_deleted && !i.m_synchronized) + ++number; + } + + return number; +} +} // namespace lightweight diff --git a/ugc/storage.hpp b/ugc/storage.hpp index 26b538d1f2..8349a63ef4 100644 --- a/ugc/storage.hpp +++ b/ugc/storage.hpp @@ -82,3 +82,8 @@ inline std::string DebugPrint(Storage::SettingResult const & result) } } } // namespace ugc + +namespace lightweight +{ +size_t GetNumberOfUnsentUGC(); +} //namespace lightweight diff --git a/ugc/ugc_tests/storage_tests.cpp b/ugc/ugc_tests/storage_tests.cpp index 918acdedd3..1de799e66b 100644 --- a/ugc/ugc_tests/storage_tests.cpp +++ b/ugc/ugc_tests/storage_tests.cpp @@ -405,3 +405,34 @@ UNIT_CLASS_TEST(StorageTest, NumberOfUnsynchronized) TEST(DeleteIndexFile(), ()); } + +UNIT_CLASS_TEST(StorageTest, GetNumberOfUnsentSeparately) +{ + TEST_EQUAL(lightweight::GetNumberOfUnsentUGC(), 0, ()); + auto & builder = MwmBuilder::Builder(); + m2::PointD const cafePoint(1.0, 1.0); + builder.Build({TestCafe(cafePoint)}); + auto const cafeId = builder.FeatureIdForCafeAtPoint(cafePoint); + auto const cafeUGC = MakeTestUGCUpdate(Time(chrono::hours(24 * 10))); + + { + Storage storage(builder.GetIndex()); + storage.Load(); + TEST_EQUAL(storage.SetUGCUpdate(cafeId, cafeUGC), Storage::SettingResult::Success, ()); + storage.SaveIndex(); + TEST_EQUAL(storage.GetNumberOfUnsynchronized(), 1, ()); + } + + TEST_EQUAL(lightweight::GetNumberOfUnsentUGC(), 1, ()); + + { + Storage storage(builder.GetIndex()); + storage.Load(); + storage.MarkAllAsSynchronized(); + TEST_EQUAL(storage.GetNumberOfUnsynchronized(), 0, ()); + storage.SaveIndex(); + } + + TEST_EQUAL(lightweight::GetNumberOfUnsentUGC(), 0, ()); + TEST(DeleteIndexFile(), ()); +} diff --git a/xcode/map/map.xcodeproj/project.pbxproj b/xcode/map/map.xcodeproj/project.pbxproj index 91f41993ea..7675687bef 100644 --- a/xcode/map/map.xcodeproj/project.pbxproj +++ b/xcode/map/map.xcodeproj/project.pbxproj @@ -147,6 +147,7 @@ F6C269F91F16174E00EB6519 /* libugc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F6C269F81F16174E00EB6519 /* libugc.a */; }; F6D2CE7E1EDEB7F500636DFD /* routing_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6D2CE7C1EDEB7F500636DFD /* routing_manager.cpp */; }; F6D2CE7F1EDEB7F500636DFD /* routing_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6D2CE7D1EDEB7F500636DFD /* routing_manager.hpp */; }; + F6D67CE32063F4980032FD38 /* framework_light.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6D67CE22063F4980032FD38 /* framework_light.hpp */; }; F6FC3CB51FC323430001D929 /* discovery_client_params.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6FC3CB21FC323420001D929 /* discovery_client_params.hpp */; }; F6FC3CB61FC323430001D929 /* discovery_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6FC3CB31FC323420001D929 /* discovery_manager.cpp */; }; F6FC3CB71FC323430001D929 /* discovery_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6FC3CB41FC323420001D929 /* discovery_manager.hpp */; }; @@ -315,6 +316,7 @@ F6C269F81F16174E00EB6519 /* libugc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libugc.a; path = "../../../../Library/Developer/Xcode/DerivedData/omim-fbvotunmmtqmjnezabjibwxwryev/Build/Products/Debug/libugc.a"; sourceTree = ""; }; F6D2CE7C1EDEB7F500636DFD /* routing_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = routing_manager.cpp; sourceTree = ""; }; F6D2CE7D1EDEB7F500636DFD /* routing_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = routing_manager.hpp; sourceTree = ""; }; + F6D67CE22063F4980032FD38 /* framework_light.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = framework_light.hpp; sourceTree = ""; }; F6DA2A961CCE24DB00F087B5 /* libdrape_frontend.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdrape_frontend.a; path = "../../../omim-xcode-build/Debug/libdrape_frontend.a"; sourceTree = ""; }; F6DA2A981CCE252600F087B5 /* libeditor.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libeditor.a; path = "../../../omim-xcode-build/Debug/libeditor.a"; sourceTree = ""; }; F6DA2A991CCE252600F087B5 /* liboauthcpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liboauthcpp.a; path = "../../../omim-xcode-build/Debug/liboauthcpp.a"; sourceTree = ""; }; @@ -508,6 +510,7 @@ 675345BD1A4054AD00A0A8C3 /* map */ = { isa = PBXGroup; children = ( + F6D67CE22063F4980032FD38 /* framework_light.hpp */, BBFC7E38202D29BF00531BE7 /* user_mark_layer.cpp */, BBFC7E39202D29BF00531BE7 /* user_mark_layer.hpp */, 675345CB1A4054E800A0A8C3 /* address_finder.cpp */, @@ -648,6 +651,7 @@ 675346491A4054E800A0A8C3 /* bookmark_manager.hpp in Headers */, F6B2830A1C1B03320081957A /* gps_track.hpp in Headers */, 3D4E99A21FB4A6410025B48C /* booking_filter_cache.hpp in Headers */, + F6D67CE32063F4980032FD38 /* framework_light.hpp in Headers */, 45F6EE9D1FB1C77600019892 /* search_api.hpp in Headers */, F6FC3CB51FC323430001D929 /* discovery_client_params.hpp in Headers */, 0831F23C200E53600034C365 /* bookmarks_search_params.hpp in Headers */,