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

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

PCN requires a birth certificate upload.

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