Ignore:
Timestamp:
12 Mar 2015, 05:29:43 (10 years ago)
Author:
uli
Message:

Merge changes from uli-payments back into trunk.

Location:
main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_browser.py

    r12663 r12741  
    11## $Id$
    2 ## 
     2##
    33## Copyright (C) 2014 Uli Fouquet & Henrik Bettermann
    44## This program is free software; you can redistribute it and/or modify
     
    66## the Free Software Foundation; either version 2 of the License, or
    77## (at your option) any later version.
    8 ## 
     8##
    99## This program is distributed in the hope that it will be useful,
    1010## but WITHOUT ANY WARRANTY; without even the implied warranty of
    1111## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1212## GNU General Public License for more details.
    13 ## 
     13##
    1414## You should have received a copy of the GNU General Public License
    1515## along with this program; if not, write to the Free Software
     
    2222import tempfile
    2323import logging
    24 import pytz
    2524import base64
    2625from decimal import Decimal
     
    4241from waeup.ikoba.testing import FunctionalLayer, FunctionalTestCase
    4342from waeup.ikoba.app import Company
    44 from waeup.ikoba.customers.interfaces import ICustomersUtils
    45 from waeup.ikoba.customers.customer import Customer
    4643from waeup.ikoba.interfaces import (
    4744    IUserAccount, IJobManager, APPROVED, SUBMITTED,
    48     IFileStoreNameChooser, IExtFileStore, IFileStoreHandler, NotIdValue)
    49 from waeup.ikoba.imagestorage import (
    50     FileStoreNameChooser, ExtFileStore, DefaultFileStoreHandler,
    51     DefaultStorage)
    52 from waeup.ikoba.authentication import LocalRoleSetEvent
     45    IFileStoreNameChooser, NotIdValue)
     46from waeup.ikoba.imagestorage import ExtFileStore
    5347from waeup.ikoba.tests.test_async import FunctionalAsyncTestCase
    5448from waeup.ikoba.interfaces import VERIFIED
     
    6155SAMPLE_IMAGE_BMP = os.path.join(os.path.dirname(__file__), 'test_image.bmp')
    6256SAMPLE_PDF = os.path.join(os.path.dirname(__file__), 'test_pdf.pdf')
     57
    6358
    6459def lookup_submit_value(name, value, browser):
     
    7267            break
    7368    return None
     69
    7470
    7571class CustomersFullSetup(FunctionalTestCase):
     
    119115        prodoption.fee = Decimal('99.9')
    120116        prodoption.currency = 'USD'
    121         self.product.options = [prodoption,]
     117        self.product.options = [prodoption, ]
    122118        self.app['products'].addProduct(self.product)
    123119
     
    138134        self.document.document_id = u'DOC1'
    139135        self.assertRaises(
    140             NotIdValue, setattr, self.document, 'document_id', u'id with spaces')
     136            NotIdValue, setattr, self.document, 'document_id',
     137            u'id with spaces')
    141138        self.customer['documents'].addDocument(self.document)
    142139        self.contract = createObject(self._contract_factory)
    143140        self.contract.contract_id = u'CON1'
    144141        self.assertRaises(
    145             NotIdValue, setattr, self.contract, 'contract_id', u'id with spaces')
     142            NotIdValue, setattr, self.contract, 'contract_id',
     143            u'id with spaces')
    146144        self.customer['contracts'].addContract(self.contract)
    147145
     
    299297        return
    300298
     299
    301300class OfficerUITests(CustomersFullSetup):
    302301    # Tests for Customer class views and pages
    303 
    304302
    305303    def setup_logging(self):
     
    331329        self.browser.getLink("Logout").click()
    332330        self.assertTrue('You have been logged out' in self.browser.contents)
    333         # But we are still logged in since we've used basic authentication here.
    334         # Wikipedia says: Existing browsers retain authentication information
    335         # until the tab or browser is closed or the user clears the history.
    336         # HTTP does not provide a method for a server to direct clients to
    337         # discard these cached credentials. This means that there is no
    338         # effective way for a server to "log out" the user without closing
    339         # the browser. This is a significant defect that requires browser
    340         # manufacturers to support a "logout" user interface element ...
     331        # But we are still logged in since we've used basic
     332        # authentication here.  Wikipedia says: Existing browsers
     333        # retain authentication information until the tab or browser
     334        # is closed or the user clears the history.  HTTP does not
     335        # provide a method for a server to direct clients to discard
     336        # these cached credentials. This means that there is no
     337        # effective way for a server to "log out" the user without
     338        # closing the browser. This is a significant defect that
     339        # requires browser manufacturers to support a "logout" user
     340        # interface element ...
    341341        self.assertTrue('Manager' in self.browser.contents)
    342342
     
    378378        self.browser.open(self.customer_path)
    379379        self.browser.getLink("Send email").click()
    380         self.browser.getControl(name="form.subject").value = 'Important subject'
     380        self.browser.getControl(
     381            name="form.subject").value = 'Important subject'
    381382        self.browser.getControl(name="form.body").value = 'Hello!'
    382383        self.browser.getControl("Send message now").click()
     
    410411        self.assertTrue('passport.jpg deleted' in self.browser.contents)
    411412
    412 
    413413    def test_manage_workflow_send_transition_information(self):
    414414        # Managers can pass through the whole workflow
     
    417417        self.setup_logging()
    418418        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
    419         customer = self.app['customers'][self.customer_id]
     419        self.customer = self.app['customers'][self.customer_id]
    420420        self.browser.open(self.trigtrans_path)
    421421        self.browser.getControl(name="transition").value = ['start']
     
    459459        self.browser.getControl("Apply").click()
    460460        self.browser.open(self.trigtrans_path)
    461         self.browser.getControl(name="transition").value = ['approve_provisionally']
     461        self.browser.getControl(name="transition").value = [
     462            'approve_provisionally']
    462463        self.browser.getControl("Apply").click()
    463464        self.browser.open(self.trigtrans_path)
     
    499500        self.browser.getControl('Perform import').click()
    500501        self.assertTrue('Processing of 1 rows failed' in self.browser.contents)
    501         self.assertTrue('Successfully processed 2 rows' in self.browser.contents)
     502        self.assertTrue(
     503            'Successfully processed 2 rows' in self.browser.contents)
    502504        self.assertTrue('Batch processing finished' in self.browser.contents)
    503505
     
    535537        self.browser.getLink("History").click()
    536538        self.assertTrue(
    537             'Customer account deactivated by Manager<br />' in self.browser.contents)
    538         self.assertTrue(
    539             'Customer account activated by Manager<br />' in self.browser.contents)
     539            'Customer account deactivated by Manager<br />'
     540            in self.browser.contents)
     541        self.assertTrue(
     542            'Customer account activated by Manager<br />'
     543            in self.browser.contents)
    540544        # ... and actions have been logged.
    541545        logfile = os.path.join(
    542546            self.app['datacenter'].storage, 'logs', 'customers.log')
    543547        logcontent = open(logfile).read()
    544         self.assertTrue('zope.mgr - customers.browser.CustomerDeactivatePage - '
    545                         'K1000000 - account deactivated' in logcontent)
    546         self.assertTrue('zope.mgr - customers.browser.CustomerActivatePage - '
    547                         'K1000000 - account activated' in logcontent)
    548 
     548        self.assertTrue(
     549            'zope.mgr - customers.browser.CustomerDeactivatePage - '
     550            'K1000000 - account deactivated' in logcontent)
     551        self.assertTrue(
     552            'zope.mgr - customers.browser.CustomerActivatePage - '
     553            'K1000000 - account activated' in logcontent)
    549554
    550555    def test_login_as_customer(self):
     
    554559        self.app['users']['mrofficer'].title = 'Harry Actor'
    555560        prmglobal = IPrincipalRoleManager(self.app)
    556         prmglobal.assignRoleToPrincipal('waeup.CustomerImpersonator', 'mrofficer')
     561        prmglobal.assignRoleToPrincipal(
     562            'waeup.CustomerImpersonator', 'mrofficer')
    557563        prmglobal.assignRoleToPrincipal('waeup.CustomersManager', 'mrofficer')
    558564        self.assertEqual(self.customer.state, 'created')
     
    574580        # We are logged in as customer and can see the 'My Data' tab
    575581        self.assertMatches(
    576             '...<a href="#" class="dropdown-toggle" data-toggle="dropdown">...',
     582            '...<a href="#" class="dropdown-toggle"'
     583            ' data-toggle="dropdown">...',
    577584            self.browser.contents)
    578585        self.assertMatches(
     
    724731        self.assertMatches(
    725732            '...<div class="alert alert-warning">'
    726             'Your account has been deactivated.</div>...', self.browser.contents)
     733            'Your account has been deactivated.</div>...',
     734            self.browser.contents)
    727735        # If suspended_comment is set this message will be flashed instead
    728736        self.customer.suspended_comment = u'Aetsch baetsch!'
     
    778786        self.assertTrue('An email with' in self.browser.contents)
    779787
     788
    780789class CustomerRegistrationTests(CustomersFullSetup):
    781790    # Tests for customer registration
     
    823832            cat.searchResults(
    824833            email=('new@yy.zz', 'new@yy.zz')))
    825         self.assertEqual(self.customer,results[0])
     834        self.assertEqual(self.customer, results[0])
    826835        logfile = os.path.join(
    827836            self.app['datacenter'].storage, 'logs', 'main.log')
    828837        logcontent = open(logfile).read()
    829         self.assertTrue('zope.anybody - customers.browser.CustomerRequestPasswordPage - '
    830                         '123 (K1000000) - new@yy.zz' in logcontent)
     838        self.assertTrue(
     839            'zope.anybody - customers.browser.CustomerRequestPasswordPage - '
     840            '123 (K1000000) - new@yy.zz' in logcontent)
    831841        return
    832842
     
    841851        self.browser.getControl(name="form.email").value = 'newcustomer@xx.zz'
    842852        self.browser.getControl("Send login credentials").click()
    843         self.assertTrue('Your request was successful.' in self.browser.contents)
     853        self.assertTrue(
     854            'Your request was successful.' in self.browser.contents)
    844855        # Customer can be found in the catalog via the email address
    845856        cat = queryUtility(ICatalog, name='customers_catalog')
     
    849860        self.assertEqual(self.app['customers']['K1000001'], results[0])
    850861        self.assertEqual(self.app['customers']['K1000001'].firstname, 'Ruben')
    851         self.assertEqual(self.app['customers']['K1000001'].lastname, 'Gonzales')
     862        self.assertEqual(
     863            self.app['customers']['K1000001'].lastname, 'Gonzales')
    852864        logfile = os.path.join(
    853865            self.app['datacenter'].storage, 'logs', 'main.log')
    854866        logcontent = open(logfile).read()
    855         self.assertTrue('zope.anybody - customers.browser.CustomerCreateAccountPage - '
    856                         'K1000001 - newcustomer@xx.zz' in logcontent)
     867        self.assertTrue(
     868            'zope.anybody - customers.browser.CustomerCreateAccountPage - '
     869            'K1000001 - newcustomer@xx.zz' in logcontent)
    857870        return
     871
    858872
    859873class CustomerDataExportTests(CustomersFullSetup, FunctionalAsyncTestCase):
     
    929943        self.browser.getControl("Add document").click()
    930944        self.assertTrue('PDF Document added.' in self.browser.contents)
    931         docid = [i for i in self.customer['documents'].keys() if len(i) > 10][0]
     945        docid = [i for i in self.customer['documents'].keys()
     946                 if len(i) > 10][0]
    932947        document = self.customer['documents'][docid]
    933948
     
    950965        self.browser.getControl(name="transition").value = ['verify']
    951966        self.browser.getControl("Apply").click()
    952         self.assertTrue('Customer has not yet been approved' in self.browser.contents)
     967        self.assertTrue(
     968            'Customer has not yet been approved' in self.browser.contents)
    953969        IWorkflowState(self.customer).setState(APPROVED)
    954970        # Document can only be verified if files have been uploaded before
     
    958974        self.assertTrue('No file uploaded' in self.browser.contents)
    959975        self.assertEqual(document.state, 'submitted')
    960         # We set state here manually (verification is tested in test_verify_document)
     976        # We set state here manually (verification is tested in
     977        # test_verify_document)
    961978        IWorkflowState(document).setState(VERIFIED)
    962979
     
    964981        self.browser.open(self.documents_path + '/' + docid + '/index')
    965982        self.assertFalse(
    966             'href="http://localhost/app/customers/K1000000/documents/%s/manage"'
     983            'href="http://localhost/app/customers/K1000000/'
     984            'documents/%s/manage"'
    967985            % docid in self.browser.contents)
    968986        self.browser.open(self.documents_path + '/' + docid + '/manage')
     
    10121030        self.browser.getLink("Documents").click()
    10131031        self.browser.getControl("Add document").click()
    1014         self.assertTrue('The requested form is locked' in self.browser.contents)
     1032        self.assertTrue(
     1033            'The requested form is locked' in self.browser.contents)
    10151034        # Customer is in wrong state
    10161035        IWorkflowState(self.customer).setState(APPROVED)
    10171036        self.browser.getControl("Add document").click()
    1018         self.browser.getControl(name="doctype").value = ['CustomerSampleDocument']
     1037        self.browser.getControl(name="doctype").value = [
     1038            'CustomerSampleDocument']
    10191039        self.browser.getControl(name="form.title").value = 'My Sample Document'
    10201040        self.browser.getControl("Add document").click()
    10211041        self.assertTrue('Sample Document added.' in self.browser.contents)
    1022         docid = [i for i in self.customer['documents'].keys() if len(i) > 10][0]
     1042        docid = [i for i in self.customer['documents'].keys()
     1043                 if len(i) > 10][0]
    10231044        document = self.customer['documents'][docid]
    10241045        self.browser.getControl(name="form.title").value = 'My second doc'
     
    10381059            name='upload_samplescaneditupload').click()
    10391060        self.assertTrue(
    1040             'href="http://localhost/app/customers/K1000000/documents/%s/sample"'
     1061            'href="http://localhost/app/customers/K1000000/'
     1062            'documents/%s/sample"'
    10411063            % docid in self.browser.contents)
    10421064        # Customer can submit the form. The form is also saved.
     
    10451067        self.assertEqual(document.title, 'My third doc')
    10461068        self.assertEqual(document.state, 'submitted')
    1047         self.assertTrue('Document State: submitted for verification' in self.browser.contents)
     1069        self.assertTrue(
     1070            'Document State: submitted for verification'
     1071            in self.browser.contents)
    10481072        # Customer can't edit the document once it has been submitted
    10491073        self.browser.open(self.documents_path + '/%s/edit' % docid)
    1050         self.assertTrue('The requested form is locked' in self.browser.contents)
     1074        self.assertTrue(
     1075            'The requested form is locked' in self.browser.contents)
    10511076
    10521077    def test_manage_upload_sample_file(self):
     
    10551080        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
    10561081        self.browser.open(self.customer_path + '/documents/DOC1/manage')
    1057         # Create a pseudo image file and select it to be uploaded 
     1082        # Create a pseudo image file and select it to be uploaded
    10581083        image = open(SAMPLE_IMAGE, 'rb')
    10591084        ctrl = self.browser.getControl(name='samplescanmanageupload')
     
    10611086        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
    10621087        # The Save action does not upload files
    1063         self.browser.getControl("Save").click() # submit form
     1088        self.browser.getControl("Save").click()  # submit form
    10641089        self.assertFalse(
    1065             'href="http://localhost/app/customers/K1000000/documents/DOC1/sample"'
     1090            'href="http://localhost/app/customers/K1000000/'
     1091            'documents/DOC1/sample"'
    10661092            in self.browser.contents)
    10671093        # ... but the correct upload submit button does
     
    10731099            name='upload_samplescanmanageupload').click()
    10741100        self.assertTrue(
    1075             'href="http://localhost/app/customers/K1000000/documents/DOC1/sample"'
     1101            'href="http://localhost/app/customers/K1000000/'
     1102            'documents/DOC1/sample"'
    10761103            in self.browser.contents)
    10771104        # Browsing the link shows a real image
     
    10981125            'Uploaded file is too big' in self.browser.contents)
    10991126        # We do not rely on filename extensions given by uploaders
    1100         image = open(SAMPLE_IMAGE, 'rb') # a jpg-file
     1127        image = open(SAMPLE_IMAGE, 'rb')  # a jpg-file
    11011128        ctrl = self.browser.getControl(name='samplescanmanageupload')
    11021129        file_ctrl = ctrl.mech_control
     
    11521179        self.browser.getControl(name="form.title").value = 'My PDF Document'
    11531180        self.browser.getControl("Add document").click()
    1154         docid = [i for i in self.customer['documents'].keys() if len(i) > 10][0]
     1181        docid = [
     1182            i for i in self.customer['documents'].keys() if len(i) > 10][0]
    11551183        self.browser.open(self.documents_path + '/%s/manage' % docid)
    11561184        # Create a pseudo image file and select it to be uploaded
     
    11771205            name='upload_pdfscanmanageupload').click()
    11781206        self.assertTrue(
    1179             'href="http://localhost/app/customers/K1000000/documents/%s/sample.pdf">%s.pdf</a>'
     1207            'href="http://localhost/app/customers/K1000000/'
     1208            'documents/%s/sample.pdf">%s.pdf</a>'
    11801209            % (docid, docid[:9]) in self.browser.contents)
    11811210        # Browsing the link shows a real pdf
     
    11941223        self.browser.getLink("Download documents overview").click()
    11951224        self.assertEqual(self.browser.headers['Status'], '200 Ok')
    1196         self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
     1225        self.assertEqual(
     1226            self.browser.headers['Content-Type'], 'application/pdf')
    11971227        path = os.path.join(samples_dir(), 'documents_overview_slip.pdf')
    11981228        open(path, 'wb').write(self.browser.contents)
     
    12001230        # Officers can open document slips which shows a thumbnail of
    12011231        # the jpeg file attached.
    1202         file_id = IFileStoreNameChooser(self.document).chooseName(attr='sample.jpg')
     1232        file_id = IFileStoreNameChooser(self.document).chooseName(
     1233            attr='sample.jpg')
    12031234        fs = ExtFileStore(root=self.dc_root)
    12041235        jpegfile = open(SAMPLE_IMAGE, 'rb')
     
    12071238        self.browser.getLink("Download document slip").click()
    12081239        self.assertEqual(self.browser.headers['Status'], '200 Ok')
    1209         self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
     1240        self.assertEqual(
     1241            self.browser.headers['Content-Type'], 'application/pdf')
    12101242        path = os.path.join(samples_dir(), 'document_slip.pdf')
    12111243        open(path, 'wb').write(self.browser.contents)
     
    12161248        self.customer['documents'].addDocument(pdfdocument)
    12171249        # Add pdf file
    1218         file_id = IFileStoreNameChooser(pdfdocument).chooseName(attr='sample.pdf')
     1250        file_id = IFileStoreNameChooser(pdfdocument).chooseName(
     1251            attr='sample.pdf')
    12191252        fs = ExtFileStore(root=self.dc_root)
    12201253        pdffile = open(SAMPLE_PDF, 'rb')
    12211254        fs.createFile(file_id, pdffile)
    1222         docid = [i for i in self.customer['documents'].keys() if len(i) > 10][0]
     1255        docid = [i for i in self.customer['documents'].keys()
     1256                 if len(i) > 10][0]
    12231257        self.browser.open(self.customer_path + '/documents/' + docid)
    12241258        self.browser.getLink("Download document slip").click()
    12251259        self.assertEqual(self.browser.headers['Status'], '200 Ok')
    1226         self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
     1260        self.assertEqual(
     1261            self.browser.headers['Content-Type'], 'application/pdf')
    12271262        path = os.path.join(samples_dir(), 'pdfdocument_slip.pdf')
    12281263        open(path, 'wb').write(self.browser.contents)
     
    12321267        # A proper file name chooser is registered for customer documents.
    12331268        # This is not a UI test. It's just a functional test.
    1234         file_id = IFileStoreNameChooser(self.document).chooseName(attr='sample')
     1269        file_id = IFileStoreNameChooser(self.document).chooseName(
     1270            attr='sample')
    12351271        fs = ExtFileStore(root=self.dc_root)
    12361272        fs.createFile(file_id, StringIO('my sample 1'))
    12371273        result = fs.getFileByContext(self.document, attr='sample')
    1238         self.assertEqual(file_id, '__file-customerdocument__01000/K1000000/sample_DOC1_K1000000')
     1274        self.assertEqual(
     1275            file_id, '__file-customerdocument__01000/'
     1276            'K1000000/sample_DOC1_K1000000')
    12391277        self.assertEqual(result.read(), 'my sample 1')
    1240         self.assertEqual(self.document.connected_files[0][1].read(), 'my sample 1')
     1278        self.assertEqual(
     1279            self.document.connected_files[0][1].read(), 'my sample 1')
    12411280        self.document.setMD5()
    1242         self.assertEqual(self.document.sample_md5, 'a406995ee8eb6772bacf51aa4b0caa24')
     1281        self.assertEqual(
     1282            self.document.sample_md5, 'a406995ee8eb6772bacf51aa4b0caa24')
    12431283        return
    12441284
     
    12461286class ContractUITests(CustomersFullSetup):
    12471287    # Tests for contract related views and pages
     1288
     1289    never_ending_button_text = (
     1290        'Select payment method (final submission)')
     1291
     1292    def add_product_option(self, contract):
     1293        prodoption = ProductOption()
     1294        prodoption.title = u'Any product option'
     1295        prodoption.fee = Decimal('88.8')
     1296        prodoption.currency = 'EUR'
     1297        contract.product_options = [prodoption, ]
     1298
     1299    def prepare_payment_select(self):
     1300        IWorkflowState(self.customer).setState('approved')
     1301        IWorkflowState(self.document).setState('verified')
     1302        self.contract.document_object = self.document
     1303        self.add_product_option(self.contract)
     1304        IWorkflowState(self.contract).setState('created')
     1305        # login as customer
     1306        self.browser.open(self.login_path)
     1307        self.browser.getControl(name="form.login").value = self.customer_id
     1308        self.browser.getControl(name="form.password").value = 'cpwd'
     1309        self.browser.getControl("Login").click()
    12481310
    12491311    def test_manage_contract(self):
     
    12611323        self.browser.getControl("Add contract").click()
    12621324        self.assertTrue('Sample Contract added.' in self.browser.contents)
    1263         conid = [i for i in self.customer['contracts'].keys() if len(i) > 10][0]
     1325        conid = [i for i in self.customer['contracts'].keys()
     1326                 if len(i) > 10][0]
    12641327        contract = self.customer['contracts'][conid]
    12651328        self.assertEqual(
    1266             self.browser.url, self.contracts_path + '/%s/selectproduct' % conid)
     1329            self.browser.url,
     1330            self.contracts_path + '/%s/selectproduct' % conid)
    12671331        # SAM is in the correct contract_category
    12681332        self.assertTrue('<option value="SAM">' in self.browser.contents)
    12691333        # So far last_product_id is None.
    1270         self.assertTrue(self.customer['contracts'][conid].last_product_id is None)
     1334        self.assertTrue(
     1335            self.customer['contracts'][conid].last_product_id is None)
    12711336        self.browser.getControl(name="form.product_object").value = ['SAM']
    12721337        self.browser.getControl("Save and proceed").click()
     
    12741339            self.browser.url, self.contracts_path + '/%s/manage' % conid)
    12751340        self.browser.getLink("View").click()
    1276         self.assertEqual(self.browser.url, self.contracts_path + '/%s/index' % conid)
     1341        self.assertEqual(
     1342            self.browser.url, self.contracts_path + '/%s/index' % conid)
    12771343        self.assertEqual(contract.tc_dict, {'en': u'Hello world'})
    12781344
     
    13421408        self.assertFalse('Add contract' in self.browser.contents)
    13431409        self.browser.open(self.contracts_path + '/addcontract')
    1344         self.assertTrue('The requested form is locked' in self.browser.contents)
     1410        self.assertTrue(
     1411            'The requested form is locked' in self.browser.contents)
    13451412        IWorkflowState(self.customer).setState(APPROVED)
    13461413        self.browser.open(self.contracts_path)
     
    13501417        self.browser.getControl("Add contract").click()
    13511418        self.assertTrue('Sample Contract added.' in self.browser.contents)
    1352         conid = [i for i in self.customer['contracts'].keys() if len(i) > 10][0]
     1419        conid = [i for i in self.customer['contracts'].keys()
     1420                 if len(i) > 10][0]
    13531421        contract = self.customer['contracts'][conid]
    13541422        self.assertEqual(
    1355             self.browser.url, self.contracts_path + '/%s/selectproduct' % conid)
     1423            self.browser.url,
     1424            self.contracts_path + '/%s/selectproduct' % conid)
    13561425        # SAM is in the correct contract_category ...
    13571426        self.assertTrue('<option value="SAM">' in self.browser.contents)
     
    13591428        self.assertFalse('<option value="LIC">' in self.browser.contents)
    13601429        # So far last_product_id is None.
    1361         self.assertTrue(self.customer['contracts'][conid].last_product_id is None)
     1430        self.assertTrue(
     1431            self.customer['contracts'][conid].last_product_id is None)
    13621432        self.browser.getControl(name="form.product_object").value = ['SAM']
    13631433        self.browser.getControl("Save and proceed").click()
     
    13661436        # Document is a required field on edit form page.
    13671437        self.browser.getControl("Save").click()
    1368         self.assertTrue('Document: <span class="error">Required input is missing.</span>'
     1438        self.assertTrue(
     1439            'Document: <span class="error">Required input is missing.</span>'
    13691440            in self.browser.contents)
    13701441        # But our document can't be selected because it's not submitted
     
    13761447        # After saving the form, last_product_id and other attributes are set
    13771448        self.assertTrue('Form has been saved.' in self.browser.contents)
    1378         self.assertEqual(self.customer['contracts'][conid].last_product_id, 'SAM')
     1449        self.assertEqual(
     1450            self.customer['contracts'][conid].last_product_id, 'SAM')
    13791451        self.assertEqual(contract.title, 'Our Sample Product')
    13801452        self.assertEqual(contract.product_object, self.product)
     
    13821454        # Saving the form again does not unset last_product_id
    13831455        self.browser.getControl("Save").click()
    1384         self.assertEqual(self.customer['contracts'][conid].last_product_id, 'SAM')
     1456        self.assertEqual(
     1457            self.customer['contracts'][conid].last_product_id, 'SAM')
    13851458        self.assertTrue('Form has been saved.' in self.browser.contents)
    13861459        # So far we have not yet set product options.
     
    13901463        prodoption.fee = Decimal('88.8')
    13911464        prodoption.currency = 'EUR'
    1392         contract.product_options = [prodoption,]
     1465        contract.product_options = [prodoption, ]
    13931466        self.browser.open(self.contracts_path + '/%s/edit' % conid)
    13941467        # We can see both the stored and the recent product options
    13951468        # from the chosen product.
    1396         self.assertTrue('<option selected="selected" value="Any product option">'
    1397                         'Any product option @ 88.8 Euro</option>'
    1398                         in self.browser.contents)
     1469        self.assertTrue(
     1470            '<option selected="selected" value="Any product option">'
     1471            'Any product option @ 88.8 Euro</option>'
     1472            in self.browser.contents)
    13991473        self.assertTrue('<option value="First option">First option '
    14001474                        '@ 99.9 US Dollar</option>' in self.browser.contents)
     
    14021476        self.browser.getControl(
    14031477            name="form.product_options.0.").value = ['First option']
    1404         self.assertEqual(contract.product_options[0].title, 'Any product option')
     1478        self.assertEqual(
     1479            contract.product_options[0].title, 'Any product option')
    14051480        self.browser.getControl("Save").click()
    14061481        self.assertEqual(contract.product_options[0].title, 'First option')
    14071482        self.browser.getLink("View").click()
    1408         self.assertTrue('<span>First option @ 99.9 US Dollar</span>' in self.browser.contents)
    1409         self.assertEqual(self.browser.url, self.contracts_path + '/%s/index' % conid)
     1483        self.assertTrue(
     1484            '<span>First option @ 99.9 US Dollar</span>'
     1485            in self.browser.contents)
     1486        self.assertEqual(
     1487            self.browser.url, self.contracts_path + '/%s/index' % conid)
    14101488        # An href attribute is referring to the document and product objects
    14111489        self.assertTrue('<a href="http://localhost/app/products/SAM">SAM -'
    14121490            in self.browser.contents)
    14131491        self.assertTrue(
    1414             '<a href="http://localhost/app/customers/K1000000/documents/DOC1">DOC1 -'
     1492            '<a href="http://localhost/app/customers/K1000000/'
     1493            'documents/DOC1">DOC1 -'
    14151494            in self.browser.contents)
    14161495        # Customer can submit the form if confirmation box is ticket.
     
    14181497        self.browser.getLink("Edit").click()
    14191498        self.browser.getControl("Proceed to checkout").click()
    1420         self.assertTrue('confirm your acceptance of these by ticking' in self.browser.contents)
     1499        self.assertTrue(
     1500            'confirm your acceptance of these by ticking'
     1501            in self.browser.contents)
    14211502        self.assertEqual(contract.state, 'created')
    14221503        self.browser.getControl(name="confirm_tc").value = True
    14231504        self.browser.getControl("Proceed to checkout").click()
    14241505        self.assertEqual(contract.state, 'created')
     1506        radio_ctrl = self.browser.getControl(name='gw')
     1507        radio_ctrl.value = [radio_ctrl.options[0]]  # pick first payment opt
    14251508        self.browser.getControl("Select payment method").click()
    14261509        self.assertEqual(contract.state, 'awaiting')
    14271510        # Customer can't edit the contract once it has been submitted
    14281511        self.browser.open(self.contracts_path + '/%s/edit' % conid)
    1429         self.assertTrue('The requested form is locked' in self.browser.contents)
     1512        self.assertTrue(
     1513            'The requested form is locked' in self.browser.contents)
    14301514
    14311515    def test_view_slips(self):
     
    14351519        self.browser.getLink("Download contracts overview").click()
    14361520        self.assertEqual(self.browser.headers['Status'], '200 Ok')
    1437         self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
     1521        self.assertEqual(
     1522            self.browser.headers['Content-Type'], 'application/pdf')
    14381523        path = os.path.join(samples_dir(), 'contracts_overview_slip.pdf')
    14391524        open(path, 'wb').write(self.browser.contents)
     
    14511536        self.browser.getLink("Download contract slip").click()
    14521537        self.assertEqual(self.browser.headers['Status'], '200 Ok')
    1453         self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
     1538        self.assertEqual(
     1539            self.browser.headers['Content-Type'], 'application/pdf')
    14541540        path = os.path.join(samples_dir(), 'contract_slip.pdf')
    14551541        open(path, 'wb').write(self.browser.contents)
     
    14861572        # InvalidTransitionError is catched
    14871573        self.assertTrue(
    1488             '<div class="alert alert-warning">Attached documents must be verified first.</div>'
     1574            '<div class="alert alert-warning">Attached documents '
     1575            'must be verified first.</div>'
    14891576            in self.browser.contents)
    14901577        self.browser.open(self.contracts_path + '/CON1/trigtrans')
     
    14931580        self.browser.getControl("Apply").click()
    14941581        self.assertEqual(IWorkflowState(self.contract).getState(), 'approved')
     1582
     1583    def test_select_payment(self):
     1584        # select payment
     1585        self.prepare_payment_select()
     1586        self.browser.open('%s/CON1/edit' % self.contracts_path)
     1587        self.browser.getControl("Proceed to checkout").click()
     1588        self.assertTrue(
     1589            "Select payment method" in self.browser.contents)
     1590        self.assertTrue(
     1591            'Credit Card (Demo Payments)' in self.browser.contents)
     1592
     1593    def test_select_payment_no_choice(self):
     1594        # we get warned if no payment was selected
     1595        self.prepare_payment_select()
     1596        self.browser.open(
     1597            '%s/CON1/select_payment_method' % self.contracts_path)
     1598        self.browser.getControl(self.never_ending_button_text).click()
     1599        self.assertTrue(
     1600            'Please pick a payment method' in self.browser.contents)
     1601
     1602    def test_select_payment_demo_provider(self):
     1603        # we can proceed with payments if we select a payment method
     1604        self.prepare_payment_select()
     1605        self.browser.open(
     1606            '%s/CON1/select_payment_method' % self.contracts_path)
     1607        radio_ctrl = self.browser.getControl(name='gw')
     1608        radio_ctrl.displayValue = ['Credit Card (Demo Payments)']
     1609        self.browser.getControl(self.never_ending_button_text).click()
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_contract.py

    r12259 r12741  
    1919Tests for contracts.
    2020"""
     21import decimal
    2122from zope.interface.verify import verifyClass, verifyObject
    22 from zope.component import createObject
     23from zope.component import createObject, getUtility, getUtilitiesFor
     24from zope.component.hooks import setSite
    2325from hurry.workflow.interfaces import (
    2426    IWorkflowInfo, IWorkflowState, InvalidTransitionError)
    2527from waeup.ikoba.customers.interfaces import (
    2628    IContractsContainer, IContract)
    27 from waeup.ikoba.interfaces import IObjectHistory
    2829from waeup.ikoba.customers.contracts import (
    29     ContractsContainer, SampleContract)
     30    ContractsContainer, SampleContract, ContractPayer, ContractFinder,
     31    PayableContract,
     32    )
     33from waeup.ikoba.app import Company
     34from waeup.ikoba.customers.customer import Customer
     35from waeup.ikoba.payments.interfaces import (
     36    IPaymentItem, IPayer, IPayableFinder, IPayable,
     37    )
     38from waeup.ikoba.products.productoptions import ProductOption
    3039from waeup.ikoba.testing import (FunctionalLayer, FunctionalTestCase)
     40
    3141
    3242class ContractsContainerTestCase(FunctionalTestCase):
     
    8999        self.assertTrue('Contract created by system' in messages)
    90100        return
     101
     102
     103class TestContractHelpers(FunctionalTestCase):
     104
     105    layer = FunctionalLayer
     106
     107    def test_payer_adapter(self):
     108        # we can adapt IContract to IPayer (i.e. create a payer)
     109        customer = Customer()
     110        customer.firstname, customer.lastname = u'Anna', u'Tester'
     111        contract = createObject(u'waeup.SampleContract')
     112        customer['contracts'] = ContractsContainer()
     113        customer['contracts'].addContract(contract)
     114        result = IPayer(contract)
     115        self.assertTrue(isinstance(result, ContractPayer))
     116        verifyObject(IPayer, result)
     117        self.assertEqual(result.first_name, u'Anna')
     118        self.assertEqual(result.last_name, u'Tester')
     119        self.assertEqual(result.payer_id, customer.customer_id)
     120
     121    def test_contract_finder_iface(self):
     122        # we have a contract finder that returns IPayableFinder data.
     123        verifyClass(IPayableFinder, ContractFinder)
     124
     125    def test_contract_finder_registered(self):
     126        # the contract finder is a utility registered on startup
     127        util = getUtility(IPayableFinder, name='contracts_finder')
     128        self.assertTrue(isinstance(util, ContractFinder))
     129        utils = [util for name, util in getUtilitiesFor(IPayableFinder)
     130                 if isinstance(util, ContractFinder)]
     131        self.assertEqual(len(utils), 1)
     132
     133    def create_contract_and_site(self):
     134        contract = SampleContract()
     135        option1 = ProductOption(u"Fee 1", decimal.Decimal("31.10"), "USD")
     136        option2 = ProductOption(u"Fee 2", decimal.Decimal("12.12"), "USD")
     137        contract.product_options = [option1, option2]
     138        contract.contract_id = u'CON1234'
     139        self.getRootFolder()['app'] = Company()
     140        app = self.getRootFolder()['app']
     141        setSite(app)
     142        return contract, app
     143
     144    def test_contract_finder(self):
     145        # the contract finder can really find contracts
     146        contract, app = self.create_contract_and_site()
     147        app['mycontract'] = contract  # trigger cataloging
     148        finder = ContractFinder()
     149        result = finder.get_payable_by_id('CON1234')
     150        self.assertTrue(result is contract)
     151
     152    def test_contract_finder_not_stored(self):
     153        # we get none if an id is not stored
     154        contract, app = self.create_contract_and_site()
     155        app['mycontract'] = contract  # trigger cataloging
     156        finder = ContractFinder()
     157        result = finder.get_payable_by_id('Not-a-valid-id')
     158        self.assertTrue(result is None)
     159
     160    def test_contract_finder_no_catalog(self):
     161        # contract finder does not complain about missing catalog
     162        finder = ContractFinder()
     163        result = finder.get_payable_by_id('CON1234')
     164        self.assertTrue(result is None)
     165
     166
     167class TestContractAsPayable(FunctionalTestCase):
     168
     169    layer = FunctionalLayer
     170
     171    def test_adaptable(self):
     172        # we can turn contracts into payables.
     173        contract = SampleContract()
     174        payable = IPayable(contract)
     175        self.assertTrue(payable is not None)
     176        self.assertTrue(isinstance(payable, PayableContract))
     177
     178    def test_payable_iface(self):
     179        # PayableContracts really provide IPayable
     180        contract = SampleContract()
     181        option1 = ProductOption(u"Fee 1", decimal.Decimal("31.10"), "USD")
     182        option2 = ProductOption(u"Fee 2", decimal.Decimal("12.12"), "USD")
     183        contract.product_options = [option1, option2]
     184        payable = PayableContract(contract)
     185        verifyObject(IPayable, payable)
     186        verifyClass(IPayable, PayableContract)
     187
     188    def test_payable_simple_attributes(self):
     189        # the simple attribs are set correctly, according to context contract
     190        contract = SampleContract()
     191        contract.title = u'the title'
     192        option1 = ProductOption(u"Fee 1", decimal.Decimal("31.10"), "EUR")
     193        option2 = ProductOption(u"Fee 2", decimal.Decimal("12.12"), "EUR")
     194        contract.product_options = [option1, option2]
     195        payable = PayableContract(contract)
     196        self.assertTrue(contract.contract_id, payable.payable_id)
     197        self.assertEqual(payable.title, contract.title)
     198        self.assertEqual(payable.currency, 'EUR')
     199
     200    def test_payable_items(self):
     201        # we can get payment items from payable
     202        contract = SampleContract()
     203        option1 = ProductOption(u"Fee 1", decimal.Decimal("31.10"), "EUR")
     204        option2 = ProductOption(u"Fee 2", decimal.Decimal("12.12"), "EUR")
     205        contract.product_options = [option1, option2]
     206        payable = PayableContract(contract)
     207        items = payable.payment_items
     208        self.assertTrue(isinstance(items, tuple))
     209        self.assertEqual(len(items), 2)
     210        verifyObject(IPaymentItem, items[0])
     211        verifyObject(IPaymentItem, items[1])
     212        self.assertEqual(items[0].item_id, '0')
     213        self.assertEqual(items[0].title, u'Fee 1')
     214        self.assertEqual(items[0].amount, decimal.Decimal("31.10"))
     215
     216    def test_payable_no_items(self):
     217        # payables work also with no options set on contract
     218        contract = SampleContract()
     219        payable = PayableContract(contract)
     220        items = payable.payment_items
     221        self.assertTrue(isinstance(items, tuple))
     222        self.assertEqual(len(items), 0)
     223        self.assertEqual(payable.currency, None)
     224
     225    def test_different_currencies_forbiddedn(self):
     226        # we do not accept different currencies in payment items
     227        contract = SampleContract()
     228        option1 = ProductOption(u"Fee 1", decimal.Decimal("31.10"), "EUR")
     229        option2 = ProductOption(u"Fee 2", decimal.Decimal("12.12"), "USD")
     230        contract.product_options = [option1, option2]
     231        self.assertRaises(ValueError, PayableContract, contract)
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_customer.py

    r12297 r12741  
    2121import re
    2222import unittest
    23 import grok
    2423from cStringIO import StringIO
    25 from datetime import tzinfo
    26 from zope.component import getUtility, queryUtility, createObject
    27 from zope.catalog.interfaces import ICatalog
     24from zope.component import getUtility, getUtilitiesFor
     25from zope.component.hooks import setSite
    2826from zope.component.interfaces import IFactory
    29 from zope.event import notify
    3027from zope.interface import verify
    31 from zope.schema.interfaces import RequiredMissing
    3228from waeup.ikoba.interfaces import IExtFileStore, IFileStoreNameChooser
     29from waeup.ikoba.app import Company
    3330from waeup.ikoba.customers.customer import (
    34     Customer, CustomerFactory, handle_customer_removed, path_from_custid)
     31    Customer, CustomerFactory, handle_customer_removed, path_from_custid,
     32    CustomerPayer, CustomerFinder,
     33    )
    3534from waeup.ikoba.customers.interfaces import (
    3635    ICustomer, ICustomerNavigation, ICustomersUtils)
    3736from waeup.ikoba.customers.tests.test_batching import CustomerImportExportSetup
     37from waeup.ikoba.payments.interfaces import IPayer, IPayerFinder
    3838from waeup.ikoba.testing import FunctionalLayer, FunctionalTestCase
     39
    3940
    4041class HelperTests(unittest.TestCase):
     
    5960            path_from_custid('KM123456'), u'00120/KM123456')
    6061        return
     62
    6163
    6264class CustomerTest(FunctionalTestCase):
     
    9294
    9395
     96class TestCustomerHelpers(FunctionalTestCase):
     97
     98    layer = FunctionalLayer
     99
     100    def test_payer_adapter(self):
     101        # we can adapt ICustomer to IPayer (i.e. create a payer)
     102        customer = Customer()
     103        customer.firstname, customer.lastname = u'Anna', u'Tester'
     104        result = IPayer(customer)
     105        self.assertTrue(isinstance(result, CustomerPayer))
     106        verify.verifyObject(IPayer, result)
     107        self.assertEqual(result.first_name, u'Anna')
     108        self.assertEqual(result.last_name, u'Tester')
     109        self.assertEqual(result.payer_id, customer.customer_id)
     110
     111    def test_customer_finder_iface(self):
     112        # we have a customer finder that returns IPayableFinder data.
     113        verify.verifyClass(IPayerFinder, CustomerFinder)
     114
     115    def test_customer_finder_registered(self):
     116        # the customer finder is a utility registered on startup
     117        util = getUtility(IPayerFinder, name='customer_finder')
     118        self.assertTrue(isinstance(util, CustomerFinder))
     119        utils = [util for name, util in getUtilitiesFor(IPayerFinder)
     120                 if isinstance(util, CustomerFinder)]
     121        self.assertEqual(len(utils), 1)
     122
     123    def create_customer_and_site(self):
     124        customer = Customer()
     125        customer.customer_id = u'CUST1'
     126        self.getRootFolder()['app'] = Company()
     127        app = self.getRootFolder()['app']
     128        setSite(app)
     129        return customer, app
     130
     131    def test_customer_finder(self):
     132        # the customer finder can really find customers
     133        customer, app = self.create_customer_and_site()
     134        app['mycustomer'] = customer  # trigger cataloging
     135        finder = CustomerFinder()
     136        result = finder.get_payer_by_id('CUST1')
     137        self.assertTrue(result is customer)
     138
     139    def test_customer_finder_not_stored(self):
     140        # we get none if an id is not stored
     141        customer, app = self.create_customer_and_site()
     142        app['mycustomer'] = customer  # trigger cataloging
     143        finder = CustomerFinder()
     144        result = finder.get_payer_by_id('Not-a-valid-id')
     145        self.assertTrue(result is None)
     146
     147    def test_customer_finder_no_catalog(self):
     148        # customer finder does not complain about missing catalog
     149        finder = CustomerFinder()
     150        result = finder.get_payer_by_id('CUST1')
     151        self.assertTrue(result is None)
     152
     153
    94154class CustomerRemovalTests(CustomerImportExportSetup):
    95155    # Test handle_customer_removed
     
    192252        return
    193253
     254
    194255class CustomerFactoryTest(FunctionalTestCase):
    195256
Note: See TracChangeset for help on using the changeset viewer.