source: main/ikobacustom.skeleton/trunk/src/ikobacustom/skeleton/customers/tests/test_browser.py @ 12382

Last change on this file since 12382 was 12382, checked in by Henrik Bettermann, 10 years ago

Uups, we agreed to attach only one file to each document.

  • Property svn:keywords set to Id
File size: 14.2 KB
Line 
1## $Id: test_browser.py 12382 2015-01-03 15:28:53Z 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"""
19Document browser and functional tests.
20"""
21import os
22import grok
23import datetime
24from cStringIO import StringIO
25from zope.component import queryUtility, getUtility, createObject
26from zope.event import notify
27from zope.interface.verify import verifyObject, verifyClass
28from zope.testbrowser.testing import Browser
29from hurry.workflow.interfaces import IWorkflowState
30from waeup.ikoba.customers.tests.test_batching import CustomerImportExportSetup
31from waeup.ikoba.customers.tests.test_browser import CustomersFullSetup
32from ikobacustom.skeleton.customers.export import (
33    SkeletonCustomerExporter,
34    SkeletonCustomerDocumentExporter,
35    SkeletonContractExporter)
36from ikobacustom.skeleton.customers.batching import (
37    SkeletonCustomerProcessor,
38    SkeletonCustomerDocumentProcessor,
39    SkeletonContractProcessor)
40from ikobacustom.skeleton.testing import FunctionalLayer, samples_dir
41
42SAMPLE_IMAGE = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
43SAMPLE_IMAGE_BMP = os.path.join(os.path.dirname(__file__), 'test_image.bmp')
44SAMPLE_PDF = os.path.join(os.path.dirname(__file__), 'test_pdf.pdf')
45
46class CustomerImportExportTest(CustomerImportExportSetup):
47
48    layer = FunctionalLayer
49
50    def setup_for_export(self):
51        customer = createObject(u'waeup.Customer')
52        customer.firstname = u'Beate'
53        customer.lastname = u'Mueller'
54        customer.reg_number = u'123'
55        customer.sex = u'f'
56        IWorkflowState(customer).setState('started')
57        self.app['customers'].addCustomer(customer)
58        document = createObject(u'waeup.SkeletonCustomerDocument')
59        document.title = u'My first document'
60        customer['documents'].addDocument(document)
61        contract = createObject(u'waeup.SkeletonContract')
62        contract.tc_dict = {'en':u'Hello World'}
63        customer['contracts'].addContract(contract)
64        self.customer = customer
65        self.document = document
66        self.contract = contract
67        self.outfile = os.path.join(self.workdir, 'myoutput.csv')
68        return
69
70    def test_export_reimport_customers(self):
71        # we can export all customers in a portal
72        # set values we can expect in export file
73        self.setup_for_export()
74        exporter = SkeletonCustomerExporter()
75        exporter.export_all(self.app, self.outfile)
76        result = open(self.outfile, 'rb').read()
77        self.assertEqual(result,
78            'customer_id,email,firstname,lastname,middlename,phone,'
79            'reg_number,sex,suspended,suspended_comment,password,state,history\r\n'
80            'K1000000,,Beate,Mueller,,,123,f,0,,,started,[]\r\n')
81        # We can reimport the file ...
82        processor = SkeletonCustomerProcessor()
83        result = processor.doImport(
84            self.outfile,
85            ['customer_id','email','firstname','lastname','middlename','phone',
86            'reg_number','sex','suspended','suspended_comment','password','state'],
87            mode='create')
88        num, num_fail, finished_path, failed_path = result
89        self.assertEqual(num_fail,1)
90        # ... if we remove the original customer.
91        del self.app['customers']['K1000000']
92        result = processor.doImport(
93            self.outfile,
94            ['customer_id','email','firstname','lastname','middlename','phone',
95            'reg_number','sex','suspended','suspended_comment','password','state'],
96            mode='create')
97        num_succ, num_fail, finished_path, failed_path = result
98        self.assertEqual(num_fail,0)
99        # We can import the same file in update mode if we ignore the reg_number.
100        result = processor.doImport(
101            self.outfile,
102            ['customer_id','email','firstname','lastname','middlename','phone',
103            'xx_reg_number','sex','suspended','suspended_comment','password','state'],
104            mode='update')
105        num_succ, num_fail, finished_path, failed_path = result
106        self.assertEqual(num_succ,1)
107        self.assertEqual(num_fail,0)
108        return
109
110    def test_export_reimport_documents(self):
111        # we can export all documents in a portal
112        # set values we can expect in export file
113        self.setup_for_export()
114        exporter = SkeletonCustomerDocumentExporter()
115        exporter.export_all(self.app, self.outfile)
116        result = open(self.outfile, 'rb').read()
117        self.assertMatches(result,
118            'class_name,document_id,history,state,title,user_id\r\n'
119            'SkeletonCustomerDocument,%s,'
120            '[u\'2014-12-21 17:00:36 WAT - Document created by system\'],'
121            'created,My first document,K1000000\r\n'
122            % self.document.document_id)
123        # We can reimport the file if we change the header (user_id -> customer_id)
124        processor = SkeletonCustomerDocumentProcessor()
125        open(self.outfile, 'wb').write(
126            'customer_id,class_name,document_id,state,title\r\n'
127            'K1000000,SkeletonCustomerDocument,%s,started,My first title\r\n'
128            % self.document.document_id)
129        result = processor.doImport(
130            self.outfile,
131            ['customer_id','class_name','document_id','state','title'],
132            mode='create')
133        num, num_fail, finished_path, failed_path = result
134        # The object exists.
135        self.assertEqual(num_fail,1)
136        # We remove the original document.
137        del self.customer['documents'][self.document.document_id]
138        result = processor.doImport(
139            self.outfile,
140            ['customer_id','class_name','document_id','state','title'],
141            mode='create')
142        num_succ, num_fail, finished_path, failed_path = result
143        self.assertEqual(num_fail,0)
144        # We can import the same file in update mode.
145        result = processor.doImport(
146            self.outfile,
147            ['customer_id','class_name','document_id','state','title'],
148            mode='update')
149        num_succ, num_fail, finished_path, failed_path = result
150        self.assertEqual(num_succ,1)
151        self.assertEqual(num_fail,0)
152        return
153
154    def test_export_reimport_contracts(self):
155        # we can export all contracts in a portal
156        # set values we can expect in export file
157        self.setup_for_export()
158        exporter = SkeletonContractExporter()
159        exporter.export_all(self.app, self.outfile)
160        result = open(self.outfile, 'rb').read()
161        self.assertMatches(result,
162            'class_name,contract_category,contract_id,document_object,'
163            'history,last_product_id,product_object,product_options,'
164            'state,tc_dict,title,user_id\r\n'
165            'SkeletonContract,sample,%s,,'
166            '[u\'2014-12-21 22:26:00 WAT - Contract created by system\']'
167            ',,,[],created,{\'en\': u\'Hello World\'},,K1000000\r\n'
168            % self.contract.contract_id)
169        # We can reimport the file if we change the header (user_id -> customer_id)
170        processor = SkeletonContractProcessor()
171        open(self.outfile, 'wb').write(
172            'class_name,contract_category,contract_id,document_object,'
173            'history,last_product_id,product_object,product_options,'
174            'state,tc_dict,title,user_id\r\n'
175            'SkeletonContract,sample,%s,,'
176            '[u\'2014-12-21 22:26:00 WAT - Contract created by system\']'
177            ',,,[],created,{\'en\': u\'Hello World\'},,K1000000\r\n'
178            % self.contract.contract_id)
179        result = processor.doImport(
180            self.outfile,
181            ['class_name','contract_category','contract_id','document_object',
182            'history','last_product_id','product_object','product_options',
183            'state','tc_dict','title','customer_id'],
184            mode='create')
185        num, num_fail, finished_path, failed_path = result
186        # The object exists.
187        self.assertEqual(num_fail,1)
188        # We remove the original contract.
189        del self.customer['contracts'][self.contract.contract_id]
190        result = processor.doImport(
191            self.outfile,
192            ['class_name','contract_category','contract_id','document_object',
193            'history','last_product_id','product_object','product_options',
194            'state','tc_dict','title','customer_id'],
195            mode='create')
196        num_succ, num_fail, finished_path, failed_path = result
197        self.assertEqual(num_fail,0)
198        # We can import the same file in update mode.
199        result = processor.doImport(
200            self.outfile,
201            ['class_name','contract_category','contract_id','document_object',
202            'history','last_product_id','product_object','product_options',
203            'state','tc_dict','title','customer_id'],
204            mode='update')
205        num_succ, num_fail, finished_path, failed_path = result
206        self.assertEqual(num_succ,1)
207        self.assertEqual(num_fail,0)
208        return
209
210class DocumentUITests(CustomersFullSetup):
211    # Tests for customer document related views and pages
212
213    layer = FunctionalLayer
214
215    def test_manage_upload_sample_file(self):
216        # Managers can upload a file via the DocumentManageFormPage
217        # The image is stored even if form has errors
218        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
219        self.browser.open(self.customer_path + '/documents/DOC1/manage')
220        # Create a pseudo image file and select it to be uploaded
221        image = open(SAMPLE_IMAGE, 'rb')
222        ctrl = self.browser.getControl(name='samplescanmanageupload')
223        file_ctrl = ctrl.mech_control
224        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
225        # The Save action does not upload files
226        self.browser.getControl("Save").click() # submit form
227        self.assertFalse(
228            'href="http://localhost/app/customers/K1000000/documents/DOC1/sample"'
229            in self.browser.contents)
230        # ... but the correct upload submit button does
231        image = open(SAMPLE_IMAGE)
232        ctrl = self.browser.getControl(name='samplescanmanageupload')
233        file_ctrl = ctrl.mech_control
234        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
235        self.browser.getControl(
236            name='upload_samplescanmanageupload').click()
237        self.assertTrue(
238            'href="http://localhost/app/customers/K1000000/documents/DOC1/sample"'
239            in self.browser.contents)
240        # Browsing the link shows a real image
241        self.browser.open('sample')
242        self.assertEqual(
243            self.browser.headers['content-type'], 'image/jpeg')
244        self.assertEqual(len(self.browser.contents), 2787)
245        # We can't reupload a file. The existing file must be deleted first.
246        self.browser.open(self.customer_path + '/documents/DOC1/manage')
247        self.assertFalse(
248            'upload_samplescanmanageupload' in self.browser.contents)
249        # File must be deleted first
250        self.browser.getControl(name='delete_samplescanmanageupload').click()
251        self.assertTrue(
252            'sample deleted' in self.browser.contents)
253        # Uploading a file which is bigger than 150k will raise an error
254        big_image = StringIO(open(SAMPLE_IMAGE, 'rb').read() * 75)
255        ctrl = self.browser.getControl(name='samplescanmanageupload')
256        file_ctrl = ctrl.mech_control
257        file_ctrl.add_file(big_image, filename='my_sample_scan.jpg')
258        self.browser.getControl(
259            name='upload_samplescanmanageupload').click()
260        self.assertTrue(
261            'Uploaded file is too big' in self.browser.contents)
262        # We do not rely on filename extensions given by uploaders
263        image = open(SAMPLE_IMAGE, 'rb') # a jpg-file
264        ctrl = self.browser.getControl(name='samplescanmanageupload')
265        file_ctrl = ctrl.mech_control
266        # Tell uploaded file is bmp
267        file_ctrl.add_file(image, filename='my_sample_scan.bmp')
268        self.browser.getControl(
269            name='upload_samplescanmanageupload').click()
270        self.assertTrue(
271            # jpg file was recognized
272            'File sample.jpg uploaded.' in self.browser.contents)
273        # Delete file again
274        self.browser.getControl(name='delete_samplescanmanageupload').click()
275        self.assertTrue(
276            'sample deleted' in self.browser.contents)
277        # File names must meet several conditions
278        bmp_image = open(SAMPLE_IMAGE_BMP, 'rb')
279        ctrl = self.browser.getControl(name='samplescanmanageupload')
280        file_ctrl = ctrl.mech_control
281        file_ctrl.add_file(bmp_image, filename='my_sample_scan.bmp')
282        self.browser.getControl(
283            name='upload_samplescanmanageupload').click()
284        self.assertTrue('Only the following extensions are allowed'
285            in self.browser.contents)
286
287class ContractUITests(CustomersFullSetup):
288    # Tests for contract related views and pages
289
290    layer = FunctionalLayer
291
292    def test_view_slips(self):
293        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
294        # Officers can open contract slips.
295        # First we add a submitted document and a product.
296        IWorkflowState(self.document).setState('submitted')
297        self.contract.document_object = self.document
298        self.contract.product_object = self.product
299        self.contract.tc_dict = {'en': u'<strong>Hello world</strong>'}
300        self.browser.open(self.customer_path + '/contracts/CON1')
301        self.browser.getLink("Download contract slip").click()
302        self.assertEqual(self.browser.headers['Status'], '200 Ok')
303        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
304        path = os.path.join(samples_dir(), 'contract_slip.pdf')
305        open(path, 'wb').write(self.browser.contents)
306        print "Sample contract_slip.pdf written to %s" % path
Note: See TracBrowser for help on using the repository browser.