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

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

Revert changes from revision 12791.

  • Property svn:keywords set to Id
File size: 22.5 KB
Line 
1## $Id: test_browser.py 12794 2015-03-19 11:44:54Z 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            'fee_based,history,last_product_id,lga,product_object,'
227            'product_options,res_address,state,state_of_origin,superintendent,'
228            'tc_dict,title,user_id,valid_from,valid_to,work_address,work_email,work_phone,'
229            'year_qualification\r\n'
230            '[],RONContract,,ron,%s,0,'
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,fee_based,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,valid_from,valid_to,'
290            'work_address\r\n'
291
292            '[],ROPContract,rop,%s,,0,'
293            '[u\'2015-01-20 18:51:03 WAT - License created by system\']'
294            ',,,,,,,,,,[],,,created,,{\'en\': u\'Hello World\'},,K1000000,,,\r\n'
295            % self.contract2.contract_id)
296        # We can reimport the file if we change the header
297        # (user_id -> customer_id). Not all columns are necessary.
298        processor = ROPContractProcessor()
299        open(self.outfile, 'wb').write(
300            'class_name,contract_category,contract_id,document_object,'
301            'history,last_product_id,product_object,product_options,'
302            'state,tc_dict,title,user_id\r\n'
303            'ROPContract,rop,%s,,'
304            '[u\'2014-12-21 22:26:00 WAT - License created by system\']'
305            ',,,[],created,{\'en\': u\'Hello World\'},,K1000000\r\n'
306            % self.contract2.contract_id)
307        result = processor.doImport(
308            self.outfile,
309            ['class_name','contract_category','contract_id','document_object',
310            'history','last_product_id','product_object','product_options',
311            'state','tc_dict','title','customer_id'],
312            mode='create')
313        num, num_fail, finished_path, failed_path = result
314        # The object exists.
315        self.assertEqual(num_fail,1)
316        # We remove the original contract.
317        del self.customer['contracts'][self.contract2.contract_id]
318        result = processor.doImport(
319            self.outfile,
320            ['class_name','contract_category','contract_id','document_object',
321            'history','last_product_id','product_object','product_options',
322            'state','tc_dict','title','customer_id'],
323            mode='create')
324        num_succ, num_fail, finished_path, failed_path = result
325        self.assertEqual(num_fail,0)
326        # We can import the same file in update mode.
327        result = processor.doImport(
328            self.outfile,
329            ['class_name','contract_category','contract_id','document_object',
330            'history','last_product_id','product_object','product_options',
331            'state','tc_dict','title','customer_id'],
332            mode='update')
333        num_succ, num_fail, finished_path, failed_path = result
334        self.assertEqual(num_succ,1)
335        self.assertEqual(num_fail,0)
336        return
337
338
339class CustomerUITests(CustomersFullSetup):
340
341    layer = FunctionalLayer
342
343    def setup_customizable_params(self):
344        self._contract_category = u'ron'
345        self._document_factory = 'waeup.PCNCustomerPDFDocument'
346        self._contract_factory = 'waeup.RONContract'
347        return
348
349    def test_customer_edit_upload_upload_and_request(self):
350        # Customer cant login if their password is not set
351        self.browser.open(self.login_path)
352        self.browser.getControl(name="form.login").value = self.customer_id
353        self.browser.getControl(name="form.password").value = 'cpwd'
354        self.browser.getControl("Login").click()
355        self.assertMatches(
356            '...You logged in...', self.browser.contents)
357        self.browser.getLink("Edit").click()
358        self.browser.getControl(name="form.email").value = 'new_email@aa.ng'
359        self.browser.getControl("Save", index=0).click()
360        self.assertMatches('...Form has been saved...',
361                           self.browser.contents)
362        self.browser.getControl("Save and request registration").click()
363        self.assertMatches('...Passport picture is missing...',
364                           self.browser.contents)
365        self.assertEqual(self.customer.state, 'started')
366        # Customer must upload a passport picture. We are already on
367        # the upload page.
368        ctrl = self.browser.getControl(name='passporteditupload')
369        file_obj = open(SAMPLE_IMAGE, 'rb')
370        file_ctrl = ctrl.mech_control
371        file_ctrl.add_file(file_obj, filename='my_photo.jpg')
372        self.browser.getControl(
373            name='upload_passporteditupload').click()
374        self.assertTrue(
375            'src="http://localhost/app/customers/K1000000/passport.jpg"'
376            in self.browser.contents)
377        self.browser.getControl(name="CANCEL").click()
378        self.assertEqual(self.browser.url, self.customer_path)
379        self.browser.getLink("Edit").click()
380        self.browser.getControl("Save and request registration").click()
381        self.assertMatches('...Birth certificate is missing...',
382                           self.browser.contents)
383        self.assertEqual(self.customer.state, 'started')
384        ctrl = self.browser.getControl(name='birthcertificateeditupload')
385        file_obj = open(SAMPLE_PDF, 'rb')
386        file_ctrl = ctrl.mech_control
387        file_ctrl.add_file(file_obj, filename='my_bc.pdf')
388        self.browser.getControl(
389            name='upload_birthcertificateeditupload').click()
390        self.assertTrue(
391            'href="http://localhost/app/customers/K1000000/birth_certificate.pdf"'
392            in self.browser.contents)
393        self.browser.getControl(name="CANCEL").click()
394        self.browser.getLink("Edit").click()
395        self.browser.getControl("Save and request registration").click()
396        self.assertMatches('...Registration form has been submitted...',
397                           self.browser.contents)
398        self.assertEqual(self.customer.state, 'requested')
399        # Customer can view history
400        self.browser.getLink("History").click()
401        self.assertMatches('...Registration record created by system...',
402            self.browser.contents)
403
404
405class DocumentUITests(CustomersFullSetup):
406    # Tests for customer document related views and pages
407
408    layer = FunctionalLayer
409
410    def setup_customizable_params(self):
411        self._contract_category = u'ron'
412        self._document_factory = 'waeup.PCNCustomerPDFDocument'
413        self._contract_factory = 'waeup.RONContract'
414        return
415
416    def test_manage_upload_pdf_file(self):
417        # Managers can upload a file via the DocumentManageFormPage
418        # The image is stored even if form has errors
419        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
420        self.browser.open(self.customer_path + '/documents')
421        self.browser.getControl("Add document").click()
422        self.browser.getControl(name="doctype").value = ['PCNCustomerPDFDocument']
423        self.browser.getControl(name="form.title").value = 'My PCN Document'
424        self.browser.getControl("Add document").click()
425        docid = [i for i in self.customer['documents'].keys() if len(i) > 10][0]
426        self.browser.open(self.documents_path + '/%s/manage' % docid)
427        # Create a pseudo image file and select it to be uploaded
428        image = open(SAMPLE_IMAGE, 'rb')
429        ctrl = self.browser.getControl(name='pdfscanmanageupload')
430        file_ctrl = ctrl.mech_control
431        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
432        self.browser.getControl(
433            name='upload_pdfscanmanageupload').click()
434        self.assertTrue(
435            'pdf file format expected' in self.browser.contents)
436        ctrl = self.browser.getControl(name='pdfscanmanageupload')
437        file_ctrl = ctrl.mech_control
438        file_ctrl.add_file(image, filename='my_sample_scan.pdf')
439        self.browser.getControl(
440            name='upload_pdfscanmanageupload').click()
441        self.assertTrue(
442            'Could not determine file type' in self.browser.contents)
443        pdf = open(SAMPLE_PDF, 'rb')
444        ctrl = self.browser.getControl(name='pdfscanmanageupload')
445        file_ctrl = ctrl.mech_control
446        file_ctrl.add_file(pdf, filename='my_sample_scan.pdf')
447        self.browser.getControl(
448            name='upload_pdfscanmanageupload').click()
449        self.assertTrue(
450            'href="http://localhost/app/customers/K1000000/documents/%s/scan.pdf">%s.pdf</a>'
451            % (docid, docid[:9]) in self.browser.contents)
452        # Browsing the link shows a real pdf
453        self.browser.open('scan.pdf')
454        self.assertEqual(
455            self.browser.headers['content-type'], 'application/pdf')
456        # The name of the downloaded file will be different
457        self.assertEqual(
458            self.browser.headers['Content-Disposition'],
459            'attachment; filename="%s.pdf' % docid[:9])
460
461
462class ContractUITests(CustomersFullSetup):
463    # Tests for contract related views and pages
464
465    layer = FunctionalLayer
466
467    def setup_customizable_params(self):
468        self._contract_category = u'ron'
469        self._document_factory = 'waeup.PCNCustomerPDFDocument'
470        self._contract_factory = 'waeup.RONContract'
471        return
472
473    def test_view_slips(self):
474        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
475        # Officers can open contract slips.
476        # First we add a submitted document and a product.
477        IWorkflowState(self.document).setState('submitted')
478        self.contract.title = u'Contract Title'
479        self.contract.document_object = self.document
480        self.contract.product_object = self.product
481        self.contract.tc_dict = {'en': u'<strong>Hello world</strong>'}
482        self.browser.open(self.customer_path + '/contracts/CON1')
483        self.browser.getLink("Download license slip").click()
484        self.assertEqual(self.browser.headers['Status'], '200 Ok')
485        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
486        path = os.path.join(samples_dir(), 'contract_slip.pdf')
487        open(path, 'wb').write(self.browser.contents)
488        print "Sample contract_slip.pdf written to %s" % path
Note: See TracBrowser for help on using the repository browser.