From 45722ea7b14519248affcdfd1bc0b094510dd90e Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 14:48:50 +0200 Subject: [PATCH 01/14] Update tests to use uweb3test as username and password --- .github/workflows/python-app.yml | 4 ++-- aquarium.sqlite | Bin 0 -> 12288 bytes sqlite.db | Bin 0 -> 16384 bytes test/test_model.py | 2 +- test/test_model_alchemy.py | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 aquarium.sqlite create mode 100644 sqlite.db diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 2342e35a..9fcf0dc7 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -20,8 +20,8 @@ jobs: image: mysql:latest env: MYSQL_DATABASE: uweb_test - MYSQL_USER: stef - MYSQL_PASSWORD: password + MYSQL_USER: uweb3test + MYSQL_PASSWORD: uweb3test MYSQL_ALLOW_EMPTY_PASSWORD: yes ports: - 3306:3306 diff --git a/aquarium.sqlite b/aquarium.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..bfaa6047d49d17064ba06534f286d8d98dfb07ed GIT binary patch literal 12288 zcmeI%y-LJD5C`zt#1B$PY(m;8JqUu>3VP}y2SG5V(86Ms+}(1wiQWdmM(|;LC>wjL zdj)sn9VqAnocxDOGTAV@$*)^-d6Db3;$bs0s^xv!CL!pEnMk}7QRs3J;@K5z%R6@! z-|9a~H^=Vb+m?G8#3PDd-3b8!2tWV=5P$##AOHafKmY;|_`d=N!A6=S;-*!%)2dbV z#Ak3)$bKog>>uZn{m9PXln3XfJd;JnwK5f#@~Z4zi%sACl637uZO1;tAMJkR_x6nK zeRZcR+f9~r3oTda`MtS_Kgb;j2tWV=5P$##AOHafKmY;|fB*zmT_6!*w3q8gU5~hE z8pHNs>i+zH?f>T#&sY5e@%|8i00bZa0SG_<0uX=z1Rwwb2rL9*u^y#qWR)>bcC2QT EPgVm*H2?qr literal 0 HcmV?d00001 diff --git a/sqlite.db b/sqlite.db new file mode 100644 index 0000000000000000000000000000000000000000..e1c7ce3535cad3828fa364d5cc34de84bad88c39 GIT binary patch literal 16384 zcmeI&y$ZrG5Ww+^ikr2YYeq$JaTcx8&B3q5NvcE;s#05@(5Gd8<`)78Ab Date: Thu, 28 Jul 2022 14:49:00 +0200 Subject: [PATCH 02/14] Formatting --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1ae753d0..497d18e2 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ def Version(): """Returns the version of the library as read from the __init__.py file""" main_lib = os.path.join(os.path.dirname(__file__), "uweb3", "__init__.py") with open(main_lib) as v_file: - return re.match(".*__version__ = \"(.*?)\"", v_file.read(), re.S).group(1) + return re.match('.*__version__ = "(.*?)"', v_file.read(), re.S).group(1) setup( From 1e3209ff83b2f5c40077c801e7e3ffc86726a1f1 Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 14:49:04 +0200 Subject: [PATCH 03/14] Delete sqlite.db --- test/sqlite.db | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test/sqlite.db diff --git a/test/sqlite.db b/test/sqlite.db deleted file mode 100644 index e69de29b..00000000 From ae397bef088691d805495459df832838375055da Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 14:49:40 +0200 Subject: [PATCH 04/14] Add uweb3tests to uweb3 --- test/test_uweb3tests.py | 488 +++++++++++++++++++ test/uweb3tests/__init__.py | 63 +++ test/uweb3tests/config.ini | 23 + test/uweb3tests/model.py | 60 +++ test/uweb3tests/pages.py | 188 +++++++ test/uweb3tests/serve.py | 16 + test/uweb3tests/setup/schema.sql | 51 ++ test/uweb3tests/static/SVG_Logo.svg | 56 +++ test/uweb3tests/static/favicon.png | Bin 0 -> 317 bytes test/uweb3tests/static/text.txt | 1 + test/uweb3tests/static/text.xml | 7 + test/uweb3tests/templates/404.html | 15 + test/uweb3tests/templates/index.html | 12 + test/uweb3tests/templates/sparse.html | 6 + test/uweb3tests/templates/sparse_target.html | 11 + test/uweb3tests/templates/test.html | 4 + 16 files changed, 1001 insertions(+) create mode 100755 test/test_uweb3tests.py create mode 100644 test/uweb3tests/__init__.py create mode 100644 test/uweb3tests/config.ini create mode 100644 test/uweb3tests/model.py create mode 100644 test/uweb3tests/pages.py create mode 100644 test/uweb3tests/serve.py create mode 100644 test/uweb3tests/setup/schema.sql create mode 100644 test/uweb3tests/static/SVG_Logo.svg create mode 100644 test/uweb3tests/static/favicon.png create mode 100644 test/uweb3tests/static/text.txt create mode 100644 test/uweb3tests/static/text.xml create mode 100644 test/uweb3tests/templates/404.html create mode 100644 test/uweb3tests/templates/index.html create mode 100644 test/uweb3tests/templates/sparse.html create mode 100644 test/uweb3tests/templates/sparse_target.html create mode 100644 test/uweb3tests/templates/test.html diff --git a/test/test_uweb3tests.py b/test/test_uweb3tests.py new file mode 100755 index 00000000..abb2a5e9 --- /dev/null +++ b/test/test_uweb3tests.py @@ -0,0 +1,488 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""This script attempts to connect to the webserver running form this same +directory. It communicates over http and checks the output of each route. + +You can start the webserver by issuing: python3 serve.py +You can test test all the functions by issuing: python3 testrunner.py -v +""" +import os +import unittest +import requests +import hashlib + +baseurl = "http://127.0.0.1:8002/" +BASE_DIR = os.path.join(os.path.dirname(__file__), "uweb3tests") + + +def escape_html(string): + """Quick and very dirty html escaping""" + string = string.replace("'", "'") + string = string.replace("<", "<") + string = string.replace(">", ">") + string = string.replace('"', """) + return string + + +def HashContent(string): + """Helper function for hashing of template files, this is needed to allow + users to download raw templates on their own which they know the hash for.""" + return hashlib.sha256(string.encode("utf-8")).hexdigest() + + +class ConfigTest(unittest.TestCase): + """Test if the server is using the config file""" + + def test_port(self): + """The config for the test server tells us we are live on 8002""" + r = requests.get(baseurl) + self.assertEqual(r.status_code, 200) + + +class ContentTests(unittest.TestCase): + """Test the content of routes""" + + def test_content(self): + """Lets see if the index route returns valid content""" + r = requests.get(baseurl) + self.assertEqual(r.encoding, "utf-8") + with open(os.path.join(BASE_DIR, "templates/index.html"), "r") as template: + templatecontent = template.read() + self.assertEqual(r.status_code, 200) + self.assertMultiLineEqual(templatecontent, r.text) + + def test_decorator_content(self): + """Lets see if the template decorated route returns valid content""" + url = baseurl + "templatedecorator" + r = requests.get(url) + self.assertEqual(r.encoding, "utf-8") + with open(os.path.join(BASE_DIR, "templates/index.html"), "r") as template: + templatecontent = template.read() + self.assertEqual(r.status_code, 200) + self.assertMultiLineEqual(templatecontent, r.text) + + def test_post(self): + """Lets see if the posted data is reflected as json""" + url = baseurl + "post" + data = {"key": "value"} + r = requests.post(url, data) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json; charset=utf-8") + self.assertEqual(r.json(), data) + + def test_returnNone(self): + """Lets see if a None survives the response""" + url = baseurl + "none" + r = requests.get(url) + response = "None" + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, response) + + def test_returnEmptystr(self): + """Lets see if an Empty string survives the response""" + url = baseurl + "emptystr" + r = requests.get(url) + response = "" + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, response) + + def test_templateparser(self): + """This tests if the pagemaker can return dicts to the decorator, + It tests if the _PostInit variables are present, and if the sparse list is + populated based on the given tagname. + It also tests if the content is properly escaped due to not being htmlSafe + """ + url = baseurl + "templateglobals" + r = requests.get(url) + response = """path test
+sparse path test
+pagemaker return test
+<b>escaped html test</b>""" + + self.assertEqual(r.status_code, 200) + self.assertTrue(r.text.startswith(response)) + + @unittest.skip("Unknown encoding is broken since conversion to py3.") + def test_unknown_encoding(self): + """Lets see if our a record is served correctly as 'unknown' encoding""" + url = baseurl + "mysql/read/1/unknown" + r = requests.get(url) + returnvalue = "Tank({'ID': 1, 'name': 'Living Room'})" + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, returnvalue) + self.assertEqual(r.headers["Content-Type"], "unknown") + + +class HeadersTests(unittest.TestCase): + """Test the headers""" + + def test_404(self): + """Do we see 404 headers?""" + url = baseurl + "nonexistant" + r = requests.get(url) + self.assertEqual(r.status_code, 404) + + def test_redirect_headers(self): + """Do we see redirect headers?""" + url = baseurl + "redirect" + r = requests.get(url, allow_redirects=False) + self.assertEqual(r.status_code, 307) + + def test_redirect_location(self): + """Do we see redirect headers?""" + url = baseurl + "redirect" + r = requests.get(url) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.url, baseurl) + + def test_post(self): + """Lets see if the page returns a json/utf-8 content-type""" + url = baseurl + "post" + data = {"key": "value"} + r = requests.post(url, data) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json; charset=utf-8") + + +class RouteTests(unittest.TestCase): + """Test the method routing""" + + def test_text_get_optional_missing(self): + """Lets see if the method route with GET returns valid content""" + url = baseurl + "text/arguments/1/word" + r = requests.get(url) + response = """('1', 'word', 'test')""" + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, response) + + def test_text_get_optional(self): + """Lets see if the method route with GET returns valid content""" + url = baseurl + "text/arguments/1/word/optional" + r = requests.get(url) + response = """('1', 'word', 'optional')""" + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, response) + + +class MethodTests(unittest.TestCase): + """Test the method routing""" + + def test_get(self): + """Lets see if the method route with GET returns valid content""" + url = baseurl + "method" + r = requests.get(url) + self.assertEqual(r.encoding, "utf-8") + with open(os.path.join(BASE_DIR, "templates/index.html"), "r") as template: + templatecontent = template.read() + self.assertEqual(r.status_code, 200) + self.assertMultiLineEqual(templatecontent, r.text) + + def test_post(self): + """Lets see if the method route with POST returns a json reflection of our + input""" + url = baseurl + "method" + data = {"key": "value"} + r = requests.post(url, data) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.json(), data) + self.assertEqual(r.headers["Content-Type"], "application/json; charset=utf-8") + + def test_put(self): + """Lets see if the method route with PUT returns the value from our put""" + url = baseurl + "method" + data = {"key": "value"} + r = requests.put(url, data) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, data["key"]) + + def test_put_keyerror(self): + """Lets see if the method route with PUT returns the failover value from our put""" + url = baseurl + "method" + data = {"nokey": "value"} + r = requests.put(url, data) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, "invalid") + + def test_del(self): + """Lets see if the method route with DEL returns a text/plain content-type""" + url = baseurl + "method" + r = requests.delete(url) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, "delete done") + self.assertEqual(r.headers["Content-Type"], "text/plain; charset=utf-8") + + +class CookieTests(unittest.TestCase): + """Test the cookies.""" + + def test_setcookie(self): + """Lets see if cookieset route gives us a cookie.""" + url = baseurl + "cookie/set" + data = '"this is an example cookie value set by uWeb"' + r = requests.get(url) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.cookies["example"], data) + + def test_setsecurecookie(self): + """Lets see if cookieset route gives us a cookie with the secure flag on.""" + url = baseurl + "cookie/set/secure" + data = '"this is an example cookie value set by uWeb"' + r = requests.get(url) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.cookies["example"], data) + for cookie in r.cookies: + self.assertTrue(cookie.secure) + + def test_setcookie_redirect(self): + """Lets see if cookieset route gives us a cookie even after a redirect.""" + url = baseurl + "cookie/set/redirect" + data = '"this is an example cookie value set by uWeb"' + r = requests.get(url, allow_redirects=False) + self.assertEqual(r.status_code, 307) + self.assertEqual(r.cookies["example"], data) + + def test_templatedecoratedsetcookie(self): + """Lets see if cookieset route gives us a cookie when combined with the template decorator.""" + url = baseurl + "cookie/set/templatedecorated" + data = '"this is an example cookie value set by uWeb"' + r = requests.get(url) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.cookies["example"], data) + + def test_reflectcookie(self): + """Lets see if cookies are parsed and the value is reflected + + uWeb stores cookies quote encapsulated. But reads them without the quotes. + """ + url = baseurl + "cookie/reflect" + jar = requests.cookies.RequestsCookieJar() + data = '"this is an example cookie value set by uWeb"' + jar.set("cookie", data) + r = requests.get(url, cookies=jar) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, data[1:-1]) + + def test_secure_clear(self): + """Lets see if we can set a cookie, and not have it reflected when we dont send it in for a second request.""" + + url_set = baseurl + "signedcookie/set" + r_set = requests.get(url_set) + + url_fetch = baseurl + "signedcookie/reflect" + r_fetch = requests.get(url_fetch) + + self.assertEqual(r_fetch.text, "") + self.assertEqual(r_fetch.cookies.keys(), []) + self.assertEqual(r_fetch.status_code, 200) + + def test_secure_cookie(self): + """Lets see if secure cookieset reflects our cookie when send ntampered for a second request. + This also checks""" + session = requests.session() + + url_set = baseurl + "signedcookie/set" + r_set = session.get(url_set) + + url_fetch = baseurl + "signedcookie/reflect" + r_fetch = session.get(url_fetch) + + content = escape_html("{'key': 'this is an example cookie value set by uWeb'}") + self.assertEqual(r_fetch.text, content) + self.assertEqual(r_set.cookies.keys(), ["signedExample"]) + self.assertEqual(r_fetch.status_code, 200) + + def test_secure_cookie_tampered(self): + """Lets see if Signed cookieset route gives us a cookie even after a redirect.""" + jar = requests.cookies.RequestsCookieJar() + jar.set("signedExample", "tampered") + url_fetch = baseurl + "signedcookie/reflect" + r_fetch = requests.get(url_fetch, cookies=jar) + self.assertEqual(r_fetch.text, "") + self.assertEqual(r_fetch.status_code, 200) + + +class StaticTests(unittest.TestCase): + """Test the static handler.""" + + def test_textfile(self): + """Lets see if our text file is served correctly""" + url = baseurl + "static/text.txt" + r = requests.get(url) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text.rstrip(), "text content") + self.assertEqual(r.headers["Content-Type"], "text/plain; charset=utf-8") + + def test_missingfile(self): + """Lets see if our text file is served correctly""" + url = baseurl + "static/invalid.txt" + r = requests.get(url) + self.assertEqual(r.status_code, 404) + + def test_image(self): + """Lets see if the image is returned""" + url = baseurl + "static/favicon.png" + r = requests.get(url) + with open(os.path.join(BASE_DIR, "static/favicon.png"), "rb") as template: + imagecontent = template.read() + self.assertEqual(r.status_code, 200) + self.assertEqual(r.content, imagecontent) + self.assertEqual(r.headers["Content-Type"], "image/png") + + def test_svgfile(self): + """Lets see if our SVG file is served correctly""" + url = baseurl + "static/SVG_Logo.svg" + r = requests.get(url) + with open(os.path.join(BASE_DIR, "static/SVG_Logo.svg"), "r") as template: + svgcontent = template.read() + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, svgcontent) + self.assertEqual(r.headers["Content-Type"], "image/svg+xml") + + def test_xmlfile(self): + """Lets see if our xml file is served correctly""" + url = baseurl + "static/text.xml" + r = requests.get(url) + with open(os.path.join(BASE_DIR, "static/text.xml"), "r") as template: + xmlcontent = template.read() + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, xmlcontent) + self.assertEqual(r.headers["Content-Type"], "application/xml") + + +class SQLitetests(unittest.TestCase): + def test_record(self): + """Lets see if our complete record is served correctly""" + url = baseurl + "sqlite/read/1" + r = requests.get(url) + returnvalue = escape_html( + """Fish({'ID': 1, 'name': 'sammy', 'species': 'shark', 'tank': Tank({'ID': 1, 'name': 'Living Room sqlite'})})""" + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, returnvalue) + + def test_missingfile(self): + """Lets see if our missing record is served correctly""" + url = baseurl + "sqlite/read/3" + r = requests.get(url) + self.assertEqual(r.status_code, 404) + + +class Mysqltests(unittest.TestCase): + def test_record(self): + """Lets see if our complete record is served correctly""" + url = baseurl + "mysql/read/1" + r = requests.get(url) + returnvalue = escape_html("""Tank({'ID': 1, 'name': 'Living Room'})""") + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, returnvalue) + + def test_missingrecord(self): + """Lets see if our missing record is served correctly""" + url = baseurl + "mysql/read/-1" + r = requests.get(url) + self.assertEqual(r.status_code, 404) + + def test_post_write(self): + """Lets see if the page returns a posted and insterted mysql record""" + url = baseurl + "mysql/write" + data = {"name": "Squid Tank"} + r = requests.post(url, data) + self.assertEqual(r.status_code, 200) + self.assertTrue(escape_html("""'name': 'Squid Tank'""") in r.text) + + +class EscapingTest(unittest.TestCase): + def test_get_optional_missing(self): + """Lets see if the method route with GET returns valid content""" + url = baseurl + "arguments/1/word" + r = requests.get(url) + response = escape_html("""('1', 'word', 'test')""") + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, response) + + def test_get_optional(self): + """Lets see if the method route with GET returns valid content""" + url = baseurl + "arguments/1/word/optional" + r = requests.get(url) + response = escape_html("""('1', 'word', 'optional')""") + self.assertEqual(r.status_code, 200) + self.assertEqual(r.text, response) + + def test_get_jsonstring(self): + """Lets see if a string dumped ot trough the json headers is correctly escaped and encasulated in json""" + url = baseurl + "jsonstring" + r = requests.get(url) + response = '{"message": "Hello, World!"}' + self.assertEqual(r.status_code, 200) + self.assertEqual(r.json(), response) + self.assertEqual(r.headers["Content-Type"], "application/json; charset=utf-8") + + def test_post_write_html_reflection(self): + """Lets see if the page returns a posted and insterted mysql record""" + url = baseurl + "mysql/write" + data = {"name": "Squid Tank"} + returnvalue = """Tank({'ID': 2, 'name': 'Squid Tank'})""" + r = requests.post(url, data) + self.assertEqual(r.status_code, 200) + self.assertTrue("Tank" not in r.text) + + +class ErrorTest(unittest.TestCase): + def test_500(self): + """Lets see if a deliberate error page is returned correctly.""" + url = baseurl + "error" + response = escape_html("name 'test' is not defined") + r = requests.get(url) + self.assertEqual(r.status_code, 500) + self.assertTrue(response in r.text) + + +class PathTraversalTest(unittest.TestCase): + def test_500(self): + """Lets see if a deliberate invalid template returns an error""" + url = baseurl + "templatetraversal" + response = escape_html("Could not load template") + invalidresponse = escape_html("[development]") + r = requests.get(url) + self.assertEqual(r.status_code, 500) + self.assertTrue(response in r.text) + self.assertFalse(invalidresponse in r.text) + + def test_statictraversal(self): + """Lets see if our text file is served correctly""" + url = baseurl + "static/../config.ini" + invalidresponse = escape_html("[development]") + r = requests.get(url) + self.assertEqual(r.status_code, 404) + self.assertFalse(invalidresponse in r.text) + + +class SmartClientTests(unittest.TestCase): + """Test the 'smart' client functionality""" + + def test_get(self): + """Lets see if the method route with GET returns valid content""" + url = baseurl + "templateglobals" + r = requests.get(url, headers={"Accept": "application/json"}) + self.assertEqual(r.encoding, "utf-8") + + with open(os.path.join(BASE_DIR, "templates/test.html"), "r") as template: + templatehash = HashContent(template.read()) + + returnvalue = ( + """{"template": "/test.html", "replacements": {"[header:part]": "path test", "[header:1:test:2]": "sparse path test", "[test]": "pagemaker return test", "[footer]": "<b>escaped html test</b>"}, "template_hash": "%s"}""" + % templatehash + ) + + self.assertEqual(r.status_code, 200) + self.assertMultiLineEqual(returnvalue, r.text) + + templateurl = baseurl + "template/%s/%s" % (templatehash, "test.html") + tr = requests.get(templateurl) + self.assertEqual(tr.encoding, "utf-8") + self.assertEqual(tr.status_code, 200) + self.assertMultiLineEqual(templatehash, HashContent(tr.text)) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/uweb3tests/__init__.py b/test/uweb3tests/__init__.py new file mode 100644 index 00000000..fec94e09 --- /dev/null +++ b/test/uweb3tests/__init__.py @@ -0,0 +1,63 @@ +"""A minimal uWeb3 project scaffold.""" +import os + +# Third-party modules +import uweb3 + +# Application +from . import pages + +__version__ = "0.1" + + +def main(): + """Creates a uWeb3 application. + + The application is created from the following components: + + - The presenter class (PageMaker) which implements the request handlers. + - The routes iterable, where each 2-tuple defines a url-pattern and the + name of a presenter method which should handle it. + - The execution path, internally used to find templates etc. + """ + return uweb3.uWeb( + pages.PageMaker, + [ + ("/", "Index"), + ("/post", "Post"), + ("/method", "Index", "GET"), + ("/method", "Post", "POST"), + ("/method", "Put", "PUT"), + ("/method", "Delete", "DELETE"), + ("/arguments/(\d+)/(\w+)/?(.*?)", "HtmlArgumentReflect"), + ("/text/arguments/(\d+)/(\w+)/?(.*?)", "TextArgumentReflect"), + ("/cookie/set", "Cookieset"), + ("/cookie/set/secure", "Cookiesetsecure"), + ("/cookie/reflect", "Cookiereflect"), + ("/cookie/set/redirect", "CookiesetRedirect"), + ("/cookie/set/templatedecorated", "TemplateDecoratedCookieset"), + ("/signedcookie/set", "SignedCookieset"), + ("/signedcookie/reflect", "SignedCookieReflect"), + ("/templatedecorator", "TemplateDecorator"), + ("/templateglobals", "TemplateGlobals"), + ("/templatetraversal", "TemplateTraversal"), + ("/sqlite/read/(.*)", "SqliteRead"), + ("/mysql/read/(\d+)/?(.*)?", "MysqlRead"), + ("/mysql/write", "MysqlWrite", "POST"), + ("/jsonapi/read/(.*)", "JsonApiRead"), + ("/redirect", "Redirect"), + ("/static/(.*)", "Static"), + ("/error", "ThrowError"), + ("/none", "ReturnNone"), + ("/emptystr", "ReturnEmptyStr"), + ("/json", "ReturnJson"), + ("/jsonstring", "ReturnJsonString"), + ("/contenttypedecorator", "ReturnJsonDecorated"), + ("/sparsetests", "SparseTests"), + ("/sparseteststarget", "SparseTestsTarget"), + ("/template/(\w+)/(.*?)", "SparseTemplateProvider"), + ("/sparse.js", "SparseRenderedProvider"), + ("/(.*)", "FourOhFour"), + ], + os.path.dirname(__file__), + ) diff --git a/test/uweb3tests/config.ini b/test/uweb3tests/config.ini new file mode 100644 index 00000000..e6d8c244 --- /dev/null +++ b/test/uweb3tests/config.ini @@ -0,0 +1,23 @@ +[development] +host = 127.0.0.1 +port = 8002 +error_logging = False + +[log] +access_logging = False +error_logging = False + +[sqlite] +database = aquarium.sqlite + +[mysql] +database = uweb_test +user = uweb3test +password = uweb3test + +[restfulljson] +url = https://jsonplaceholder.typicode.com/ + +[signedCookie] +secret = + diff --git a/test/uweb3tests/model.py b/test/uweb3tests/model.py new file mode 100644 index 00000000..16ccae42 --- /dev/null +++ b/test/uweb3tests/model.py @@ -0,0 +1,60 @@ +"""Model for the uweb3 test server""" + +from uweb3 import model + + +class SignedExample(model.SecureCookie): + """Model for the Singed Cookie example""" + + +class Fish(model.Record): + """Model for the Sqlite example""" + + _CONNECTOR = "sqlite" + + @classmethod + def create_table(cls, connection): + with connection as cursor: + cursor.Execute("DROP TABLE IF EXISTS fish") + cursor.Execute("DROP TABLE IF EXISTS tank") + cursor.Execute( + "CREATE TABLE fish(ID INTEGER, name TEXT, species TEXT, tank INTEGER)" + ) + cursor.Execute("CREATE TABLE tank(ID INTEGER, name TEXT)") + cursor.Execute("""INSERT INTO tank(ID, name) VALUES (1, "Living Room sqlite")""") + cursor.Execute( + """INSERT INTO fish(ID, name, species, tank) VALUES (1, "sammy", "shark", 1)""" + ) + + +class Tank(model.Record): + """Model for the Mysql example""" + + @classmethod + def create_table(cls, connection): + with connection as cursor: + cursor.Execute("DROP TABLE IF EXISTS tank") + cursor.Execute( + """ + CREATE TABLE `tank` ( + `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(45) DEFAULT NULL, + PRIMARY KEY (`ID`) + ) + """ + ) + cursor.Execute( + "INSERT INTO `tank` VALUES (1,'Living Room'),(2,'Squid Tank');" + ) + + +class Posts(model.Record): + """Model for the Mysql example""" + + _CONNECTOR = "restfulljson" + + +class Albums(model.Record): + """Model for the Mysql example""" + + _CONNECTOR = "restfulljson" diff --git a/test/uweb3tests/pages.py b/test/uweb3tests/pages.py new file mode 100644 index 00000000..6f380a81 --- /dev/null +++ b/test/uweb3tests/pages.py @@ -0,0 +1,188 @@ +#!/usr/bin/python +"""Request handlers for the uWeb3 project scaffold""" +# standard modules +import json + +# modules +import uweb3 + +# package imports +from . import model + + +class PageMaker(uweb3.DebuggingPageMaker, uweb3.SparseAsyncPages): + """Holds all the request handlers for the application""" + + def _PostInit(self): + """Register some vars to be used in the template parser later on""" + self.parser.RegisterTag("header:part", "path test") + self.parser.RegisterTag("header:1:test:2", "sparse path test") + self.parser.RegisterTag("footer", "escaped html test") + model.Fish.create_table(self.connection) + model.Tank.create_table(self.connection) + + def Index(self): + """Returns the index template""" + return self.parser.Parse("index.html") + + def Post(self): + """Returns the posted data as json""" + return uweb3.Response( + uweb3.JSONsafestring(json.dumps(self.post, cls=uweb3.JsonEncoder)), + content_type="application/json", + ) + + def Put(self): + """Returns the put data as text""" + return uweb3.Response( + self.put.getfirst("key", "invalid"), content_type="text/plain" + ) + + def Delete(self): + """Returns the delete string as text""" + return uweb3.Response("delete done", content_type="text/plain") + + def Cookieset(self): + """Returns the index template and sets a cookie + + As cookies should not contain UTF8 we just use ascii.""" + self.req.AddCookie("example", "this is an example cookie value set by uWeb") + return self.parser.Parse("index.html") + + def Cookiesetsecure(self): + """Returns the index template and sets a cookie with a secure flag.""" + self.req.AddCookie( + "example", "this is an example cookie value set by uWeb", secure=True + ) + return self.parser.Parse("index.html") + + def Cookiereflect(self): + """Returns the cookies value.""" + return self.cookies["cookie"] + + def CookiesetRedirect(self): + """Returns to the index and sets a cookie""" + self.req.AddCookie("example", "this is an example cookie value set by uWeb") + return self.req.Redirect("/") + + def SignedCookieset(self): + """Returns the index template and sets a signed cookie + + As signed cookies should not contain UTF8 we just use ascii.""" + data = "this is an example cookie value set by uWeb" + model.SignedExample.Create(self.connection, {"key": data}) + return self.parser.Parse("index.html") + + def SignedCookieReflect(self): + """Returns signed cookie if valid.""" + return model.SignedExample(self.connection) + + def HtmlArgumentReflect(self, numeric, string, optional="test"): + """Returns the url arguments as parsed by the router.""" + return (numeric, string, optional) + + def TextArgumentReflect(self, numeric, string, optional="test"): + """Returns the url arguments as parsed by the router.""" + return uweb3.Response((numeric, string, optional), content_type="text/plain") + + @uweb3.decorators.TemplateParser("index.html") + def TemplateDecoratedCookieset(self): + """Returns the index template and sets a cookie""" + self.req.AddCookie("example", "this is an example cookie value set by uWeb") + + @uweb3.decorators.TemplateParser("index.html") + def TemplateDecorator(self): + """Returns the index template""" + + @uweb3.decorators.TemplateParser("test.html") + def TemplateGlobals(self): + """Returns the index template""" + return {"test": "pagemaker return test"} + + @uweb3.decorators.TemplateParser("sparse.html") + def SparseTests(self): + """Returns the sparse template""" + + @uweb3.decorators.TemplateParser("sparse_target.html") + def SparseTestsTarget(self): + """Returns the sparse_target template""" + + @uweb3.decorators.TemplateParser("../config.ini") + def TemplateTraversal(self): + """Tries to load an invalid template by traversing up the tree""" + return {"test": "pagemaker return test"} + + def Redirect(self): + """Redirects to the homepage""" + return uweb3.Redirect("/") + + def SqliteRead(self, fish=1): + """Reads form the SQLite db""" + try: + return model.Fish.FromPrimary(self.connection, int(fish)) + except uweb3.model.NotExistError: + return uweb3.Response( + "No such fish", httpcode=404, content_type="text/plain" + ) + + def MysqlRead(self, tank=1, contenttype="html"): + """Reads form the Mysql db""" + try: + record = model.Tank.FromPrimary(self.connection, int(tank)) + if contenttype != "html": + return uweb3.Response(record, content_type=contenttype) + return record + except uweb3.model.NotExistError: + return uweb3.Response( + "No such tank", httpcode=404, content_type="text/plain" + ) + + def MysqlWrite(self): + """Writes to the Mysql db""" + newtank = model.Tank.Create( + self.connection, {"name": self.post.getfirst("name", "Empty post")} + ) + return newtank + + def JsonApiRead(self, post=1): + """Reads form the Json API""" + try: + return model.Posts.FromPrimary(self.connection, int(post)) + except uweb3.model.NotExistError: + return uweb3.Response( + "No such post", httpcode=404, content_type="text/plain" + ) + + def ThrowError(self): + """The request could not be fulfilled, this returns a 500.""" + return test + + def ReturnNone(self): + """returns a Python None.""" + return None + + def ReturnEmptyStr(self): + """returns a Python empty str.""" + return "" + + def ReturnJsonString(self): + """Returns a string, escaped by the json handler to become a json safe tring instead.""" + return uweb3.Response( + '{"message": "Hello, World!"}', content_type="application/json" + ) + + def ReturnJson(self): + """Returns a json page""" + return uweb3.Response( + {"message": "Hello, World!"}, content_type="application/json" + ) + + @uweb3.decorators.ContentType("application/json") + def ReturnJsonDecorated(self): + """Returns a json page""" + return {"message": "Hello, World!"} + + def FourOhFour(self, path): + """The request could not be fulfilled, this returns a 404.""" + self.req.response.httpcode = 404 + return self.parser.Parse("404.html", path=path) diff --git a/test/uweb3tests/serve.py b/test/uweb3tests/serve.py new file mode 100644 index 00000000..5aa92517 --- /dev/null +++ b/test/uweb3tests/serve.py @@ -0,0 +1,16 @@ +#!/usr/bin/python3 +"""Starts a simple application development server. +Just execute `./serve.py` or `python3 serve.py` +""" + +# Application +from test import uweb3tests + + +def main(): + app = uweb3tests.main() + app.serve() + + +if __name__ == "__main__": + main() diff --git a/test/uweb3tests/setup/schema.sql b/test/uweb3tests/setup/schema.sql new file mode 100644 index 00000000..6d595161 --- /dev/null +++ b/test/uweb3tests/setup/schema.sql @@ -0,0 +1,51 @@ +-- MySQL dump 10.13 Distrib 5.7.31, for Linux (x86_64) +-- +-- Host: localhost Database: aquarium +-- ------------------------------------------------------ +-- Server version 5.7.31-0ubuntu0.18.04.1 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `tank` +-- + +DROP TABLE IF EXISTS `tank`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tank` ( + `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(45) DEFAULT NULL, + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `tank` +-- + +LOCK TABLES `tank` WRITE; +/*!40000 ALTER TABLE `tank` DISABLE KEYS */; +INSERT INTO `tank` VALUES (1,'Living Room'),(2,'Squid Tank'); +/*!40000 ALTER TABLE `tank` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2020-10-27 16:52:37 diff --git a/test/uweb3tests/static/SVG_Logo.svg b/test/uweb3tests/static/SVG_Logo.svg new file mode 100644 index 00000000..55af5b8e --- /dev/null +++ b/test/uweb3tests/static/SVG_Logo.svg @@ -0,0 +1,56 @@ + + + SVG Logo + Designed for the SVG Logo Contest in 2006 by Harvey Rayner, and adopted by W3C in 2009. It is available under the Creative Commons license for those who have an SVG product or who are using SVG on their site. + + + + + SVG Logo + 14-08-2009 + + W3C + Harvey Rayner, designer + + See document description + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/uweb3tests/static/favicon.png b/test/uweb3tests/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..a1a952771a2cc11ed1675bd46a3380968c5940f9 GIT binary patch literal 317 zcmV-D0mA-?P)nH!ga-uR28-IQ$(F^84!$6ur2A$vkkAa;Niwp1pn9W;e{bTs__CJ^p^FK*p@blY$ z++hIom!>%r*r^~I20pz75~>Ugb|K6RPjCN+y9mVvAWb05C(OX$lg7-z&V^8L0qAd# z1zHx246d=54n|4JAiseWgA79kpnwC}j7@If^8&M!loTjb9LUYi009O7B%etRjsNn* P00000NkvXXu0mjf5s7{T literal 0 HcmV?d00001 diff --git a/test/uweb3tests/static/text.txt b/test/uweb3tests/static/text.txt new file mode 100644 index 00000000..c182a933 --- /dev/null +++ b/test/uweb3tests/static/text.txt @@ -0,0 +1 @@ +text content diff --git a/test/uweb3tests/static/text.xml b/test/uweb3tests/static/text.xml new file mode 100644 index 00000000..d3f0eca2 --- /dev/null +++ b/test/uweb3tests/static/text.xml @@ -0,0 +1,7 @@ + + + Tove + Jani + Reminder + Don't forget me this weekend! + diff --git a/test/uweb3tests/templates/404.html b/test/uweb3tests/templates/404.html new file mode 100644 index 00000000..95c91fd8 --- /dev/null +++ b/test/uweb3tests/templates/404.html @@ -0,0 +1,15 @@ + + + + + µWeb3 project scaffold + + + +

This is not the page you're looking for (HTTP 404)

+

+ The URL you requested ("[path]") doesn't exist. +

+ + + \ No newline at end of file diff --git a/test/uweb3tests/templates/index.html b/test/uweb3tests/templates/index.html new file mode 100644 index 00000000..f47039cc --- /dev/null +++ b/test/uweb3tests/templates/index.html @@ -0,0 +1,12 @@ + + + + + qwe project test + + + +

Hello µWeb3.

+ + + \ No newline at end of file diff --git a/test/uweb3tests/templates/sparse.html b/test/uweb3tests/templates/sparse.html new file mode 100644 index 00000000..f328a379 --- /dev/null +++ b/test/uweb3tests/templates/sparse.html @@ -0,0 +1,6 @@ + + + + To sparse target + + \ No newline at end of file diff --git a/test/uweb3tests/templates/sparse_target.html b/test/uweb3tests/templates/sparse_target.html new file mode 100644 index 00000000..56116076 --- /dev/null +++ b/test/uweb3tests/templates/sparse_target.html @@ -0,0 +1,11 @@ + + + + To sparse tests +
+ + + +
+ + \ No newline at end of file diff --git a/test/uweb3tests/templates/test.html b/test/uweb3tests/templates/test.html new file mode 100644 index 00000000..37ff81c0 --- /dev/null +++ b/test/uweb3tests/templates/test.html @@ -0,0 +1,4 @@ +[header:part]
+[header:1:test:2]
+[test]
+[footer] \ No newline at end of file From 90665928d147dca8947be1b30688a0e8321c1bcf Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 14:49:45 +0200 Subject: [PATCH 05/14] formatting --- uweb3/logger.py | 1 - uweb3/pagemaker/__init__.py | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/uweb3/logger.py b/uweb3/logger.py index 01d954e3..2f94d1fe 100644 --- a/uweb3/logger.py +++ b/uweb3/logger.py @@ -1,7 +1,6 @@ import logging from typing import NamedTuple - from uweb3.request import IndexedFieldStorage DEBUG_FORMAT = ( diff --git a/uweb3/pagemaker/__init__.py b/uweb3/pagemaker/__init__.py index cebff008..907525e1 100644 --- a/uweb3/pagemaker/__init__.py +++ b/uweb3/pagemaker/__init__.py @@ -18,12 +18,12 @@ import uweb3 from uweb3.logger import ( + DebuggingDetails, + UwebDebuggingAdapter, + default_data_scrubber, setup_debug_logger, setup_debug_stream_logger, setup_error_logger, - UwebDebuggingAdapter, - DebuggingDetails, - default_data_scrubber, ) from uweb3.request import IndexedFieldStorage From c3b18007a5db530df8d0871b9c5df879b7ea14b1 Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 14:52:21 +0200 Subject: [PATCH 06/14] Update python-app.yml --- .github/workflows/python-app.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 9fcf0dc7..fa9fe2ee 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -47,3 +47,4 @@ jobs: python3 -m unittest test.test_model python3 -m unittest test.test_request python3 -m unittest test.test_templateparser + python3 -m test.uweb3tests.serve & sleep 5 && python3 -m unittest test_uweb3tests From c1aec06a11cc1774458e9278edabee693d117109 Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 14:52:52 +0200 Subject: [PATCH 07/14] Update python-app.yml --- .github/workflows/python-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index fa9fe2ee..ed8820a9 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -5,7 +5,7 @@ name: Python application on: push: - branches: [ dev ] + branches: [ dev, uweb3tests_intergration ] pull_request: branches: [ dev ] permissions: From 4087a1630184e467d74cc222d75f8784dfb7ccc4 Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 14:57:09 +0200 Subject: [PATCH 08/14] Formatting --- test/test_model.py | 6 +++++- test/test_uweb3tests.py | 3 ++- test/uweb3tests/config.ini | 3 +-- test/uweb3tests/model.py | 6 ++++-- test/uweb3tests/static/SVG_Logo.svg | 6 +++--- test/uweb3tests/templates/404.html | 2 +- test/uweb3tests/templates/index.html | 2 +- test/uweb3tests/templates/sparse.html | 2 +- test/uweb3tests/templates/sparse_target.html | 2 +- test/uweb3tests/templates/test.html | 2 +- 10 files changed, 20 insertions(+), 14 deletions(-) diff --git a/test/test_model.py b/test/test_model.py index 4ab82bab..b4622853 100755 --- a/test/test_model.py +++ b/test/test_model.py @@ -670,7 +670,11 @@ def testMultipleCommits(self): def DatabaseConnection(): """Returns an SQLTalk database connection to 'uWeb3_model_test'.""" return mysql.Connect( - host="localhost", user="uweb3test", passwd="uweb3test", db="uweb_test", charset="utf8" + host="localhost", + user="uweb3test", + passwd="uweb3test", + db="uweb_test", + charset="utf8", ) diff --git a/test/test_uweb3tests.py b/test/test_uweb3tests.py index abb2a5e9..97257c82 100755 --- a/test/test_uweb3tests.py +++ b/test/test_uweb3tests.py @@ -6,10 +6,11 @@ You can start the webserver by issuing: python3 serve.py You can test test all the functions by issuing: python3 testrunner.py -v """ +import hashlib import os import unittest + import requests -import hashlib baseurl = "http://127.0.0.1:8002/" BASE_DIR = os.path.join(os.path.dirname(__file__), "uweb3tests") diff --git a/test/uweb3tests/config.ini b/test/uweb3tests/config.ini index e6d8c244..effd14be 100644 --- a/test/uweb3tests/config.ini +++ b/test/uweb3tests/config.ini @@ -19,5 +19,4 @@ password = uweb3test url = https://jsonplaceholder.typicode.com/ [signedCookie] -secret = - +secret = diff --git a/test/uweb3tests/model.py b/test/uweb3tests/model.py index 16ccae42..cd5f2356 100644 --- a/test/uweb3tests/model.py +++ b/test/uweb3tests/model.py @@ -21,7 +21,9 @@ def create_table(cls, connection): "CREATE TABLE fish(ID INTEGER, name TEXT, species TEXT, tank INTEGER)" ) cursor.Execute("CREATE TABLE tank(ID INTEGER, name TEXT)") - cursor.Execute("""INSERT INTO tank(ID, name) VALUES (1, "Living Room sqlite")""") + cursor.Execute( + """INSERT INTO tank(ID, name) VALUES (1, "Living Room sqlite")""" + ) cursor.Execute( """INSERT INTO fish(ID, name, species, tank) VALUES (1, "sammy", "shark", 1)""" ) @@ -40,7 +42,7 @@ def create_table(cls, connection): `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(45) DEFAULT NULL, PRIMARY KEY (`ID`) - ) + ) """ ) cursor.Execute( diff --git a/test/uweb3tests/static/SVG_Logo.svg b/test/uweb3tests/static/SVG_Logo.svg index 55af5b8e..a05c274f 100644 --- a/test/uweb3tests/static/SVG_Logo.svg +++ b/test/uweb3tests/static/SVG_Logo.svg @@ -2,7 +2,7 @@ SVG Logo Designed for the SVG Logo Contest in 2006 by Harvey Rayner, and adopted by W3C in 2009. It is available under the Creative Commons license for those who have an SVG product or who are using SVG on their site. - + @@ -28,7 +28,7 @@ - + @@ -53,4 +53,4 @@ - \ No newline at end of file + diff --git a/test/uweb3tests/templates/404.html b/test/uweb3tests/templates/404.html index 95c91fd8..47713207 100644 --- a/test/uweb3tests/templates/404.html +++ b/test/uweb3tests/templates/404.html @@ -12,4 +12,4 @@

This is not the page you're looking for (HTTP 404)

- \ No newline at end of file + diff --git a/test/uweb3tests/templates/index.html b/test/uweb3tests/templates/index.html index f47039cc..3a968c3f 100644 --- a/test/uweb3tests/templates/index.html +++ b/test/uweb3tests/templates/index.html @@ -9,4 +9,4 @@

Hello µWeb3.

- \ No newline at end of file + diff --git a/test/uweb3tests/templates/sparse.html b/test/uweb3tests/templates/sparse.html index f328a379..9cb3007e 100644 --- a/test/uweb3tests/templates/sparse.html +++ b/test/uweb3tests/templates/sparse.html @@ -3,4 +3,4 @@ To sparse target - \ No newline at end of file + diff --git a/test/uweb3tests/templates/sparse_target.html b/test/uweb3tests/templates/sparse_target.html index 56116076..c92eae8e 100644 --- a/test/uweb3tests/templates/sparse_target.html +++ b/test/uweb3tests/templates/sparse_target.html @@ -8,4 +8,4 @@ - \ No newline at end of file + diff --git a/test/uweb3tests/templates/test.html b/test/uweb3tests/templates/test.html index 37ff81c0..505cf93a 100644 --- a/test/uweb3tests/templates/test.html +++ b/test/uweb3tests/templates/test.html @@ -1,4 +1,4 @@ [header:part]
[header:1:test:2]
[test]
-[footer] \ No newline at end of file +[footer] From e274e13ceff071ad2b3d06660a2de0a1d05cebe8 Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 14:57:20 +0200 Subject: [PATCH 09/14] Fix linting issues --- test/test_uweb3tests.py | 1 - test/uweb3tests/pages.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/test_uweb3tests.py b/test/test_uweb3tests.py index 97257c82..4fc981ff 100755 --- a/test/test_uweb3tests.py +++ b/test/test_uweb3tests.py @@ -422,7 +422,6 @@ def test_post_write_html_reflection(self): """Lets see if the page returns a posted and insterted mysql record""" url = baseurl + "mysql/write" data = {"name": "Squid Tank"} - returnvalue = """Tank({'ID': 2, 'name': 'Squid Tank'})""" r = requests.post(url, data) self.assertEqual(r.status_code, 200) self.assertTrue("Tank" not in r.text) diff --git a/test/uweb3tests/pages.py b/test/uweb3tests/pages.py index 6f380a81..1ea0cacb 100644 --- a/test/uweb3tests/pages.py +++ b/test/uweb3tests/pages.py @@ -155,7 +155,7 @@ def JsonApiRead(self, post=1): def ThrowError(self): """The request could not be fulfilled, this returns a 500.""" - return test + raise Exception("error") def ReturnNone(self): """returns a Python None.""" From bed5cb1427717ea090d0b595be9663df2233e72d Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 14:59:00 +0200 Subject: [PATCH 10/14] remove unused variable --- test/test_uweb3tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_uweb3tests.py b/test/test_uweb3tests.py index 4fc981ff..9454d7c0 100755 --- a/test/test_uweb3tests.py +++ b/test/test_uweb3tests.py @@ -267,7 +267,7 @@ def test_secure_clear(self): """Lets see if we can set a cookie, and not have it reflected when we dont send it in for a second request.""" url_set = baseurl + "signedcookie/set" - r_set = requests.get(url_set) + requests.get(url_set) url_fetch = baseurl + "signedcookie/reflect" r_fetch = requests.get(url_fetch) From d0970fa0ef5b16f740f4be3873373f8659b8de5b Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 15:01:04 +0200 Subject: [PATCH 11/14] Point to `test.test_uweb3tests` instead of `test_uweb3tests` --- .github/workflows/python-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index ed8820a9..1ae35336 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -47,4 +47,4 @@ jobs: python3 -m unittest test.test_model python3 -m unittest test.test_request python3 -m unittest test.test_templateparser - python3 -m test.uweb3tests.serve & sleep 5 && python3 -m unittest test_uweb3tests + python3 -m test.uweb3tests.serve & sleep 5 && python3 -m unittest test.test_uweb3tests From 0693accdc6e94bde80f417539395815dca5e21b4 Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 15:03:07 +0200 Subject: [PATCH 12/14] remove `pytest` and add `requests` to pip packages --- .github/workflows/python-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 1ae35336..f2a0256e 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -35,7 +35,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install flake8 pytest + pip install flake8 requests if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with flake8 run: | From 2f78553910f22636d4179de5c820585943cf3f93 Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 15:09:25 +0200 Subject: [PATCH 13/14] Set Exception message to the same as if we are attempting to access an undefined variable test. Instead of writing invalid python we raise an exception here, this results into the same behavior and keeps the linters happy. --- test/uweb3tests/pages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/uweb3tests/pages.py b/test/uweb3tests/pages.py index 1ea0cacb..42ba80a7 100644 --- a/test/uweb3tests/pages.py +++ b/test/uweb3tests/pages.py @@ -155,7 +155,7 @@ def JsonApiRead(self, post=1): def ThrowError(self): """The request could not be fulfilled, this returns a 500.""" - raise Exception("error") + raise Exception("name 'test' is not defined") def ReturnNone(self): """returns a Python None.""" From 3c285269a015c07de6dd74244a29be9b5ec99ce3 Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 28 Jul 2022 15:12:41 +0200 Subject: [PATCH 14/14] Remove current branch from push triggers. --- .github/workflows/python-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index f2a0256e..2fe299eb 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -5,7 +5,7 @@ name: Python application on: push: - branches: [ dev, uweb3tests_intergration ] + branches: [ dev ] pull_request: branches: [ dev ] permissions: