aboutsummaryrefslogtreecommitdiff
path: root/test/haketilo_test/unit/test_CORS_bypass_server.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/haketilo_test/unit/test_CORS_bypass_server.py')
-rw-r--r--test/haketilo_test/unit/test_CORS_bypass_server.py109
1 files changed, 109 insertions, 0 deletions
diff --git a/test/haketilo_test/unit/test_CORS_bypass_server.py b/test/haketilo_test/unit/test_CORS_bypass_server.py
new file mode 100644
index 0000000..45e4ebb
--- /dev/null
+++ b/test/haketilo_test/unit/test_CORS_bypass_server.py
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: CC0-1.0
+
+"""
+Haketilo unit tests - routing HTTP requests through background script
+"""
+
+# This file is part of Haketilo
+#
+# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the CC0 1.0 Universal License as published by
+# the Creative Commons Corporation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# CC0 1.0 Universal License for more details.
+
+import pytest
+import json
+from selenium.webdriver.support.ui import WebDriverWait
+
+from ..script_loader import load_script
+from ..world_wide_library import some_data
+
+urls = {
+ 'resource': 'https://anotherdoma.in/resource/blocked/by/CORS.json',
+ 'nonexistent': 'https://nxdoma.in/resource.json',
+ 'invalid': 'w3csucks://invalid.url/'
+}
+
+content_script = '''\
+const urls = %s;
+
+function fetch_data(url) {
+ return {
+ url,
+ to_get: ["ok", "status"],
+ to_call: ["text", "json"]
+ };
+}
+
+async function fetch_resources() {
+ const results = {};
+ const promises = [];
+ for (const [name, url] of Object.entries(urls)) {
+ const sending = browser.runtime.sendMessage(["CORS_bypass",
+ fetch_data(url)]);
+ promises.push(sending.then(response => results[name] = response));
+ }
+
+ await Promise.all(promises);
+
+ window.wrappedJSObject.haketilo_fetch_results = results;
+}
+
+fetch_resources();
+'''
+
+content_script = content_script % json.dumps(urls);
+
+@pytest.mark.ext_data({
+ 'content_script': content_script,
+ 'background_script':
+ lambda: load_script('background/CORS_bypass_server.js') + '; start();'
+})
+@pytest.mark.usefixtures('webextension')
+def test_CORS_bypass_server(driver, execute_in_page):
+ """
+ Test if CORS bypassing works and if errors get properly forwarded.
+ """
+ driver.get('https://gotmyowndoma.in/')
+
+ # First, verify that requests without CORS bypass measures fail.
+ results = execute_in_page(
+ '''
+ const result = {};
+ let promises = [];
+ for (const [name, url] of Object.entries(arguments[0])) {
+ const [ok_cb, err_cb] =
+ ["ok", "err"].map(status => () => result[name] = status);
+ promises.push(fetch(url).then(ok_cb, err_cb));
+ }
+ // Make the promises non-failing.
+ promises = promises.map(p => new Promise(cb => p.then(cb, cb)));
+ returnval(Promise.all(promises).then(() => result));
+ ''',
+ {**urls, 'sameorigin': './nonexistent_resource'})
+
+ assert results == dict([*[(k, 'err') for k in urls.keys()],
+ ('sameorigin', 'ok')])
+
+ done = lambda d: d.execute_script('return window.haketilo_fetch_results;')
+ results = WebDriverWait(driver, 10).until(done)
+
+ assert set(results['invalid'].keys()) == {'error'}
+
+ assert set(results['nonexistent'].keys()) == \
+ {'ok', 'status', 'text', 'error_json'}
+ assert results['nonexistent']['ok'] == False
+ assert results['nonexistent']['status'] == 404
+ assert results['nonexistent']['text'] == 'Handler for this URL not found.'
+
+ assert set(results['resource'].keys()) == {'ok', 'status', 'text', 'json'}
+ assert results['resource']['ok'] == True
+ assert results['resource']['status'] == 200
+ assert results['resource']['text'] == some_data
+ assert results['resource']['json'] == json.loads(some_data)