From 50bdaf41451e648af7832a1202671e6157a20979 Mon Sep 17 00:00:00 2001 From: Andreas Kaiser Date: Sat, 10 Oct 2015 01:31:03 +0200 Subject: [PATCH 1/4] Replace browser-cache.txt with equivalent webtest tests. --- kotti/tests/browser-cache.txt | 136 ---------------------------------- kotti/tests/test_cache.py | 79 ++++++++++++++++++++ 2 files changed, 79 insertions(+), 136 deletions(-) delete mode 100644 kotti/tests/browser-cache.txt diff --git a/kotti/tests/browser-cache.txt b/kotti/tests/browser-cache.txt deleted file mode 100644 index 3bd4e92fd..000000000 --- a/kotti/tests/browser-cache.txt +++ /dev/null @@ -1,136 +0,0 @@ -Caching browser tests -===================== - -Setup ------ - - >>> from kotti.resources import get_root - >>> from kotti import testing - >>> tools = testing.setUpFunctional() - >>> browser = tools['Browser']() - >>> root = get_root() - -Some convenience functions: - - >>> import datetime, time - >>> def parse_expires(date_string): - ... return datetime.datetime(* - ... (time.strptime(date_string, - ... "%a, %d %b %Y %H:%M:%S GMT")[0:6])) - >>> def delta(date_string): - ... now = datetime.datetime.utcnow() - ... return parse_expires(date_string) - now - -Add a file and an image: - - >>> from kotti.resources import File, Image - >>> image = testing.asset('sendeschluss.jpg').read() - >>> root['textfile'] = File("file contents", u"mytext.txt", u"text/plain") - >>> root['image'] = Image(image, u"sendeschluss.jpg", u"image/jpeg") - ---------- -Anonymous ---------- - -Cache HTML ----------- - -We define different caching policies for different kinds of items. A -document: - - >>> browser.open(testing.BASE_URL) - >>> browser.headers['X-Caching-Policy'] - 'Cache HTML' - >>> browser.headers['Cache-Control'] - 'max-age=0,s-maxage=3600' - >>> d = delta(browser.headers['Expires']) - >>> (d.days, d.seconds) < (0, 0) - True - -Cache Media Content -------------------- - - >>> browser.open(testing.BASE_URL + '/textfile/inline-view') - >>> browser.headers['X-Caching-Policy'] - 'Cache Media Content' - >>> browser.headers['Cache-Control'] - 'max-age=14400' - >>> d = delta(browser.headers['Expires']) - >>> (d.days, d.seconds) > (0, 14000) - True - >>> browser.open(testing.BASE_URL + '/image/inline-view') - >>> browser.headers['X-Caching-Policy'] - 'Cache Media Content' - -Cache Resource --------------- - - >>> browser.open(testing.BASE_URL + '/static-kotti/base.css') - >>> browser.headers['X-Caching-Policy'] - 'Cache Resource' - >>> browser.headers['Cache-Control'] - 'max-age=2764800,public' - >>> d = delta(browser.headers['Expires']) - >>> (d.days, d.seconds) > (30, 0) - True - >>> 'Last-Modified' in browser.headers - True - -POST request ------------- - - >>> browser.post(testing.BASE_URL, '') - >>> 'X-Caching-Policy' in browser.headers - False - ---------- -Logged in ---------- - - >>> browser.open(testing.BASE_URL + '/edit') - >>> "Log in" in browser.contents - True - >>> browser.getControl("Username or email", index=0).value = "admin" - >>> browser.getControl("Password").value = "secret" - >>> browser.getControl(name="submit").click() - >>> "Welcome, Administrator" in browser.contents - True - -Cache HTML ----------- - - >>> browser.open(testing.BASE_URL) - >>> browser.headers['X-Caching-Policy'] - 'No Cache' - -Cache Media Content -------------------- - - >>> browser.open(testing.BASE_URL + '/textfile/inline-view') - >>> browser.headers['X-Caching-Policy'] - 'No Cache' - >>> browser.open(testing.BASE_URL + '/image/inline-view') - >>> browser.headers['X-Caching-Policy'] - 'No Cache' - -Cache Resource --------------- - - >>> browser.open(testing.BASE_URL + '/static-kotti/base.css') - >>> browser.headers['X-Caching-Policy'] - 'Cache Resource' - -=== -404 -=== - - >>> browser.open(testing.BASE_URL + '/this-isnt-here') - Traceback (most recent call last): - HTTPError: HTTP Error 404: Not Found - >>> 'X-Caching-Policy' in browser.headers - False - -TearDown --------- - - >>> testing.tearDown() diff --git a/kotti/tests/test_cache.py b/kotti/tests/test_cache.py index e66b15de6..528468bb1 100644 --- a/kotti/tests/test_cache.py +++ b/kotti/tests/test_cache.py @@ -1,13 +1,34 @@ import datetime +import time from mock import patch from mock import MagicMock import pytest +from kotti.resources import File +from kotti.resources import Image +from kotti.testing import asset from kotti.testing import Dummy from kotti.views.cache import set_max_age +def parse_expires(date_string): + return datetime.datetime(*( + time.strptime(date_string, "%a, %d %b %Y %H:%M:%S GMT")[0:6])) + + +def delta(date_string): + now = datetime.datetime.utcnow() + return parse_expires(date_string) - now + + +@pytest.fixture +def cachetest_content(root, filedepot): + image = asset('sendeschluss.jpg').read() + root['textfile'] = File("file contents", u"mytext.txt", u"text/plain") + root['image'] = Image(image, u"sendeschluss.jpg", u"image/jpeg") + + class TestSetMaxAge: def test_preserve_existing_headers(self): response = Dummy(headers={ @@ -76,3 +97,61 @@ def test_request_has_no_context(self): set_cache_headers(event) assert chooser.call_count == 0 + + +class TestBrowser: + + def test_cache_unauth(self, webtest, cachetest_content): + + # html + resp = webtest.app.get('/') + assert resp.headers.get('X-Caching-Policy') == 'Cache HTML' + assert resp.headers.get('Cache-Control') == 'max-age=0,s-maxage=3600' + d = delta(resp.headers.get('Expires')) + assert (d.days, d.seconds) < (0, 0) + + # media content + resp = webtest.app.get('/textfile/inline-view') + assert resp.headers.get('X-Caching-Policy') == 'Cache Media Content' + assert resp.headers.get('Cache-Control') == 'max-age=14400' + d = delta(resp.headers.get('Expires')) + assert (d.days, d.seconds) > (0, 14000) + resp = webtest.app.get('/image/inline-view') + assert resp.headers.get('X-Caching-Policy') == 'Cache Media Content' + + # resources + resp = webtest.app.get('/static-kotti/base.css') + assert resp.headers.get('X-Caching-Policy') == 'Cache Resource' + assert resp.headers.get('Cache-Control') == 'max-age=2764800,public' + d = delta(resp.headers.get('Expires')) + assert (d.days, d.seconds) > (30, 0) + assert 'Last-Modified' in resp.headers + + # post + resp = webtest.app.post('/', '') + assert 'X-Caching-Policy' not in resp.headers + + # 404 + resp = webtest.app.get('/this-isnt-here', status=404) + assert 'X-Caching-Policy' not in resp.headers + + @pytest.mark.user('admin') + def test_cache_auth(self, webtest, cachetest_content): + + # html + resp = webtest.app.get('/') + assert resp.headers.get('X-Caching-Policy') == 'No Cache' + + # media content + resp = webtest.app.get('/textfile/inline-view') + assert resp.headers.get('X-Caching-Policy') == 'No Cache' + resp = webtest.app.get('/image/inline-view') + assert resp.headers.get('X-Caching-Policy') == 'No Cache' + + # resources + resp = webtest.app.get('/static-kotti/base.css') + assert resp.headers.get('X-Caching-Policy') == 'Cache Resource' + + # 404 + resp = webtest.app.get('/this-isnt-here', status=404) + assert 'X-Caching-Policy' not in resp.headers From 52b630dcbf8f3565ec6d70b5894289b18409cfbc Mon Sep 17 00:00:00 2001 From: Andreas Kaiser Date: Sat, 10 Oct 2015 01:49:22 +0200 Subject: [PATCH 2/4] Replace browser-errors.txt with equivalent webtest tests. --- kotti/tests/browser-errors.txt | 45 ------------------------------ kotti/tests/test_httpexceptions.py | 16 +++++++++++ 2 files changed, 16 insertions(+), 45 deletions(-) delete mode 100644 kotti/tests/browser-errors.txt create mode 100644 kotti/tests/test_httpexceptions.py diff --git a/kotti/tests/browser-errors.txt b/kotti/tests/browser-errors.txt deleted file mode 100644 index a28ecf618..000000000 --- a/kotti/tests/browser-errors.txt +++ /dev/null @@ -1,45 +0,0 @@ -Kotti HTTP Exception browser tests -================================== - -Setup ------ -Create references to some useful tools: - - >>> from kotti import testing - >>> tools = testing.setUpFunctional() - >>> browser = tools['Browser']() - >>> ctrl = browser.getControl - -Tell the zope test browser to not raise errors for HTTP exceptions: - - >>> browser.raiseHttpErrors = False - -Open the front page: - - >>> browser.open(testing.BASE_URL) - - -HTTP Not Found (404) --------------------- -A 404 Not Found view results in a nicely formatted, albeit plain page: - - >>> browser.open(testing.BASE_URL + '/non-existent') - >>> 'Not Found' in browser.contents - True - -The not found view renders similarly for authenticated users. - -After logging in: - - >>> browser.open(testing.BASE_URL + '/login') - >>> ctrl("Username or email", index=0).value = "admin" - >>> ctrl("Password").value = "secret" - >>> ctrl(name="submit").click() - -We should see the error message when visiting a URL that does not exist: - - >>> browser.open(testing.BASE_URL + '/non-existent') - >>> 'Not Found' in browser.contents - True - - diff --git a/kotti/tests/test_httpexceptions.py b/kotti/tests/test_httpexceptions.py new file mode 100644 index 000000000..2712d6a54 --- /dev/null +++ b/kotti/tests/test_httpexceptions.py @@ -0,0 +1,16 @@ +""" Kotti HTTP Exception browser tests """ + +import pytest + + +def test_404_anon(webtest, root): + + resp = webtest.app.get('/non-existent', status=404) + assert 'Not Found' in resp.text + + +@pytest.mark.user('admin') +def test_404_anon(webtest, root): + + resp = webtest.app.get('/non-existent', status=404) + assert 'Not Found' in resp.text From c9e6bc1769d339f233384642b351b9acf01c645e Mon Sep 17 00:00:00 2001 From: Andreas Kaiser Date: Sat, 10 Oct 2015 01:31:03 +0200 Subject: [PATCH 3/4] Replace browser-cache.txt with equivalent webtest tests. --- kotti/tests/browser-cache.txt | 136 ---------------------------------- kotti/tests/test_cache.py | 79 ++++++++++++++++++++ 2 files changed, 79 insertions(+), 136 deletions(-) delete mode 100644 kotti/tests/browser-cache.txt diff --git a/kotti/tests/browser-cache.txt b/kotti/tests/browser-cache.txt deleted file mode 100644 index 3bd4e92fd..000000000 --- a/kotti/tests/browser-cache.txt +++ /dev/null @@ -1,136 +0,0 @@ -Caching browser tests -===================== - -Setup ------ - - >>> from kotti.resources import get_root - >>> from kotti import testing - >>> tools = testing.setUpFunctional() - >>> browser = tools['Browser']() - >>> root = get_root() - -Some convenience functions: - - >>> import datetime, time - >>> def parse_expires(date_string): - ... return datetime.datetime(* - ... (time.strptime(date_string, - ... "%a, %d %b %Y %H:%M:%S GMT")[0:6])) - >>> def delta(date_string): - ... now = datetime.datetime.utcnow() - ... return parse_expires(date_string) - now - -Add a file and an image: - - >>> from kotti.resources import File, Image - >>> image = testing.asset('sendeschluss.jpg').read() - >>> root['textfile'] = File("file contents", u"mytext.txt", u"text/plain") - >>> root['image'] = Image(image, u"sendeschluss.jpg", u"image/jpeg") - ---------- -Anonymous ---------- - -Cache HTML ----------- - -We define different caching policies for different kinds of items. A -document: - - >>> browser.open(testing.BASE_URL) - >>> browser.headers['X-Caching-Policy'] - 'Cache HTML' - >>> browser.headers['Cache-Control'] - 'max-age=0,s-maxage=3600' - >>> d = delta(browser.headers['Expires']) - >>> (d.days, d.seconds) < (0, 0) - True - -Cache Media Content -------------------- - - >>> browser.open(testing.BASE_URL + '/textfile/inline-view') - >>> browser.headers['X-Caching-Policy'] - 'Cache Media Content' - >>> browser.headers['Cache-Control'] - 'max-age=14400' - >>> d = delta(browser.headers['Expires']) - >>> (d.days, d.seconds) > (0, 14000) - True - >>> browser.open(testing.BASE_URL + '/image/inline-view') - >>> browser.headers['X-Caching-Policy'] - 'Cache Media Content' - -Cache Resource --------------- - - >>> browser.open(testing.BASE_URL + '/static-kotti/base.css') - >>> browser.headers['X-Caching-Policy'] - 'Cache Resource' - >>> browser.headers['Cache-Control'] - 'max-age=2764800,public' - >>> d = delta(browser.headers['Expires']) - >>> (d.days, d.seconds) > (30, 0) - True - >>> 'Last-Modified' in browser.headers - True - -POST request ------------- - - >>> browser.post(testing.BASE_URL, '') - >>> 'X-Caching-Policy' in browser.headers - False - ---------- -Logged in ---------- - - >>> browser.open(testing.BASE_URL + '/edit') - >>> "Log in" in browser.contents - True - >>> browser.getControl("Username or email", index=0).value = "admin" - >>> browser.getControl("Password").value = "secret" - >>> browser.getControl(name="submit").click() - >>> "Welcome, Administrator" in browser.contents - True - -Cache HTML ----------- - - >>> browser.open(testing.BASE_URL) - >>> browser.headers['X-Caching-Policy'] - 'No Cache' - -Cache Media Content -------------------- - - >>> browser.open(testing.BASE_URL + '/textfile/inline-view') - >>> browser.headers['X-Caching-Policy'] - 'No Cache' - >>> browser.open(testing.BASE_URL + '/image/inline-view') - >>> browser.headers['X-Caching-Policy'] - 'No Cache' - -Cache Resource --------------- - - >>> browser.open(testing.BASE_URL + '/static-kotti/base.css') - >>> browser.headers['X-Caching-Policy'] - 'Cache Resource' - -=== -404 -=== - - >>> browser.open(testing.BASE_URL + '/this-isnt-here') - Traceback (most recent call last): - HTTPError: HTTP Error 404: Not Found - >>> 'X-Caching-Policy' in browser.headers - False - -TearDown --------- - - >>> testing.tearDown() diff --git a/kotti/tests/test_cache.py b/kotti/tests/test_cache.py index e66b15de6..528468bb1 100644 --- a/kotti/tests/test_cache.py +++ b/kotti/tests/test_cache.py @@ -1,13 +1,34 @@ import datetime +import time from mock import patch from mock import MagicMock import pytest +from kotti.resources import File +from kotti.resources import Image +from kotti.testing import asset from kotti.testing import Dummy from kotti.views.cache import set_max_age +def parse_expires(date_string): + return datetime.datetime(*( + time.strptime(date_string, "%a, %d %b %Y %H:%M:%S GMT")[0:6])) + + +def delta(date_string): + now = datetime.datetime.utcnow() + return parse_expires(date_string) - now + + +@pytest.fixture +def cachetest_content(root, filedepot): + image = asset('sendeschluss.jpg').read() + root['textfile'] = File("file contents", u"mytext.txt", u"text/plain") + root['image'] = Image(image, u"sendeschluss.jpg", u"image/jpeg") + + class TestSetMaxAge: def test_preserve_existing_headers(self): response = Dummy(headers={ @@ -76,3 +97,61 @@ def test_request_has_no_context(self): set_cache_headers(event) assert chooser.call_count == 0 + + +class TestBrowser: + + def test_cache_unauth(self, webtest, cachetest_content): + + # html + resp = webtest.app.get('/') + assert resp.headers.get('X-Caching-Policy') == 'Cache HTML' + assert resp.headers.get('Cache-Control') == 'max-age=0,s-maxage=3600' + d = delta(resp.headers.get('Expires')) + assert (d.days, d.seconds) < (0, 0) + + # media content + resp = webtest.app.get('/textfile/inline-view') + assert resp.headers.get('X-Caching-Policy') == 'Cache Media Content' + assert resp.headers.get('Cache-Control') == 'max-age=14400' + d = delta(resp.headers.get('Expires')) + assert (d.days, d.seconds) > (0, 14000) + resp = webtest.app.get('/image/inline-view') + assert resp.headers.get('X-Caching-Policy') == 'Cache Media Content' + + # resources + resp = webtest.app.get('/static-kotti/base.css') + assert resp.headers.get('X-Caching-Policy') == 'Cache Resource' + assert resp.headers.get('Cache-Control') == 'max-age=2764800,public' + d = delta(resp.headers.get('Expires')) + assert (d.days, d.seconds) > (30, 0) + assert 'Last-Modified' in resp.headers + + # post + resp = webtest.app.post('/', '') + assert 'X-Caching-Policy' not in resp.headers + + # 404 + resp = webtest.app.get('/this-isnt-here', status=404) + assert 'X-Caching-Policy' not in resp.headers + + @pytest.mark.user('admin') + def test_cache_auth(self, webtest, cachetest_content): + + # html + resp = webtest.app.get('/') + assert resp.headers.get('X-Caching-Policy') == 'No Cache' + + # media content + resp = webtest.app.get('/textfile/inline-view') + assert resp.headers.get('X-Caching-Policy') == 'No Cache' + resp = webtest.app.get('/image/inline-view') + assert resp.headers.get('X-Caching-Policy') == 'No Cache' + + # resources + resp = webtest.app.get('/static-kotti/base.css') + assert resp.headers.get('X-Caching-Policy') == 'Cache Resource' + + # 404 + resp = webtest.app.get('/this-isnt-here', status=404) + assert 'X-Caching-Policy' not in resp.headers From 8b8777a517ea25d2f517e139d9b8401c10ff3459 Mon Sep 17 00:00:00 2001 From: Andreas Kaiser Date: Sat, 10 Oct 2015 01:49:22 +0200 Subject: [PATCH 4/4] Replace browser-errors.txt with equivalent webtest tests. --- kotti/tests/browser-errors.txt | 45 ------------------------------ kotti/tests/test_httpexceptions.py | 16 +++++++++++ 2 files changed, 16 insertions(+), 45 deletions(-) delete mode 100644 kotti/tests/browser-errors.txt create mode 100644 kotti/tests/test_httpexceptions.py diff --git a/kotti/tests/browser-errors.txt b/kotti/tests/browser-errors.txt deleted file mode 100644 index a28ecf618..000000000 --- a/kotti/tests/browser-errors.txt +++ /dev/null @@ -1,45 +0,0 @@ -Kotti HTTP Exception browser tests -================================== - -Setup ------ -Create references to some useful tools: - - >>> from kotti import testing - >>> tools = testing.setUpFunctional() - >>> browser = tools['Browser']() - >>> ctrl = browser.getControl - -Tell the zope test browser to not raise errors for HTTP exceptions: - - >>> browser.raiseHttpErrors = False - -Open the front page: - - >>> browser.open(testing.BASE_URL) - - -HTTP Not Found (404) --------------------- -A 404 Not Found view results in a nicely formatted, albeit plain page: - - >>> browser.open(testing.BASE_URL + '/non-existent') - >>> 'Not Found' in browser.contents - True - -The not found view renders similarly for authenticated users. - -After logging in: - - >>> browser.open(testing.BASE_URL + '/login') - >>> ctrl("Username or email", index=0).value = "admin" - >>> ctrl("Password").value = "secret" - >>> ctrl(name="submit").click() - -We should see the error message when visiting a URL that does not exist: - - >>> browser.open(testing.BASE_URL + '/non-existent') - >>> 'Not Found' in browser.contents - True - - diff --git a/kotti/tests/test_httpexceptions.py b/kotti/tests/test_httpexceptions.py new file mode 100644 index 000000000..2712d6a54 --- /dev/null +++ b/kotti/tests/test_httpexceptions.py @@ -0,0 +1,16 @@ +""" Kotti HTTP Exception browser tests """ + +import pytest + + +def test_404_anon(webtest, root): + + resp = webtest.app.get('/non-existent', status=404) + assert 'Not Found' in resp.text + + +@pytest.mark.user('admin') +def test_404_anon(webtest, root): + + resp = webtest.app.get('/non-existent', status=404) + assert 'Not Found' in resp.text