def setUp(self): self.app = Holocron(conf={ 'sitename': 'MyTestSite', 'siteurl': 'www.mytest.com', 'author': 'Tester', 'encoding': { 'output': 'my-enc', }, 'paths': { 'output': 'path/to/output', }, 'ext': { 'enabled': [], 'tags': { 'output': 'mypath/tags/{tag}', }, }, }) self.tags = Tags(self.app) self.date_early = datetime(2012, 2, 2) self.date_moderate = datetime(2013, 4, 1) self.date_late = datetime(2014, 6, 12) self.post_early = mock.Mock( spec=Post, published=self.date_early, tags=['testtag1', 'testtag2'], title='MyTestPost', url='www.post_early.com') self.post_moderate = mock.Mock( spec=Post, published=self.date_moderate, url='www.post_moderate.com', tags=['testtag2', 'testtag3']) self.post_late = mock.Mock( spec=Post, published=self.date_late, url='www.post_late.com', tags=['testtag2']) self.post_malformed = mock.Mock( spec=Post, short_source='test', tags='testtag') self.page = mock.Mock(spec=Page) self.static = mock.Mock(spec=Static) self.open_fn = 'holocron.ext.tags.open'
class TestTagsGenerator(HolocronTestCase): """ Test tags generator. """ #: generate html headers with years that is used for grouping in templates h_year = '<span class="year">{0}</span>'.format def setUp(self): self.app = Holocron(conf={ 'sitename': 'MyTestSite', 'siteurl': 'www.mytest.com', 'author': 'Tester', 'encoding': { 'output': 'my-enc', }, 'paths': { 'output': 'path/to/output', }, 'ext': { 'enabled': [], 'tags': { 'output': 'mypath/tags/{tag}', }, }, }) self.tags = Tags(self.app) self.date_early = datetime(2012, 2, 2) self.date_moderate = datetime(2013, 4, 1) self.date_late = datetime(2014, 6, 12) self.post_early = mock.Mock( spec=Post, published=self.date_early, tags=['testtag1', 'testtag2'], title='MyTestPost', url='www.post_early.com') self.post_moderate = mock.Mock( spec=Post, published=self.date_moderate, url='www.post_moderate.com', tags=['testtag2', 'testtag3']) self.post_late = mock.Mock( spec=Post, published=self.date_late, url='www.post_late.com', tags=['testtag2']) self.post_malformed = mock.Mock( spec=Post, short_source='test', tags='testtag') self.page = mock.Mock(spec=Page) self.static = mock.Mock(spec=Static) self.open_fn = 'holocron.ext.tags.open' @mock.patch('holocron.ext.tags.mkdir', mock.Mock()) def _get_content(self, documents): """ This helper method mocks the open function and return the content passed as input to write function. """ with mock.patch(self.open_fn, mock.mock_open(), create=True) as mopen: self.tags.generate(documents) # extract what was generated and what was passed to f.write() content, = mopen().write.call_args[0] return content @mock.patch('holocron.ext.tags.mkdir') def _get_tags_content(self, documents, mock_mkdir): with mock.patch(self.open_fn, mock.mock_open(), create=True) as mopen: self.tags.generate(documents) open_calls = [c[0][0] for c in mopen.call_args_list if c != ''] write_calls = [c[0][0] for c in mopen().write.call_args_list] mkdir_calls = [c[0][0] for c in mock_mkdir.call_args_list] # form a tuple that contains corresponding open and write calls # and sort it aplhabetically, so the testtag1 comes first content = list(zip(open_calls, write_calls, mkdir_calls)) content.sort() return content def test_tag_template_building(self): """ Test that tags function writes a post to a tag template. """ posts = [self.post_early, self.post_moderate] content = self._get_tags_content(posts) # check that open, write and mkdir functions were called three times # according to the number of different tags in test documents for entry in content: self.assertEqual(len(entry), 3) # test that output html contains early_post with its unique tag self.assertEqual( 'path/to/output/mypath/tags/testtag1/index.html', content[0][0]) self.assertIn(self.h_year(2012), content[0][1]) self.assertIn('<a href="www.post_early.com">', content[0][1]) self.assertEqual('path/to/output/mypath/tags/testtag1', content[0][2]) # test that output html contains posts with common tag self.assertEqual( 'path/to/output/mypath/tags/testtag2/index.html', content[1][0]) self.assertIn(self.h_year(2012), content[1][1]) self.assertIn(self.h_year(2013), content[1][1]) self.assertIn('<a href="www.post_early.com">', content[1][1]) self.assertIn('<a href="www.post_moderate.com">', content[1][1]) self.assertEqual('path/to/output/mypath/tags/testtag2', content[1][2]) # test that output html contains moderate_post with its unique tag self.assertEqual( 'path/to/output/mypath/tags/testtag3/index.html', content[2][0]) self.assertIn(self.h_year(2013), content[2][1]) self.assertIn('<a href="www.post_moderate.com">', content[2][1]) self.assertEqual('path/to/output/mypath/tags/testtag3', content[2][2]) def test_sorting_out_mixed_documents(self): """ Test that Tags sorts out post documents from documents of other types. """ documents = [self.page, self.static, self.post_late] content = self._get_content(documents) self.assertIn(self.h_year(2014), content) self.assertIn('<a href="www.post_late.com">', content) def test_posts_patching_with_tag_objects(self): """ Test that Tags patches post's tags attribute. """ posts = [self.post_late] self._get_tags_content(posts) self.assertEquals(self.post_late.tags[0].name, 'testtag2') self.assertEquals(self.post_late.tags[0].url, '/mypath/tags/testtag2/') @mock.patch('holocron.content.os.mkdir', mock.Mock()) @mock.patch('holocron.content.os.path.getmtime') @mock.patch('holocron.content.os.path.getctime') def test_tags_are_shown_in_post(self, _, __): """ Test that tags are actually get to the output. """ # since we're interested in rendered page, let's register # a fake converter for that purpose self.app.add_converter(FakeConverter()) data = textwrap.dedent('''\ --- tags: [tag1, tag2] --- some text''') open_fn = 'holocron.content.open' with mock.patch(open_fn, mock.mock_open(read_data=data), create=True): post = Post('2015/05/23/filename.fake', self.app) self._get_content([post]) with mock.patch(open_fn, mock.mock_open(), create=True) as mopen: post.build() content = mopen().write.call_args[0][0] err = 'Could not find link for #tag1.' self.assertIn('<a href="/mypath/tags/tag1/">#tag1</a>', content, err) err = 'Could not find link for #tag2.' self.assertIn('<a href="/mypath/tags/tag2/">#tag2</a>', content, err) @mock.patch('holocron.ext.tags.mkdir') def test_malformed_tags_are_skipped(self, mock_mkdir): """ Test if tags formatting is correct. """ content = self._get_tags_content([self.post_malformed]) self.assertEqual(content, [])