""" Package to test the openlp.core.lib.htmlbuilder module. """ from unittest import TestCase from unittest.mock import MagicMock, patch from PyQt5 import QtCore, QtWebKit from openlp.core.common import Settings from openlp.core.lib.htmlbuilder import build_html, build_background_css, build_lyrics_css, build_lyrics_outline_css, \ build_lyrics_format_css, build_footer_css, webkit_version, build_chords_css from openlp.core.lib.theme import HorizontalType, VerticalType from tests.helpers.testmixin import TestMixin HTML = """ OpenLP Display plugin HTML
""" BACKGROUND_CSS_RADIAL = 'background: -webkit-gradient(radial, 5 50%, 100, 5 50%, 5, from(#000000), to(#FFFFFF)) fixed' LYRICS_CSS = """ .lyricstable { z-index: 5; position: absolute; display: table; left: 10px; top: 20px; } .lyricscell { display: table-cell; word-wrap: break-word; -webkit-transition: opacity 0.4s ease; lyrics_format_css } .lyricsmain { text-shadow: #000000 5px 5px; } """ LYRICS_OUTLINE_CSS = ' -webkit-text-stroke: 0.125em #000000; -webkit-text-fill-color: #FFFFFF; ' LYRICS_FORMAT_CSS = """ word-wrap: break-word; text-align: justify; vertical-align: bottom; font-family: Arial; font-size: 40pt; color: #FFFFFF; line-height: 108%; margin: 0; padding: 0; padding-bottom: 0.5em; padding-left: 2px; width: 1580px; height: 810px; font-style: italic; font-weight: bold; """ FOOTER_CSS_BASE = """ left: 10px; bottom: 0px; width: 1260px; font-family: Arial; font-size: 12pt; color: #FFFFFF; text-align: left; white-space: %s; """ FOOTER_CSS = FOOTER_CSS_BASE % ('nowrap') FOOTER_CSS_WRAP = FOOTER_CSS_BASE % ('normal') FOOTER_CSS_INVALID = '' CHORD_CSS_ENABLED = """ .chordline { line-height: 2.0em; } .chordline span.chord span { position: relative; } .chordline span.chord span strong { position: absolute; top: -0.8em; left: 0; font-size: 75%; font-weight: normal; line-height: normal; display: inline; } .firstchordline { line-height: 2.1em; } .ws { display: inline; white-space: pre-wrap; }""" __default_settings__ = { 'songs/mainview chords': False, 'songs/enable chords': True } class Htmbuilder(TestCase, TestMixin): """ Test the functions in the Htmlbuilder module """ def setUp(self): """ Create the UI """ self.build_settings() Settings().extend_default_settings(__default_settings__) def tearDown(self): """ Delete all the C++ objects at the end so that we don't have a segfault """ self.destroy_settings() def test_build_html(self): """ Test the build_html() function """ # GIVEN: Mocked arguments and function. with patch('openlp.core.lib.htmlbuilder.build_background_css') as mocked_build_background_css, \ patch('openlp.core.lib.htmlbuilder.build_footer_css') as mocked_build_footer_css, \ patch('openlp.core.lib.htmlbuilder.build_lyrics_css') as mocked_build_lyrics_css: # Mocked function. mocked_build_background_css.return_value = '' mocked_build_footer_css.return_value = 'dummy: dummy;' mocked_build_lyrics_css.return_value = '' # Mocked arguments. item = MagicMock() item.bg_image_bytes = None screen = MagicMock() is_live = False background = None plugin = MagicMock() plugin.get_display_css.return_value = 'plugin CSS' plugin.get_display_javascript.return_value = 'plugin JS' plugin.get_display_html.return_value = 'plugin HTML' plugins = [plugin] # WHEN: Create the html. html = build_html(item, screen, is_live, background, plugins=plugins) # THEN: The returned html should match. self.assertEqual(html, HTML, 'The returned html should match') def test_build_background_css_radial(self): """ Test the build_background_css() function with a radial background """ # GIVEN: Mocked arguments. item = MagicMock() item.theme_data.background_start_color = '#000000' item.theme_data.background_end_color = '#FFFFFF' width = 10 # WHEN: Create the css. css = build_background_css(item, width) # THEN: The returned css should match. self.assertEqual(BACKGROUND_CSS_RADIAL, css, 'The background css should be equal.') def test_build_lyrics_css(self): """ Test the build_lyrics_css() function """ # GIVEN: Mocked method and arguments. with patch('openlp.core.lib.htmlbuilder.build_lyrics_format_css') as mocked_build_lyrics_format_css, \ patch('openlp.core.lib.htmlbuilder.build_lyrics_outline_css') as mocked_build_lyrics_outline_css: mocked_build_lyrics_format_css.return_value = 'lyrics_format_css' mocked_build_lyrics_outline_css.return_value = '' item = MagicMock() item.main = QtCore.QRect(10, 20, 10, 20) item.theme_data.font_main_shadow = True item.theme_data.font_main_shadow_color = '#000000' item.theme_data.font_main_shadow_size = 5 # WHEN: Create the css. css = build_lyrics_css(item) # THEN: The css should be equal. self.assertEqual(LYRICS_CSS, css, 'The lyrics css should be equal.') def test_build_lyrics_outline_css(self): """ Test the build_lyrics_outline_css() function """ # GIVEN: The mocked theme data. theme_data = MagicMock() theme_data.font_main_outline = True theme_data.font_main_outline_size = 2 theme_data.font_main_color = '#FFFFFF' theme_data.font_main_outline_color = '#000000' # WHEN: Create the css. css = build_lyrics_outline_css(theme_data) # THEN: The css should be equal. self.assertEqual(LYRICS_OUTLINE_CSS, css, 'The outline css should be equal.') def test_build_lyrics_format_css(self): """ Test the build_lyrics_format_css() function """ # GIVEN: Mocked arguments. theme_data = MagicMock() theme_data.display_horizontal_align = HorizontalType.Justify theme_data.display_vertical_align = VerticalType.Bottom theme_data.font_main_name = 'Arial' theme_data.font_main_size = 40 theme_data.font_main_color = '#FFFFFF' theme_data.font_main_italics = True theme_data.font_main_bold = True theme_data.font_main_line_adjustment = 8 width = 1580 height = 810 # WHEN: Get the css. css = build_lyrics_format_css(theme_data, width, height) # THEN: They should be equal. self.assertEqual(LYRICS_FORMAT_CSS, css, 'The lyrics format css should be equal.') def test_build_footer_css(self): """ Test the build_footer_css() function """ # GIVEN: Create a theme. item = MagicMock() item.footer = QtCore.QRect(10, 921, 1260, 103) item.theme_data.font_footer_name = 'Arial' item.theme_data.font_footer_size = 12 item.theme_data.font_footer_color = '#FFFFFF' height = 1024 # WHEN: create the css with default settings. css = build_footer_css(item, height) # THEN: THE css should be the same. self.assertEqual(FOOTER_CSS, css, 'The footer strings should be equal.') def test_build_footer_css_wrap(self): """ Test the build_footer_css() function """ # GIVEN: Create a theme. item = MagicMock() item.footer = QtCore.QRect(10, 921, 1260, 103) item.theme_data.font_footer_name = 'Arial' item.theme_data.font_footer_size = 12 item.theme_data.font_footer_color = '#FFFFFF' height = 1024 # WHEN: Settings say that footer should wrap Settings().setValue('themes/wrap footer', True) css = build_footer_css(item, height) # THEN: Footer should wrap self.assertEqual(FOOTER_CSS_WRAP, css, 'The footer strings should be equal.') def test_build_footer_invalid(self): """ Test the build_footer_css() function """ # GIVEN: Create a theme. css = [] item = MagicMock() item.theme_data = None item.footer = 'FAIL' height = 1024 # WHEN: Settings say that footer should wrap css.append(build_footer_css(item, height)) item.theme_data = 'TEST' item.footer = None css.append(build_footer_css(item, height)) # THEN: Footer should wrap self.assertEqual(FOOTER_CSS_INVALID, css[0], 'The footer strings should be blank.') self.assertEqual(FOOTER_CSS_INVALID, css[1], 'The footer strings should be blank.') def test_webkit_version(self): """ Test the webkit_version() function """ # GIVEN: Webkit webkit_ver = float(QtWebKit.qWebKitVersion()) # WHEN: Retrieving the webkit version # THEN: Webkit versions should match self.assertEquals(webkit_version(), webkit_ver, "The returned webkit version doesn't match the installed one") def test_build_chords_css(self): """ Test the build_chords_css() function """ # GIVEN: A setting that activates chords on the mainview Settings().setValue('songs/enable chords', True) Settings().setValue('songs/mainview chords', True) # WHEN: Building the chord CSS chord_css = build_chords_css() # THEN: The build css should look as expected self.assertEqual(CHORD_CSS_ENABLED, chord_css, 'The chord CSS should look as expected')