def test_publish_from_path_hard_links_stale_file(self): instance = StaticGenerator() instance.publish_from_path('/some_path', content='some_content') self.assertEqual(os.stat('test_web_root/fresh/some_path').st_ino, os.stat('test_web_root/stale/some_path').st_ino)
def test_extract_resources_when_resource_is_a_model(): mox = Mox() http_request, model_base, manager, model, queryset = get_mocks(mox) class Model(object): def get_absolute_url(self): return 'some_model_url' resources_mock = Model() model = Model settings = CustomSettings(WEB_ROOT="some_web_root") mox.ReplayAll() instance = StaticGenerator(resources_mock, http_request=http_request, model_base=model_base, manager=manager, model=model, queryset=queryset, settings=settings) assert len(instance.resources) == 1 assert instance.resources[0] == 'some_model_url' mox.VerifyAll()
def test_delete_from_path(): mox = Mox() http_request, model_base, manager, model, queryset = get_mocks(mox) fs_mock = mox.CreateMockAnything() fs_mock.join("test_web_root", "some_path/index.html").AndReturn("test_web_root/some_path") fs_mock.dirname("test_web_root/some_path").AndReturn("test_web_root") fs_mock.exists("test_web_root/some_path").AndReturn(True) fs_mock.remove("test_web_root/some_path") fs_mock.rmdir("test_web_root") settings = CustomSettings(WEB_ROOT="test_web_root") mox.ReplayAll() instance = StaticGenerator(http_request=http_request, model_base=model_base, manager=manager, model=model, queryset=queryset, settings=settings, fs=fs_mock) instance.delete_from_path("some_path") mox.VerifyAll()
def test_publish_from_path_creates_current_file(self): instance = StaticGenerator() instance.publish_from_path('/some_path', content='some_content') self.assertEqual('some_content', open('test_web_root/fresh/some_path').read())
def test_publish_raises_when_unable_to_create_folder(): mox = Mox() http_request, model_base, manager, model, queryset = get_mocks(mox) fs_mock = mox.CreateMockAnything() fs_mock.join("test_web_root", "some_path").AndReturn("test_web_root/some_path") fs_mock.dirname("test_web_root/some_path").AndReturn("test_web_root") fs_mock.exists("test_web_root").AndReturn(False) fs_mock.makedirs("test_web_root").AndRaise(ValueError()) settings = CustomSettings(WEB_ROOT="test_web_root") mox.ReplayAll() instance = StaticGenerator(http_request=http_request, model_base=model_base, manager=manager, model=model, queryset=queryset, settings=settings, fs=fs_mock) try: instance.publish_from_path("some_path", content="some_content") except StaticGeneratorException, e: assert str(e) == 'Could not create the directory: test_web_root' mox.VerifyAll() return
def test_extract_resources_when_resource_is_a_str(self): resources_mock = "some_str" instance = StaticGenerator(resources_mock) self.assertEqual(1, len(instance.resources)) self.assertEqual('some_str', instance.resources[0])
def test_extract_resources_when_resource_is_a_model(self): resources_mock = Model(url='some_model_url') instance = StaticGenerator(resources_mock) self.assertEqual(1, len(instance.resources)) self.assertEqual('some_model_url', instance.resources[0])
def test_delete_raises_when_unable_to_delete_file(): mox = Mox() http_request, model_base, manager, model, queryset = get_mocks(mox) fs_mock = mox.CreateMockAnything() fs_mock.join("test_web_root", "some_path").AndReturn("test_web_root/some_path") fs_mock.dirname("test_web_root/some_path").AndReturn("test_web_root") fs_mock.exists("test_web_root/some_path").AndReturn(True) fs_mock.remove("test_web_root/some_path").AndRaise(ValueError()) settings = CustomSettings(WEB_ROOT="test_web_root") mox.ReplayAll() instance = StaticGenerator(http_request=http_request, model_base=model_base, manager=manager, model=model, queryset=queryset, settings=settings, fs=fs_mock) try: instance.delete_from_path("some_path") except StaticGeneratorException, e: assert str(e) == 'Could not delete file: test_web_root/some_path' mox.VerifyAll() return
def test_publish_from_path(): mox = Mox() http_request, model_base, manager, model, queryset = get_mocks(mox) fs_mock = mox.CreateMockAnything() fs_mock.join("test_web_root", "some_path").AndReturn("test_web_root/some_path") fs_mock.dirname("test_web_root/some_path").AndReturn("test_web_root") fs_mock.exists("test_web_root").AndReturn(True) f = mox.CreateMockAnything() filename = "some_temp_file" fs_mock.tempfile(directory="test_web_root").AndReturn([f, filename]) fs_mock.write(f, "some_content") fs_mock.close(f) fs_mock.chmod(filename, stat.S_IREAD | stat.S_IWRITE | stat.S_IWUSR | stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) fs_mock.rename('some_temp_file', 'test_web_root/some_path') settings = CustomSettings(WEB_ROOT="test_web_root") mox.ReplayAll() instance = StaticGenerator(http_request=http_request, model_base=model_base, manager=manager, model=model, queryset=queryset, settings=settings, fs=fs_mock) instance.publish_from_path("some_path", content="some_content") mox.VerifyAll()
def test_delete_ignores_folder_delete_when_unable_to_delete_folder(): mox = Mox() http_request, model_base, manager, model, queryset = get_mocks(mox) fs_mock = mox.CreateMockAnything() fs_mock.join("test_web_root", "some_path").AndReturn("test_web_root/some_path") fs_mock.dirname("test_web_root/some_path").AndReturn("test_web_root") fs_mock.exists("test_web_root/some_path").AndReturn(True) fs_mock.remove("test_web_root/some_path") fs_mock.rmdir("test_web_root").AndRaise(OSError()) settings = CustomSettings(WEB_ROOT="test_web_root") mox.ReplayAll() instance = StaticGenerator(http_request=http_request, model_base=model_base, manager=manager, model=model, queryset=queryset, settings=settings, fs=fs_mock) instance.delete_from_path("some_path") assert True, "Should work even when raising OSError"
def test_delete_loops_through_all_resources(): mox = Mox() http_request, model_base, manager, model, queryset = get_mocks(mox) fs_mock = mox.CreateMockAnything() fs_mock.join('test_web_root', 'some_path').AndReturn("test_web_root/some_path") fs_mock.dirname("test_web_root/some_path").AndReturn("test_web_root") fs_mock.exists("test_web_root/some_path").AndReturn(True) fs_mock.remove("test_web_root/some_path") fs_mock.rmdir("test_web_root") fs_mock.join('test_web_root', 'some_path_2').AndReturn("test_web_root/some_path_2") fs_mock.dirname('test_web_root/some_path_2').AndReturn("test_web_root") fs_mock.exists("test_web_root/some_path_2").AndReturn(True) fs_mock.remove("test_web_root/some_path_2") fs_mock.rmdir("test_web_root") settings = CustomSettings(WEB_ROOT="test_web_root") mox.ReplayAll() instance = StaticGenerator("some_path", "some_path_2", http_request=http_request, model_base=model_base, manager=manager, model=model, queryset=queryset, settings=settings, fs=fs_mock) instance.delete() mox.VerifyAll()
def test_get_filename_from_path_when_path_ends_with_slash(): mox = Mox() http_request, model_base, manager, model, queryset = get_mocks(mox) settings = CustomSettings(WEB_ROOT="test_web_root") fs_mock = mox.CreateMockAnything() fs_mock.join("test_web_root", "foo/bar/index.html").AndReturn("test_web_root/foo/bar/index.html") fs_mock.dirname("test_web_root/foo/bar/index.html").AndReturn("test_web_root/foo/bar") path_mock = '/foo/bar/' mox.ReplayAll() instance = StaticGenerator(http_request=http_request, model_base=model_base, manager=manager, model=model, queryset=queryset, settings=settings, fs=fs_mock) result = instance.get_filename_from_path(path_mock) assert result == ('test_web_root/foo/bar/index.html', 'test_web_root/foo/bar') mox.VerifyAll()
class StaticGeneratorMiddleware(object): """ This requires settings.STATIC_GENERATOR_URLS tuple to match on URLs Example:: STATIC_GENERATOR_URLS = ( r'^/$', r'^/blog', ) """ urls = tuple([re.compile(url) for url in settings.STATIC_GENERATOR_URLS]) gen = StaticGenerator() def process_response(self, request, response): if not getattr(settings, 'ENABLE_STATIC_GENERATOR', False): return response if response.status_code == 200: for url in self.urls: if url.match(request.path_info): self.gen.publish_from_path(request.path_info, response.content) break return response
def test_get_server_name_gets_name_from_site(self): with patch('django.contrib.sites.models' '.Site.objects.get_current') as get_current: get_current().domain = 'custom_domain' instance = StaticGenerator() self.assertEqual('custom_domain', instance.server_name)
def test_publish_fails_silently_when_unable_to_rename_temp_file(self): instance = StaticGenerator() with patch('os.rename') as rename: rename.side_effect = ValueError('message') instance.publish_from_path('/some_path', content='some_content') self.assertFalse(os.path.exists('test_web_root/fresh/some_path'))
def test_get_content_from_path(self): response_mock = Mock(content='foo', status_code=200) instance = StaticGenerator() with patch.object(staticgenerator, 'DummyHandler') as DummyHandler: DummyHandler().return_value = response_mock result = instance.get_content_from_path('/some_path') self.assertEqual('foo', result)
def test_publish_loops_through_all_resources(): mox = Mox() http_request, model_base, manager, model, queryset = get_mocks(mox) fs_mock = mox.CreateMockAnything() f = mox.CreateMockAnything() fs_mock.join( 'test_web_root', 'some_path_1/index.html').AndReturn('test_web_root/some_path_1') fs_mock.dirname('test_web_root/some_path_1').AndReturn('test_web_root') fs_mock.exists("test_web_root").AndReturn(True) filename = "some_temp_file" fs_mock.tempfile(directory="test_web_root").AndReturn([f, filename]) fs_mock.write(f, "some_content") fs_mock.close(f) fs_mock.chmod( filename, stat.S_IREAD | stat.S_IWRITE | stat.S_IWUSR | stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) fs_mock.rename('some_temp_file', 'test_web_root/some_path_1') fs_mock.join( 'test_web_root', 'some_path_2/index.html').AndReturn('test_web_root/some_path_2') fs_mock.dirname('test_web_root/some_path_2').AndReturn('test_web_root') fs_mock.exists("test_web_root").AndReturn(True) filename = "some_temp_file" fs_mock.tempfile(directory="test_web_root").AndReturn([f, filename]) fs_mock.write(f, "some_content") fs_mock.close(f) fs_mock.chmod( filename, stat.S_IREAD | stat.S_IWRITE | stat.S_IWUSR | stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) fs_mock.rename('some_temp_file', 'test_web_root/some_path_2') settings = CustomSettings(WEB_ROOT="test_web_root") mox.ReplayAll() try: get_content_from_path = StaticGenerator.get_content_from_path StaticGenerator.get_content_from_path = lambda self, path: "some_content" instance = StaticGenerator("some_path_1", "some_path_2", http_request=http_request, model_base=model_base, manager=manager, model=model, queryset=queryset, settings=settings, fs=fs_mock) instance.publish() mox.VerifyAll() finally: StaticGenerator.get_content_from_path = get_content_from_path
def test_delete_ignores_folder_delete_when_unable_to_delete_folder(self): instance = StaticGenerator() rmdir = Mock(side_effect=OSError) with nested(patch('os.path.exists', Mock(return_value=True)), patch('os.remove'), patch('os.rmdir', rmdir)): instance.delete_from_path('/some_path') rmdir.assert_called_once_with('test_web_root/fresh')
def test_delete_from_path_deletes_current_file(self): instance = StaticGenerator() remove = Mock() with nested(patch('os.path.exists', Mock(return_value=True)), patch('os.remove', remove)): instance.delete_from_path('/some_path') remove.assert_has_calls([call('test_web_root/fresh/some_path'), call('test_web_root/fresh/some_path.gz')])
def test_delete_from_path_does_not_delete_stale_file(self): instance = StaticGenerator() remove = Mock() with nested(patch('os.path.exists', Mock(return_value=True)), patch('os.remove', remove)): instance.delete_from_path('/some_path') self.assertNotIn(call('test_web_root/stale/some_path'), remove.call_args_list)
class StaticGeneratorMiddleware(object): """ This requires settings.STATIC_GENERATOR_URLS tuple to match on URLs Example:: STATIC_GENERATOR_URLS = ( r'^/$', r'^/blog', ) """ urls = tuple([re.compile(url) for url in settings.STATIC_GENERATOR_URLS]) excluded_urls = tuple([ re.compile(url) for url in getattr(settings, 'STATIC_GENERATOR_EXCLUDE_URLS', []) ]) exclude_params = dict( (key, 1) for key in getattr(settings, 'STATIC_GENERATOR_EXCLUDE_PARAMS', [])) gen = StaticGenerator() def process_response(self, request, response): path = request.path_info query_string = request.META.get('QUERY_STRING', '') if response.status_code == 200: if (getattr(settings, 'STATIC_GENERATOR_ANONYMOUS_ONLY', False) and not request.user.is_anonymous()): print "Not anonymous" return response excluded = False for url in self.excluded_urls: if url.match(path): excluded = True print "Excluding this url" break intersect = list( set(request.GET.keys()) & set(getattr(settings, 'STATIC_GENERATOR_EXCLUDE_PARAMS', [])) ) if len(intersect) > 0: print "Excluding because of params" excluded = True if not excluded: for url in self.urls: if url.match(path): print "Generating cache file" self.gen.publish_from_path(path, query_string, response.content) break return response
class StaticGeneratorMiddleware(object): """ This requires settings.STATIC_GENERATOR_URLS tuple to match on URLs Example:: STATIC_GENERATOR_URLS = ( r'^/$', r'^/blog', ) """ urls = tuple([re.compile(url) for url in settings.STATIC_GENERATOR_URLS]) excluded_urls = tuple([ re.compile(url) for url in getattr(settings, 'STATIC_GENERATOR_EXCLUDE_URLS', []) ]) excluded_queries = tuple([ re.compile(url) for url in getattr(settings, 'STATIC_GENERATOR_EXCLUDE_QUERIES', []) ]) # this is a bit of a blunt interim instrument - needs design decision gen = StaticGenerator() def process_response(self, request, response): path = request.path_info query_string = request.META.get('QUERY_STRING', '') if response.status_code == 200: if getattr(settings, 'STATIC_GENERATOR_ANONYMOUS_ONLY', False) and not request.user.is_anonymous(): return response excluded = False for url in self.excluded_urls: if url.match(path): excluded = True break for qstring in self.excluded_queries: if qstring.search(query_string): excluded = True break if not excluded: for url in self.urls: if url.match(path): if request.GET.get('format') == 'xml': self.gen.publish_from_path(path, query_string, response.content, 'xml') else: self.gen.publish_from_path(path, query_string, response.content) break return response
def test_publish_raises_when_unable_to_create_temp_file(self): instance = StaticGenerator() with nested(patch('tempfile.mkstemp'), self.assertRaises(StaticGeneratorException) ) as (mkstemp, cm): mkstemp.side_effect = ValueError('message') instance.publish_from_path('/some_path', content='some_content') self.assertEqual('Could not write temporary fresh file', str(cm.exception)) self.assertEqual('test_web_root/fresh', cm.exception.fresh_directory)
def test_get_lang_aware_filename_from_path_when_path_ends_with_slash(self): for lang in ('uk', 'ru'): # activate first non-default language if lang != settings.LANGUAGE_CODE: activate('ru') instance = StaticGenerator() result = instance.get_filename_from_path('/foo/bar/', '') self.assertEqual('test_web_root/foo/bar/{}.index.html%3F'.format(lang), result)
def test_publish_raises_when_unable_to_hard_link_stale_file(self): instance = StaticGenerator() with nested(patch('os.link'), self.assertRaises(StaticGeneratorException) ) as (link, cm): link.side_effect = OSError(2, 'message') instance.publish_from_path('/some_path', content='some_content') self.assertEqual('Could not link file', str(cm.exception)) self.assertEqual('test_web_root/fresh/some_path', cm.exception.src) self.assertEqual('test_web_root/stale/some_path', cm.exception.dst)
def test_publish_loops_through_all_resources(self): instance = StaticGenerator('/some_path_1', '/some_path_2') rename = Mock(wraps=os.rename) with nested(patch('os.rename', rename), patch.object(instance, 'get_content_from_path', Mock(return_value='some_content'))): instance.publish() rename.assert_has_calls([ call(ANY, 'test_web_root/fresh/some_path_1'), call(ANY, 'test_web_root/fresh/some_path_2')])
def test_extract_resources_when_resource_is_a_model_base(self): instance_mock = Model(url='some_url1') instance_mock2 = Model(url='some_url2') queryset = queryset_mock_factory(instance_mock, instance_mock2) with patch.object(Model.objects, 'all') as model_objects_all: model_objects_all.return_value = queryset instance = StaticGenerator(Model) self.assertEqual(2, len(instance.resources)) self.assertEqual('some_url1', instance.resources[0]) self.assertEqual('some_url2', instance.resources[1])
def test_not_found_raises_proper_exception(self): response_mock = Mock(content='foo', status_code=404) instance = StaticGenerator() with nested(patch('staticgenerator.DummyHandler'), self.assertRaises(StaticGeneratorException) ) as (handler_mock, cm): handler_mock.return_value = Mock(return_value=response_mock) instance.get_content_from_path('/some_path') self.assertEqual(('The requested page("/some_path") returned ' 'http code 404. Static Generation failed.'), str(cm.exception))
def test_publish_raises_when_unable_to_create_current_folder(self): instance = StaticGenerator() with nested(patch('os.path.exists'), patch('os.makedirs'), self.assertRaises(StaticGeneratorException) ) as (exists, makedirs, cm): exists.return_value = False makedirs.side_effect = ValueError('message') instance.publish_from_path('/some_path', content='some_content') self.assertEqual('Could not create directory', str(cm.exception)) self.assertEqual('test_web_root/fresh', cm.exception.directory)
def test_request_exception_raises_proper_exception(self): instance = StaticGenerator() with nested(patch('staticgenerator.DummyHandler'), self.assertRaises(StaticGeneratorException) ) as (handler_mock, cm): handler_mock.return_value = Mock( side_effect=ValueError('exception')) instance.get_content_from_path('/some_path') self.assertEqual('The requested page("/some_path") raised an ' 'exception. Static Generation failed. ' 'Error: exception', str(cm.exception))