From 5b7a65724a91cd4beebb31f2e5bd43d658638ec9 Mon Sep 17 00:00:00 2001 From: Raphael Groner Date: Mon, 16 Mar 2020 22:39:30 +0100 Subject: [PATCH] add tests --- example.css | 1 + example.html | 7 + example2.css | 1 + pdfkit-tests.py | 333 +++++++++++++++++++++++++++++++++++++++++++++ python-pdfkit.spec | 23 +++- sources | 2 +- 6 files changed, 365 insertions(+), 2 deletions(-) create mode 100644 example.css create mode 100644 example.html create mode 100644 example2.css create mode 100644 pdfkit-tests.py diff --git a/example.css b/example.css new file mode 100644 index 0000000..1e2acd0 --- /dev/null +++ b/example.css @@ -0,0 +1 @@ +body { font-size: 80px; } \ No newline at end of file diff --git a/example.html b/example.html new file mode 100644 index 0000000..8b15991 --- /dev/null +++ b/example.html @@ -0,0 +1,7 @@ + + + + +

Oh Hai!

+ + \ No newline at end of file diff --git a/example2.css b/example2.css new file mode 100644 index 0000000..016db27 --- /dev/null +++ b/example2.css @@ -0,0 +1 @@ +a { color: blue; } \ No newline at end of file diff --git a/pdfkit-tests.py b/pdfkit-tests.py new file mode 100644 index 0000000..f8225ed --- /dev/null +++ b/pdfkit-tests.py @@ -0,0 +1,333 @@ +# -*- coding: utf-8 -*- +import os +import io +import sys +import codecs +import unittest + +#Prepend ../ to PYTHONPATH so that we can import PDFKIT form there. +TESTS_ROOT = os.path.abspath(os.path.dirname(__file__)) +sys.path.insert(0, os.path.realpath(os.path.join(TESTS_ROOT, '..'))) + +import pdfkit + + +class TestPDFKitInitialization(unittest.TestCase): + """Test init""" + + def test_html_source(self): + r = pdfkit.PDFKit('

Oh hai

