Index: test/WebRequest.cpp |
diff --git a/test/WebRequest.cpp b/test/WebRequest.cpp |
index 46d6614ef3d340634ac94ae6c1e4b0ec356e8c3b..2e2e6e6b1b6d04193643cd32003b0ccbf8f1636a 100644 |
--- a/test/WebRequest.cpp |
+++ b/test/WebRequest.cpp |
@@ -18,6 +18,10 @@ |
#include <sstream> |
#include "BaseJsTest.h" |
#include "../src/Thread.h" |
+#include <atomic> |
+#include <mutex> |
+ |
+using namespace AdblockPlus; |
namespace |
{ |
@@ -74,6 +78,198 @@ TEST_F(MockWebRequestTest, SuccessfulRequest) |
ASSERT_EQ("{\"Foo\":\"Bar\"}", jsEngine->Evaluate("JSON.stringify(foo.responseHeaders)")->AsString()); |
} |
+TEST_F(MockWebRequestTest, ConnectionIsAllowedOnJsEngine) |
+{ |
+ std::atomic<int> isConnectionAllowedCalledTimes(0); |
+ jsEngine->SetIsConnectionAllowedCallback([&isConnectionAllowedCalledTimes]()->bool |
+ { |
+ ++isConnectionAllowedCalledTimes; |
+ return true; |
+ }); |
+ jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(result) {foo = result;} )"); |
+ ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
+ AdblockPlus::Sleep(200); |
+ EXPECT_EQ(1u, isConnectionAllowedCalledTimes); |
+ EXPECT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->AsInt()); |
+ EXPECT_EQ(123, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
+ EXPECT_EQ("http://example.com/\nX\nY", jsEngine->Evaluate("foo.responseText")->AsString()); |
+ EXPECT_EQ("{\"Foo\":\"Bar\"}", jsEngine->Evaluate("JSON.stringify(foo.responseHeaders)")->AsString()); |
+} |
+ |
+TEST_F(MockWebRequestTest, ConnectionIsNotAllowedOnJsEngine) |
+{ |
+ std::atomic<int> isConnectionAllowedCalledTimes(0); |
+ jsEngine->SetIsConnectionAllowedCallback([&isConnectionAllowedCalledTimes]()->bool |
+ { |
+ ++isConnectionAllowedCalledTimes; |
+ return false; |
+ }); |
+ jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(result) {foo = result;} )"); |
+ ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
+ AdblockPlus::Sleep(200); |
+ EXPECT_EQ(1u, isConnectionAllowedCalledTimes); |
+ EXPECT_EQ(AdblockPlus::WebRequest::NS_ERROR_CONNECTION_REFUSED, jsEngine->Evaluate("foo.status")->AsInt()); |
+ EXPECT_EQ(0, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
+ EXPECT_EQ("", jsEngine->Evaluate("foo.responseText")->AsString()); |
+ EXPECT_EQ("{}", jsEngine->Evaluate("JSON.stringify(foo.responseHeaders)")->AsString()); |
+} |
+ |
+namespace |
+{ |
+ 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; |
+ }; |
+} |
+ |
+TEST_F(MockWebRequestTest, ConnectionIsAllowedOnFilterEngine1) |
+{ |
+ FilterEngine::CreateParameters createParams; |
+ std::string predefinedAllowedConnectionType = "non-metered"; |
+ createParams.preconfiguredPrefs.emplace("allowed_connection_type", jsEngine->NewValue(predefinedAllowedConnectionType)); |
+ auto receivedConnectionTypes = std::make_shared<SyncStrings>(); |
+ createParams.isConnectionAllowed = [receivedConnectionTypes](const std::string* allowedConnectionType)->bool { |
+ receivedConnectionTypes->Add(allowedConnectionType); |
+ return true; |
+ }; |
+ auto filterEngine = FilterEngine::Create(jsEngine, createParams); |
+ jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(result) {foo = result;} )"); |
+ ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
+ AdblockPlus::Sleep(200); |
+ auto receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
+ EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
+ for (const auto& connectionType : receivedConnectionTypesStrings) |
+ { |
+ EXPECT_TRUE(connectionType.first); |
+ EXPECT_EQ(predefinedAllowedConnectionType, connectionType.second); |
+ } |
+ EXPECT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->AsInt()); |
+ EXPECT_EQ(123, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
+ EXPECT_EQ("http://example.com/\nX\nY", jsEngine->Evaluate("foo.responseText")->AsString()); |
+ EXPECT_EQ("{\"Foo\":\"Bar\"}", jsEngine->Evaluate("JSON.stringify(foo.responseHeaders)")->AsString()); |
+} |
+ |
+TEST_F(MockWebRequestTest, ConnectionIsAllowedOnFilterEngine2) |
+{ |
+ FilterEngine::CreateParameters createParams; |
+ auto receivedConnectionTypes = std::make_shared<SyncStrings>(); |
+ createParams.isConnectionAllowed = [receivedConnectionTypes](const std::string* allowedConnectionType)->bool { |
+ receivedConnectionTypes->Add(allowedConnectionType); |
+ return true; |
+ }; |
+ auto filterEngine = FilterEngine::Create(jsEngine, createParams); |
+ jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(result) {foo = result;} )"); |
+ ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
+ AdblockPlus::Sleep(200); |
+ auto receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
+ EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
+ for (const auto& connectionType : receivedConnectionTypesStrings) |
+ { |
+ EXPECT_FALSE(connectionType.first); |
+ } |
+ EXPECT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->AsInt()); |
+ EXPECT_EQ(123, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
+ EXPECT_EQ("http://example.com/\nX\nY", jsEngine->Evaluate("foo.responseText")->AsString()); |
+ EXPECT_EQ("{\"Foo\":\"Bar\"}", jsEngine->Evaluate("JSON.stringify(foo.responseHeaders)")->AsString()); |
+} |
+ |
+TEST_F(MockWebRequestTest, ConnectionIsAllowedOnFilterEngine3) |
+{ |
+ // initially allowed connection type is not defined |
+ FilterEngine::CreateParameters createParams; |
+ auto receivedConnectionTypes = std::make_shared<SyncStrings>(); |
+ createParams.isConnectionAllowed = [receivedConnectionTypes](const std::string* allowedConnectionType)->bool { |
+ receivedConnectionTypes->Add(allowedConnectionType); |
+ return true; |
+ }; |
+ auto filterEngine = FilterEngine::Create(jsEngine, createParams); |
+ |
+ jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(result) {foo = result;} )"); |
+ ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
+ AdblockPlus::Sleep(200); |
+ auto receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
+ EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
+ for (const auto& connectionType : receivedConnectionTypesStrings) |
+ { |
+ EXPECT_FALSE(connectionType.first); |
+ } |
+ EXPECT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->AsInt()); |
+ EXPECT_EQ(123, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
+ EXPECT_EQ("http://example.com/\nX\nY", jsEngine->Evaluate("foo.responseText")->AsString()); |
+ EXPECT_EQ("{\"Foo\":\"Bar\"}", jsEngine->Evaluate("JSON.stringify(foo.responseHeaders)")->AsString()); |
+ |
+ // set allowed connection type |
+ std::string allowedConnectionType = "test-connection"; |
+ filterEngine->SetAllowedConnectionType(&allowedConnectionType); |
+ receivedConnectionTypes->Clear(); |
+ jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(result) {foo = result;} )"); |
+ AdblockPlus::Sleep(200); |
+ receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
+ EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
+ for (const auto& connectionType : receivedConnectionTypesStrings) |
+ { |
+ EXPECT_TRUE(connectionType.first); |
+ EXPECT_EQ(allowedConnectionType, connectionType.second); |
+ } |
+ |
+ // remove allowed connection type |
+ filterEngine->SetAllowedConnectionType(nullptr); |
+ receivedConnectionTypes->Clear(); |
+ jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(result) {foo = result;} )"); |
+ AdblockPlus::Sleep(200); |
+ receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
+ EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
+ for (const auto& connectionType : receivedConnectionTypesStrings) |
+ { |
+ EXPECT_FALSE(connectionType.first); |
+ } |
+} |
+ |
+TEST_F(MockWebRequestTest, ConnectionIsNotAllowedOnFilterEngine) |
+{ |
+ FilterEngine::CreateParameters createParams; |
+ std::string predefinedAllowedConnectionType = "non-metered"; |
+ createParams.preconfiguredPrefs.emplace("allowed_connection_type", jsEngine->NewValue(predefinedAllowedConnectionType)); |
+ auto receivedConnectionTypes = std::make_shared<SyncStrings>(); |
+ createParams.isConnectionAllowed = [receivedConnectionTypes](const std::string* allowedConnectionType)->bool { |
+ receivedConnectionTypes->Add(allowedConnectionType); |
+ return false; |
+ }; |
+ auto filterEngine = FilterEngine::Create(jsEngine, createParams); |
+ jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(result) {foo = result;} )"); |
+ ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
+ AdblockPlus::Sleep(200); |
+ auto receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
+ EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
+ for (const auto& connectionType : receivedConnectionTypesStrings) |
+ { |
+ EXPECT_TRUE(connectionType.first); |
+ EXPECT_EQ(predefinedAllowedConnectionType, connectionType.second); |
+ } |
+ EXPECT_EQ(AdblockPlus::WebRequest::NS_ERROR_CONNECTION_REFUSED, jsEngine->Evaluate("foo.status")->AsInt()); |
+ EXPECT_EQ(0, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
+ EXPECT_EQ("", jsEngine->Evaluate("foo.responseText")->AsString()); |
+ EXPECT_EQ("{}", jsEngine->Evaluate("JSON.stringify(foo.responseHeaders)")->AsString()); |
+} |
+ |
#if defined(HAVE_CURL) || defined(_WIN32) |
TEST_F(DefaultWebRequestTest, RealWebRequest) |
{ |
@@ -132,7 +328,7 @@ TEST_F(DefaultWebRequestTest, DummyWebRequest) |
TEST_F(DefaultWebRequestTest, XMLHttpRequest) |
{ |
- AdblockPlus::FilterEngine filterEngine(jsEngine); |
+ auto filterEngine = AdblockPlus::FilterEngine::Create(jsEngine); |
jsEngine->Evaluate("\ |
var result;\ |