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

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

Adjust to changes made in base package.

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