# -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import
import os
import sys
import unittest
import mock
import nikola
import nikola.plugins.command.import_wordpress
from .base import BaseTestCase
class BasicCommandImportWordpress(BaseTestCase):
def setUp(self):
self.module = nikola.plugins.command.import_wordpress
self.import_command = self.module.CommandImportWordpress()
self.import_filename = os.path.abspath(os.path.join(
os.path.dirname(__file__), 'wordpress_export_example.xml'))
def tearDown(self):
del self.import_command
del self.import_filename
class TestXMLGlueing(BasicCommandImportWordpress):
def test_making_correct_newlines(self):
xml = [b"Some information about how to (un)subscripe to a google group with a normal mail client.\n",
b"
\n",
b" - to post: groupname@googlegroups.com
\n",
b" - to subscribe: groupname+subscribe@googlegroups.com
\n",
b" - to unsubscribe: groupname+unsubscribe@googlegroups.com
\n",
b"
\n",
b"Easy.\n"]
expected_xml = b"""Some information about how to (un)subscripe to a google group with a normal mail client.
- to post: groupname@googlegroups.com
- to subscribe: groupname+subscribe@googlegroups.com
- to unsubscribe: groupname+unsubscribe@googlegroups.com
Easy.
"""
self.assertEqual(expected_xml, self.import_command._glue_xml_lines(xml))
class TestQTranslateContentSeparation(BasicCommandImportWordpress):
def test_conserves_qtranslate_less_post(self):
content = """Si vous préférez savoir à qui vous parlez commencez par visiter l'À propos.
Quoiqu'il en soit, commentaires, questions et suggestions sont les bienvenues !"""
content_translations = self.module.separate_qtranslate_content(content)
self.assertEqual(1, len(content_translations))
self.assertEqual(content, content_translations[""])
def test_split_a_two_language_post(self):
content = """Si vous préférez savoir à qui vous parlez commencez par visiter l'À propos.
Quoiqu'il en soit, commentaires, questions et suggestions sont les bienvenues !
If you'd like to know who you're talking to, please visit the about page.
Comments, questions and suggestions are welcome !
"""
content_translations = self.module.separate_qtranslate_content(content)
self.assertEqual("""Si vous préférez savoir à qui vous parlez commencez par visiter l'À propos.
Quoiqu'il en soit, commentaires, questions et suggestions sont les bienvenues !
""", content_translations["fr"])
self.assertEqual("""If you'd like to know who you're talking to, please visit the about page.
Comments, questions and suggestions are welcome !
""", content_translations["en"])
def test_split_a_two_language_post_with_teaser(self):
content = """Si vous préférez savoir à qui vous parlez commencez par visiter l'À propos.
Quoiqu'il en soit, commentaires, questions et suggestions sont les bienvenues !
If you'd like to know who you're talking to, please visit the about page.
Comments, questions and suggestions are welcome !
Plus de détails ici !
More details here !
"""
content_translations = self.module.separate_qtranslate_content(content)
self.assertEqual("""Si vous préférez savoir à qui vous parlez commencez par visiter l'À propos.
Quoiqu'il en soit, commentaires, questions et suggestions sont les bienvenues !
\n\
Plus de détails ici !
""", content_translations["fr"])
self.assertEqual("""If you'd like to know who you're talking to, please visit the about page.
Comments, questions and suggestions are welcome !
\n\
More details here !
""", content_translations["en"])
def test_split_a_two_language_post_with_intermission(self):
content = """Voila voilaCOMMONBLA"""
content_translations = self.module.separate_qtranslate_content(content)
self.assertEqual("Voila voila COMMON", content_translations["fr"])
self.assertEqual("COMMON BLA", content_translations["en"])
def test_split_a_two_language_post_with_uneven_repartition(self):
content = """Voila voilaCOMMONMOUFBLA"""
content_translations = self.module.separate_qtranslate_content(content)
self.assertEqual("Voila voila COMMON MOUF", content_translations["fr"])
self.assertEqual("COMMON BLA", content_translations["en"])
def test_split_a_two_language_post_with_uneven_repartition_bis(self):
content = """Voila voilaBLACOMMONMOUF"""
content_translations = self.module.separate_qtranslate_content(content)
self.assertEqual("Voila voila COMMON MOUF", content_translations["fr"])
self.assertEqual("BLA COMMON", content_translations["en"])
class CommandImportWordpressRunTest(BasicCommandImportWordpress):
def setUp(self):
super(self.__class__, self).setUp()
self.data_import = mock.MagicMock()
self.site_generation = mock.MagicMock()
self.write_urlmap = mock.MagicMock()
self.write_configuration = mock.MagicMock()
site_generation_patch = mock.patch('os.system', self.site_generation)
data_import_patch = mock.patch(
'nikola.plugins.command.import_wordpress.CommandImportWordpress.import_posts', self.data_import)
write_urlmap_patch = mock.patch(
'nikola.plugins.command.import_wordpress.CommandImportWordpress.write_urlmap_csv', self.write_urlmap)
write_configuration_patch = mock.patch(
'nikola.plugins.command.import_wordpress.CommandImportWordpress.write_configuration', self.write_configuration)
self.patches = [site_generation_patch, data_import_patch,
write_urlmap_patch, write_configuration_patch]
for patch in self.patches:
patch.start()
def tearDown(self):
del self.data_import
del self.site_generation
del self.write_urlmap
del self.write_configuration
for patch in self.patches:
patch.stop()
del self.patches
super(self.__class__, self).tearDown()
def test_create_import(self):
valid_import_arguments = (
dict(options={'output_folder': 'some_folder'},
args=[self.import_filename]),
dict(args=[self.import_filename]),
dict(args=[self.import_filename, 'folder_argument']),
)
for arguments in valid_import_arguments:
self.import_command.execute(**arguments)
self.assertTrue(self.site_generation.called)
self.assertTrue(self.data_import.called)
self.assertTrue(self.write_urlmap.called)
self.assertTrue(self.write_configuration.called)
self.assertFalse(self.import_command.exclude_drafts)
def test_ignoring_drafts(self):
valid_import_arguments = (
dict(options={'exclude_drafts': True}, args=[
self.import_filename]),
dict(
options={'exclude_drafts': True,
'output_folder': 'some_folder'},
args=[self.import_filename]),
)
for arguments in valid_import_arguments:
self.import_command.execute(**arguments)
self.assertTrue(self.import_command.exclude_drafts)
class CommandImportWordpressTest(BasicCommandImportWordpress):
def test_create_import_work_without_argument(self):
# Running this without an argument must not fail.
# It should show the proper usage of the command.
self.import_command.execute()
def test_populate_context(self):
channel = self.import_command.get_channel_from_file(
self.import_filename)
context = self.import_command.populate_context(channel)
for required_key in ('POSTS', 'PAGES', 'COMPILERS'):
self.assertTrue(required_key in context)
self.assertEqual('de', context['DEFAULT_LANG'])
self.assertEqual('Wordpress blog title', context['BLOG_TITLE'])
self.assertEqual('Nikola test blog ;) - with moré Ümläüts',
context['BLOG_DESCRIPTION'])
self.assertEqual('http://some.blog/', context['SITE_URL'])
self.assertEqual('mail@some.blog', context['BLOG_EMAIL'])
self.assertEqual('Niko', context['BLOG_AUTHOR'])
def test_importing_posts_and_attachments(self):
channel = self.import_command.get_channel_from_file(
self.import_filename)
self.import_command.context = self.import_command.populate_context(
channel)
self.import_command.base_dir = ''
self.import_command.output_folder = 'new_site'
self.import_command.squash_newlines = True
self.import_command.no_downloads = False
# Ensuring clean results
self.import_command.url_map = {}
self.module.links = {}
write_metadata = mock.MagicMock()
write_content = mock.MagicMock()
download_mock = mock.MagicMock()
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.write_content', write_content):
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.write_metadata', write_metadata):
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.download_url_content_to_file', download_mock):
with mock.patch('nikola.plugins.command.import_wordpress.os.makedirs'):
self.import_command.import_posts(channel)
self.assertTrue(download_mock.called)
qpath = 'new_site/files/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover.png'
download_mock.assert_any_call(
'http://some.blog/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover.png',
qpath.replace('/', os.sep))
self.assertTrue(write_metadata.called)
write_metadata.assert_any_call(
'new_site/stories/kontakt.meta'.replace('/', os.sep), 'Kontakt',
'kontakt', '2009-07-16 20:20:32', None, [])
self.assertTrue(write_content.called)
write_content.assert_any_call('new_site/posts/2007/04/hoert.wp'.replace('/', os.sep),
"""An image.
Some source code.
~~~~~~~~~~~~{.Python}
import sys
print sys.version
~~~~~~~~~~~~
The end.
""")
write_content.assert_any_call(
'new_site/posts/2008/07/arzt-und-pfusch-s-i-c-k.wp'.replace('/', os.sep),
'''
Arzt+Pfusch - S.I.C.K.Gerade bin ich \xfcber das Album S.I.C.K von Arzt+Pfusch gestolpert, welches Arzt+Pfusch zum Download f\xfcr lau anbieten. Das Album steht unter einer Creative Commons BY-NC-ND-Lizenz.
Die Ladung noisebmstupidevildustrial gibts als MP3s mit 64kbps und VBR, als Ogg Vorbis und als FLAC (letztere hier). Artwork und Lyrics gibts nochmal einzeln zum Download.''')
write_content.assert_any_call(
'new_site/stories/kontakt.wp'.replace('/', os.sep), """Datenschutz
Ich erhebe und speichere automatisch in meine Server Log Files Informationen, die dein Browser an mich \xfcbermittelt. Dies sind:
- Browsertyp und -version
- verwendetes Betriebssystem
- Referrer URL (die zuvor besuchte Seite)
- IP Adresse des zugreifenden Rechners
- Uhrzeit der Serveranfrage.
Diese Daten sind f\xfcr mich nicht bestimmten Personen zuordenbar. Eine Zusammenf\xfchrung dieser Daten mit anderen Datenquellen wird nicht vorgenommen, die Daten werden einzig zu statistischen Zwecken erhoben.""")
self.assertTrue(len(self.import_command.url_map) > 0)
self.assertEqual(
self.import_command.url_map['http://some.blog/2007/04/hoert/'],
'http://some.blog/posts/2007/04/hoert.html')
self.assertEqual(
self.import_command.url_map[
'http://some.blog/2008/07/arzt-und-pfusch-s-i-c-k/'],
'http://some.blog/posts/2008/07/arzt-und-pfusch-s-i-c-k.html')
self.assertEqual(
self.import_command.url_map['http://some.blog/kontakt/'],
'http://some.blog/stories/kontakt.html')
image_thumbnails = [
'http://some.blog/wp-content/uploads/2012/12/2012-12-19-1355925145_1024x600_scrot-64x64.png',
'http://some.blog/wp-content/uploads/2012/12/2012-12-19-1355925145_1024x600_scrot-300x175.png',
'http://some.blog/wp-content/uploads/2012/12/2012-12-19-1355925145_1024x600_scrot-36x36.png',
'http://some.blog/wp-content/uploads/2012/12/2012-12-19-1355925145_1024x600_scrot-24x24.png',
'http://some.blog/wp-content/uploads/2012/12/2012-12-19-1355925145_1024x600_scrot-96x96.png',
'http://some.blog/wp-content/uploads/2012/12/2012-12-19-1355925145_1024x600_scrot-96x96.png',
'http://some.blog/wp-content/uploads/2012/12/2012-12-19-1355925145_1024x600_scrot-48x48.png',
'http://some.blog/wp-content/uploads/2012/12/2012-12-19-1355925145_1024x600_scrot-96x96.png',
'http://some.blog/wp-content/uploads/2012/12/2012-12-19-1355925145_1024x600_scrot-150x150.png'
]
for link in image_thumbnails:
self.assertTrue(
link in self.module.links,
'No link to "{0}" found in {map}.'.format(
link,
map=self.module.links
)
)
def test_transforming_content(self):
"""Applying markup conversions to content."""
transform_sourcecode = mock.MagicMock()
transform_caption = mock.MagicMock()
transform_newlines = mock.MagicMock()
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.transform_sourcecode', transform_sourcecode):
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.transform_caption', transform_caption):
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.transform_multiple_newlines', transform_newlines):
self.import_command.transform_content("random content")
self.assertTrue(transform_sourcecode.called)
self.assertTrue(transform_caption.called)
self.assertTrue(transform_newlines.called)
def test_transforming_source_code(self):
"""
Tests the handling of sourcecode tags.
"""
content = """Hello World.
[sourcecode language="Python"]
import sys
print sys.version
[/sourcecode]"""
content = self.import_command.transform_sourcecode(content)
self.assertFalse('[/sourcecode]' in content)
self.assertFalse('[sourcecode language=' in content)
replaced_content = """Hello World.
~~~~~~~~~~~~{.Python}
import sys
print sys.version
~~~~~~~~~~~~
"""
self.assertEqual(content, replaced_content)
def test_transform_caption(self):
caption = '[caption id="attachment_16" align="alignnone" width="739" caption="beautiful picture"]
[/caption]'
transformed_content = self.import_command.transform_caption(caption)
expected_content = '
'
self.assertEqual(transformed_content, expected_content)
def test_transform_multiple_captions_in_a_post(self):
content = """asdasdas
[caption id="attachment_16" align="alignnone" width="739" caption="beautiful picture"]
[/caption]
asdasdas
asdasdas
[caption id="attachment_16" align="alignnone" width="739" caption="beautiful picture"]
[/caption]
asdasdas"""
expected_content = """asdasdas
asdasdas
asdasdas
asdasdas"""
self.assertEqual(
expected_content, self.import_command.transform_caption(content))
def test_transform_multiple_newlines(self):
content = """This
has
way to many
newlines.
"""
expected_content = """This
has
way to many
newlines.
"""
self.import_command.squash_newlines = False
self.assertEqual(content,
self.import_command.transform_multiple_newlines(content))
self.import_command.squash_newlines = True
self.assertEqual(expected_content,
self.import_command.transform_multiple_newlines(content))
def test_transform_caption_with_link_inside(self):
content = """[caption caption="Fehlermeldung"]
[/caption]"""
transformed_content = self.import_command.transform_caption(content)
expected_content = """
"""
self.assertEqual(expected_content, transformed_content)
def test_get_configuration_output_path(self):
self.import_command.output_folder = 'new_site'
default_config_path = os.path.join('new_site', 'conf.py')
self.import_command.import_into_existing_site = False
self.assertEqual(default_config_path,
self.import_command.get_configuration_output_path())
self.import_command.import_into_existing_site = True
config_path_with_timestamp = self.import_command.get_configuration_output_path(
)
self.assertNotEqual(default_config_path, config_path_with_timestamp)
self.assertTrue(self.import_command.name in config_path_with_timestamp)
def test_write_content_does_not_detroy_text(self):
content = b"""Installation
Follow the instructions described here.
Plugins
There are many plugins.
Violations
You can use the Violations plugin."""
open_mock = mock.mock_open()
with mock.patch('nikola.plugins.basic_import.open', open_mock, create=True):
self.import_command.write_content('some_file', content)
open_mock.assert_called_once_with('some_file', 'wb+')
call_context = open_mock()
call_context.write.assert_called_once_with(
content.join([b'', b'']))
def test_configure_redirections(self):
"""
Testing the configuration of the redirections.
We need to make sure that we have valid sources and target links.
"""
url_map = {
'/somewhere/else': 'http://foo.bar/posts/somewhereelse.html'
}
redirections = self.import_command.configure_redirections(url_map)
self.assertEqual(1, len(redirections))
self.assertTrue(('somewhere/else/index.html', '/posts/somewhereelse.html') in redirections)
if __name__ == '__main__':
unittest.main()