source: main/waeup.ikoba/trunk/src/waeup/ikoba/documents/tests/test_browser.py @ 15256

Last change on this file since 15256 was 13264, checked in by Henrik Bettermann, 9 years ago

Show file size of pdf documents in the documents section.

  • Property svn:keywords set to Id
File size: 16.3 KB
Line 
1## $Id: test_browser.py 13264 2015-09-17 08:33:26Z henrik $
2##
3## Copyright (C) 2014 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""
19Test the document-related UI components.
20"""
21import shutil
22import tempfile
23from datetime import datetime, timedelta, date
24from StringIO import StringIO
25import os
26from zope.event import notify
27from zope.component import createObject, queryUtility, getUtility
28from zope.component.hooks import setSite, clearSite
29from zope.schema.interfaces import ConstraintNotSatisfied
30from zope.catalog.interfaces import ICatalog
31from zope.security.interfaces import Unauthorized
32from zope.securitypolicy.interfaces import IPrincipalRoleManager
33from zope.testbrowser.testing import Browser
34from hurry.workflow.interfaces import (
35    IWorkflowInfo, IWorkflowState, InvalidTransitionError)
36from waeup.ikoba.testing import FunctionalLayer, FunctionalTestCase
37from waeup.ikoba.app import Company
38from waeup.ikoba.interfaces import (
39    IUserAccount, IJobManager, APPROVED, SUBMITTED, PUBLISHED,
40    IFileStoreNameChooser, IExtFileStore, IFileStoreHandler)
41from waeup.ikoba.imagestorage import (
42    FileStoreNameChooser, ExtFileStore, DefaultFileStoreHandler,
43    DefaultStorage)
44from waeup.ikoba.authentication import LocalRoleSetEvent
45from waeup.ikoba.tests.test_async import FunctionalAsyncTestCase
46from waeup.ikoba.interfaces import VERIFIED
47from waeup.ikoba.browser.tests.test_pdf import samples_dir
48
49PH_LEN = 15911  # Length of placeholder file
50
51SAMPLE_IMAGE = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
52#SAMPLE_IMAGE_BMP = os.path.join(os.path.dirname(__file__), 'test_image.bmp')
53SAMPLE_PDF = os.path.join(os.path.dirname(__file__), 'test_pdf.pdf')
54
55class FullSetup(FunctionalTestCase):
56    # A test case that only contains a setup and teardown
57    #
58    # Complete setup for customers handlings is rather complex and
59    # requires lots of things created before we can start. This is a
60    # setup that does all this, creates a company etc.
61    # so that we do not have to bother with that in different
62    # test cases.
63
64    layer = FunctionalLayer
65
66    def setUp(self):
67        super(FullSetup, self).setUp()
68
69        # Setup a sample site for each test
70        app = Company()
71        self.dc_root = tempfile.mkdtemp()
72        app['datacenter'].setStoragePath(self.dc_root)
73
74        # Prepopulate the ZODB...
75        self.getRootFolder()['app'] = app
76        # we add the site immediately after creation to the
77        # ZODB. Catalogs and other local utilities are not setup
78        # before that step.
79        self.app = self.getRootFolder()['app']
80        # Set site here. Some of the following setup code might need
81        # to access grok.getSite() and should get our new app then
82        setSite(app)
83
84        self.login_path = 'http://localhost/app/login'
85        self.container_path = 'http://localhost/app/documents'
86
87        # Put the prepopulated site into test ZODB and prepare test
88        # browser
89        self.browser = Browser()
90        self.browser.handleErrors = False
91
92    def tearDown(self):
93        super(FullSetup, self).tearDown()
94        clearSite()
95        shutil.rmtree(self.dc_root)
96
97
98class DocumentUITests(FullSetup):
99    # Tests for document related views and pages
100
101    def test_manage_file_document(self):
102        # Managers can access the pages of documentsconter
103        # and can perform actions
104        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
105        self.browser.open('http://localhost/app')
106        self.assertEqual(self.browser.headers['Status'], '200 Ok')
107        self.browser.getLink("Documents").click()
108        self.assertEqual(self.browser.url, self.container_path)
109        self.browser.getLink("Manage").click()
110        self.browser.getControl("Add document").click()
111        self.browser.getControl(name="doctype").value = ['PDFDocument']
112        self.browser.getControl(name="form.title").value = 'My PDF Document'
113        self.browser.getControl(name="form.document_id").value = 'DOC1'
114        self.browser.getControl("Add document").click()
115        self.assertTrue('PDF Document added.' in self.browser.contents)
116        document = self.app['documents']['DOC1']
117
118        # Document can be edited
119        self.browser.getControl(name="form.title").value = 'My first doc'
120        self.browser.getControl("Save").click()
121        self.assertTrue('Form has been saved.' in self.browser.contents)
122        self.browser.getLink("View").click()
123        self.assertEqual(self.browser.url, self.container_path + '/DOC1/index')
124
125        # File can be uploaded
126        self.browser.getLink("Manage").click()
127        # Create a pseudo image file and select it to be uploaded
128        image = open(SAMPLE_IMAGE, 'rb')
129        ctrl = self.browser.getControl(name='pdfscanmanageupload')
130        file_ctrl = ctrl.mech_control
131        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
132        self.browser.getControl(
133            name='upload_pdfscanmanageupload').click()
134        self.assertTrue(
135            'pdf file format expected' in self.browser.contents)
136        ctrl = self.browser.getControl(name='pdfscanmanageupload')
137        file_ctrl = ctrl.mech_control
138        file_ctrl.add_file(image, filename='my_sample_scan.pdf')
139        self.browser.getControl(
140            name='upload_pdfscanmanageupload').click()
141        self.assertTrue(
142            'Could not determine file type' in self.browser.contents)
143        pdf = open(SAMPLE_PDF, 'rb')
144        ctrl = self.browser.getControl(name='pdfscanmanageupload')
145        file_ctrl = ctrl.mech_control
146        file_ctrl.add_file(pdf, filename='my_sample_scan.pdf')
147        self.browser.getControl(
148            name='upload_pdfscanmanageupload').click()
149        # The file size is shown
150        self.assertTrue(
151            'href="http://localhost/app/documents/DOC1/file.pdf">DOC1.pdf (23.7 kB)</a>'
152            in self.browser.contents)
153        # Also on display page the file size is displayed.
154        self.browser.open(self.container_path + '/DOC1')
155        self.assertTrue(
156            'href="http://localhost/app/documents/DOC1/file.pdf">DOC1.pdf (23.7 kB)</a>'
157            in self.browser.contents)
158        # The file can be found in the file system
159        file = getUtility(IExtFileStore).getFileByContext(
160            document, attr='file.pdf')
161        file_content = file.read()
162        pdf.seek(0)
163        pdf_content = pdf.read()
164        self.assertEqual(file_content, pdf_content)
165        # Browsing the link shows a real pdf only if the document
166        # has been published
167        self.browser.getLink("DOC1.pdf").click()
168        self.assertTrue(
169            'The document requested has not yet been published'
170            in self.browser.contents)
171        IWorkflowState(document).setState(PUBLISHED)
172        self.browser.open(self.container_path + '/DOC1/file.pdf')
173        self.assertEqual(
174            self.browser.headers['content-type'], 'application/pdf')
175        # The name of the downloaded file will be different
176        self.assertEqual(
177            self.browser.headers['Content-Disposition'],
178            'attachment; filename="DOC1.pdf')
179
180        # Transitions can be performed
181        self.assertEqual(document.state, 'published')
182        self.browser.open(self.container_path + '/DOC1')
183        self.browser.getLink("Transition").click()
184        self.browser.getControl(name="transition").value = ['retract']
185        self.browser.getControl("Apply now").click()
186        self.assertEqual(document.state, 'created')
187
188        # Documents can be removed
189        self.browser.getLink("Documents").click()
190        self.browser.getLink("Manage").click()
191        ctrl = self.browser.getControl(name='val_id')
192        ctrl.getControl(value=document.document_id).selected = True
193        self.browser.getControl("Remove selected", index=0).click()
194        self.assertTrue('Successfully removed' in self.browser.contents)
195
196        # File has been removed too
197        file = getUtility(IExtFileStore).getFileByContext(
198            document, attr='file.pdf')
199        self.assertTrue(file is None)
200
201        # All actions are being logged
202        logfile = os.path.join(
203            self.app['datacenter'].storage, 'logs', 'main.log')
204        logcontent = open(logfile).read()
205
206        self.assertTrue(
207            'INFO - zope.mgr - %s - Document created' % document.document_id
208            in logcontent)
209        self.assertTrue(
210            'INFO - zope.mgr - documents.browser.DocumentAddFormPage - added: PDF Document %s'
211            % document.document_id in logcontent)
212        self.assertTrue(
213            'INFO - zope.mgr - documents.browser.DocumentManageFormPage - %s - saved: title'
214            % document.document_id in logcontent)
215        self.assertTrue(
216            'INFO - zope.mgr - documents.browser.DocumentManageFormPage - %s - uploaded: file.pdf (my_sample_scan.pdf)'
217            % document.document_id in logcontent)
218        self.assertTrue(
219            'INFO - zope.mgr - %s - Document retracted' % document.document_id
220            in logcontent)
221        self.assertTrue(
222            'INFO - zope.mgr - documents.browser.DocumentsContainerManageFormPage - removed: %s'
223            % document.document_id in logcontent)
224
225    def test_manage_html_document(self):
226        # Managers can access the pages of documentsconter
227        # and can perform actions
228        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
229        self.browser.open('http://localhost/app')
230        self.assertEqual(self.browser.headers['Status'], '200 Ok')
231        self.browser.getLink("Documents").click()
232        self.assertEqual(self.browser.url, self.container_path)
233        self.browser.getLink("Manage").click()
234        self.browser.getControl("Add document").click()
235        self.browser.getControl(name="doctype").value = ['HTMLDocument']
236        self.browser.getControl(name="form.document_id").value = 'DOC2'
237        self.browser.getControl(name="form.title").value = 'My HTML Document'
238        self.browser.getControl("Add document").click()
239        self.assertTrue('HTML Document added.' in self.browser.contents)
240        document = self.app['documents']['DOC2']
241        # All form action buttons are there
242        self.assertTrue('value="Add local role"' in self.browser.contents)
243        self.assertTrue('value="Save"' in self.browser.contents)
244        self.assertTrue('value="Cancel"' in self.browser.contents)
245        # Document can be edited
246        self.browser.getControl(name="form.title").value = 'My second doc'
247        self.browser.getControl(name="form.html_multilingual").value = """
248<h1>Hello World</h1>
249>>de<<
250<h1>Hallo Welt</h1>
251"""
252        self.browser.getControl("Save").click()
253        self.assertTrue('Form has been saved.' in self.browser.contents)
254        self.browser.getLink("View").click()
255        self.assertEqual(self.browser.url, self.container_path + '/DOC2/index')
256        self.assertTrue(
257            '<h1>Hello World</h1>' in self.browser.contents)
258        self.assertFalse(
259            '<h1>Hallo Welt</h1>' in self.browser.contents)
260        self.browser.getLink("de").click()
261        self.assertFalse(
262            '<h1>Hello World</h1>' in self.browser.contents)
263        self.assertTrue(
264            '<h1>Hallo Welt</h1>' in self.browser.contents)
265        # The content can't be rendered yet
266        self.browser.open(self.container_path + '/DOC2/display')
267        self.assertTrue(
268            'The document requested has not yet been published'
269            in self.browser.contents)
270        # We have been redirected to the portal root
271        self.assertEqual(self.browser.url, 'http://localhost/app')
272
273        # Transitions can be performed
274        self.browser.open(self.container_path + '/DOC2')
275        self.browser.getLink("Transition").click()
276        self.browser.getControl(name="transition").value = ['publish']
277        self.browser.getControl("Jetzt anwenden").click()
278        self.assertEqual(document.state, 'published')
279
280        # The content can be rendered
281        self.browser.open(self.container_path + '/DOC2/display')
282        self.assertTrue(
283            '<h1>Hallo Welt</h1>' in self.browser.contents)
284
285        # Documents can be removed
286        self.browser.getLink("en", index=3).click()
287        self.browser.getLink("Documents").click()
288        self.browser.getLink("Manage").click()
289        ctrl = self.browser.getControl(name='val_id')
290        ctrl.getControl(value=document.document_id).selected = True
291        self.browser.getControl("Remove selected", index=0).click()
292        self.assertTrue('Successfully removed' in self.browser.contents)
293
294        # All actions are being logged
295        logfile = os.path.join(
296            self.app['datacenter'].storage, 'logs', 'main.log')
297        logcontent = open(logfile).read()
298
299        self.assertTrue(
300            'INFO - zope.mgr - %s - Document created' % document.document_id
301            in logcontent)
302        self.assertTrue(
303            'INFO - zope.mgr - documents.browser.DocumentAddFormPage - added: HTML Document %s'
304            % document.document_id in logcontent)
305        self.assertTrue(
306            'INFO - zope.mgr - documents.browser.HTMLDocumentManageFormPage - %s - saved: title + html_multilingual'
307            % document.document_id in logcontent)
308        self.assertTrue(
309            'INFO - zope.mgr - %s - Document published' % document.document_id
310            in logcontent)
311        self.assertTrue(
312            'INFO - zope.mgr - documents.browser.DocumentsContainerManageFormPage - removed: %s'
313            % document.document_id in logcontent)
314
315    def test_manage_rest_document(self):
316        # Managers can access the pages of documentsconter
317        # and can perform actions
318        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
319        self.browser.open('http://localhost/app')
320        self.assertEqual(self.browser.headers['Status'], '200 Ok')
321        self.browser.getLink("Documents").click()
322        self.assertEqual(self.browser.url, self.container_path)
323        self.browser.getLink("Manage").click()
324        self.browser.getControl("Add document").click()
325        self.browser.getControl(name="doctype").value = ['RESTDocument']
326        self.browser.getControl(name="form.document_id").value = 'DOC3'
327        self.browser.getControl(name="form.title").value = 'My REST Document'
328        self.browser.getControl("Add document").click()
329        self.assertTrue('REST Document added.' in self.browser.contents)
330        document = self.app['documents']['DOC3']
331
332        # Document can be edited
333        self.browser.getControl(name="form.rest_multilingual").value = """
334----------
335Main Title
336----------
337
338Subtitle
339========
340>>de<<
341----------
342Haupttitel
343----------
344
345Untertitel
346==========
347"""
348        self.browser.getControl("Save").click()
349        self.assertTrue('Form has been saved.' in self.browser.contents)
350        self.browser.getLink("View").click()
351        self.assertEqual(self.browser.url, self.container_path + '/DOC3/index')
352        self.assertTrue(
353            '<h1 class="title">Main Title</h1>' in self.browser.contents)
354        self.assertTrue(
355            '<h2 class="subtitle" id="subtitle">Subtitle</h2>'
356            in self.browser.contents)
357        self.assertFalse(
358            '<h1 class="title">Haupttitel</h1>' in self.browser.contents)
359        self.browser.getLink("de").click()
360        self.assertFalse(
361            '<h1 class="title">Main Title</h1>' in self.browser.contents)
362        self.assertTrue(
363            '<h1 class="title">Haupttitel</h1>' in self.browser.contents)
364        # The content can be rendered
365        IWorkflowState(document).setState(PUBLISHED)
366        self.browser.open(self.container_path + '/DOC3/display')
367        self.assertTrue(
368            '<h1 class="title">Haupttitel</h1>' in self.browser.contents)
369        # The page label (object title) is not displayed
370        self.assertFalse(
371            '<h1 class="ikoba-content-label">My REST Document</h1>'
372            in self.browser.contents)
Note: See TracBrowser for help on using the repository browser.