|
1 # -*- coding: utf-8 -*- |
|
2 # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
3 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
4 # |
|
5 # This file is part of CubicWeb. |
|
6 # |
|
7 # CubicWeb is free software: you can redistribute it and/or modify it under the |
|
8 # terms of the GNU Lesser General Public License as published by the Free |
|
9 # Software Foundation, either version 2.1 of the License, or (at your option) |
|
10 # any later version. |
|
11 # |
|
12 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
|
13 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
14 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
|
15 # details. |
|
16 # |
|
17 # You should have received a copy of the GNU Lesser General Public License along |
|
18 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
|
19 from contextlib import contextmanager |
|
20 |
1 from logilab.common import tempattr |
21 from logilab.common import tempattr |
2 from logilab.common.testlib import tag, Tags |
22 from logilab.common.testlib import Tags |
3 from cubicweb.devtools.testlib import CubicWebTC |
23 from cubicweb.devtools.testlib import CubicWebTC |
4 |
24 |
5 import os |
25 import os |
6 import os.path as osp |
26 import os.path as osp |
7 import glob |
27 import glob |
8 |
28 |
9 from cubicweb.utils import HTMLHead |
29 from cubicweb.utils import HTMLHead |
10 from cubicweb.web.views.staticcontrollers import ConcatFilesHandler |
30 from cubicweb.web.views.staticcontrollers import ConcatFilesHandler |
11 |
31 |
12 class StaticControllerCacheTC(CubicWebTC): |
32 class staticfilespublishermixin(object): |
13 |
33 |
|
34 @contextmanager |
|
35 def _publish_static_files(self, url, header={}): |
|
36 with self.admin_access.web_request(headers=header) as req: |
|
37 req._url = url |
|
38 self.app_handle_request(req, url) |
|
39 yield req |
|
40 |
|
41 class StaticControllerCacheTC(staticfilespublishermixin, CubicWebTC): |
14 tags = CubicWebTC.tags | Tags('static_controller', 'cache', 'http') |
42 tags = CubicWebTC.tags | Tags('static_controller', 'cache', 'http') |
15 |
43 |
16 |
|
17 def _publish_static_files(self, url, header={}): |
|
18 req = self.request(headers=header) |
|
19 req._url = url |
|
20 return self.app_handle_request(req, url), req |
|
21 |
|
22 def test_static_file_are_cached(self): |
44 def test_static_file_are_cached(self): |
23 _, req = self._publish_static_files('data/cubicweb.css') |
45 with self._publish_static_files('data/cubicweb.css') as req: |
24 self.assertEqual(200, req.status_out) |
46 self.assertEqual(200, req.status_out) |
25 self.assertIn('last-modified', req.headers_out) |
47 self.assertIn('last-modified', req.headers_out) |
26 next_headers = { |
48 next_headers = { |
27 'if-modified-since': req.get_response_header('last-modified', raw=True), |
49 'if-modified-since': req.get_response_header('last-modified', raw=True), |
28 } |
50 } |
29 _, req = self._publish_static_files('data/cubicweb.css', next_headers) |
51 with self._publish_static_files('data/cubicweb.css', next_headers) as req: |
30 self.assertEqual(304, req.status_out) |
52 self.assertEqual(304, req.status_out) |
31 |
53 |
32 |
54 |
33 |
55 |
34 class DataControllerTC(CubicWebTC): |
56 class DataControllerTC(staticfilespublishermixin, CubicWebTC): |
35 |
|
36 tags = CubicWebTC.tags | Tags('static_controller', 'data', 'http') |
57 tags = CubicWebTC.tags | Tags('static_controller', 'data', 'http') |
37 |
58 |
38 def _publish_static_files(self, url, header={}): |
|
39 req = self.request(headers=header) |
|
40 req._url = url |
|
41 return self.app_handle_request(req, url), req |
|
42 |
|
43 def _check_datafile_ok(self, fname): |
59 def _check_datafile_ok(self, fname): |
44 _, req = self._publish_static_files(fname) |
60 with self._publish_static_files(fname) as req: |
45 self.assertEqual(200, req.status_out) |
61 self.assertEqual(200, req.status_out) |
46 self.assertIn('last-modified', req.headers_out) |
62 self.assertIn('last-modified', req.headers_out) |
47 next_headers = { |
63 next_headers = { |
48 'if-modified-since': req.get_response_header('last-modified', raw=True), |
64 'if-modified-since': req.get_response_header('last-modified', raw=True), |
49 } |
65 } |
50 _, req = self._publish_static_files(fname, next_headers) |
66 with self._publish_static_files(fname, next_headers) as req: |
51 self.assertEqual(304, req.status_out) |
67 self.assertEqual(304, req.status_out) |
52 |
68 |
53 def _check_no_datafile(self, fname): |
69 def _check_no_datafile(self, fname): |
54 _, req = self._publish_static_files(fname) |
70 with self._publish_static_files(fname) as req: |
55 self.assertEqual(404, req.status_out) |
71 self.assertEqual(404, req.status_out) |
56 |
72 |
57 def test_static_data_mode(self): |
73 def test_static_data_mode(self): |
58 hash = self.vreg.config.instance_md5_version() |
74 hash = self.vreg.config.instance_md5_version() |
59 self.assertEqual(32, len(hash)) |
75 self.assertEqual(32, len(hash)) |
60 |
76 |
81 def _cleanup_concat_cache(self): |
97 def _cleanup_concat_cache(self): |
82 uicachedir = osp.join(self.config.apphome, 'uicache') |
98 uicachedir = osp.join(self.config.apphome, 'uicache') |
83 for fname in glob.glob(osp.join(uicachedir, 'cache_concat_*')): |
99 for fname in glob.glob(osp.join(uicachedir, 'cache_concat_*')): |
84 os.unlink(osp.join(uicachedir, fname)) |
100 os.unlink(osp.join(uicachedir, fname)) |
85 |
101 |
|
102 @contextmanager |
86 def _publish_js_files(self, js_files): |
103 def _publish_js_files(self, js_files): |
87 req = self.request() |
104 with self.admin_access.web_request() as req: |
88 head = HTMLHead(req) |
105 head = HTMLHead(req) |
89 url = head.concat_urls([req.data_url(js_file) for js_file in js_files])[len(req.base_url()):] |
106 url = head.concat_urls([req.data_url(js_file) |
90 req._url = url |
107 for js_file in js_files])[len(req.base_url()):] |
91 return self.app_handle_request(req, url), req |
108 req._url = url |
|
109 res = self.app_handle_request(req, url) |
|
110 yield res, req |
92 |
111 |
93 def expected_content(self, js_files): |
112 def expected_content(self, js_files): |
94 content = u'' |
113 content = u'' |
95 for js_file in js_files: |
114 for js_file in js_files: |
96 dirpath, rid = self.config.locate_resource(js_file) |
115 dirpath, rid = self.config.locate_resource(js_file) |
99 content += f.read() + '\n' |
118 content += f.read() + '\n' |
100 return content |
119 return content |
101 |
120 |
102 def test_cache(self): |
121 def test_cache(self): |
103 js_files = ('cubicweb.ajax.js', 'jquery.js') |
122 js_files = ('cubicweb.ajax.js', 'jquery.js') |
104 result, req = self._publish_js_files(js_files) |
123 with self._publish_js_files(js_files) as (result, req): |
105 self.assertNotEqual(404, req.status_out) |
124 self.assertNotEqual(404, req.status_out) |
106 # check result content |
125 # check result content |
107 self.assertEqual(result, self.expected_content(js_files)) |
126 self.assertEqual(result, self.expected_content(js_files)) |
108 # make sure we kept a cached version on filesystem |
127 # make sure we kept a cached version on filesystem |
109 concat_hander = ConcatFilesHandler(self.config) |
128 concat_hander = ConcatFilesHandler(self.config) |
110 filepath = concat_hander.build_filepath(js_files) |
129 filepath = concat_hander.build_filepath(js_files) |
111 self.assertTrue(osp.isfile(filepath)) |
130 self.assertTrue(osp.isfile(filepath)) |
112 |
131 |
113 |
132 |
114 def test_invalid_file_in_debug_mode(self): |
133 def test_invalid_file_in_debug_mode(self): |
115 js_files = ('cubicweb.ajax.js', 'dummy.js') |
134 js_files = ('cubicweb.ajax.js', 'dummy.js') |
116 # in debug mode, an error is raised |
135 # in debug mode, an error is raised |
117 self.config.debugmode = True |
136 self.config.debugmode = True |
118 try: |
137 try: |
119 result, req = self._publish_js_files(js_files) |
138 with self._publish_js_files(js_files) as (result, req): |
120 #print result |
139 #print result |
121 self.assertEqual(404, req.status_out) |
140 self.assertEqual(404, req.status_out) |
122 finally: |
141 finally: |
123 self.config.debugmode = False |
142 self.config.debugmode = False |
124 |
143 |
125 def test_invalid_file_in_production_mode(self): |
144 def test_invalid_file_in_production_mode(self): |
126 js_files = ('cubicweb.ajax.js', 'dummy.js') |
145 js_files = ('cubicweb.ajax.js', 'dummy.js') |
127 result, req = self._publish_js_files(js_files) |
146 with self._publish_js_files(js_files) as (result, req): |
128 self.assertNotEqual(404, req.status_out) |
147 self.assertNotEqual(404, req.status_out) |
129 # check result content |
148 # check result content |
130 self.assertEqual(result, self.expected_content(js_files)) |
149 self.assertEqual(result, self.expected_content(js_files)) |
131 |
150 |
132 |
151 |
133 if __name__ == '__main__': |
152 if __name__ == '__main__': |
134 from logilab.common.testlib import unittest_main |
153 from logilab.common.testlib import unittest_main |
135 unittest_main() |
154 unittest_main() |