Index: /main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_browser.py
===================================================================
--- /main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_browser.py	(revision 11977)
+++ /main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_browser.py	(revision 11978)
@@ -693,2 +693,56 @@
                         '123 (K1000000) - new@yy.zz' in logcontent)
         return
+
+class CustomerDataExportTests(CustomersFullSetup, FunctionalAsyncTestCase):
+    # Tests for CustomersContainer class views and pages
+
+    layer = FunctionalLayer
+
+    def wait_for_export_job_completed(self):
+        # helper function waiting until the current export job is completed
+        manager = getUtility(IJobManager)
+        job_id = self.app['datacenter'].running_exports[0][0]
+        job = manager.get(job_id)
+        wait_for_result(job)
+        return job_id
+
+    def test_datacenter_export(self):
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open('http://localhost/app/datacenter/@@export')
+        self.browser.getControl(name="exporter").value = ['customers']
+        self.browser.getControl("Create CSV file").click()
+
+        # When the job is finished and we reload the page...
+        job_id = self.wait_for_export_job_completed()
+        # ... the csv file can be downloaded ...
+        self.browser.open('http://localhost/app/datacenter/@@export')
+        self.browser.getLink("Download").click()
+        self.assertEqual(self.browser.headers['content-type'],
+            'text/csv; charset=UTF-8')
+        self.assertTrue(
+            'filename="WAeUP.Ikoba_customers_%s.csv' % job_id in
+            self.browser.headers['content-disposition'])
+        self.assertEqual(len(self.app['datacenter'].running_exports), 1)
+        job_id = self.app['datacenter'].running_exports[0][0]
+        # ... and discarded
+        self.browser.open('http://localhost/app/datacenter/@@export')
+        self.browser.getControl("Discard").click()
+        self.assertEqual(len(self.app['datacenter'].running_exports), 0)
+        # Creation, downloading and discarding is logged
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'datacenter.log')
+        logcontent = open(logfile).read()
+        self.assertTrue(
+            'zope.mgr - browser.pages.ExportCSVPage - exported: '
+            'customers, job_id=%s'
+            % job_id in logcontent
+            )
+        self.assertTrue(
+            'zope.mgr - browser.pages.ExportCSVView - downloaded: '
+            'WAeUP.Ikoba_customers_%s.csv, job_id=%s'
+            % (job_id, job_id) in logcontent
+            )
+        self.assertTrue(
+            'zope.mgr - browser.pages.ExportCSVPage - discarded: '
+            'job_id=%s' % job_id in logcontent
+            )
Index: /main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_export.py
===================================================================
--- /main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_export.py	(revision 11978)
+++ /main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_export.py	(revision 11978)
@@ -0,0 +1,107 @@
+import os
+import grok
+import datetime
+from cStringIO import StringIO
+from zope.component import queryUtility, getUtility
+from zope.event import notify
+from zope.interface.verify import verifyObject, verifyClass
+from waeup.ikoba.interfaces import (
+    ICSVExporter, IExtFileStore, IFileStoreNameChooser)
+from waeup.ikoba.customers.catalog import CustomersQuery
+from waeup.ikoba.customers.export import (
+    CustomersExporter, get_customers)
+from waeup.ikoba.customers.interfaces import ICSVCustomerExporter
+from waeup.ikoba.customers.customer import Customer
+from waeup.ikoba.customers.tests.test_batching import CustomerImportExportSetup
+from waeup.ikoba.testing import FunctionalLayer
+
+curr_year = datetime.datetime.now().year
+year_range = range(curr_year - 9, curr_year + 1)
+year_range_str = ','.join([str(i) for i in year_range])
+
+class ExportHelperTests(CustomerImportExportSetup):
+    layer = FunctionalLayer
+    def setUp(self):
+        super(ExportHelperTests, self).setUp()
+        customer = Customer()
+        self.app['customers'].addCustomer(customer)
+        customer = self.setup_customer(customer)
+        notify(grok.ObjectModifiedEvent(customer))
+        self.customer = self.app['customers'][customer.customer_id]
+        return
+
+    def test_get_customers_plain(self):
+        # without a filter we get all customers
+        result = get_customers(self.app)
+        self.assertEqual(len(list(result)), 1)
+        return
+
+class CustomersExporterTest(CustomerImportExportSetup):
+
+    layer = FunctionalLayer
+
+    def setUp(self):
+        super(CustomersExporterTest, self).setUp()
+        self.setup_for_export()
+        return
+
+    def test_ifaces(self):
+        # make sure we fullfill interface contracts
+        obj = CustomersExporter()
+        verifyObject(ICSVCustomerExporter, obj)
+        verifyClass(ICSVCustomerExporter, CustomersExporter)
+        return
+
+    def test_get_as_utility(self):
+        # we can get an customer exporter as utility
+        result = queryUtility(ICSVExporter, name="customers")
+        self.assertTrue(result is not None)
+        return
+
+    def test_export(self):
+        # we can really export customers
+        # set values we can expect in export file
+        self.setup_customer(self.customer)
+        exporter = CustomersExporter()
+        exporter.export([self.customer], self.outfile)
+        result = open(self.outfile, 'rb').read()
+        self.assertTrue(
+            'customer_id,email,firstname,lastname,middlename,phone,'
+            'reg_number,sex,suspended,suspended_comment,password,state,'
+            'history\r\n'
+            'A111111,anna@sample.com,Anna,Tester,M.,+234-123-12345#,'
+            '123,,0,,,created'
+            in result
+            )
+        return
+
+    def test_export_all(self):
+        # we can really export customers
+        # set values we can expect in export file
+        self.setup_customer(self.customer)
+        exporter = CustomersExporter()
+        exporter.export_all(self.app, self.outfile)
+        result = open(self.outfile, 'rb').read()
+        self.assertTrue(
+            'customer_id,email,firstname,lastname,middlename,phone,'
+            'reg_number,sex,suspended,suspended_comment,password,state,history\r\n'
+            'A111111,anna@sample.com,Anna,Tester,M.,+234-123-12345#,'
+            '123,,0,,,created'
+            in result
+            )
+        return
+
+    def test_export_customer(self):
+        # we can export a single customer
+        self.setup_customer(self.customer)
+        exporter = CustomersExporter()
+        exporter.export_customer(self.customer, self.outfile)
+        result = open(self.outfile, 'rb').read()
+        self.assertTrue(
+            'customer_id,email,firstname,lastname,middlename,phone,reg_number,'
+            'sex,suspended,suspended_comment,password,state,history\r\n'
+            'A111111,anna@sample.com,Anna,Tester,M.,+234-123-12345#,'
+            '123,,0,,,created,'
+            in result
+            )
+        return
