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

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

Update tests.

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