Test coverage for vnccollab.theme.portlets.redmine_tickets

vnccollab/      covered 69% (1245 of 4098 uncovered)
    theme/      covered 69% (1245 of 4098 uncovered)
        portlets/      covered 68% (353 of 1108 uncovered)
            redmine_tickets.py      covered 59% (49 of 120 uncovered)

    1: import logging
    1: import textile
    1: from pyactiveresource.activeresource import ActiveResource
       
    1: from zope.component import getMultiAdapter, getUtility
    1: from zope.formlib import form
    1: from zope.interface import implements
    1: from zope import schema
       
    1: from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
    1: from Products.CMFCore.utils import getToolByName
    1: from Products.CMFPlone.utils import safe_unicode
       
    1: from plone.registry.interfaces import IRegistry
    1: from plone.memoize.instance import memoize
    1: from plone.portlets.interfaces import IPortletDataProvider
    1: from plone.app.portlets.portlets import base
       
    1: from vnccollab.common.portlets import deferred
    1: from vnccollab.theme.portlets.zimbra_mail import logException
    1: from vnccollab.theme import messageFactory as _
       
    1: logger = logging.getLogger('vnccollab.theme.RedmineTicketsPortlet')
       
       
    2: class IRedmineTicketsPortlet(IPortletDataProvider):
       
    1:     header = schema.TextLine(
    1:         title=_(u"Header"),
    1:         description=_(u"Header of the portlet."),
    1:         required=True,
    1:         default=u'Redmine Tickets')
       
    1:     count = schema.Int(
    1:         title=_(u"Number of items to display"),
    1:         description=_(u"How many items to list."),
    1:         required=True,
    1:         default=5)
       
    1:     request_timeout = schema.Int(
    1:         title=_(u"Request timeout"),
    1:         description=_(u"How many seconds to wait for hanging Redmine request."),
    1:         required=True,
    1:         default=15)
       
       
    2: class Assignment(base.Assignment):
    1:     implements(IRedmineTicketsPortlet)
       
    1:     header = u''
    1:     count = 5
    1:     request_timeout = 15
       
    1:     @property
           def title(self):
               """Return portlet header"""
>>>>>> return self.header
1: def __init__(self, header=u'', count=5, request_timeout=15): 1: self.header = header 1: self.count = count 1: self.request_timeout = request_timeout 2: class Renderer(deferred.DeferredRenderer): 1: render_preload = render_full = ZopeTwoPageTemplateFile( 1: 'templates/redmine_tickets.pt') 1: def refresh(self): '''Calculates the data needed for deferred_update.'''
>>>>>> self.getTickets()
1: def getTicketsURL(self): """Returns tickets root url"""
>>>>>> return '%s/issues' % self._url()
1: def getTickets(self): """Returns list of opened issues for authenticated user""" 1: username, password = self.getAuthCredentials() 1: if not username or not password: 1: return ()
>>>>>> return self._tickets(self._url(), username, password)
1: @memoize def _tickets(self, url, username, password): """Requests redmine for list of opened issues for current user""" # create ActiveResource classes to fetch data from Redmine over REST API
>>>>>> attrs = {'_site': url, '_user': username, '_password': password}
>>>>>> if self.data.request_timeout:
>>>>>> attrs['_timeout'] = self.data.request_timeout
>>>>>> Issue = type("Issue", (ActiveResource,), attrs.copy())
>>>>>> User = type("User", (ActiveResource,), attrs.copy())
# do actual calls to redmine
>>>>>> try:
# fetch opened issues belonging to authenticated user
>>>>>> data = Issue.find(assigned_to_id=User.find('current').id,
>>>>>> status_id='o',
>>>>>> sort='updated_on:desc')
>>>>>> except:
>>>>>> logException(_(u"Error during fetching redmine tickets %s" % url),
>>>>>> context=self.context, logger=logger)
>>>>>> return ()
>>>>>> plone_view = getMultiAdapter((self.context, self.request),
>>>>>> name=u'plone')
# process retrieved data
>>>>>> tickets = []
>>>>>> limit = self.data.count
>>>>>> counter = 0
>>>>>> for item in data:
# we've got enough tickets
>>>>>> if counter >= limit:
>>>>>> break
>>>>>> info = item.to_dict()
# skip invalid entries
>>>>>> if not info.get('id') or not info.get('subject'):
>>>>>> continue
# prepare date
>>>>>> date = info.get('updated_on', '')
>>>>>> if date:
>>>>>> date = plone_view.toLocalizedTime(date, long_format=1)
# prepare ticket body
>>>>>> body = safe_unicode(info.get('description', ''))
>>>>>> if body:
# convert textile to html and do not cut down ticket # description anymore
>>>>>> try:
>>>>>> body = textile.textile(body)
>>>>>> except:
>>>>>> pass
# crop length to 160 characters # body = plone_view.cropText(body, 160, ellipsis=u'...')
>>>>>> tickets.append({
>>>>>> 'id': info['id'],
>>>>>> 'title': safe_unicode(info['subject']),
>>>>>> 'body': body,
>>>>>> 'date': date,
>>>>>> 'url': '%s/issues/%s' % (url, info['id'])
})
>>>>>> counter += 1
>>>>>> return tuple(tickets)
1: @memoize def getAuthCredentials(self): """Returns username and password for redmine user.""" # take username and password from authenticated user Zimbra creds 1: mtool = getToolByName(self.context, 'portal_membership') 1: member = mtool.getAuthenticatedMember() 1: username, password = member.getProperty('redmine_username', ''), \ 1: member.getProperty('redmine_password', '') # password could contain non-ascii chars, ensure it's properly encoded 1: return username, safe_unicode(password).encode('utf-8') 1: @memoize def _url(self): """Redmine root url"""
>>>>>> registry = getUtility(IRegistry)
>>>>>> return registry.get('vnccollab.theme.redmine.url')
1: @property def title(self): """return title of feed for portlet"""
>>>>>> return self.data.header
2: class AddForm(base.AddForm): 1: form_fields = form.Fields(IRedmineTicketsPortlet) 1: label = _(u"Add Redmine Tickets Portlet") 1: description = _(u"Renders list of opened Redmine Tickets for authenticated " "user.") 1: def create(self, data):
>>>>>> return Assignment(**data)
2: class EditForm(base.EditForm): 1: form_fields = form.Fields(IRedmineTicketsPortlet) 1: label = _(u"Edit Redmine Tickets Portlet") 1: description = _(u"Renders list of opened Redmine Tickets for authenticated " "user.")