testOOoDynamicStyle.py 13.8 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 32
##############################################################################
#
# 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 sys
import unittest
33 34 35 36
from cStringIO import StringIO
from zipfile import ZipFile
from Products.ERP5Type.tests.backportUnittest import skip
from Products.ERP5Type.tests.utils import FileUpload
37
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
38
from Products.ERP5Type.tests.backportUnittest import expectedFailure
39 40 41 42
from AccessControl.SecurityManagement import newSecurityManager
from Products.ERP5Type.tests.utils import DummyLocalizer
from zLOG import LOG
from Products.ERP5OOo.tests.utils import Validator
43
from Products.ERP5OOo.OOoUtils import OOoBuilder
44

45

46
class TestOooDynamicStyle(ERP5TypeTestCase):
47 48 49
  manager_username = 'tatuya'
  manager_password = 'tatuya'
  content_type_writer = 'application/vnd.oasis.opendocument.text'
50
  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>"
51 52 53 54

  def getTitle(self):
    return "TestOOoDynamicStyle"

55
  def getBusinessTemplateList(self):
56 57 58 59 60 61
    return ('erp5_core_proxy_field_legacy',
            'erp5_full_text_myisam_catalog',
            'erp5_base',
            'erp5_ingestion_mysql_innodb_catalog',
            'erp5_ingestion',
            'erp5_web', 
62 63
            'erp5_dms',
            'erp5_odt_style')
64

65 66 67

  def afterSetUp(self):
    self.login()
68
    self.getPortal().Localizer = DummyLocalizer()
69
    v12schema_url = os.path.join(os.path.dirname(__file__),
70
                                 'OpenDocument-v1.2-os-schema.rng') 
71
    self.validator = Validator(schema_url=v12schema_url)
72 73 74 75 76 77 78 79 80
    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')

81 82 83 84 85 86 87 88 89
    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='',
        precondition='', content_type=self.content_type_writer)
    if getattr(self.getPortal(), 'Test_getODTStyleSheet_ja', None) is None:
      addStyleSheet(id='Test_getODTStyleSheet_ja', file=ja_file, title='',
        precondition='', content_type=self.content_type_writer)
    if getattr(self.getPortal(), 'Base_getODTStyleSheetByLanguage', None) is None:
      script_body = """
90 91 92
current_language = context.Localizer.get_selected_language()
return getattr(context, "%s_%s" % (parameter, current_language))
"""
93 94 95 96
      dispatcher = self.getPortal().manage_addProduct['PythonScripts']
      dispatcher.manage_addPythonScript('Base_getODTStyleSheetByLanguage')
      script = self.getPortal().Base_getODTStyleSheetByLanguage
      script.ZPythonScript_edit('parameter', script_body)
97 98 99 100 101 102 103 104 105 106 107 108

  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
109
    addOOoTemplate = self.getPortal().manage_addProduct['ERP5OOo'].addOOoTemplate
110
    addOOoTemplate(id='Dynamic_viewAsOdt', title='')
111
    Dynamic_viewAsOdt = self.getPortal().Dynamic_viewAsOdt
112 113 114
    # The stylesheet file 'Test_getODTStyleSheet' is not exist in this site.
    # So, the 'Base_getODTStyleSheet', a python script creates dynamically 
    # exsited stylesheet file name. 
115 116 117
    self.assertFalse(self.getPortal().hasObject('Test_getODTStyleSheet'))
    self.assertTrue(self.getPortal().hasObject('Test_getODTStyleSheet_ja'))
    self.assertTrue(self.getPortal().hasObject('Test_getODTStyleSheet_en'))
118 119 120 121 122 123
    Dynamic_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                 ooo_stylesheet='Test_getODTStyleSheet', 
                                 script_name='Base_getODTStyleSheetByLanguage')
    Dynamic_viewAsOdt.pt_edit(self.content, content_type='application/vnd.oasis.opendocument.text')

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

133 134
    ooo_builder = OOoBuilder(response.getBody())
    styles_xml_body = ooo_builder.extract('styles.xml')
135 136 137 138
    self.assertTrue(len(styles_xml_body) > 0)
    # 'Style sheet ja' text is in the odt document header, 
    # and the header is in the 'styles.xml'.
    self.assertTrue(styles_xml_body.find('Style sheet ja') > 0)
Nicolas Delaby's avatar
Nicolas Delaby committed
139

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

150 151 152 153
    # 3. test a fail case, reset a not existed stylesheet
    Dynamic_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                 ooo_stylesheet='NotFound_getODTStyleSheet', 
                                 script_name='Base_getODTStyleSheet')
154 155 156 157 158
    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))
159 160 161 162 163 164 165 166 167 168
    # then, it is not a zip stream 
    self.assertFalse(response.getBody().startswith('PK'))
    self.assertTrue(500, response.getStatus())
   

  def test_02_static(self):
    """
    Test applying stylesheet statically, using a stylesheet File object.
    """
    request = self.app.REQUEST
169
    addOOoTemplate = self.getPortal().manage_addProduct['ERP5OOo'].addOOoTemplate
170
    addOOoTemplate(id='Static_viewAsOdt', title='')
171
    Static_viewAsOdt = self.getPortal().Static_viewAsOdt
172
    # Test_getODTStyleSheet_ja is statically exist.
173
    self.assertTrue(self.getPortal().hasObject('Test_getODTStyleSheet_ja'))
174 175 176 177 178
    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
179
    response = self.publish('/' + self.getPortal().Static_viewAsOdt.absolute_url(1))
180 181 182
    self.assertTrue(200, response.getStatus())
    self.assertEqual('application/vnd.oasis.opendocument.text',
                     response.getHeader('content-type').split(';')[0])
183
    self.assertEqual('attachment; filename="Static_viewAsOdt.odt"',
184 185
                     response.getHeader('content-disposition'))
    self._validate(response.getBody()) 
186 187
    ooo_builder = OOoBuilder(response.getBody())
    styles_xml_body = ooo_builder.extract('styles.xml')
188 189
    self.assertTrue(len(styles_xml_body) > 0)
    self.assertTrue(styles_xml_body.find('Style sheet ja') > 0)
Nicolas Delaby's avatar
Nicolas Delaby committed
190

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

203
    # 3. test a fail case
204
    self.assertFalse(self.getPortal().hasObject('NotFound_getODTStyleSheet'))
205 206
    Static_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                ooo_stylesheet='NotFound_getODTStyleSheet', script_name='')
207
    response = self.publish('/' + self.getPortal().Static_viewAsOdt.absolute_url(1))
208 209
    self.assertFalse(response.getBody().startswith('PK'))
    self.assertTrue(500, response.getStatus())
Nicolas Delaby's avatar
Nicolas Delaby committed
210

211
  @expectedFailure
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
  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)
    upload_file = FileUpload(file_path, filename)
    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()
    response = self.publish('/' + self.getPortal().Base_viewIncludeImageAsOdt.absolute_url(1))
    self.assertEqual('application/vnd.oasis.opendocument.text',
                     response.getHeader('content-type').split(';')[0])
    self.assertEqual('attachment; filename="Base_viewIncludeImageAsOdt.odt"',
                     response.getHeader('content-disposition'))
    self.assertTrue(200, response.getStatus())
    cs = StringIO()
    cs.write(response.getBody())
    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)

256 257 258 259 260

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