source: main/ikobacustom.pcn/trunk/src/ikobacustom/pcn/customers/tests/test_browser.py @ 12801

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

Rename state_of_origin.

  • Property svn:keywords set to Id
File size: 22.6 KB
Line 
1## $Id: test_browser.py 12798 2015-03-19 16:58:47Z 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.pcn.customers.export import (
33    PCNCustomerExporter,
34    PCNCustomerPDFDocumentExporter,
35    PCNCustomerJPGDocumentExporter,
36    RONContractExporter,
37    ROPContractExporter)
38from ikobacustom.pcn.customers.batching import (
39    PCNCustomerProcessor,
40    PCNCustomerPDFDocumentProcessor,
41    PCNCustomerJPGDocumentProcessor,
42    RONContractProcessor,
43    ROPContractProcessor)
44from ikobacustom.pcn.testing import FunctionalLayer, samples_dir
45
46SAMPLE_IMAGE = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
47SAMPLE_IMAGE_BMP = os.path.join(os.path.dirname(__file__), 'test_image.bmp')
48SAMPLE_PDF = os.path.join(os.path.dirname(__file__), 'test_pdf.pdf')
49
50class CustomerImportExportTest(CustomerImportExportSetup):
51
52    layer = FunctionalLayer
53
54    def setup_customizable_params(self):
55        self._contract_category = u'ron'
56        return
57
58    def setup_for_export(self):
59        customer = createObject(u'waeup.Customer')
60        customer.firstname = u'Beate'
61        customer.lastname = u'Mueller'
62        customer.reg_number = u'123'
63        customer.sex = u'f'
64        customer.email = u'aa@aa.aa'
65        customer.res_address = u'My address'
66        customer.date_of_birth = datetime.date(1981, 2, 4)
67        IWorkflowState(customer).setState('started')
68        self.app['customers'].addCustomer(customer)
69        document1 = createObject(u'waeup.PCNCustomerPDFDocument')
70        document1.title = u'My first document'
71        document2 = createObject(u'waeup.PCNCustomerJPGDocument')
72        document2.title = u'My second document'
73        customer['documents'].addDocument(document1)
74        customer['documents'].addDocument(document2)
75        contract1 = createObject(u'waeup.RONContract')
76        contract1.tc_dict = {'en':u'Hello World'}
77        customer['contracts'].addContract(contract1)
78        contract2 = createObject(u'waeup.ROPContract')
79        contract2.tc_dict = {'en':u'Hello World'}
80        customer['contracts'].addContract(contract2)
81        self.customer = customer
82        self.document1 = document1
83        self.document2 = document2
84        self.contract1 = contract1
85        self.contract2 = contract2
86        self.outfile = os.path.join(self.workdir, 'myoutput.csv')
87        return
88
89    def test_export_reimport_customers(self):
90        # we can export all customers in a portal
91        # set values we can expect in export file
92        self.setup_for_export()
93        exporter = PCNCustomerExporter()
94        exporter.export_all(self.app, self.outfile)
95        result = open(self.outfile, 'rb').read()
96        self.assertEqual(result,
97            'customer_id,date_of_birth,email,firstname,lastname,middlename,phone,'
98            'reg_number,res_address,sex,suspended,suspended_comment,password,state,history\r\n'
99            'K1000000,1981-02-04#,aa@aa.aa,Beate,Mueller,,,123,My address,f,0,,,started,[]\r\n')
100        # We can reimport the file ...
101        processor = PCNCustomerProcessor()
102        result = processor.doImport(
103            self.outfile,
104            ['customer_id','date_of_birth','email','firstname','lastname','middlename','phone',
105            'reg_number','res_address','sex','suspended','suspended_comment','password','state'],
106            mode='create')
107        num, num_fail, finished_path, failed_path = result
108        self.assertEqual(num_fail,1)
109        # ... if we remove the original customer.
110        del self.app['customers']['K1000000']
111        result = processor.doImport(
112            self.outfile,
113            ['customer_id','date_of_birth','email','firstname','lastname','middlename','phone',
114            'reg_number','res_address','sex','suspended','suspended_comment','password','state'],
115            mode='create')
116        num_succ, num_fail, finished_path, failed_path = result
117        self.assertEqual(num_fail,0)
118        # We can import the same file in update mode if we ignore
119        # the reg_number and email address
120        result = processor.doImport(
121            self.outfile,
122            ['customer_id','date_of_birth','xx_email','firstname','lastname','middlename','phone',
123            'xx_reg_number','res_address','sex','suspended','suspended_comment','password','state'],
124            mode='update')
125        num_succ, num_fail, finished_path, failed_path = result
126        self.assertEqual(num_succ,1)
127        self.assertEqual(num_fail,0)
128        return
129
130    def test_export_reimport_pdf_documents(self):
131        # we can export all documents in a portal
132        # set values we can expect in export file
133        self.setup_for_export()
134        exporter = PCNCustomerPDFDocumentExporter()
135        exporter.export_all(self.app, self.outfile)
136        result = open(self.outfile, 'rb').read()
137        self.assertMatches(result,
138            'class_name,document_id,history,state,title,user_id\r\n'
139            'PCNCustomerPDFDocument,%s,'
140            '[u\'2014-12-21 17:00:36 WAT - Document created by system\'],'
141            'created,My first document,K1000000\r\n'
142            % self.document1.document_id)
143        # We can reimport the file if we change the header (user_id -> customer_id)
144        processor = PCNCustomerPDFDocumentProcessor()
145        open(self.outfile, 'wb').write(
146            'customer_id,class_name,document_id,state,title\r\n'
147            'K1000000,PCNCustomerPDFDocument,%s,started,My first title\r\n'
148            % self.document1.document_id)
149        result = processor.doImport(
150            self.outfile,
151            ['customer_id','class_name','document_id','state','title'],
152            mode='create')
153        num, num_fail, finished_path, failed_path = result
154        # The object exists.
155        self.assertEqual(num_fail,1)
156        # We remove the original document.
157        del self.customer['documents'][self.document1.document_id]
158        result = processor.doImport(
159            self.outfile,
160            ['customer_id','class_name','document_id','state','title'],
161            mode='create')
162        num_succ, num_fail, finished_path, failed_path = result
163        self.assertEqual(num_fail,0)
164        # We can import the same file in update mode.
165        result = processor.doImport(
166            self.outfile,
167            ['customer_id','class_name','document_id','state','title'],
168            mode='update')
169        num_succ, num_fail, finished_path, failed_path = result
170        self.assertEqual(num_succ,1)
171        self.assertEqual(num_fail,0)
172        return
173
174    def test_export_reimport_jpg_documents(self):
175        # we can export all documents in a portal
176        # set values we can expect in export file
177        self.setup_for_export()
178        exporter = PCNCustomerJPGDocumentExporter()
179        exporter.export_all(self.app, self.outfile)
180        result = open(self.outfile, 'rb').read()
181        self.assertMatches(result,
182            'class_name,document_id,history,state,title,user_id\r\n'
183            'PCNCustomerJPGDocument,%s,'
184            '[u\'2014-12-21 17:00:36 WAT - Document created by system\'],'
185            'created,My second document,K1000000\r\n'
186            % self.document2.document_id)
187        # We can reimport the file if we change the header (user_id -> customer_id)
188        processor = PCNCustomerJPGDocumentProcessor()
189        open(self.outfile, 'wb').write(
190            'customer_id,class_name,document_id,state,title\r\n'
191            'K1000000,PCNCustomerJPGDocument,%s,started,My second title\r\n'
192            % self.document2.document_id)
193        result = processor.doImport(
194            self.outfile,
195            ['customer_id','class_name','document_id','state','title'],
196            mode='create')
197        num, num_fail, finished_path, failed_path = result
198        # The object exists.
199        self.assertEqual(num_fail,1)
200        # We remove the original document.
201        del self.customer['documents'][self.document2.document_id]
202        result = processor.doImport(
203            self.outfile,
204            ['customer_id','class_name','document_id','state','title'],
205            mode='create')
206        num_succ, num_fail, finished_path, failed_path = result
207        self.assertEqual(num_fail,0)
208        # We can import the same file in update mode.
209        result = processor.doImport(
210            self.outfile,
211            ['customer_id','class_name','document_id','state','title'],
212            mode='update')
213        num_succ, num_fail, finished_path, failed_path = result
214        self.assertEqual(num_succ,1)
215        self.assertEqual(num_fail,0)
216        return
217
218    def test_export_reimport_roncontracts(self):
219        # we can export all contracts in a portal
220        # set values we can expect in export file
221        self.setup_for_export()
222        exporter = RONContractExporter()
223        exporter.export_all(self.app, self.outfile)
224        result = open(self.outfile, 'rb').read()
225        self.assertMatches(result,
226            'categories_practice,class_name,comment,contract_category,contract_id,'
227            'fee_based,history,last_product_id,lga,nationality,product_object,'
228            'product_options,state,superintendent,'
229            'tc_dict,title,user_id,valid_from,valid_to,work_address,work_email,work_phone,'
230            'year_qualification\r\n'
231            '[],RONContract,,ron,%s,0,'
232            '[u\'2015-01-18 16:40:01 WAT - License created by system\'],,,,,'
233            '[],created,,{\'en\': u\'Hello World\'},,K1000000,,,,,,\r\n'
234            % self.contract1.contract_id)
235        # We can reimport the file if we change the header
236        # (user_id -> customer_id). Not all columns are necessary.
237        processor = RONContractProcessor()
238        open(self.outfile, 'wb').write(
239            'class_name,contract_category,contract_id,document_object,'
240            'history,last_product_id,product_object,product_options,'
241            'state,tc_dict,title,user_id\r\n'
242            'RONContract,license,%s,,'
243            '[u\'2014-12-21 22:26:00 WAT - License created by system\']'
244            ',,,[],created,{\'en\': u\'Hello World\'},,K1000000\r\n'
245            % self.contract1.contract_id)
246        result = processor.doImport(
247            self.outfile,
248            ['class_name','contract_category','contract_id','document_object',
249            'history','last_product_id','product_object','product_options',
250            'state','tc_dict','title','customer_id'],
251            mode='create')
252        num, num_fail, finished_path, failed_path = result
253        # The object exists.
254        self.assertEqual(num_fail,1)
255        # We remove the original contract.
256        del self.customer['contracts'][self.contract1.contract_id]
257        result = processor.doImport(
258            self.outfile,
259            ['class_name','contract_category','contract_id','document_object',
260            'history','last_product_id','product_object','product_options',
261            'state','tc_dict','title','customer_id'],
262            mode='create')
263        num_succ, num_fail, finished_path, failed_path = result
264        self.assertEqual(num_fail,0)
265        # We can import the same file in update mode.
266        result = processor.doImport(
267            self.outfile,
268            ['class_name','contract_category','contract_id','document_object',
269            'history','last_product_id','product_object','product_options',
270            'state','tc_dict','title','customer_id'],
271            mode='update')
272        num_succ, num_fail, finished_path, failed_path = result
273        self.assertEqual(num_succ,1)
274        self.assertEqual(num_fail,0)
275        return
276
277    def test_export_reimport_ropcontracts(self):
278        # we can export all contracts in a portal
279        # set values we can expect in export file
280        self.setup_for_export()
281        exporter = ROPContractExporter()
282        exporter.export_all(self.app, self.outfile)
283        result = open(self.outfile, 'rb').read()
284        self.assertMatches(result,
285            'categories_practice,class_name,contract_category,contract_id,'
286            'date_of_qualification,fee_based,history,inspected,last_license_number,'
287            'last_product_id,official_in_state,other_directors,'
288            'pharmacists_directors,premises_address,premises_certificate,'
289            'product_object,product_options,recommended,'
290            'state,superintendent,tc_dict,title,user_id,valid_from,valid_to,'
291            'work_address\r\n'
292
293            '[],ROPContract,rop,%s,,0,'
294            '[u\'2015-01-20 18:51:03 WAT - License created by system\']'
295            ',,,,,,,,,,[],,created,,{\'en\': u\'Hello World\'},,K1000000,,,\r\n'
296            % self.contract2.contract_id)
297        # We can reimport the file if we change the header
298        # (user_id -> customer_id). Not all columns are necessary.
299        processor = ROPContractProcessor()
300        open(self.outfile, 'wb').write(
301            'class_name,contract_category,contract_id,document_object,'
302            'history,last_product_id,product_object,product_options,'
303            'state,tc_dict,title,user_id\r\n'
304            'ROPContract,rop,%s,,'
305            '[u\'2014-12-21 22:26:00 WAT - License created by system\']'
306            ',,,[],created,{\'en\': u\'Hello World\'},,K1000000\r\n'
307            % self.contract2.contract_id)
308        result = processor.doImport(
309            self.outfile,
310            ['class_name','contract_category','contract_id','document_object',
311            'history','last_product_id','product_object','product_options',
312            'state','tc_dict','title','customer_id'],
313            mode='create')
314        num, num_fail, finished_path, failed_path = result
315        # The object exists.
316        self.assertEqual(num_fail,1)
317        # We remove the original contract.
318        del self.customer['contracts'][self.contract2.contract_id]
319        result = processor.doImport(
320            self.outfile,
321            ['class_name','contract_category','contract_id','document_object',
322            'history','last_product_id','product_object','product_options',
323            'state','tc_dict','title','customer_id'],
324            mode='create')
325        num_succ, num_fail, finished_path, failed_path = result
326        self.assertEqual(num_fail,0)
327        # We can import the same file in update mode.
328        result = processor.doImport(
329            self.outfile,
330            ['class_name','contract_category','contract_id','document_object',
331            'history','last_product_id','product_object','product_options',
332            'state','tc_dict','title','customer_id'],
333            mode='update')
334        num_succ, num_fail, finished_path, failed_path = result
335        self.assertEqual(num_succ,1)
336        self.assertEqual(num_fail,0)
337        return
338
339
340class CustomerUITests(CustomersFullSetup):
341
342    layer = FunctionalLayer
343
344    def setup_customizable_params(self):
345        self._contract_category = u'ron'
346        self._document_factory = 'waeup.PCNCustomerPDFDocument'
347        self._contract_factory = 'waeup.RONContract'
348        return
349
350    def test_customer_edit_upload_upload_and_request(self):
351        # Customer cant login if their password is not set
352        self.browser.open(self.login_path)
353        self.browser.getControl(name="form.login").value = self.customer_id
354        self.browser.getControl(name="form.password").value = 'cpwd'
355        self.browser.getControl("Login").click()
356        self.assertMatches(
357            '...You logged in...', self.browser.contents)
358        self.browser.getLink("Edit").click()
359        self.browser.getControl(name="form.email").value = 'new_email@aa.ng'
360        self.browser.getControl(name="form.res_address").value = 'My address'
361        self.browser.getControl("Save", index=0).click()
362        self.assertMatches('...Form has been saved...',
363                           self.browser.contents)
364        self.browser.getControl("Save and request registration").click()
365        self.assertMatches('...Passport picture is missing...',
366                           self.browser.contents)
367        self.assertEqual(self.customer.state, 'started')
368        # Customer must upload a passport picture. We are already on
369        # the upload page.
370        ctrl = self.browser.getControl(name='passporteditupload')
371        file_obj = open(SAMPLE_IMAGE, 'rb')
372        file_ctrl = ctrl.mech_control
373        file_ctrl.add_file(file_obj, filename='my_photo.jpg')
374        self.browser.getControl(
375            name='upload_passporteditupload').click()
376        self.assertTrue(
377            'src="http://localhost/app/customers/K1000000/passport.jpg"'
378            in self.browser.contents)
379        self.browser.getControl(name="CANCEL").click()
380        self.assertEqual(self.browser.url, self.customer_path)
381        self.browser.getLink("Edit").click()
382        self.browser.getControl("Save and request registration").click()
383        self.assertMatches('...Birth certificate is missing...',
384                           self.browser.contents)
385        self.assertEqual(self.customer.state, 'started')
386        ctrl = self.browser.getControl(name='birthcertificateeditupload')
387        file_obj = open(SAMPLE_PDF, 'rb')
388        file_ctrl = ctrl.mech_control
389        file_ctrl.add_file(file_obj, filename='my_bc.pdf')
390        self.browser.getControl(
391            name='upload_birthcertificateeditupload').click()
392        self.assertTrue(
393            'href="http://localhost/app/customers/K1000000/birth_certificate.pdf"'
394            in self.browser.contents)
395        self.browser.getControl(name="CANCEL").click()
396        self.browser.getLink("Edit").click()
397        self.browser.getControl("Save and request registration").click()
398        self.assertMatches('...Registration form has been submitted...',
399                           self.browser.contents)
400        self.assertEqual(self.customer.state, 'requested')
401        # Customer can view history
402        self.browser.getLink("History").click()
403        self.assertMatches('...Registration record created by system...',
404            self.browser.contents)
405
406
407class DocumentUITests(CustomersFullSetup):
408    # Tests for customer document related views and pages
409
410    layer = FunctionalLayer
411
412    def setup_customizable_params(self):
413        self._contract_category = u'ron'
414        self._document_factory = 'waeup.PCNCustomerPDFDocument'
415        self._contract_factory = 'waeup.RONContract'
416        return
417
418    def test_manage_upload_pdf_file(self):
419        # Managers can upload a file via the DocumentManageFormPage
420        # The image is stored even if form has errors
421        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
422        self.browser.open(self.customer_path + '/documents')
423        self.browser.getControl("Add document").click()
424        self.browser.getControl(name="doctype").value = ['PCNCustomerPDFDocument']
425        self.browser.getControl(name="form.title").value = 'My PCN Document'
426        self.browser.getControl("Add document").click()
427        docid = [i for i in self.customer['documents'].keys() if len(i) > 10][0]
428        self.browser.open(self.documents_path + '/%s/manage' % docid)
429        # Create a pseudo image file and select it to be uploaded
430        image = open(SAMPLE_IMAGE, 'rb')
431        ctrl = self.browser.getControl(name='pdfscanmanageupload')
432        file_ctrl = ctrl.mech_control
433        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
434        self.browser.getControl(
435            name='upload_pdfscanmanageupload').click()
436        self.assertTrue(
437            'pdf file format expected' in self.browser.contents)
438        ctrl = self.browser.getControl(name='pdfscanmanageupload')
439        file_ctrl = ctrl.mech_control
440        file_ctrl.add_file(image, filename='my_sample_scan.pdf')
441        self.browser.getControl(
442            name='upload_pdfscanmanageupload').click()
443        self.assertTrue(
444            'Could not determine file type' in self.browser.contents)
445        pdf = open(SAMPLE_PDF, 'rb')
446        ctrl = self.browser.getControl(name='pdfscanmanageupload')
447        file_ctrl = ctrl.mech_control
448        file_ctrl.add_file(pdf, filename='my_sample_scan.pdf')
449        self.browser.getControl(
450            name='upload_pdfscanmanageupload').click()
451        self.assertTrue(
452            'href="http://localhost/app/customers/K1000000/documents/%s/scan.pdf">%s.pdf</a>'
453            % (docid, docid[:9]) in self.browser.contents)
454        # Browsing the link shows a real pdf
455        self.browser.open('scan.pdf')
456        self.assertEqual(
457            self.browser.headers['content-type'], 'application/pdf')
458        # The name of the downloaded file will be different
459        self.assertEqual(
460            self.browser.headers['Content-Disposition'],
461            'attachment; filename="%s.pdf' % docid[:9])
462
463
464class ContractUITests(CustomersFullSetup):
465    # Tests for contract related views and pages
466
467    layer = FunctionalLayer
468
469    def setup_customizable_params(self):
470        self._contract_category = u'ron'
471        self._document_factory = 'waeup.PCNCustomerPDFDocument'
472        self._contract_factory = 'waeup.RONContract'
473        return
474
475    def test_view_slips(self):
476        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
477        # Officers can open contract slips.
478        # First we add a submitted document and a product.
479        IWorkflowState(self.document).setState('submitted')
480        self.contract.title = u'Contract Title'
481        self.contract.document_object = self.document
482        self.contract.product_object = self.product
483        self.contract.tc_dict = {'en': u'<strong>Hello world</strong>'}
484        self.browser.open(self.customer_path + '/contracts/CON1')
485        self.browser.getLink("Download license slip").click()
486        self.assertEqual(self.browser.headers['Status'], '200 Ok')
487        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
488        path = os.path.join(samples_dir(), 'contract_slip.pdf')
489        open(path, 'wb').write(self.browser.contents)
490        print "Sample contract_slip.pdf written to %s" % path
Note: See TracBrowser for help on using the repository browser.