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

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

Add Registration as Pharmaceutical Chemist contract.

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