', 'string') + self.assertTrue(r.source.isString()) + + def test_url_source(self): + r = pdfkit.PDFKit('http://ya.ru', 'url') + self.assertTrue(r.source.isUrl()) + + def test_file_source(self): + r = pdfkit.PDFKit('fixtures/example.html', 'file') + self.assertTrue(r.source.isFile()) + + def test_file_object_source(self): + with open('fixtures/example.html') as fl: + r = pdfkit.PDFKit(fl, 'file') + self.assertTrue(r.source.isFileObj()) + + def test_file_source_with_path(self): + r = pdfkit.PDFKit('test', 'string') + with io.open('fixtures/example.css') as f: + self.assertTrue(r.source.isFile(path=f)) + with codecs.open('fixtures/example.css', encoding='UTF-8') as f: + self.assertTrue(r.source.isFile(path=f)) + + def test_options_parsing(self): + r = pdfkit.PDFKit('html', 'string', options={'page-size': 'Letter'}) + self.assertTrue(r.options['--page-size']) + + def test_options_parsing_with_dashes(self): + r = pdfkit.PDFKit('html', 'string', options={'--page-size': 'Letter'}) + self.assertTrue(r.options['--page-size']) + + def test_custom_configuration(self): + conf = pdfkit.configuration() + self.assertEqual('pdfkit-', conf.meta_tag_prefix) + conf = pdfkit.configuration(meta_tag_prefix='prefix-') + self.assertEqual('prefix-', conf.meta_tag_prefix) + with self.assertRaises(IOError): + conf = pdfkit.configuration(wkhtmltopdf='wrongpath') + + +class TestPDFKitCommandGeneration(unittest.TestCase): + """Test command() method""" + + def test_command_construction(self): + r = pdfkit.PDFKit('html', 'string', options={'page-size': 'Letter', 'toc-l1-font-size': 12}) + command = r.command() + self.assertEqual(command[0], r.wkhtmltopdf) + self.assertEqual(command[command.index('--page-size') + 1], 'Letter') + self.assertEqual(command[command.index('--toc-l1-font-size') + 1], '12') + + def test_lists_of_input_args(self): + urls = ['http://ya.ru', 'http://google.com'] + paths = ['fixtures/example.html', 'fixtures/example.html'] + r = pdfkit.PDFKit(urls, 'url') + r2 = pdfkit.PDFKit(paths, 'file') + cmd = r.command() + cmd2 = r2.command() + self.assertEqual(cmd[-3:], ['http://ya.ru', 'http://google.com', '-']) + self.assertEqual(cmd2[-3:], ['fixtures/example.html', 'fixtures/example.html', '-']) + + def test_read_source_from_stdin(self): + r = pdfkit.PDFKit('html', 'string') + self.assertEqual(r.command()[-2:], ['-', '-']) + + def test_url_in_command(self): + r = pdfkit.PDFKit('http://ya.ru', 'url') + self.assertEqual(r.command()[-2:], ['http://ya.ru', '-']) + + def test_file_path_in_command(self): + path = 'fixtures/example.html' + r = pdfkit.PDFKit(path, 'file') + self.assertEqual(r.command()[-2:], [path, '-']) + + def test_output_path(self): + out = '/test/test2/out.pdf' + r = pdfkit.PDFKit('html', 'string') + self.assertEqual(r.command(out)[-1:], ['/test/test2/out.pdf']) + + def test_pdfkit_meta_tags(self): + body = """ + + + + + + """ + + r = pdfkit.PDFKit(body, 'string') + command = r.command() + self.assertEqual(command[command.index('--page-size') + 1], 'Legal') + self.assertEqual(command[command.index('--orientation') + 1], 'Landscape') + + def test_pdfkit_meta_tags_in_bad_markup(self): + body = """ + + + + + +
+ + """ + + r = pdfkit.PDFKit(body, 'string') + command = r.command() + self.assertEqual(command[command.index('--page-size') + 1], 'Legal') + self.assertEqual(command[command.index('--orientation') + 1], 'Landscape') + + def test_skip_nonpdfkit_tags(self): + body = """ + + + + + +
+ + """ + + r = pdfkit.PDFKit(body, 'string') + command = r.command() + self.assertEqual(command[command.index('--orientation') + 1], 'Landscape') + + def test_toc_handling_without_options(self): + r = pdfkit.PDFKit('hmtl', 'string', toc={'xsl-style-sheet': 'test.xsl'}) + self.assertEqual(r.command()[1], 'toc') + self.assertEqual(r.command()[2], '--xsl-style-sheet') + + def test_toc_with_options(self): + options = { + 'page-size': 'Letter', + 'margin-top': '0.75in', + 'margin-right': '0.75in', + 'margin-bottom': '0.75in', + 'margin-left': '0.75in', + 'encoding': "UTF-8" + } + r = pdfkit.PDFKit('html', 'string', options=options, toc={'xsl-style-sheet': 'test.xsl'}) + + self.assertEqual(r.command()[1 + len(options) * 2], 'toc') + self.assertEqual(r.command()[1 + len(options) * 2 + 1], '--xsl-style-sheet') + + def test_cover_without_options(self): + r = pdfkit.PDFKit('html', 'string', cover='test.html') + + self.assertEqual(r.command()[1], 'cover') + self.assertEqual(r.command()[2], 'test.html') + + def test_cover_with_options(self): + options = { + 'page-size': 'Letter', + 'margin-top': '0.75in', + 'margin-right': '0.75in', + 'margin-bottom': '0.75in', + 'margin-left': '0.75in', + 'encoding': "UTF-8" + } + r = pdfkit.PDFKit('html', 'string', options=options, cover='test.html') + + self.assertEqual(r.command()[1 + len(options) * 2], 'cover') + self.assertEqual(r.command()[1 + len(options) * 2 + 1], 'test.html') + + def test_cover_and_toc(self): + options = { + 'page-size': 'Letter', + 'margin-top': '0.75in', + 'margin-right': '0.75in', + 'margin-bottom': '0.75in', + 'margin-left': '0.75in', + 'encoding': "UTF-8" + } + r = pdfkit.PDFKit('html', 'string', options=options, toc={'xsl-style-sheet': 'test.xsl'}, cover='test.html') + command = r.command() + self.assertEqual(command[-7:], ['toc', '--xsl-style-sheet', 'test.xsl', 'cover', 'test.html', '-', '-']) + + def test_outline_options(self): + options = { + 'outline': None, + 'outline-depth': 1 + } + + r = pdfkit.PDFKit('ya.ru', 'url', options=options) + cmd = r.command() + #self.assertEqual(cmd[1:], ['--outline', '--outline-depth', '1', 'ya.ru', '-']) + self.assertIn('--outline', cmd) + self.assertEqual(cmd[cmd.index('--outline-depth') + 1], '1') + + def test_filter_empty_and_none_values_in_opts(self): + options = { + 'outline': '', + 'footer-line': None, + 'quiet': False + } + + r = pdfkit.PDFKit('html', 'string', options=options) + cmd = r.command() + self.assertEqual(len(cmd), 6) + + +class TestPDFKitGeneration(unittest.TestCase): + """Test to_pdf() method""" + + def setUp(self): + pass + + def tearDown(self): + if os.path.exists('out.pdf'): + os.remove('out.pdf') + + def test_pdf_generation(self): + r = pdfkit.PDFKit('html', 'string', options={'page-size': 'Letter'}) + pdf = r.to_pdf('out.pdf') + self.assertTrue(pdf) + + def test_raise_error_with_invalid_url(self): + r = pdfkit.PDFKit('wrongurl', 'url') + with self.assertRaises(IOError): + r.to_pdf('out.pdf') + + def test_raise_error_with_invalid_file_path(self): + paths = ['frongpath.html', 'wrongpath2.html'] + with self.assertRaises(IOError): + pdfkit.PDFKit('wrongpath.html', 'file') + with self.assertRaises(IOError): + pdfkit.PDFKit(paths, 'file') + + def test_stylesheet_adding_to_the_head(self): + #TODO rewrite this part of pdfkit.py + r = pdfkit.PDFKit('Hai!', 'string', + css='fixtures/example.css') + + with open('fixtures/example.css') as f: + css = f.read() + + r._prepend_css('fixtures/example.css') + self.assertIn('' % css, r.source.to_s()) + + def test_stylesheet_adding_without_head_tag(self): + r = pdfkit.PDFKit('Hai!', 'string', + options={'quiet': None}, css='fixtures/example.css') + + with open('fixtures/example.css') as f: + css = f.read() + + r._prepend_css('fixtures/example.css') + self.assertIn('' % css, r.source.to_s()) + + def test_multiple_stylesheets_adding_to_the_head(self): + #TODO rewrite this part of pdfkit.py + css_files = ['fixtures/example.css', 'fixtures/example2.css'] + r = pdfkit.PDFKit('Hai!', 'string', + css=css_files) + + css=[] + for css_file in css_files: + with open(css_file) as f: + css.append(f.read()) + + r._prepend_css(css_files) + self.assertIn('' % "\n".join(css), r.source.to_s()) + + def test_multiple_stylesheet_adding_without_head_tag(self): + css_files = ['fixtures/example.css', 'fixtures/example2.css'] + r = pdfkit.PDFKit('Hai!', 'string', + options={'quiet': None}, css=css_files) + + css=[] + for css_file in css_files: + with open(css_file) as f: + css.append(f.read()) + + r._prepend_css(css_files) + self.assertIn('' % "\n".join(css), r.source.to_s()) + + def test_stylesheet_throw_error_when_url(self): + r = pdfkit.PDFKit('http://ya.ru', 'url', css='fixtures/example.css') + + with self.assertRaises(r.ImproperSourceError): + r.to_pdf() + + def test_stylesheet_adding_to_file_with_option(self): + css = 'fixtures/example.css' + r = pdfkit.PDFKit('fixtures/example.html', 'file', css=css) + self.assertEqual(r.css, css) + r._prepend_css(css) + self.assertIn('font-size', r.source.to_s()) + + def test_wkhtmltopdf_error_handling(self): + r = pdfkit.PDFKit('clearlywrongurl.asdf', 'url') + with self.assertRaises(IOError): + r.to_pdf() + + def test_pdf_generation_from_file_like(self): + with open('fixtures/example.html', 'r') as f: + r = pdfkit.PDFKit(f, 'file') + output = r.to_pdf() + self.assertEqual(output[:4].decode('utf-8'), '%PDF') + + def test_raise_error_with_wrong_css_path(self): + css = 'fixtures/wrongpath.css' + r = pdfkit.PDFKit('fixtures/example.html', 'file', css=css) + with self.assertRaises(IOError): + r.to_pdf() + + def test_raise_error_if_bad_wkhtmltopdf_option(self): + r = pdfkit.PDFKit('Hai!', 'string', + options={'bad-option': None}) + with self.assertRaises(IOError) as cm: + r.to_pdf() + + raised_exception = cm.exception + self.assertRegexpMatches(str(raised_exception), '^wkhtmltopdf exited with non-zero code 1. error:\nUnknown long argument --bad-option\r?\n') + +if __name__ == "__main__": + unittest.main() diff --git a/python-pdfkit.spec b/python-pdfkit.spec index 8b078f1..f580e7e 100644 --- a/python-pdfkit.spec +++ b/python-pdfkit.spec @@ -1,18 +1,29 @@ %global pypi_name pdfkit +%global commit0 d1c218ab4bb9e4c3790638070ad41bec6077537e +%global testurl https://raw.githubusercontent.com/JazzCore/python-pdfkit/%{commit0}/tests/ Name: python-%{pypi_name} Version: 0.5.0 -Release: 17%{?dist} +Release: 18%{?dist} Summary: Wkhtmltopdf python wrapper License: MIT URL: https://github.com/JazzCore/python-pdfkit Source0: https://pypi.python.org/packages/source/p/%{pypi_name}/%{pypi_name}-%{version}.zip +# tests taken from github due to not part of pypi +Source10: %{testurl}/pdfkit-tests.py +Source11: %{testurl}/fixtures/example.css +Source12: %{testurl}/fixtures/example.html +Source13: %{testurl}/fixtures/example2.css + BuildArch: noarch BuildRequires: python3-setuptools BuildRequires: python3-devel BuildRequires: python3 +BuildRequires: python3-pytest +BuildRequires: wkhtmltopdf + Requires: python3 Requires: wkhtmltopdf @@ -26,6 +37,7 @@ This is an adapted version of Ruby PDFKit. %package -n python3-%{pypi_name} Summary: Wkhtmltopdf python wrapper %{?python_provide:%python_provide python3-%{pypi_name}} + %description -n python3-%{pypi_name} Python 3 wrapper for wkhtmltopdf utility to convert HTML to PDF using Webkit. @@ -42,6 +54,12 @@ rm -rf %{pypi_name}.egg-info %install %py3_install +%check +mkdir -p tests/fixtures +cp -t tests %{SOURCE10} +cp -t tests/fixtures %{SOURCE11} %{SOURCE12} %{SOURCE13} +%{__python3} setup.py test + %files -n python3-%{pypi_name} %{!?_licensedir:%global license %%doc} %license LICENSE @@ -50,6 +68,9 @@ rm -rf %{pypi_name}.egg-info %{python3_sitelib}/%{pypi_name}-%{version}-py?.?.egg-info %changelog +* Mon Mar 16 2020 Raphael Groner - 0.5.0-18 +- add tests + * Thu Jan 30 2020 Fedora Release Engineering - 0.5.0-17 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild diff --git a/sources b/sources index ba78f2b..18e7ed3 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -5cbe42c43d463f0794272a01e37a553f pdfkit-0.5.0.zip +SHA512 (pdfkit-0.5.0.zip) = 7d310d36503305bf71065b9b96bb313cb21f40ad7c347554b6f7a82e3d7ee8a7e3122ce54a522fbbacb5c50f0ddb72c9827bc0b38aa1ebea891e5c91b2668841