Changeset 14173


Ignore:
Timestamp:
22 Sep 2016, 19:43:09 (8 years ago)
Author:
Henrik Bettermann
Message:

Add reports and exports purge buttons.

Add more tests.

Location:
main/waeup.ikoba/trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.ikoba/trunk/CHANGES.txt

    r13806 r14173  
    440.2.dev0 (unreleased)
    55=====================
     6
     7* Add reports and exports purge buttons.
    68
    79* Add portal maintenance mode.
  • main/waeup.ikoba/trunk/src/waeup/ikoba/browser/pages.py

    r13809 r14173  
    196196    return
    197197
    198 def doll_up(view, user=None):
     198def doll_up(view, user=None, purge=False):
    199199    """Doll up export jobs for displaying in table.
    200200    """
     201    ob_class = view.__implemented__.__name__.replace('waeup.ikoba.','')
    201202    job_entries = view.context.get_running_export_jobs(user)
    202203    job_manager = getUtility(IJobManager)
     
    222223                               job.failed and time_delta and \
    223224                               time_delta.days < 1
     225        if not show_download_button and purge:
     226            entry = view.context.entry_from_job_id(job_id)
     227            view.context.delete_export_entry(entry)
     228            view.context.logger.info(
     229                '%s - purged: job_id=%s' % (ob_class, job_id))
     230            continue
    224231        new_entry = dict(
    225232            job=job_id,
     
    16281635        return sorted(title_name_tuples)
    16291636
    1630     def update(self, CREATE=None, DISCARD=None, exporter=None,
     1637    def update(self, CREATE=None, DISCARD=None, PURGE=None, exporter=None,
    16311638               job_id=None, CANCEL=None):
    16321639        if CANCEL is not None:
     
    16571664                '%s - discarded: job_id=%s' % (ob_class, job_id))
    16581665            self.flash(_('Discarded export') + ' %s' % job_id)
    1659         self.entries = doll_up(self, user=None)
     1666        self.entries = doll_up(self, user=None, purge=PURGE)
     1667        if PURGE:
     1668            self.flash(_('Exports successfully purged.'))
    16601669        return
    16611670
  • main/waeup.ikoba/trunk/src/waeup/ikoba/browser/reports.py

    r12659 r14173  
    1919"""
    2020import grok
     21from datetime import datetime, timedelta
    2122from zope.component import getUtility, queryUtility
    2223from zope.location.location import located
     24from zope.security import checkPermission
    2325from waeup.ikoba.interfaces import IJobManager, IIkobaUtils
    2426from waeup.ikoba.interfaces import MessageFactory as _
    25 from waeup.ikoba.browser.layout import IkobaPage
     27from waeup.ikoba.browser.layout import IkobaPage, jsaction
    2628from waeup.ikoba.reports import IReportsContainer, IReportGenerator
    2729from waeup.ikoba.reports import get_generators
     
    4244        return self.url(self.context, '%s/pdf' % job_id)
    4345
    44     def update(self, job_id=None, DISCARD=None, DOWNLOAD=None):
     46    def update(self, job_id=None, DISCARD=None, DOWNLOAD=None, PURGE=None):
    4547        self.entries = []
     48        ob_class = self.__implemented__.__name__.replace('waeup.ikoba.', '')
    4649        if job_id and DISCARD:
    4750            entry = self.context.report_entry_from_job_id(job_id)
    4851            self.context.delete_report_entry(entry)
    49             self.flash('Report discarded: %s' % job_id)
    50             ob_class = self.__implemented__.__name__.replace('waeup.ikoba.','')
     52            self.flash('Report %s discarded' % job_id)
    5153            grok.getSite().logger.info(
    5254                '%s - report %s discarded' % (ob_class, job_id))
    53         self.entries = self._generate_entries(user_id=None)
     55        if not checkPermission('waeup.manageReports', self.context):
     56            user_id = get_current_principal().id
     57        else:
     58            user_id = None
     59        self.entries = self._generate_entries(user_id=user_id)
    5460        if job_id and DOWNLOAD:
    5561            self.redirect(self._report_url(job_id))
    5662            return
     63        if PURGE:
     64            counter = 0
     65            for entry in self.context.get_running_report_jobs(user_id=user_id):
     66                job_id, gen_name, user = entry
     67                job = getUtility(IJobManager).get(job_id)
     68                starttime = getattr(job, 'begin_after', None)
     69                delta = timedelta(weeks=4)
     70                tz = getUtility(IIkobaUtils).tzinfo
     71                if datetime.now(tz) - delta > starttime:
     72                    self.context.delete_report_entry(entry)
     73                    counter += 1
     74                    grok.getSite().logger.info(
     75                        '%s - report %s purged' % (ob_class, job_id))
     76            self.flash('%s report(s) purged.' % counter)
     77            self.redirect(self.url(self.context))
    5778        return
    5879
  • main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/datacenterexportpage.pt

    r12633 r14173  
    7979          <a href="" class="btn btn-primary btn-xs"
    8080                 tal:attributes="href job/download_url"
    81                  tal:condition="job/show_download_button">
     81                 tal:condition="job/show_download_button"
     82                 i18n:translate="">
    8283            Download</a>
    8384          <input type="hidden" name="job_id"
     
    8586          <input type="submit" class="btn btn-default btn-xs"
    8687                 name="DISCARD" value="Discard"
    87                  tal:condition="job/show_discard_button" />
     88                 tal:condition="job/show_discard_button"
     89                 i18n:translate=""/>
    8890        </form>
    8991      </td>
     
    9193  </tbody>
    9294</table>
     95
     96<form method="POST" i18n:domain="waeup.ikoba">
     97  <div class="form-group">
     98    <input type="submit" class="btn btn-primary"
     99      name="PURGE" value="Purge outdated exports"
     100      data-toggle="tooltip"
     101      title="All exports older than 24 hours will be discarded!"
     102      i18n:translate=""
     103      />
     104  </div>
     105</form>
  • main/waeup.ikoba/trunk/src/waeup/ikoba/browser/templates/reportscontainerpage.pt

    r11949 r14173  
    4848</table>
    4949<form method="POST" i18n:domain="waeup.ikoba">
    50   <a tal:attributes="href python:view.url(context, 'create')"
    51      class="btn btn-primary" i18n:translate="">
    52     Create new report
    53   </a>
     50  <div class="form-group">
     51    <a tal:attributes="href python:view.url(context, 'create')"
     52       class="btn btn-primary" i18n:translate="">
     53      Create new report
     54    </a>
     55    <input type="submit" class="btn btn-default"
     56      name="PURGE" value="Purge outdated reports"
     57      data-toggle="tooltip" title="All reports older than 4 weeks will be discarded!"
     58      onclick="return window.confirm('Are you really sure?')"/>
     59  </div>
    5460</form>
  • main/waeup.ikoba/trunk/src/waeup/ikoba/browser/tests/test_browser.py

    r13808 r14173  
    2424import os
    2525import grok
     26from datetime import datetime, timedelta
    2627from zc.async.testing import wait_for_result
    2728from zope.component import createObject, getUtility
     
    3233from waeup.ikoba.testing import FunctionalLayer, FunctionalTestCase
    3334from waeup.ikoba.app import Company
    34 from waeup.ikoba.interfaces import IJobManager, IUserAccount
     35from waeup.ikoba.interfaces import IJobManager, IUserAccount, IIkobaUtils
    3536from waeup.ikoba.tests.test_async import FunctionalAsyncTestCase
    3637
     
    8384        wait_for_result(job)
    8485        return job_id
     86
     87    def trigger_export(self):
     88        # helper to start an export. Make sure to remove the result file
     89        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
     90        self.browser.open(self.datacenter_path)
     91        self.browser.getLink("Export data").click()
     92        self.browser.getControl(name="exporter").value = ['products']
     93        self.browser.getControl("Create CSV file").click()
     94        return
    8595
    8696    def cleanup_run_job(self):
     
    194204        return
    195205
     206    def test_export_download(self):
     207        # we can download a generated export result
     208        self.trigger_export()
     209        # while the export file is created, we get a reload button
     210        # (or a loading bar if javascript is enabled)...
     211        self.assertTrue('Reload' in self.browser.contents)
     212        # ...which is displayed as long as the job is not finished.
     213        # When the job is finished and we reload the page...
     214        job_id = self.wait_for_export_job_completed()
     215        self.browser.open(self.datacenter_path + '/export')
     216        self.assertFalse('Reload' in self.browser.contents)
     217        # ...we can download the result
     218        self.browser.getLink("Download").click()
     219        self.assertEqual(self.browser.headers['content-type'],
     220                         'text/csv; charset=UTF-8')
     221        self.assertEqual(self.browser.headers['content-disposition'],
     222            'attachment; filename="WAeUP.Ikoba_products_%s.csv' % job_id)
     223        self.assertEqual(self.browser.contents,
     224            'contract_category,contract_title,description,options,'
     225            'product_id,terms_and_conditions,title,valid_from,valid_to,'
     226            'users_with_local_roles\r\n')
     227        # Thew job can be discarded
     228        self.browser.open(self.datacenter_path + '/export')
     229        self.browser.getControl("Discard").click()
     230        self.assertEqual(len(self.app['datacenter'].running_exports), 0)
     231        logfile = os.path.join(
     232            self.app['datacenter'].storage, 'logs', 'datacenter.log')
     233        logcontent = open(logfile).read()
     234        self.assertTrue('zope.mgr - browser.pages.ExportCSVPage - exported: '
     235                        'products, job_id=' in logcontent)
     236        self.assertTrue('zope.mgr - browser.pages.ExportCSVView - '
     237                        'downloaded: WAeUP.Ikoba_products_%s.csv, job_id=%s'
     238                        % (job_id, job_id) in logcontent)
     239        return
     240
     241    def test_export_discard(self):
     242        # we can discard a generated export result
     243        self.trigger_export()
     244        job_id = self.wait_for_export_job_completed()
     245        self.browser.open(self.datacenter_path + '/@@export')
     246        self.browser.getControl("Discard").click()
     247        self.assertTrue('Discarded export' in self.browser.contents)
     248        logfile = os.path.join(
     249            self.app['datacenter'].storage, 'logs', 'datacenter.log')
     250        logcontent = open(logfile).read()
     251        self.assertTrue(
     252            'zope.mgr - browser.pages.ExportCSVPage - discarded: job_id=%s'
     253            % job_id in logcontent)
     254        return
     255
     256    def test_export_purge(self):
     257        self.trigger_export()
     258        job_id = self.wait_for_export_job_completed()
     259        self.browser.open(self.datacenter_path + '/export')
     260        self.browser.getControl("Purge").click()
     261        # Flash message always says successful ...
     262        self.assertTrue(
     263            'Exports successfully purged.' in self.browser.contents)
     264        # ... but the export is still there
     265        self.assertEqual(len(self.app['datacenter'].running_exports), 1)
     266
     267        job_id, gen_name, user = self.app['datacenter'].get_running_export_jobs()[0]
     268        job = getUtility(IJobManager).get(job_id)
     269        tz = getUtility(IIkobaUtils).tzinfo
     270        delta = timedelta(days=5)
     271        setattr(job, '_begin_after', datetime.now(tz) - delta)
     272        self.browser.getControl("Purge").click()
     273        self.assertEqual(len(self.app['datacenter'].running_exports), 0)
     274        logfile = os.path.join(
     275            self.app['datacenter'].storage, 'logs', 'datacenter.log')
     276        logcontent = open(logfile).read()
     277        self.assertTrue('zope.mgr - browser.pages.ExportCSVPage - '
     278                        'purged: job_id=%s' % job_id in logcontent)
     279        return
     280
    196281
    197282class SupplementaryBrowserTests(CompanySetup):
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/reports/tests/test_contract_statistics.py

    r12663 r14173  
    11# Tests for contract related reports
    22import os
     3from datetime import datetime, timedelta
    34from zc.async.testing import wait_for_result
    45from zope.interface.verify import verifyClass, verifyObject
    56from zope.component import getUtility
    6 from waeup.ikoba.interfaces import IJobManager
     7from waeup.ikoba.interfaces import IJobManager, IIkobaUtils
    78from waeup.ikoba.customers.reports.contract_statistics import (
    89    get_contract_stats, ContractStatisticsReport, IContractStatisticsReport)
     
    118119            )
    119120        return
     121
     122    def test_report_purge(self):
     123        self.trigger_report_creation()
     124        job_id = self.wait_for_report_job_completed()
     125        self.browser.open('http://localhost/app/reports')
     126        self.browser.getControl("Purge").click()
     127        self.assertTrue('0 report(s) purged' in self.browser.contents)
     128        job_id, gen_name, user = self.app['reports'].get_running_report_jobs(user_id=None)[0]
     129        job = getUtility(IJobManager).get(job_id)
     130        tz = getUtility(IIkobaUtils).tzinfo
     131        delta = timedelta(weeks=5)
     132        setattr(job, '_begin_after', datetime.now(tz) - delta)
     133        self.browser.getControl("Purge").click()
     134        self.assertTrue('1 report(s) purged' in self.browser.contents)
     135        logfile = os.path.join(
     136            self.app['datacenter'].storage, 'logs', 'main.log')
     137        logcontent = open(logfile).read()
     138        self.assertTrue(
     139            'INFO - zope.mgr - browser.reports.ReportsContainerPage - '
     140            'report %s purged' % job_id in logcontent
     141            )
     142        return
Note: See TracChangeset for help on using the changeset viewer.