Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: test/FilterEngine.cpp

Issue 29402569: Issue 5074 - fix tests for "is allowed connection" (Closed)
Patch Set: Created April 4, 2017, 10:51 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/Utils.h ('k') | test/WebRequest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/FilterEngine.cpp
diff --git a/test/FilterEngine.cpp b/test/FilterEngine.cpp
index 46d26c1463e9c0dd5fc48637bbc9935d4c6d7ef8..7055032cce0b84131daee73d8aa5ee5f4d9b2430 100644
--- a/test/FilterEngine.cpp
+++ b/test/FilterEngine.cpp
@@ -17,6 +17,8 @@
#include "BaseJsTest.h"
#include <thread>
+#include "../src/Utils.h"
+#include <condition_variable>
using namespace AdblockPlus;
@@ -145,6 +147,122 @@ namespace
std::this_thread::sleep_for(std::chrono::seconds(2));
}
};
+
+ class FilterEngineIsAllowedConnectionTest : public BaseJsTest
+ {
+ class MockWebRequest : public LazyWebRequest
+ {
+ public:
+ std::map</*beginning of url*/std::string, AdblockPlus::ServerResponse> responses;
+
+ AdblockPlus::ServerResponse GET(const std::string& url,
+ const AdblockPlus::HeaderList& requestHeaders) const
+ {
+ for (const auto& response : responses)
+ {
+ if (Utils::BeginsWith(url, response.first))
+ {
+ return response.second;
+ }
+ }
+ return LazyWebRequest::GET(url, requestHeaders);
+ }
+ };
+ class SyncStrings
+ {
+ public:
+ void Add(const std::string* value)
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ strings.emplace_back(!!value, value ? *value : "");
+ }
+ std::vector<std::pair<bool, std::string>> GetStrings() const
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ return strings;
+ }
+ void Clear()
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ strings.clear();
+ }
+ private:
+ mutable std::mutex mutex;
+ std::vector<std::pair<bool, std::string>> strings;
+ };
+ protected:
+ MockWebRequest* webRequest;
+ std::string subscriptionUrlPrefix;
+ FilterEngine::CreationParameters createParams;
+ SyncStrings capturedConnectionTypes;
+ bool isConnectionAllowed;
+ FilterEnginePtr filterEngine;
+
+ struct
+ {
+ std::string url;
+ std::mutex mutex;
+ std::condition_variable cv;
+ } downloadStatusChanged;
+
+ void SetUp()
+ {
+ BaseJsTest::SetUp();
+ jsEngine->SetFileSystem(AdblockPlus::FileSystemPtr(new LazyFileSystem()));
+ jsEngine->SetWebRequest(AdblockPlus::WebRequestPtr(webRequest = new MockWebRequest()));
+ jsEngine->SetLogSystem(AdblockPlus::LogSystemPtr(new LazyLogSystem()));
+
+ subscriptionUrlPrefix = "http://example";
+ ServerResponse exampleSubscriptionResponse;
+ exampleSubscriptionResponse.responseStatus = 200;
+ exampleSubscriptionResponse.status = WebRequest::NS_OK;
+ exampleSubscriptionResponse.responseText = "[Adblock Plus 2.0]\n||example.com";
+ webRequest->responses.emplace(subscriptionUrlPrefix, exampleSubscriptionResponse);
+ createParams.preconfiguredPrefs["first_run_subscription_auto_select"] = jsEngine->NewValue(false);
+ isConnectionAllowed = true;
+ createParams.isConnectionAllowedCallback = [this](const std::string* allowedConnectionType)->bool{
+ capturedConnectionTypes.Add(allowedConnectionType);
+ return isConnectionAllowed;
+ };
+ jsEngine->SetEventCallback("filterChange", [this](const JsValueList& params/*action, item*/)
+ {
+ ASSERT_EQ(2u, params.size());
+ if (params[0]->AsString() == "subscription.downloadStatus")
+ {
+ {
+ std::lock_guard<std::mutex> lock(downloadStatusChanged.mutex);
+ downloadStatusChanged.url = params[1]->GetProperty("url")->AsString();
+ }
+ downloadStatusChanged.cv.notify_one();
+ }
+ });
+ }
+
+ SubscriptionPtr EnsureExampleSubscriptionAndForceUpdate(const std::string& apppendToUrl = std::string())
+ {
+ if (!filterEngine)
+ filterEngine = FilterEngine::Create(jsEngine, createParams);
+ auto subscriptionUrl = subscriptionUrlPrefix + apppendToUrl;
+ auto subscription = filterEngine->GetSubscription(subscriptionUrl);
+ EXPECT_EQ(0u, subscription->GetProperty("filters")->AsList().size()) << subscriptionUrl;
+ EXPECT_TRUE(subscription->GetProperty("downloadStatus")->IsNull()) << subscriptionUrl;
+ subscription->UpdateFilters();
+ {
+ std::unique_lock<std::mutex> lock(downloadStatusChanged.mutex);
+ downloadStatusChanged.cv.wait_for(lock,
+ /*don't block tests forever*/std::chrono::seconds(5),
+ [this, subscriptionUrl]()->bool
+ {
+ return subscriptionUrl == downloadStatusChanged.url;
+ });
+ // Basically it's enough to wait only for downloadStatus although there
+ // is still some JS code being executed. Any following attempt to work
+ // with subscription object will result in execution of JS, which will
+ // be blocked until finishing of currently running code.
+ }
+ return subscription;
+ }
+ };
}
TEST_F(FilterEngineTest, FilterCreation)
@@ -628,3 +746,90 @@ TEST_F(FilterEngineWithFreshFolder, DisableSubscriptionsAutoSelectOnFirstRun)
const auto subscriptions = filterEngine->GetListedSubscriptions();
EXPECT_EQ(0u, subscriptions.size());
}
+
+TEST_F(FilterEngineIsAllowedConnectionTest, AbsentCallbackAllowsUpdating)
+{
+ createParams.isConnectionAllowedCallback = FilterEngine::IsConnectionAllowedCallback();
+ auto subscription = EnsureExampleSubscriptionAndForceUpdate();
+ EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
+ EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+}
+
+TEST_F(FilterEngineIsAllowedConnectionTest, AllowingCallbackAllowsUpdating)
+{
+ // no stored allowed_connection_type preference
+ auto subscription = EnsureExampleSubscriptionAndForceUpdate();
+ EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
+ EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+ auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
+ ASSERT_EQ(1u, capturedConnectionTypes.size());
+ EXPECT_FALSE(capturedConnectionTypes[0].first);
+}
+
+TEST_F(FilterEngineIsAllowedConnectionTest, NotAllowingCallbackDoesNotAllowUpdating)
+{
+ isConnectionAllowed = false;
+ // no stored allowed_connection_type preference
+ auto subscription = EnsureExampleSubscriptionAndForceUpdate();
+ EXPECT_EQ("synchronize_connection_error", subscription->GetProperty("downloadStatus")->AsString());
+ EXPECT_EQ(0u, subscription->GetProperty("filters")->AsList().size());
+ auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
+ EXPECT_EQ(1u, capturedConnectionTypes.size());
+}
+
+TEST_F(FilterEngineIsAllowedConnectionTest, PredefinedAllowedConnectionTypeIsPassedToCallback)
+{
+ std::string predefinedAllowedConnectionType = "non-metered";
+ createParams.preconfiguredPrefs["allowed_connection_type"] = jsEngine->NewValue(predefinedAllowedConnectionType);
+ auto subscription = EnsureExampleSubscriptionAndForceUpdate();
+ EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
+ EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+ auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
+ ASSERT_EQ(1u, capturedConnectionTypes.size());
+ EXPECT_TRUE(capturedConnectionTypes[0].first);
+ EXPECT_EQ(predefinedAllowedConnectionType, capturedConnectionTypes[0].second);
+}
+
+TEST_F(FilterEngineIsAllowedConnectionTest, ConfiguredConnectionTypeIsPassedToCallback)
+{
+ // FilterEngine->RemoveSubscription is not usable here because subscriptions
+ // are cached internally by URL. So, different URLs are used in diffirent
+ // checks.
+ {
+ std::string predefinedAllowedConnectionType = "non-metered";
+ createParams.preconfiguredPrefs["allowed_connection_type"] = jsEngine->NewValue(predefinedAllowedConnectionType);
+ auto subscription = EnsureExampleSubscriptionAndForceUpdate();
+ EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
+ EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+ auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
+ ASSERT_EQ(1u, capturedConnectionTypes.size());
+ EXPECT_TRUE(capturedConnectionTypes[0].first);
+ EXPECT_EQ(predefinedAllowedConnectionType, capturedConnectionTypes[0].second);
+ }
+ capturedConnectionTypes.Clear();
+ {
+ // set no value
+ filterEngine->SetAllowedConnectionType(nullptr);
+ auto subscription = EnsureExampleSubscriptionAndForceUpdate("subA");
+ EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
+ EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+ auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
+ ASSERT_EQ(1u, capturedConnectionTypes.size());
+ EXPECT_FALSE(capturedConnectionTypes[0].first);
+ subscription->RemoveFromList();
+ this->capturedConnectionTypes.Clear();
+ }
+ capturedConnectionTypes.Clear();
+ {
+ // set some value
+ std::string testConnection = "test connection";
+ filterEngine->SetAllowedConnectionType(&testConnection);
+ auto subscription = EnsureExampleSubscriptionAndForceUpdate("subB");
+ EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
+ EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+ auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
+ ASSERT_EQ(1u, capturedConnectionTypes.size());
+ EXPECT_TRUE(capturedConnectionTypes[0].first);
+ EXPECT_EQ(testConnection, capturedConnectionTypes[0].second);
+ }
+}
« no previous file with comments | « src/Utils.h ('k') | test/WebRequest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld