testOOoDynamicStyle.py 13.5 KB
Newer Older
1
# -*- coding: utf-8 -*-
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
##############################################################################
#
# Copyright (c) 2009 Nexedi KK and Contributors. All Rights Reserved.
#                    Tatuya Kamada <tatuya@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability 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
# garantees 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################

import os
import unittest
32 33 34
from cStringIO import StringIO
from zipfile import ZipFile
from Products.ERP5Type.tests.utils import FileUpload
35
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
36 37
from Products.ERP5Type.tests.utils import DummyLocalizer
from Products.ERP5OOo.tests.utils import Validator
38
from Products.ERP5OOo.OOoUtils import OOoBuilder
39

40

41
class TestOooDynamicStyle(ERP5TypeTestCase):
42 43 44
  manager_username = 'tatuya'
  manager_password = 'tatuya'
  content_type_writer = 'application/vnd.oasis.opendocument.text'
45
  content = "<office:document-content xmlns:draw='urn:oasis:names:tc:opendocument:xmlns:drawing:1.0' xmlns:office='urn:oasis:names:tc:opendocument:xmlns:office:1.0' xmlns:text='urn:oasis:names:tc:opendocument:xmlns:text:1.0' xmlns:ooo='http://openoffice.org/2004/office' xmlns:number='urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:meta='urn:oasis:names:tc:opendocument:xmlns:meta:1.0' xmlns:table='urn:oasis:names:tc:opendocument:xmlns:table:1.0' xmlns:dr3d='urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0' xmlns:fo='urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0' xmlns:style='urn:oasis:names:tc:opendocument:xmlns:style:1.0' xmlns:xforms='http://www.w3.org/2002/xforms' xmlns:form='urn:oasis:names:tc:opendocument:xmlns:form:1.0' xmlns:script='urn:oasis:names:tc:opendocument:xmlns:script:1.0' xmlns:ooow='http://openoffice.org/2004/writer' xmlns:svg='urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0' xmlns:chart='urn:oasis:names:tc:opendocument:xmlns:chart:1.0' xmlns:dom='http://www.w3.org/2001/xml-events' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:oooc='http://openoffice.org/2004/calc' xmlns:math='http://www.w3.org/1998/Math/MathML' xmlns:tal='http://xml.zope.org/namespaces/tal' office:version='1.2'><office:scripts /><office:font-face-decls /><office:automatic-styles /><office:body><office:text /></office:body></office:document-content>"
46 47 48 49

  def getTitle(self):
    return "TestOOoDynamicStyle"

50
  def getBusinessTemplateList(self):
51
    return ('erp5_core_proxy_field_legacy',
52
            'erp5_full_text_mroonga_catalog',
53 54 55
            'erp5_base',
            'erp5_ingestion_mysql_innodb_catalog',
            'erp5_ingestion',
56
            'erp5_web',
57 58
            'erp5_dms',
            'erp5_odt_style')
59

60 61 62

  def afterSetUp(self):
    self.login()
63
    self.getPortal().Localizer = DummyLocalizer()
64
    v12schema_url = os.path.join(os.path.dirname(__file__),
65
                                 'OpenDocument-v1.2-os-schema.rng')
66
    self.validator = Validator(schema_url=v12schema_url)
67 68 69 70 71 72 73 74 75
    en_file_path = os.path.join(os.path.dirname(__file__),
                                'test_document',
                                'DYNAMIC_STYLE_en.odt')
    en_file = open(en_file_path, 'rb')
    ja_file_path = os.path.join(os.path.dirname(__file__),
                                'test_document',
                                'DYNAMIC_STYLE_ja.odt')
    ja_file = open(ja_file_path, 'rb')

76 77 78
    addStyleSheet = self.getPortal().manage_addProduct['OFSP'].manage_addFile
    if getattr(self.getPortal(), 'Test_getODTStyleSheet_en', None) is None:
      addStyleSheet(id='Test_getODTStyleSheet_en', file=en_file, title='',
79
        content_type=self.content_type_writer)
80 81
    if getattr(self.getPortal(), 'Test_getODTStyleSheet_ja', None) is None:
      addStyleSheet(id='Test_getODTStyleSheet_ja', file=ja_file, title='',
82
        content_type=self.content_type_writer)
83 84
    if getattr(self.getPortal(), 'Base_getODTStyleSheetByLanguage', None) is None:
      script_body = """
85 86 87
current_language = context.Localizer.get_selected_language()
return getattr(context, "%s_%s" % (parameter, current_language))
"""
88 89 90 91
      dispatcher = self.getPortal().manage_addProduct['PythonScripts']
      dispatcher.manage_addPythonScript('Base_getODTStyleSheetByLanguage')
      script = self.getPortal().Base_getODTStyleSheetByLanguage
      script.ZPythonScript_edit('parameter', script_body)
92 93 94 95 96 97 98 99 100 101 102 103

  def _validate(self, odf_file_data):
    error_list = self.validator.validate(odf_file_data)
    if error_list:
      self.fail(''.join(error_list))

  def test_01_dynamic(self):
    """
    Test applying stylesheet dynamically, using a Python Script with
    a stylesheet file name parameter.
    """
    request = self.app.REQUEST
104
    addOOoTemplate = self.getPortal().manage_addProduct['ERP5OOo'].addOOoTemplate
105
    addOOoTemplate(id='Dynamic_viewAsOdt', title='')
106
    Dynamic_viewAsOdt = self.getPortal().Dynamic_viewAsOdt
107
    # The stylesheet file 'Test_getODTStyleSheet' is not exist in this site.
108 109
    # So, the 'Base_getODTStyleSheet', a python script creates dynamically
    # exsited stylesheet file name.
110 111 112
    self.assertFalse(self.getPortal().hasObject('Test_getODTStyleSheet'))
    self.assertTrue(self.getPortal().hasObject('Test_getODTStyleSheet_ja'))
    self.assertTrue(self.getPortal().hasObject('Test_getODTStyleSheet_en'))
113
    Dynamic_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
114
                                 ooo_stylesheet='Test_getODTStyleSheet',
115 116 117 118
                                 script_name='Base_getODTStyleSheetByLanguage')
    Dynamic_viewAsOdt.pt_edit(self.content, content_type='application/vnd.oasis.opendocument.text')

    # 1. test a normal case, language: ja
119 120
    self.getPortal().Localizer.changeLanguage('ja')
    response = self.publish('/' + self.getPortal().Dynamic_viewAsOdt.absolute_url(1))
121 122
    self.assertEqual('application/vnd.oasis.opendocument.text',
                     response.getHeader('content-type').split(';')[0])
123
    self.assertEqual('attachment; filename="Dynamic_viewAsOdt.odt"',
124
                     response.getHeader('content-disposition'))
125
    self._validate(response.getBody())
126
    self.assertEqual(200, response.getStatus())
127

128 129
    ooo_builder = OOoBuilder(response.getBody())
    styles_xml_body = ooo_builder.extract('styles.xml')
130
    self.assertTrue(len(styles_xml_body) > 0)
131
    # 'Style sheet ja' text is in the odt document header,
132 133
    # and the header is in the 'styles.xml'.
    self.assertTrue(styles_xml_body.find('Style sheet ja') > 0)
Nicolas Delaby committed
134

135
    # 2. test a normal case, change the language to 'en',
136
    #    so that the stylesheet changes dynamically.
137
    self.getPortal().Localizer = DummyLocalizer()
138 139
    self.getPortal().Localizer.changeLanguage('en')
    response = self.publish('/' + self.getPortal().Dynamic_viewAsOdt.absolute_url(1))
140
    self._validate(response.getBody())
141 142
    ooo_builder = OOoBuilder(response.getBody())
    styles_xml_body = ooo_builder.extract('styles.xml')
143
    self.assertTrue(styles_xml_body.find('Style sheet en') > 0)
Nicolas Delaby committed
144

145 146
    # 3. test a fail case, reset a not existed stylesheet
    Dynamic_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
147
                                 ooo_stylesheet='NotFound_getODTStyleSheet',
148
                                 script_name='Base_getODTStyleSheet')
149 150 151 152 153
    self.assertFalse(self.getPortal().hasObject('NotFound_getODTStyleSheet'))
    self.assertFalse(self.getPortal().hasObject('NotFound_getODTStyleSheet_ja'))
    self.assertFalse(self.getPortal().hasObject('NotFound_getODTStyleSheet_en'))
    self.getPortal().Localizer.changeLanguage('en')
    response = self.publish('/' + self.getPortal().Dynamic_viewAsOdt.absolute_url(1))
154
    # then, it is not a zip stream
155
    self.assertFalse(response.getBody().startswith('PK'))
156
    self.assertEqual(500, response.getStatus())
157

158 159 160 161 162 163

  def test_02_static(self):
    """
    Test applying stylesheet statically, using a stylesheet File object.
    """
    request = self.app.REQUEST
164
    addOOoTemplate = self.getPortal().manage_addProduct['ERP5OOo'].addOOoTemplate
165
    addOOoTemplate(id='Static_viewAsOdt', title='')
166
    Static_viewAsOdt = self.getPortal().Static_viewAsOdt
167
    # Test_getODTStyleSheet_ja is statically exist.
168
    self.assertTrue(self.getPortal().hasObject('Test_getODTStyleSheet_ja'))
169 170 171 172 173
    Static_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                ooo_stylesheet='Test_getODTStyleSheet_ja', script_name='')
    Static_viewAsOdt.pt_edit(self.content, content_type='application/vnd.oasis.opendocument.text')

    # 1. test a normal case
174
    response = self.publish('/' + self.getPortal().Static_viewAsOdt.absolute_url(1))
175
    self.assertEqual(200, response.getStatus())
176 177
    self.assertEqual('application/vnd.oasis.opendocument.text',
                     response.getHeader('content-type').split(';')[0])
178
    self.assertEqual('attachment; filename="Static_viewAsOdt.odt"',
179
                     response.getHeader('content-disposition'))
180
    self._validate(response.getBody())
181 182
    ooo_builder = OOoBuilder(response.getBody())
    styles_xml_body = ooo_builder.extract('styles.xml')
183 184
    self.assertTrue(len(styles_xml_body) > 0)
    self.assertTrue(styles_xml_body.find('Style sheet ja') > 0)
Nicolas Delaby committed
185

186
    # 2. test a normal case, change the style sheet
187
    self.assertTrue(self.getPortal().hasObject('Test_getODTStyleSheet_en'))
188 189
    Static_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                ooo_stylesheet='Test_getODTStyleSheet_en', script_name='')
190
    response = self.publish('/' + self.getPortal().Static_viewAsOdt.absolute_url(1))
191
    self.assertEqual(200, response.getStatus())
192
    self._validate(response.getBody())
193 194
    ooo_builder = OOoBuilder(response.getBody())
    styles_xml_body = ooo_builder.extract('styles.xml')
195 196
    self.assertTrue(len(styles_xml_body) > 0)
    self.assertTrue(styles_xml_body.find('Style sheet en') > 0)
Nicolas Delaby committed
197

198
    # 3. test a fail case
199
    self.assertFalse(self.getPortal().hasObject('NotFound_getODTStyleSheet'))
200 201
    Static_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                ooo_stylesheet='NotFound_getODTStyleSheet', script_name='')
202
    response = self.publish('/' + self.getPortal().Static_viewAsOdt.absolute_url(1))
203
    self.assertFalse(response.getBody().startswith('PK'))
204
    self.assertEqual(500, response.getStatus())
Nicolas Delaby committed
205

206 207 208 209 210 211 212 213 214 215 216 217 218
  def test_include_img(self):
    """
      Create an OOoTemplate from scratch, using pt_editAction to set the
      content, the content contains an include_img, when the OOo is rendered we
      have:
       - valid odf
       - an image included in the "ZIP"
       - the image properly listed in manifest
    """
    request = self.app.REQUEST
    filename = 'cmyk_sample.jpg'
    file_path = os.path.join(os.path.dirname(__file__), 'test_document',
        filename)
219
    upload_file = FileUpload(file_path)
220 221 222 223 224 225 226 227 228 229 230 231
    document = self.portal.portal_contributions.newContent(file=upload_file)
    addOOoTemplate = self.getPortal().manage_addProduct['ERP5OOo'].addOOoTemplate
    addOOoTemplate(id='Base_viewIncludeImageAsOdt', title='')
    custom_content = self.content.replace("<office:text />",
        "<office:text><office:include_img path='%s'/></office:text>" % document.getRelativeUrl())
    Base_viewIncludeImageAsOdt = self.getPortal().Base_viewIncludeImageAsOdt
    Base_viewIncludeImageAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                ooo_stylesheet='Base_getODTStyleSheet',
                                script_name='')
    Base_viewIncludeImageAsOdt.pt_edit(custom_content,
        content_type='application/vnd.oasis.opendocument.text')
    self.tic()
232

233
    response = self.publish('/' + self.getPortal().Base_viewIncludeImageAsOdt.absolute_url(1))
234
    body = response.getBody()
235
    self.assertEqual(200, response.getStatus(), body)
236 237 238 239 240
    self.assertEqual('application/vnd.oasis.opendocument.text',
                     response.getHeader('content-type').split(';')[0])
    self.assertEqual('attachment; filename="Base_viewIncludeImageAsOdt.odt"',
                     response.getHeader('content-disposition'))
    cs = StringIO()
241
    cs.write(body)
242 243 244 245 246 247 248 249 250 251
    zip_document = ZipFile(cs)
    picture_list = filter(lambda x: "Pictures" in x.filename,
        zip_document.infolist())
    self.assertNotEquals([], picture_list)
    manifest = zip_document.read('META-INF/manifest.xml')
    content = zip_document.read('content.xml')
    for picture in picture_list:
      self.assertTrue(picture.filename in manifest)
      self.assertTrue(picture.filename in content)

252 253 254 255 256

def test_suite():
  suite = unittest.TestSuite()
  suite.addTest(unittest.makeSuite(TestOooDynamicStyle))
  return suite