Test PDF renderer
This commit is contained in:
parent
bb4cfa962a
commit
8b914d8ae2
3 changed files with 126 additions and 17 deletions
|
@ -13,8 +13,8 @@ DEFAULT_MARGIN_VERTICAL = '1.5cm'
|
||||||
DEFAULT_MARGIN_HORIZONTAL = '2.5cm'
|
DEFAULT_MARGIN_HORIZONTAL = '2.5cm'
|
||||||
|
|
||||||
STYLE_FILE = os.path.join(STATIC_DIR, 'style.css')
|
STYLE_FILE = os.path.join(STATIC_DIR, 'style.css')
|
||||||
HEADER_FILE = os.path.join(TEMPLATES_DIR, 'header.html')
|
HEADER_FILE = FILE_NAME_FORMAT.format('header')
|
||||||
FOOTER_FILE = os.path.join(TEMPLATES_DIR, 'footer.html')
|
FOOTER_FILE = FILE_NAME_FORMAT.format('footer')
|
||||||
|
|
||||||
TOC_OPTIONS = {
|
TOC_OPTIONS = {
|
||||||
'xsl-style-sheet': os.path.join(TEMPLATES_DIR, 'toc.xsl')
|
'xsl-style-sheet': os.path.join(TEMPLATES_DIR, 'toc.xsl')
|
||||||
|
@ -37,23 +37,25 @@ def export_pdf(content, config):
|
||||||
if logger.getEffectiveLevel() > logging.DEBUG:
|
if logger.getEffectiveLevel() > logging.DEBUG:
|
||||||
PDF_OPTIONS['quiet'] = ""
|
PDF_OPTIONS['quiet'] = ""
|
||||||
PDF_OPTIONS['title'] = config.get('title', 'Output')
|
PDF_OPTIONS['title'] = config.get('title', 'Output')
|
||||||
PDF_OPTIONS['replace'] = [(key, str(value)) for key, value in config['context'].items()]
|
context = config.get('context', {})
|
||||||
|
|
||||||
PDF_OPTIONS['margin-top'] = config['context'].get('margin_vertical', DEFAULT_MARGIN_VERTICAL)
|
PDF_OPTIONS['replace'] = [(key, str(value)) for key, value in context.items()]
|
||||||
PDF_OPTIONS['margin-bottom'] = config['context'].get('margin_vertical', DEFAULT_MARGIN_VERTICAL)
|
PDF_OPTIONS['margin-top'] = context.get('margin_vertical', DEFAULT_MARGIN_VERTICAL)
|
||||||
PDF_OPTIONS['margin-left'] = config['context'].get('margin_horizontal', DEFAULT_MARGIN_HORIZONTAL)
|
PDF_OPTIONS['margin-bottom'] = context.get('margin_vertical', DEFAULT_MARGIN_VERTICAL)
|
||||||
PDF_OPTIONS['margin-right'] = config['context'].get('margin_horizontal', DEFAULT_MARGIN_HORIZONTAL)
|
PDF_OPTIONS['margin-left'] = context.get('margin_horizontal', DEFAULT_MARGIN_HORIZONTAL)
|
||||||
|
PDF_OPTIONS['margin-right'] = context.get('margin_horizontal', DEFAULT_MARGIN_HORIZONTAL)
|
||||||
|
|
||||||
logger.info("Rendering PDF...")
|
logger.info("Rendering PDF...")
|
||||||
render_ok = pdfkit.from_string(
|
try:
|
||||||
content,
|
pdfkit.from_string(
|
||||||
os.path.join(os.path.abspath(config['output_dir']), 'output.pdf'),
|
content,
|
||||||
options=PDF_OPTIONS,
|
os.path.join(os.path.abspath(config['output_dir']), 'output.pdf'),
|
||||||
cover=FILE_NAME_FORMAT.format('cover'),
|
options=PDF_OPTIONS,
|
||||||
toc=TOC_OPTIONS if config.get('toc') else {},
|
cover=FILE_NAME_FORMAT.format('cover'),
|
||||||
cover_first=True
|
toc=TOC_OPTIONS if config.get('toc') else {},
|
||||||
)
|
cover_first=True
|
||||||
if not render_ok:
|
)
|
||||||
raise PDFRenderException('Failed to render PDF. ' + render_ok)
|
except OSError as e:
|
||||||
|
raise PDFRenderException('Failed to render PDF. ' + str(e))
|
||||||
return PDF_OPTIONS # mostly for testing
|
return PDF_OPTIONS # mostly for testing
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import unittest
|
import unittest
|
||||||
import os
|
import os
|
||||||
from md_pdf.consts import TEMPLATES_DIR, STATIC_DIR
|
from md_pdf.consts import TEMPLATES_DIR, STATIC_DIR
|
||||||
|
from md_pdf.build.templates import FILE_NAME_FORMAT
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +27,17 @@ class BaseTestCase(unittest.TestCase):
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def touch_file(self, file):
|
||||||
|
open(file, 'w').close()
|
||||||
|
|
||||||
|
def create_fake_templates(self):
|
||||||
|
for template in [
|
||||||
|
'header',
|
||||||
|
'footer',
|
||||||
|
'cover'
|
||||||
|
]:
|
||||||
|
self.touch_file(FILE_NAME_FORMAT.format(template))
|
||||||
|
|
||||||
def extend_config(self, *args):
|
def extend_config(self, *args):
|
||||||
base_config = self.BASE_VALID_CONFIG.copy()
|
base_config = self.BASE_VALID_CONFIG.copy()
|
||||||
for arg in args:
|
for arg in args:
|
||||||
|
@ -45,3 +57,8 @@ class BaseTestCase(unittest.TestCase):
|
||||||
self.delete_templates()
|
self.delete_templates()
|
||||||
self.remove_file(os.path.join(STATIC_DIR, 'style.css'))
|
self.remove_file(os.path.join(STATIC_DIR, 'style.css'))
|
||||||
|
|
||||||
|
def call_to_args(self, call):
|
||||||
|
args = tuple(call.call_args)[0]
|
||||||
|
kwargs = tuple(call.call_args)[1]
|
||||||
|
return args, kwargs
|
||||||
|
|
||||||
|
|
90
tests/test_pdf.py
Normal file
90
tests/test_pdf.py
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
from tests import BaseTestCase
|
||||||
|
import os
|
||||||
|
from md_pdf.build.pdf import export_pdf, TOC_OPTIONS, DEFAULT_MARGIN_VERTICAL, DEFAULT_MARGIN_HORIZONTAL
|
||||||
|
from unittest.mock import patch
|
||||||
|
from md_pdf.build.templates import FILE_NAME_FORMAT
|
||||||
|
from md_pdf.exceptions import PDFRenderException
|
||||||
|
import pdfkit
|
||||||
|
|
||||||
|
|
||||||
|
class PDFRendererTestCase(BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.content = 'test content'
|
||||||
|
self.output_file_path = os.path.join(self.BASE_VALID_CONFIG['output_dir'], 'output.pdf')
|
||||||
|
self.assertFalse(os.path.isfile(self.output_file_path))
|
||||||
|
self.create_fake_templates()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super().tearDown()
|
||||||
|
self.remove_file(self.output_file_path)
|
||||||
|
|
||||||
|
def test_renders(self):
|
||||||
|
export_pdf(self.content, self.BASE_VALID_CONFIG)
|
||||||
|
|
||||||
|
def test_title(self):
|
||||||
|
context = export_pdf(self.content, self.BASE_VALID_CONFIG)
|
||||||
|
self.assertEqual(context['title'], self.BASE_VALID_CONFIG['title'])
|
||||||
|
|
||||||
|
def test_replace_context(self):
|
||||||
|
self.BASE_VALID_CONFIG['context'] = {
|
||||||
|
'1': 2,
|
||||||
|
'2': '1'
|
||||||
|
}
|
||||||
|
context = export_pdf(self.content, self.BASE_VALID_CONFIG)
|
||||||
|
self.assertEqual(context['replace'], [
|
||||||
|
('1', '2'),
|
||||||
|
('2', '1'),
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_default_margins(self):
|
||||||
|
context = export_pdf(self.content, self.BASE_VALID_CONFIG)
|
||||||
|
self.assertEqual(context['margin-top'], DEFAULT_MARGIN_VERTICAL)
|
||||||
|
self.assertEqual(context['margin-bottom'], DEFAULT_MARGIN_VERTICAL)
|
||||||
|
self.assertEqual(context['margin-left'], DEFAULT_MARGIN_HORIZONTAL)
|
||||||
|
self.assertEqual(context['margin-right'], DEFAULT_MARGIN_HORIZONTAL)
|
||||||
|
|
||||||
|
def test_override_margin(self):
|
||||||
|
self.BASE_VALID_CONFIG['context'] = {
|
||||||
|
'margin_vertical': '1cm',
|
||||||
|
'margin_horizontal': '2cm'
|
||||||
|
}
|
||||||
|
context = export_pdf(self.content, self.BASE_VALID_CONFIG)
|
||||||
|
self.assertEqual(context['margin-top'], '1cm')
|
||||||
|
self.assertEqual(context['margin-bottom'], '1cm')
|
||||||
|
self.assertEqual(context['margin-left'], '2cm')
|
||||||
|
self.assertEqual(context['margin-right'], '2cm')
|
||||||
|
|
||||||
|
@patch.object(pdfkit, 'from_string')
|
||||||
|
def test_kit_call(self, pdf_render):
|
||||||
|
context = export_pdf(self.content, self.BASE_VALID_CONFIG)
|
||||||
|
self.assertTrue(pdf_render.called)
|
||||||
|
args, kwargs = self.call_to_args(pdf_render)
|
||||||
|
self.assertEqual(args[0], self.content)
|
||||||
|
self.assertIn(self.output_file_path, args[1])
|
||||||
|
self.assertEqual(kwargs['options'], context)
|
||||||
|
self.assertTrue(kwargs['cover_first'])
|
||||||
|
self.assertEqual(kwargs['cover'], FILE_NAME_FORMAT.format('cover'))
|
||||||
|
self.assertEqual(kwargs['toc'], {})
|
||||||
|
|
||||||
|
@patch.object(pdfkit, 'from_string')
|
||||||
|
def test_toc(self, pdf_render):
|
||||||
|
self.BASE_VALID_CONFIG['toc'] = True
|
||||||
|
export_pdf(self.content, self.BASE_VALID_CONFIG)
|
||||||
|
args, kwargs = self.call_to_args(pdf_render)
|
||||||
|
self.assertEqual(kwargs['toc'], TOC_OPTIONS)
|
||||||
|
|
||||||
|
def test_fails_if_missing_templates(self):
|
||||||
|
self.remove_file(FILE_NAME_FORMAT.format('cover'))
|
||||||
|
with self.assertRaises(PDFRenderException):
|
||||||
|
export_pdf(self.content, self.BASE_VALID_CONFIG)
|
||||||
|
|
||||||
|
def test_files_exist(self):
|
||||||
|
context = export_pdf(self.content, self.BASE_VALID_CONFIG)
|
||||||
|
self.assertTrue(os.path.isfile(context['header-html']))
|
||||||
|
self.assertTrue(os.path.isfile(context['footer-html']))
|
||||||
|
self.assertEqual(context['header-html'], FILE_NAME_FORMAT.format('header'))
|
||||||
|
self.assertEqual(context['footer-html'], FILE_NAME_FORMAT.format('footer'))
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in a new issue