Commit 4b73d897 authored by Sven Franck's avatar Sven Franck

erp5_corporate_identitiy: try to fix missing translation and svg image comparison failing tests

parent f48ad28b
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts13613456.99</string> </value> <value> <string>ts13676932.13</string> </value>
</item> </item>
<item> <item>
<key> <string>_Modify_portal_content_Permission</string> </key> <key> <string>_Modify_portal_content_Permission</string> </key>
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
</item> </item>
<item> <item>
<key> <string>content_md5</string> </key> <key> <string>content_md5</string> </key>
<value> <string>903f474be052e6b81e9a2868a45ebb5b</string> </value> <value> <string>37124d8f30168b637379ff75a8c56096</string> </value>
</item> </item>
<item> <item>
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts13613484.66</string> </value> <value> <string>ts13676955.42</string> </value>
</item> </item>
<item> <item>
<key> <string>_Modify_portal_content_Permission</string> </key> <key> <string>_Modify_portal_content_Permission</string> </key>
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
</item> </item>
<item> <item>
<key> <string>content_md5</string> </key> <key> <string>content_md5</string> </key>
<value> <string>8b09f2215c971b76ff549d92d17ab4ab</string> </value> <value> <string>2bbd525d065612d63e5110e9db2a9e16</string> </value>
</item> </item>
<item> <item>
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts13613503.43</string> </value> <value> <string>ts13676973.16</string> </value>
</item> </item>
<item> <item>
<key> <string>_Modify_portal_content_Permission</string> </key> <key> <string>_Modify_portal_content_Permission</string> </key>
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
</item> </item>
<item> <item>
<key> <string>content_md5</string> </key> <key> <string>content_md5</string> </key>
<value> <string>5707f11ee910ba779be0d6da34e16960</string> </value> <value> <string>cd1fdc9a1c66e4f4fef4ee72f7ccdfe3</string> </value>
</item> </item>
<item> <item>
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
......
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
</item> </item>
<item> <item>
<key> <string>content_md5</string> </key> <key> <string>content_md5</string> </key>
<value> <string>6db10f6aa77ec08b289005d54dd36e65</string> </value> <value> <string>558046d1290e00487a9835ee0e6d440c</string> </value>
</item> </item>
<item> <item>
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>template_test_book_input_page_9_002_en_bmp</string> </value> <value> <string>template_test_book_input_page_10_002_en_bmp</string> </value>
</item> </item>
<item> <item>
<key> <string>language</string> </key> <key> <string>language</string> </key>
......
...@@ -84,9 +84,6 @@ ...@@ -84,9 +84,6 @@
<!--tal:block tal:condition="python: book_include_reference is not None">
<tal:block metal:use-macro="context/WebPage_createBookTableOfReferences/macros/book_references" />
</tal:block-->
<h1>Synthese</h1> <h1>Synthese</h1>
<p>This document is a high level overview measures taken by Foo for Bar project. </p> <p>This document is a high level overview measures taken by Foo for Bar project. </p>
......
...@@ -170,10 +170,7 @@ ...@@ -170,10 +170,7 @@
<section class="ci-book-table-of-content"><p class="ci-book-toc-faux-h1" i18n:translate="" i18n:domain="erp5_ui">Table of Contents</p><ol><li><div><a href="#introduction">Introduction</div></a><ol><li><div><a href="#references">References</div></a><ol><li><div><a href="#applicable-documents">Applicable Documents</div></a></li><li><div><a href="#referenced-documents">Referenced Documents</div></a></li></ol><li><div><a href="#abbreviations">Abbreviations</div></a></li><li><div><a href="#figures">Figures</div></a></li><li><div><a href="#tables">Tables</div></a></li></ol><li><div><a href="#synthese">Synthese</div></a><ol><li><div><a href="#risks-and-measures">Risks and measures</div></a><ol><li><div><a href="#risk-of-casualties-if-device-does-not-stop-and-destroys-itself">Risk of casualties if device does not stop and destroys itself</div></a></li><li><div><a href="#risk-of-killing-birds-and-polluting-the-environment">Risk of killing birds and polluting the environment</div></a></li><li><div><a href="#noise-and-vibration-levels">Noise and vibration levels</div></a></li></ol></li></ol><li><div><a href="#header-embedded-document">Header Embedded Document</div></a><ol><li><div><a href="#header-embedded-document-content-examples">Header Embedded Document content Examples</div></a></li></ol><li><div><a href="#reports">Reports</div></a><ol><li><div><a href="#project-reports">Project Reports</div></a></li><li><div><a href="#sale-order-reports">Sale Order Reports</div></a></ol></ol></section> <section class="ci-book-table-of-content"><p class="ci-book-toc-faux-h1">Table of Contents</p><ol><li><div><a href="#introduction">Introduction</div></a><ol><li><div><a href="#references">References</div></a><ol><li><div><a href="#applicable-documents">Applicable Documents</div></a></li><li><div><a href="#referenced-documents">Referenced Documents</div></a></li></ol><li><div><a href="#abbreviations">Abbreviations</div></a></li><li><div><a href="#figures">Figures</div></a></li><li><div><a href="#tables">Tables</div></a></li></ol><li><div><a href="#synthese">Synthese</div></a><ol><li><div><a href="#risks-and-measures">Risks and measures</div></a><ol><li><div><a href="#risk-of-casualties-if-device-does-not-stop-and-destroys-itself">Risk of casualties if device does not stop and destroys itself</div></a></li><li><div><a href="#risk-of-killing-birds-and-polluting-the-environment">Risk of killing birds and polluting the environment</div></a></li><li><div><a href="#noise-and-vibration-levels">Noise and vibration levels</div></a></li></ol></li></ol><li><div><a href="#header-embedded-document">Header Embedded Document</div></a><ol><li><div><a href="#header-embedded-document-content-examples">Header Embedded Document content Examples</div></a></li></ol><li><div><a href="#reports">Reports</div></a><ol><li><div><a href="#project-reports">Project Reports</div></a></li><li><div><a href="#sale-order-reports">Sale Order Reports</div></a></ol></ol></section>
<!--tal:block tal:condition="python: book_include_reference is not None">
<tal:block metal:use-macro="context/WebPage_createBookTableOfReferences/macros/book_references" />
</tal:block-->
<h1><a name="introduction"></a>Introduction<a class="custom-para" href="https://softinst73908.host.vifib.net/erp5/web_page_module/template_test_book_input_001_en_html#introduction"><span style="font-size:.75em;line-height:1em;padding-left:.5em;">&para;</span></a></h1> <h1><a name="introduction"></a>Introduction<a class="custom-para" href="https://softinst73908.host.vifib.net/erp5/web_page_module/template_test_book_input_001_en_html#introduction"><span style="font-size:.75em;line-height:1em;padding-left:.5em;">&para;</span></a></h1>
<h2><a name="references"></a>References<a class="custom-para" href="https://softinst73908.host.vifib.net/erp5/web_page_module/template_test_book_input_001_en_html#references"><span style="font-size:.75em;line-height:1em;padding-left:.5em;">&para;</span></a></h2> <h2><a name="references"></a>References<a class="custom-para" href="https://softinst73908.host.vifib.net/erp5/web_page_module/template_test_book_input_001_en_html#references"><span style="font-size:.75em;line-height:1em;padding-left:.5em;">&para;</span></a></h2>
......
...@@ -83,10 +83,7 @@ ...@@ -83,10 +83,7 @@
<section class="ci-book-table-of-content"><p class="ci-book-toc-faux-h1" i18n:translate="" i18n:domain="erp5_ui">Inhaltsverzeichnis</p><ol><li><div><a href="#synthese">Synthese</div></a><ol><li><div><a href="#risks-and-measures">Risks and measures</div></a><ol><li><div><a href="#risk-of-casualties-if-device-does-not-stop-and-destroys-itself">Risk of casualties if device does not stop and destroys itself</div></a></li><li><div><a href="#risk-of-killing-birds-and-polluting-the-environment">Risk of killing birds and polluting the environment</div></a></li><li><div><a href="#noise-and-vibration-levels">Noise and vibration levels</div></a></li></ol></li></ol><li><div><a href="#reports">Reports</div></a><ol><li><div><a href="#project-reports">Project Reports</div></a></li><li><div><a href="#sale-order-reports">Sale Order Reports</div></a></ol></ol></section> <section class="ci-book-table-of-content"><p class="ci-book-toc-faux-h1">Inhaltsverzeichnis</p><ol><li><div><a href="#synthese">Synthese</div></a><ol><li><div><a href="#risks-and-measures">Risks and measures</div></a><ol><li><div><a href="#risk-of-casualties-if-device-does-not-stop-and-destroys-itself">Risk of casualties if device does not stop and destroys itself</div></a></li><li><div><a href="#risk-of-killing-birds-and-polluting-the-environment">Risk of killing birds and polluting the environment</div></a></li><li><div><a href="#noise-and-vibration-levels">Noise and vibration levels</div></a></li></ol></li></ol><li><div><a href="#reports">Reports</div></a><ol><li><div><a href="#project-reports">Project Reports</div></a></li><li><div><a href="#sale-order-reports">Sale Order Reports</div></a></ol></ol></section>
<!--tal:block tal:condition="python: book_include_reference is not None">
<tal:block metal:use-macro="context/WebPage_createBookTableOfReferences/macros/book_references" />
</tal:block-->
<h1><a name="synthese"></a>Synthese<a class="custom-para" href="https://softinst73908.host.vifib.net/erp5/web_page_module/template_test_book_input_002_de_html#synthese"><span style="font-size:.75em;line-height:1em;padding-left:.5em;">&para;</span></a></h1> <h1><a name="synthese"></a>Synthese<a class="custom-para" href="https://softinst73908.host.vifib.net/erp5/web_page_module/template_test_book_input_002_de_html#synthese"><span style="font-size:.75em;line-height:1em;padding-left:.5em;">&para;</span></a></h1>
<p>This document is a high level overview measures taken by Foo for Bar project. </p> <p>This document is a high level overview measures taken by Foo for Bar project. </p>
......
...@@ -60,7 +60,7 @@ for header in re.findall("<h[1-6].*?</h[1-6]>", doc_content or blank): ...@@ -60,7 +60,7 @@ for header in re.findall("<h[1-6].*?</h[1-6]>", doc_content or blank):
closer = int(header_current) * '</ol>' closer = int(header_current) * '</ol>'
insert = ''.join([ insert = ''.join([
'<section class="ci-book-table-of-content">', '<section class="ci-book-table-of-content">',
'<p class="ci-book-toc-faux-h1" i18n:translate="" i18n:domain="erp5_ui">%s</p>' % (doc_toc_title or "Table of Contents"), '<p class="ci-book-toc-faux-h1">%s</p>' % (doc_toc_title or "XXX"),
table_of_content, table_of_content,
closer, closer,
'</section>' '</section>'
......
...@@ -65,9 +65,6 @@ Generates the complete book (only called in HTML version) ...@@ -65,9 +65,6 @@ Generates the complete book (only called in HTML version)
<tal:block metal:use-macro="context/WebPage_createBookTableOfHistory/macros/book_history" /> <tal:block metal:use-macro="context/WebPage_createBookTableOfHistory/macros/book_history" />
</tal:block> </tal:block>
<tal:block tal:replace="structure book_table_of_content"></tal:block> <tal:block tal:replace="structure book_table_of_content"></tal:block>
<!--tal:block tal:condition="python: book_include_reference is not None">
<tal:block metal:use-macro="context/WebPage_createBookTableOfReferences/macros/book_references" />
</tal:block-->
<tal:block metal:use-macro="context/WebPage_createBookContent/macros/book_content" /> <tal:block metal:use-macro="context/WebPage_createBookContent/macros/book_content" />
<tal:block metal:use-macro="context/WebPage_createBookFooter/macros/book_footer" /> <tal:block metal:use-macro="context/WebPage_createBookFooter/macros/book_footer" />
</body> </body>
......
...@@ -237,7 +237,8 @@ if book_include_reference_table is not None: ...@@ -237,7 +237,8 @@ if book_include_reference_table is not None:
if book_format == 'html' or book_format == 'mhtml': if book_format == 'html' or book_format == 'mhtml':
book_content = book_references.encode('utf-8').strip() + book_content book_content = book_references.encode('utf-8').strip() + book_content
# table of content # table of content has to be created manually to run over everything that
# should be indexed in the toc
if book_include_content_table is not None: if book_include_content_table is not None:
book_translated_toc_title = translateText("Table of Contents") book_translated_toc_title = translateText("Table of Contents")
if book_format == "pdf": if book_format == "pdf":
......
...@@ -988,7 +988,7 @@ class TestCorporateIdentityTemplates(ERP5TypeTestCase): ...@@ -988,7 +988,7 @@ class TestCorporateIdentityTemplates(ERP5TypeTestCase):
self.runPdfTestPattern( self.runPdfTestPattern(
"template_test_book_input_001_en_html", "template_test_book_input_001_en_html",
"template_test_book_input_page_4_002_en_bmp", "template_test_book_input_page_4_002_en_bmp",
"template_test_book_input_001_en_pdf", "template_test_book_input_002_en_pdf",
**dict( **dict(
page_number=4, page_number=4,
format="pdf", format="pdf",
...@@ -1023,7 +1023,7 @@ class TestCorporateIdentityTemplates(ERP5TypeTestCase): ...@@ -1023,7 +1023,7 @@ class TestCorporateIdentityTemplates(ERP5TypeTestCase):
self.runPdfTestPattern( self.runPdfTestPattern(
"template_test_book_input_001_en_html", "template_test_book_input_001_en_html",
"template_test_book_input_page_5_002_en_bmp", "template_test_book_input_page_5_002_en_bmp",
"template_test_book_input_001_en_pdf", "template_test_book_input_002_en_pdf",
**dict( **dict(
page_number=5, page_number=5,
format="pdf", format="pdf",
...@@ -1046,7 +1046,7 @@ class TestCorporateIdentityTemplates(ERP5TypeTestCase): ...@@ -1046,7 +1046,7 @@ class TestCorporateIdentityTemplates(ERP5TypeTestCase):
) )
) )
# duplicate, just for page 9 # duplicate, just for page 10
@changeSkin('Book') @changeSkin('Book')
def testpdfBookAllOptionsDoubleDupe(self): def testpdfBookAllOptionsDoubleDupe(self):
""" """
...@@ -1057,10 +1057,10 @@ class TestCorporateIdentityTemplates(ERP5TypeTestCase): ...@@ -1057,10 +1057,10 @@ class TestCorporateIdentityTemplates(ERP5TypeTestCase):
""" """
self.runPdfTestPattern( self.runPdfTestPattern(
"template_test_book_input_001_en_html", "template_test_book_input_001_en_html",
"template_test_book_input_page_9_002_en_bmp", "template_test_book_input_page_10_002_en_bmp",
"template_test_book_input_001_en_pdf", "template_test_book_input_002_en_pdf",
**dict( **dict(
page_number=9, page_number=10,
format="pdf", format="pdf",
use_skin="Book", use_skin="Book",
test_method="WebPage_exportAsBook", test_method="WebPage_exportAsBook",
......
##############################################################################
#
# Copyright (c) 2002-2017 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.Localizer.itools.i18n.accept import AcceptLanguage
from Products.ERP5Type.tests.utils import createZODBPythonScript
from PIL import Image
import transaction
import functools
import cStringIO
import math
import re
import io
import base64
host_url = r"https?://localhost(?::[0-9]+)?/[^/]+/"
test_url = "https://softinst73908.host.vifib.net/erp5/"
#def setDomainDict(script_id, script_param, script_code):
# def wrapper(func):
# @functools.wraps(func)
# def wrapped(self, *args, **kwargs):
# if script_id in self.portal.portal_skins.custom.objectIds():
# raise ValueError('Precondition failed: %s exists in custom' % script_id)
# createZODBPythonScript(
# self.portal.portal_skins.custom,
# script_id,
# script_param,
# script_code,
# )
# try:
# func(self, *args, **kwargs)
# finally:
# if script_id in self.portal.portal_skins.custom.objectIds():
# self.portal.portal_skins.custom.manage_delObjects(script_id)
# transaction.commit()
# return wrapped
# return wrapper
def changeSkin(skin_name):
"""
Change skin for following commands and attribute resolution.
Caution: In case of more annotations, this one has to be at the bottom (last)!
"""
def decorator(func):
def wrapped(self, *args, **kwargs):
default_skin = self.portal.portal_skins.default_skin
self.portal.portal_skins.changeSkin(skin_name)
self.app.REQUEST.set('portal_skin', skin_name)
try:
v = func(self, *args, **kwargs)
finally:
self.portal.portal_skins.changeSkin(default_skin)
self.app.REQUEST.set('portal_skin', default_skin)
return v
return wrapped
return decorator
class TestCorporateIdentityTemplatesDump(ERP5TypeTestCase):
def getTitle(self):
return "Test ERP5 Corporate Identity templates."
def getBusinessTemplateList(self):
return (
'erp5_base',
'erp5_font',
'erp5_web',
'erp5_dms',
'erp5_corporate_identity',
'erp5_ui_test_core'
)
def afterSetUp(self):
# Make sure alternative language is available
self.message_catalog = self.portal.Localizer.erp5_ui
if 'de' not in self.message_catalog.get_available_languages():
self.message_catalog.add_language('de')
self.message_catalog.gettext('Notes', add=1)
self.message_catalog.message_edit('Notes', 'de', 'Notizen', '')
self.message_catalog.gettext('VAT ID', add=1)
self.message_catalog.message_edit('VAT ID', 'de', 'USt-ID', '')
self.message_catalog.gettext('Data Sheet', add=1)
self.message_catalog.message_edit('Data Sheet', 'de', 'Datenblatt', '')
self.message_catalog.gettext('Table Of Contents', add=1)
self.message_catalog.message_edit('Table Of Contents', 'de', 'Inhaltsverzeichnis', '')
# Activating a system preference if none is activated
for preference in self.portal.portal_catalog(portal_type="System Preference"):
if preference.getPreferenceState() == "global":
break
else:
self.portal.portal_preferences.default_nexedi_system_preference.enable()
self.tic()
def computeImageRenderingRootMeanSquare(self, image_data_1, image_data_2):
"""
Compute and return the RMS (Root Mean Square) of image_data_1 and 2.
This value can be used to compare two images in rendering point of view.
Both image_data should be in the same quality as most as possible
(better compare lossless format) to reduce quality differences beside
rendering differences.
"""
# https://duckduckgo.com/?q=python+compare+images&ia=qa
# https://stackoverflow.com/a/1927681/
# http://snipplr.com/view/757/compare-two-pil-images-in-python/
# http://effbot.org/zone/pil-comparing-images.htm
# http://effbot.org/imagingbook/image.htm
image1 = Image.open(cStringIO.StringIO(image_data_1))
image2 = Image.open(cStringIO.StringIO(image_data_2))
# image can be converted into greyscale without transparency
h1 = image1.histogram()
h2 = image2.histogram()
rms = math.sqrt(
#reduce(operator.add, map(lambda a, b: (a - b) ** 2, h1, h2)) / len(h1)
sum((a - b) ** 2 for a, b in zip(h1, h2)) / len(h1)
)
# Note:
# - rms is ~5300.0 same page, bmp without alpha and bmp transparent back
# - rms is ~1125.7 same page, jpg and bmp images
# - rms is ~512.9 cover (big title + short title) and introduction page
# - rms is ~1.0 if date is 2017-06-07 vs 2017-06-06 with bmp images
return rms
def convertToPng(self, img_data):
bmp_file = Image.open(io.BytesIO(img_data))
img_buff = cStringIO.StringIO()
bmp_file.save(img_buff, format='PNG', optimize=True, quality=75)
img_data = img_buff.getvalue()
return ''.join(['data:image/png;base64,', base64.encodestring(img_data)])
def assertImageRenderingEquals(self, test_image_data, expected_image_data, message="Images rendering differs", max_rms=10.0):
rms = self.computeImageRenderingRootMeanSquare(test_image_data, expected_image_data)
if rms <= max_rms:
return
raise AssertionError("%(message)s\nComparing rendered image:\n%(base64_1)s\nWith expected image:\n%(base64_2)s\nRMS: %(rms)s > %(max_rms)s\nAssertionError: %(message)s" % {
"message": message,
"base64_1": self.convertToPng(test_image_data),
"base64_2": self.convertToPng(expected_image_data),
"rms": rms,
"max_rms": max_rms,
})
def call(self, *args, **kw):
return args[0](*args[1:], **kw)
def callWithPublicCloudoooOnSystemPreference(self, *args, **kw):
"""
Calls 'doSomething' with '*args' and '**kw' after setting cloudooo server
url preference to 'https://cloudooo.erp5.net/' and finally restores the
preference to its original value.
"""
system_preference = self.portal.portal_preferences.getActiveSystemPreference()
if system_preference is None:
return args[0](*args[1:], **kw)
preferred_document_conversion_server_url = system_preference.getPreferredDocumentConversionServerUrl()
try:
system_preference.edit(
preferred_document_conversion_server_url="https://cloudooo.erp5.net/",
#https://softinst77579.host.vifib.net/
)
return args[0](*args[1:], **kw)
finally:
system_preference.edit(
preferred_document_conversion_server_url=preferred_document_conversion_server_url,
)
def callWithNewRequestAcceptLanguage(self, *args, **kw):
"""
Call 'doSomething' with '*args' and '**kw' after setting
'REQUEST["AcceptLanguage"]' to '"*"' and finally restores it to its
original value.
"""
has_original_accept_language = "AcceptLanguage" in self.app.REQUEST
if has_original_accept_language:
original_accept_language = self.app.REQUEST
try:
self.app.REQUEST["AcceptLanguage"] = AcceptLanguage()
self.app.REQUEST["AcceptLanguage"].set("*", 0)
return args[0](*args[1:], **kw)
finally:
if has_original_accept_language:
self.app.REQUEST["AcceptLanguage"] = original_accept_language
else:
# `del self.app.REQUEST["AcceptLanguage"]` raises `AttributeError: __delitem__`
self.app.REQUEST["AcceptLanguage"] = AcceptLanguage()
def callWithNewRequestForm(self, *args, **kw):
"""
Calls 'doSomething' with '*args' and '**kw' after setting 'REQUEST.form' to
'new_form' dict and finally restores it to its original value.
"""
has_original_form = hasattr(self.app.REQUEST, "form")
if has_original_form:
original_form = self.app.REQUEST.form
try:
self.app.REQUEST.form = args[0]
return args[1](portal_skin=kw.get("use_skin"), **kw)
finally:
if has_original_form:
self.app.REQUEST.form = original_form
else:
delattr(self.app.REQUEST, "form")
def runHtmlTestPattern(self, id1, id2, **kw):
"""
Compare rendered HTML page with pregenerated HTML output
"""
test_page = getattr(self.portal.web_page_module, id1)
expected_page = getattr(self.portal.web_page_module, id2)
dump = getattr(self.portal, 'dump_data', None)
kw["batch_mode"] = 1
html = getattr(test_page, kw.get("test_method"))(portal_skin=kw.get("use_skin"), **kw)
html = re.sub(host_url, test_url, html)
# update html test files or run tests
if dump:
expected_page.edit(text_content=html)
self.assertEquals(html, expected_page.getData())
def runPdfTestPattern(self, id1, id2, id3, **kw):
"""
Compare a rendered PDF page with a a pregenerated image
"""
test_page = getattr(self.portal.web_page_module, id1)
expected_image = getattr(self.portal.image_module, id2)
image_source_pdf_doc = getattr(self.portal.document_module, id3)
dump = getattr(self.portal, 'dump_data', None)
kw["batch_mode"] = 1
pdf_kw = dict(
reference=test_page.getReference(),
target_language=kw.get("lang", None) or "en",
version=test_page.getVersion(),
)
pdf_data = self.call(
self.callWithPublicCloudoooOnSystemPreference,
self.callWithNewRequestAcceptLanguage,
self.callWithNewRequestForm,
pdf_kw,
getattr(test_page, kw.get("test_method")),
**kw
)
# XXX don't overwrite file to create image, use temporary-pdf?
image_source_pdf_doc.setData(pdf_data)
_, bmp = image_source_pdf_doc.convert("bmp", frame=kw.get("page_number"))
# update bmp files
if dump:
expected_image.setData(bmp)
self.assertImageRenderingEquals(str(bmp), str(expected_image.getData()))
##############################################################################
# What rendering is tested:
# - Web Page as Slideshow, Letter, Leaflet (Two Page) and Book
##############################################################################
##############################################################################
# How to compare two images ?
# - do a root-mean-square of image histogram using PIL
# - compare with a maximum RMS value
# - better to compare lossless images
#
# How to detect line spacing distance average on non-scanned document ?
# - turn into greyscale
# - select paragraph (rectangle)
# - cut a selected part of the image into ~4px line slices
# - sum the black color of each lines (see Figure 1)
# - do a FFT of the results and get the absis value of the first spike (f)
# in the resulted curve (see Figure 2)
#
# How to detect letter spacing distance average on non-scanned document ?
# - turn into greyscale
# - select line (rectangle)
# - cut a selected part of the image into ~2px column slices
# - sum the black color of each columns (see Figure 1)
# - do a FFT of the results and get the absis value of the first spike (f)
# in the resulted curve (see Figure 2)
#
# How to detect font alteration on non-scanned document ?
# - turn into greyscale
# - select line or piece of text (rectangle)
# - use an OCR to convert selected part into a string
# - regenerate the image from the string
# - compare the images
#
#
# Figure 1:
#
# sum of black color
# ^
# |
# | /\ /\ /\ /\
# | / \ / \ / \ / \
# |/ \/ \/ \/ \
# | ...
# +-----------------------------------------------------> line/column number
#
#
# Figure 2:
#
# amplitude FFT
# ^
# | ^
# | /|\ ^
# | / | \ / \ ^
# | / | \ / \ / \
# |-' | '---' '---' '--...
# +-----+-----------------------------------------------> frequency
# f
##############################################################################
@changeSkin('Slide')
def test_htmlSlideshowDump(self):
"""
Test:
- Web Page as Slideshow
- export as mhtml
"""
self.runHtmlTestPattern(
"template_test_slideshow_input_001_en_html",
"template_test_slideshow_output_expected_004_en_html",
**dict(
use_skin="Slide",
test_method="WebPage_exportAsSlideshow",
format="mhtml"
)
)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testCorporateIdentityTemplatesDump</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Test to dump mhtml passed into cloudooo</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testCorporateIdentityTemplatesDump</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple>
<string>W: 30, 0: Unused createZODBPythonScript imported from Products.ERP5Type.tests.utils (unused-import)</string>
<string>W: 32, 0: Unused import transaction (unused-import)</string>
<string>W: 33, 0: Unused import functools (unused-import)</string>
</tuple>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData>
...@@ -6,5 +6,5 @@ organisation_module/template_test*/default** ...@@ -6,5 +6,5 @@ organisation_module/template_test*/default**
person_module/template_test* person_module/template_test*
person_module/template_test*/default** person_module/template_test*/default**
portal_preferences/default_site_preference/template_* portal_preferences/default_site_preference/template_*
portal_preferences/default_site_preference/template_* portal_tests/template_zuite/testAndUpdateTest*
web_page_module/template_test_* web_page_module/template_test_*
\ No newline at end of file
...@@ -6,5 +6,5 @@ organisation_module/template_test*/default** ...@@ -6,5 +6,5 @@ organisation_module/template_test*/default**
person_module/template_test* person_module/template_test*
person_module/template_test*/default** person_module/template_test*/default**
portal_preferences/default_site_preference/template_* portal_preferences/default_site_preference/template_*
portal_preferences/default_site_preference/template_* portal_tests/template_zuite/testAndUpdateTest*
web_page_module/template_test_* web_page_module/template_test_*
\ No newline at end of file
test.erp5.testCorporateIdentityTemplates test.erp5.testCorporateIdentityTemplates
test.erp5.testCorporateIdentityTemplatesDump \ No newline at end of file
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment