Example #1
0
    def test_props_format_wrap_leftside_unicode(self):
        self.env.config.set("notification", "mime_encoding", "none")
        ticket = Ticket(self.env)
        ticket["summary"] = u"This is a summary"
        ticket["reporter"] = u"anonymous"
        ticket["status"] = u"new"
        ticket["owner"] = u"somebody"
        ticket["type"] = u"defect"
        ticket["priority"] = u"major"
        ticket["milestone"] = u"milestone1"
        ticket["component"] = (
            u"Trac は BSD ライセンスのもとで配"
            u"布されています。[1:]このライセ"
            u"ンスの全文は、配布ファイルに"
            u"含まれている [3:COPYING] ファイル"
            u"と同じものが[2:オンライン]で参"
            u"照できます。"
        )
        ticket["version"] = u"2.0"
        ticket["resolution"] = u"fixed"
        ticket["keywords"] = u""
        ticket.insert()
        formatted = """\
  Reporter:  anonymous                           |      Owner:  somebody
      Type:  defect                              |     Status:  new
  Priority:  major                               |  Milestone:  milestone1
 Component:  Trac は BSD ライセンスのもとで配布  |    Version:  2.0
  されています。[1:]このライセンスの全文は、配   |   Keywords:
  布ファイルに含まれている [3:COPYING] ファイル  |
  と同じものが[2:オンライン]で参照できます。     |
Resolution:  fixed                               |"""
        self._validate_props_format(formatted, ticket)
Example #2
0
 def _change_ticket(self, id, history):
     ticket = Ticket(self.env, id)
     keys = history.keys()
     keys.sort()
     for key in keys:
         ticket['hours_remaining'] = history[key]
         ticket.save_changes("me", "testing", time.mktime(key.timetuple()))
Example #3
0
 def wake_up(self, *args):
     db = self.env.get_db_cnx()        
     cursor = db.cursor()
     # find still opened more recent milestone
     # select ticket whom milestone are due in less than specified delay
     cursor.execute("""
             SELECT m.name  FROM milestone m                        
             WHERE  m.completed is NULL or m.completed = 0
             AND m.due not NULL and m.due > 0
             ORDER BY m.due ASC LIMIT 1            
         """ )
     next_milestone = None
     for name, in cursor:
         next_milestone = name            
             
     # select ticket whom milestone are due in less than specified delay
     cursor.execute("""
             SELECT t.id , t.milestone  FROM ticket t, milestone m                        
             WHERE t.status != 'closed'
             AND    t.milestone = m.name  
             AND    m.completed not NULL and m.completed > 0            
         """ )        
     if next_milestone:          
         for id, milestone in cursor:
             mess = "ticket %s is opened in closed milestone %s. Should postpone this ticket to %s" % (id, milestone, next_milestone)
             self.env.log.debug(mess)
             ticket = Ticket(self.env, id)
             ticket.populate({'milestone':next_milestone})
             ticket.save_changes(self.getId(),mess)
     else:
         self.env.log.debug("No opened milestone found. Cannot postpone tickets")
Example #4
0
    def test_get_tickets(self):
        for pdata in (
            {'prefix': 'p2', 'name':'product, too', 'description': ''},
            {'prefix': 'p3', 'name':'strike three', 'description': ''},
        ):
            num_tickets = 5
            product = Product(self.global_env)
            product._data.update(pdata)
            product.insert()
            self.env = ProductEnvironment(self.global_env, product)
            for i in range(num_tickets):
                ticket = Ticket(self.env)
                ticket['summary'] = 'hello ticket #%s-%d' % (product.prefix, i)
                ticket['reporter'] = 'admin'
                tid = ticket.insert()

            # retrieve tickets using both global and product scope
            tickets_from_global = [(t['product'], t['id']) for t in
                Product.get_tickets(self.global_env, product.prefix)]
            self.assertEqual(len(tickets_from_global), num_tickets)
            tickets_from_product = [(t['product'], t['id']) for t in
                Product.get_tickets(self.env)]
            self.assertEqual(len(tickets_from_product), num_tickets)
            # both lists should contain same elements
            intersection = set(tickets_from_global) & set(tickets_from_product)
            self.assertEqual(len(intersection), num_tickets)
Example #5
0
 def set_resource_tags(self, req, ticket_or_resource, tags, comment=u'',
                       when=None):
     try:
         resource = ticket_or_resource.resource
     except AttributeError:
         resource = ticket_or_resource
         assert resource.realm == self.realm
         if not self._check_permission(req, resource, 'modify'):
             raise PermissionError(resource=resource, env=self.env)
         tag_set = set(tags)
         # Processing a call from TracTags, try to alter the ticket.
         tkt = Ticket(self.env, resource.id)
         all = self._ticket_tags(tkt)
         # Avoid unnecessary ticket changes, considering comments below.
         if tag_set != all:
             # Will only alter tags in 'keywords' ticket field.
             keywords = split_into_tags(tkt['keywords'])
             # Assume, that duplication is depreciated and consolitation
             # wanted to primarily affect 'keywords' ticket field.
             # Consequently updating ticket tags and reducing (tag)
             # 'ticket_fields' afterwards may result in undesired tag loss.
             tag_set.difference_update(all.difference(keywords))
             tkt['keywords'] = u' '.join(sorted(map(to_unicode, tag_set)))
             tkt.save_changes(get_reporter_id(req), comment)
     else:
         # Processing a change listener event.
         tags = self._ticket_tags(ticket_or_resource)
         super(TicketTagProvider,
               self).set_resource_tags(req, resource, tags)
Example #6
0
    def ticket_created(self, ticket):
        # Check for loops
        if self._check_ticket(ticket): return
        
        linkmap = {}
    
        ticket_copy = Ticket(self.env, ticket.id)
        ticket_copy['tracforge_linkmap'] = serialize_map({self.env.path: ticket.id})
        ticket_copy.tracforge_seen = ticket.tracforge_seen

        subscribers = SubscriptionManager(self.env).get_subscribers('ticket')
        for subscriber in subscribers:
            env = open_env(subscriber)
            self.log.debug('Pushing ticket number %s to %s'%(ticket_copy.id,env.path))
            id = TicketSubscribable(env)._ticket_created(ticket_copy)
            linkmap[env.path] = id
            
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        
        self.log.debug('value = %s' % serialize_map(linkmap))
        cursor.execute("UPDATE ticket_custom SET value=%s "
                       "WHERE ticket = %s AND name = %s" , (serialize_map(linkmap), ticket.id, 'tracforge_linkmap'))
                       
        db.commit()
Example #7
0
    def test_owner_from_changed_component(self):
        """
        Verify that the owner of a new ticket is updated when the component is
        changed.
        """
        component1 = Component(self.env)
        component1.name = 'test1'
        component1.owner = 'joe'
        component1.insert()

        component2 = Component(self.env)
        component2.name = 'test2'
        component2.owner = 'kate'
        component2.insert()

        ticket = Ticket(self.env)
        ticket['reporter'] = 'santa'
        ticket['summary'] = 'Foo'
        ticket['component'] = 'test1'
        ticket['status'] = 'new'
        tktid = ticket.insert()

        ticket = Ticket(self.env, tktid)
        ticket['component'] = 'test2'
        ticket.save_changes('jane', 'Testing')
        self.assertEqual('kate', ticket['owner'])
Example #8
0
 def test_set_tags(self):
     tags = ['tag3']
     ticket = Ticket(self.env, 1)
     ticket['keywords'] = tags[0]
     # Tags get updated by TicketChangeListener method.
     ticket.save_changes(self.req.authname)
     self.assertEquals(self.tag_sys.get_all_tags(self.req).keys(), tags)
Example #9
0
def ticket_setup(tc):
    ticket = Ticket(tc.env)
    ticket['reporter'] = 'santa'
    ticket['summary'] = 'This is the summary'
    ticket.insert()
    ticket['status'] = 'new'
    ticket.save_changes('claus', 'set status', 0)
Example #10
0
 def get_changelog( self , ticketid):
   t = Ticket(self.macroenv.tracenv, ticketid)
   try: 
     return( t.get_changelog() )
   except:
     self.macroenv.tracenv.log.warning("get_changelog failed on ticket %s", ticketid)
     return [] # no changelogs
 def _test_short_login(enabled):
     ticket = Ticket(self.env)
     ticket['reporter'] = 'joeuser'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     # Be sure that at least one email address is valid, so that we 
     # send a notification even if other addresses are not valid
     self.env.config.set('notification', 'smtp_always_cc',
                         '*****@*****.**')
     if enabled:
         self.env.config.set('notification', 'use_short_addr', 'true')
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should not have a 'To' header
     if not enabled:
         self.failIf('To' in headers)
     else:
         tolist = [addr.strip() for addr in headers['To'].split(',')]
     # Msg should have a 'Cc' field
     self.failIf('Cc' not in headers)
     cclist = [addr.strip() for addr in headers['Cc'].split(',')]
     if enabled:
         # Msg should be delivered to the reporter
         self.failIf(ticket['reporter'] not in tolist)
     else:
         # Msg should not be delivered to joeuser
         self.failIf(ticket['reporter'] in cclist)
     # Msg should still be delivered to the always_cc list
     self.failIf(self.env.config.get('notification',
                 'smtp_always_cc') not in cclist)
 def test_date(self):
     """Date format compliance (RFC822) 
        we do not support 'military' format""" 
     date_str = r"^((?P<day>\w{3}),\s*)*(?P<dm>\d{2})\s+" \
                r"(?P<month>\w{3})\s+(?P<year>200\d)\s+" \
                r"(?P<hour>\d{2}):(?P<min>[0-5][0-9])" \
                r"(:(?P<sec>[0-5][0-9]))*\s" \
                r"((?P<tz>\w{2,3})|(?P<offset>[+\-]\d{4}))$"
     date_re = re.compile(date_str)
     # python time module does not detect incorrect time values
     days = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
     months = ['Jan','Feb','Mar','Apr','May','Jun', \
               'Jul','Aug','Sep','Oct','Nov','Dec']
     tz = ['UT','GMT','EST','EDT','CST','CDT','MST','MDT''PST','PDT']
     ticket = Ticket(self.env)
     ticket['reporter'] = '"Joe User" <*****@*****.**>'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     self.failIf('Date' not in headers)
     mo = date_re.match(headers['Date'])
     self.failIf(not mo)
     if mo.group('day'):
         self.failIf(mo.group('day') not in days)
     self.failIf(int(mo.group('dm')) not in range(1,32))
     self.failIf(mo.group('month') not in months)
     self.failIf(int(mo.group('hour')) not in range(0,24))
     if mo.group('tz'):
         self.failIf(mo.group('tz') not in tz)
 def _test_default_domain(enabled):
     self.env.config.set('notification', 'always_notify_owner',
                         'false')
     self.env.config.set('notification', 'always_notify_reporter',
                         'false')
     self.env.config.set('notification', 'smtp_always_cc', '')
     ticket = Ticket(self.env)
     ticket['cc'] = 'joenodom, [email protected]'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     # Be sure that at least one email address is valid, so that we 
     # send a notification even if other addresses are not valid
     self.env.config.set('notification', 'smtp_always_cc',
                         '*****@*****.**')
     if enabled:
         self.env.config.set('notification', 'smtp_default_domain',
                             'example.org')
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'Cc' field
     self.failIf('Cc' not in headers)
     cclist = [addr.strip() for addr in headers['Cc'].split(',')]
     self.failIf('*****@*****.**' not in cclist)
     self.failIf('*****@*****.**' not in cclist)
     if not enabled:
         self.failIf(len(cclist) != 2)
         self.failIf('joenodom' in cclist)
     else:
         self.failIf(len(cclist) != 3)
         self.failIf('*****@*****.**' not in cclist)
 def _test_updater(disable):
     if disable:
         self.env.config.set('notification','always_notify_updater',
                             'false')
     ticket = Ticket(self.env)
     ticket['reporter'] = '*****@*****.**'
     ticket['summary'] = u'This is a súmmäry'
     ticket['cc'] = '*****@*****.**'
     ticket.insert()
     ticket['component'] = 'dummy'
     now = time.time()
     ticket.save_changes('*****@*****.**', 'This is a change',
                         when=now)
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=False, modtime=now)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # checks for header existence
     self.failIf(not headers)
     # checks for updater in the 'To' recipient list
     self.failIf('To' not in headers)
     tolist = [addr.strip() for addr in headers['To'].split(',')]
     if disable:
         self.failIf('*****@*****.**' in tolist)
     else:
         self.failIf('*****@*****.**' not in tolist)
 def test_recipients(self):
     """To/Cc recipients"""
     ticket = Ticket(self.env)
     ticket['reporter'] = '"Joe User" <*****@*****.**>'
     ticket['owner']    = '*****@*****.**'
     ticket['cc']       = '[email protected], [email protected], ' \
                          '*****@*****.**'
     ticket['summary'] = 'Foo'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     recipients = notifysuite.smtpd.get_recipients()
     # checks there is no duplicate in the recipient list
     rcpts = []
     for r in recipients:
         self.failIf(r in rcpts)
         rcpts.append(r)
     # checks that all cc recipients have been notified
     cc_list = self.env.config.get('notification', 'smtp_always_cc')
     cc_list = "%s, %s" % (cc_list, ticket['cc'])
     for r in cc_list.replace(',', ' ').split():
         self.failIf(r not in recipients)
     # checks that owner has been notified
     self.failIf(smtp_address(ticket['owner']) not in recipients)
     # checks that reporter has been notified
     self.failIf(smtp_address(ticket['reporter']) not in recipients)
Example #16
0
    def new_another_ticket(self, env, ticket, comment, author, trac):
	project_name = self.env.config.get('project','name')
	project_url = self.env.config.get('project','url')
	tkt_id = ticket.id
	tkt = Ticket(env)
	
	self.log.info("Ticket_id: %s" %(ticket.id))
                    
	tkt['status'] = 'new'
        tkt['reporter'] = project_name
        tkt['summary'] = '[' + project_name + '] #'+ str(tkt_id) +": "+ ticket['summary']
	
	description = ticket['description']
	if not comment == "":
	    comment = "\n * Comment: \n" + comment + "\n"
	ticket_url = "\n * Ticket: " + "[" + project_url + "/ticket/" + str(tkt_id) + " "  + project_name + "]"
	
        tkt['description'] = description + comment + ticket_url
	
	if ticket['taskstatus']:
	    tkt['taskstatus'] = trac['newstatus']
	
        self.log.info("tkt.insert")
	another_tkt_id = tkt.insert()
	if another_tkt_id:
	    self._insert_anotherticket(env, another_tkt_id, project_name, tkt_id)
	    self.notify(env, tkt, True)
	    return another_tkt_id
	else:
	    return False
Example #17
0
    def test_modify_missing_cnums_and_comment(self):
        """Editing a comments when all cnums are missing and one comment
        field is missing
        """
        cursor = self.db.cursor()
        cursor.execute("UPDATE ticket_change SET oldvalue='' "
                       "WHERE oldvalue='1'")
        cursor.execute("DELETE FROM ticket_change "
                       "WHERE field='comment' AND oldvalue='1.2'")
        cursor.execute("UPDATE ticket_change SET oldvalue='' "
                       "WHERE oldvalue='3'")
        self.db.commit()

        # Modify after missing comment
        ticket = Ticket(self.env, self.id)
        t = self.created + timedelta(seconds=50)
        ticket.modify_comment(self._find_change(ticket, 3),
                              'joe', 'New comment 3', t)
        self.assertChange(ticket, 3, self.t3, 'jim',
            keywords=dict(author='jim', old='a, b, c', new='a, b'),
            comment=dict(author='jim', old='', new='New comment 3'),
            _comment0=dict(author='joe', old='Comment 3',
                           new=str(to_utimestamp(t))))

        # Modify missing comment
        t = self.created + timedelta(seconds=60)
        ticket.modify_comment(self._find_change(ticket, 2),
                              'joe', 'New comment 2', t)
        self.assertChange(ticket, 2, self.t2, 'john',
            owner=dict(author='john', old='john', new='jack'),
            comment=dict(author='john', old='', new='New comment 2'),
            _comment0=dict(author='joe', old='',
                           new=str(to_utimestamp(t))))
Example #18
0
    def	change_another_ticket(self, env, tkt_id, comment, author, ticket, trac, action='another'):
	""" Change ticket in another_trac """
	self.log.info("Call change_another_ticket(%s)" %(tkt_id))
	another_proj_name = env.config.get('project','name')
	if not re.match(".* \["+ another_proj_name +"\]", author):
	    (db,cursor) = self._get_dbcursor(env)
	    utc = UTC()
	    when = datetime.now(utc)
	    project_name = self.env.config.get('project','name')
	
	    try:
		tkt = Ticket(env, tkt_id, db)
	    except util.TracError, detail:
		return False	    
	
	    if action == 'native':
		if 'closed' in ticket['status']:
		    cursor.execute("SELECT oldvalue,author FROM ticket_change WHERE ticket='"+tkt_id+"' AND field = 'owner' ORDER by time DESC LIMIT 1")
		    old_owner = cursor.fetchone()[0]
#		    tkt['owner'] = old_owner
		    tkt['owner'] = tkt['reporter']
		    if tkt['taskstatus']:
			tkt['taskstatus'] = trac['returnstatus']
		    
	
	    elif action == 'another':
		if 'closed' in tkt['status'] and 'closed' not in ticket['status']:
		    self.log.info("TICKET FIXED AND CLOSED! REOPEN IT!")
		    tkt['status'] = 'reopened'
		    tkt['resolution'] = ''
	
	    author = author + " [" + project_name + "]"
	    tkt.save_changes(author, comment, when)
	    self.notify(env, tkt, False, when)
	    return True
Example #19
0
    def test_no_disown_from_changed_component(self):
        """
        Verify that a ticket is not disowned when the component is changed to
        a non-assigned component.
        """
        component1 = Component(self.env)
        component1.name = 'test1'
        component1.owner = 'joe'
        component1.insert()

        component2 = Component(self.env)
        component2.name = 'test2'
        component2.owner = ''
        component2.insert()

        ticket = Ticket(self.env)
        ticket['reporter'] = 'santa'
        ticket['summary'] = 'Foo'
        ticket['component'] = 'test1'
        ticket['status'] = 'new'
        tktid = ticket.insert()

        ticket = Ticket(self.env, tktid)
        ticket['component'] = 'test2'
        ticket.save_changes('jane', 'Testing')
        self.assertEqual('joe', ticket['owner'])
Example #20
0
    def post_process_request(self, req, template, data, content_type):
        if template == 'timeline.html':
            filter_projects = self._filtered_projects(req)
            if not filter_projects: #no filter means likely more than 1 project, so we insert the project name
                filter_projects = [project[1] for project in self.__SmpModel.get_all_projects()]
            
            if filter_projects:               
                filtered_events = []
                tickettypes = ("newticket", "editedticket", "closedticket", "attachment", "reopenedticket")
                self._old_render_fn = []
                self._current_project = []
                self._read_idx = -1
                for event in data['events']:
                    if event['kind'] in tickettypes:
                        resource = event['kind'] == "attachment" and event['data'][0].parent or event['data'][0]
                        if resource.realm == "ticket":
                            ticket = Ticket( self.env, resource.id )   
                            project = ticket.get_value_or_default('project')
                            if project and project in filter_projects:
                                if len(filter_projects) > 1: #only if more than 1 filtered project
                                    #store the old render function and the project to be inserted
                                    self._old_render_fn.append(event['render'])
                                    self._current_project.append(project)
                                    #redirect to our new render function (which will insert the project name)
                                    event['render'] = self._render_ticket_event
                                #add to the list of displayed events
                                filtered_events.append(event)
                        
                    else:
                        filtered_events.append(event)
    
                data['events'] = filtered_events

        return template, data, content_type
Example #21
0
 def _test_default_domain(enabled):
     self.env.config.set("notification", "always_notify_owner", "false")
     self.env.config.set("notification", "always_notify_reporter", "false")
     self.env.config.set("notification", "smtp_always_cc", "")
     ticket = Ticket(self.env)
     ticket["cc"] = "joenodom, [email protected]"
     ticket["summary"] = "This is a summary"
     ticket.insert()
     # Be sure that at least one email address is valid, so that we
     # send a notification even if other addresses are not valid
     self.env.config.set("notification", "smtp_always_cc", "*****@*****.**")
     if enabled:
         self.env.config.set("notification", "smtp_default_domain", "example.org")
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'Cc' field
     self.failIf("Cc" not in headers)
     cclist = [addr.strip() for addr in headers["Cc"].split(",")]
     self.failIf("*****@*****.**" not in cclist)
     self.failIf("*****@*****.**" not in cclist)
     if not enabled:
         self.failIf(len(cclist) != 2)
         self.failIf("joenodom" in cclist)
     else:
         self.failIf(len(cclist) != 3)
         self.failIf("*****@*****.**" not in cclist)
Example #22
0
    def create(self, req, summary, description, attributes={}, notify=False):
        """ Create a new ticket, returning the ticket ID.

        PS: Borrowed from XmlRpcPlugin.
        """
        if 'product' in attributes:
            env = self.env.parent or self.env
            if attributes['product']:
                env = ProductEnvironment(env, attributes['product'])
        else:
            env = self.env

        t = Ticket(env)
        t['summary'] = summary
        t['description'] = description
        t['reporter'] = req.authname
        for k, v in attributes.iteritems():
            t[k] = v
        t['status'] = 'new'
        t['resolution'] = ''
        t.insert()

        if notify:
            try:
                tn = TicketNotifyEmail(env)
                tn.notify(t, newticket=True)
            except Exception, e:
                self.log.exception("Failure sending notification on creation "
                                   "of ticket #%s: %s" % (t.id, e))
Example #23
0
 def test_email_map(self):
     """Login-to-email mapping"""
     self.env.config.set("notification", "always_notify_owner", "true")
     self.env.config.set("notification", "always_notify_reporter", "true")
     self.env.config.set("notification", "smtp_always_cc", "*****@*****.**")
     self.env.known_users = [
         ("joeuser", "Joe User", "*****@*****.**"),
         ("jim@domain", "Jim User", "*****@*****.**"),
     ]
     ticket = Ticket(self.env)
     ticket["reporter"] = "joeuser"
     ticket["owner"] = "jim@domain"
     ticket["summary"] = "This is a summary"
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'To' field
     self.failIf("To" not in headers)
     tolist = [addr.strip() for addr in headers["To"].split(",")]
     # 'To' list should have been resolved to the real email address
     self.failIf("*****@*****.**" not in tolist)
     self.failIf("*****@*****.**" not in tolist)
     self.failIf("joeuser" in tolist)
     self.failIf("jim@domain" in tolist)
Example #24
0
    def add_tickets(self, project, customerrequest, tickets, reporter, notify=False):
        from trac.ticket.notification import TicketNotifyEmail
        from trac.util.text import exception_to_unicode
        from penelope.core.models.dashboard import User

        settings = get_current_registry().settings
        tracenvs = settings.get('penelope.trac.envs')
        request = get_current_request()

        for trac in project.tracs:
            for t in tickets:
                owner = DBSession.query(User).get(t['owner'])
                ticket = {'summary': t['summary'],
                        'description': t['description'],
                        'customerrequest': customerrequest.id,
                        'reporter': reporter.email,
                        'type': 'task',
                        'priority': 'major',
                        'milestone': 'Backlog',
                        'owner': owner.email,
                        'status': 'new'}
                tracenv = Environment('%s/%s' % (tracenvs, trac.trac_name))
                tracenv.abs_href.base = trac.api_uri
                t = Ticket(tracenv)
                t.populate(ticket)
                t.insert()
                if notify:
                    try:
                        tn = TicketNotifyEmail(tracenv)
                        tn.notify(t, newticket=True)
                    except Exception, e:
                        request.add_message('Failure sending notification on creation '
                        'of a ticket #%s: %s' % (t.id, exception_to_unicode(e)), 'error')
Example #25
0
 def test_ignore_domains(self):
     """Non-SMTP domain exclusion"""
     self.env.config.set("notification", "ignore_domains", "example.com, example.org")
     self.env.known_users = [
         ("*****@*****.**", "No Email", ""),
         ("*****@*****.**", "With Email", "*****@*****.**"),
     ]
     ticket = Ticket(self.env)
     ticket["reporter"] = "*****@*****.**"
     ticket["owner"] = "*****@*****.**"
     ticket["summary"] = "This is a summary"
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'To' field
     self.failIf("To" not in headers)
     tolist = [addr.strip() for addr in headers["To"].split(",")]
     # 'To' list should not contain addresses with non-SMTP domains
     self.failIf("*****@*****.**" in tolist)
     self.failIf("*****@*****.**" in tolist)
     # 'To' list should have been resolved to the actual email address
     self.failIf("*****@*****.**" not in tolist)
     self.failIf(len(tolist) != 1)
Example #26
0
 def _insert_ticket(self, summary, **kw):
     """Helper for inserting a ticket into the database"""
     ticket = Ticket(self.env)
     ticket['summary'] = summary
     for k, v in kw.items():
         ticket[k] = v
     return ticket.insert()
 def _insert_ticket(self, estimation, owner):
     ticket = Ticket(self.env)
     ticket['summary'] = 'Test Ticket'
     ticket['owner'] = owner
     ticket['hours_remaining'] = estimation
     ticket['milestone'] = 'milestone1'
     return ticket.insert()
Example #28
0
 def _save_changes(self, changes, author):
     """Save ticket changes."""
     if self.audit in ('log','none'):
         db = self.env.get_db_cnx()
         cursor = db.cursor()
         for id,(field,new_pos) in changes.items():
             cursor.execute("""
                 SELECT value from ticket_custom
                  WHERE name=%s AND ticket=%s
                 """, (field,id))
             result = cursor.fetchone()
             if result:
                 old_pos = result[0]
                 cursor.execute("""
                     UPDATE ticket_custom SET value=%s
                      WHERE name=%s AND ticket=%s
                     """, (new_pos,field,id))
             else:
                 old_pos = '(none)'
                 cursor.execute("""
                     INSERT INTO ticket_custom (ticket,name,value)
                      VALUES (%s,%s,%s)
                     """, (id,field,new_pos))
             if self.audit == 'log':
                 self.log.info("%s reordered ticket #%s's %s from %s to %s" \
                     % (author,id,field,old_pos,new_pos))
         db.commit()
     else:
         for id,(field,new_pos) in changes.items():
             ticket = Ticket(self.env, id)
             ticket[field] = new_pos
             ticket.save_changes(author=author, comment='')
Example #29
0
    def test_props_format_wrap_bothsides_unicode(self):
        self.env.config.set("notification", "mime_encoding", "none")
        self.env.config.set("notification", "ambiguous_char_width", "double")
        ticket = Ticket(self.env)
        ticket["summary"] = u"This is a summary"
        ticket["reporter"] = u"anonymous"
        ticket["status"] = u"new"
        ticket["owner"] = u"somebody"
        ticket["type"] = u"defect"
        ticket["priority"] = u"major"
        ticket["milestone"] = u"Trac 在经过修改的BSD协议下发布。" u"[1:]协议的完整文本可以[2:在线查" u"看]也可在发布版的 [3:COPYING] 文" u"件中找到。"
        ticket["component"] = (
            u"Trac は BSD ライセンスのもとで配"
            u"布されています。[1:]このライセ"
            u"ンスの全文は、𠀋配布ファイル"
            u"に含まれている[3:CОPYING]ファイ"
            u"ルと同じものが[2:オンライン]で"
            u"参照できます。"
        )
        ticket["version"] = u"2.0"
        ticket["resolution"] = u"fixed"
        ticket["keywords"] = u""
        ticket.insert()
        formatted = """\
  Reporter:  anonymous               |      Owner:  somebody
      Type:  defect                  |     Status:  new
  Priority:  major                   |  Milestone:  Trac 在经过修改的BSD协
 Component:  Trac は BSD ライセンス  |  议下发布。[1:]协议的完整文本可以[2:
  のもとで配布されています。[1:]こ   |  在线查看]也可在发布版的 [3:COPYING]
  のライセンスの全文は、𠀋配布ファ   |  文件中找到。
  イルに含まれている[3:CОPYING]フ   |    Version:  2.0
  ァイルと同じものが[2:オンライン]   |   Keywords:
  で参照できます。                   |
Resolution:  fixed                   |"""
        self._validate_props_format(formatted, ticket)
Example #30
0
    def test_component_change(self):
        """New ticket owner is updated when the component is changed.
        """
        self._add_component('component3', 'cowner3')
        self._add_component('component4', 'cowner4')

        ticket = Ticket(self.env)
        ticket.populate({
            'reporter': 'reporter1',
            'summary': 'the summary',
            'component': 'component3',
            'owner': 'cowner3',
            'status': 'new',
        })
        tkt_id = ticket.insert()

        req = self._create_request(method='POST', args={
            'id': tkt_id,
            'field_component': 'component4',
            'submit': True,
            'action': 'leave',
            'view_time': str(to_utimestamp(ticket['changetime'])),
        })
        self.assertRaises(RequestDone, self.ticket_module.process_request, req)
        ticket = Ticket(self.env, tkt_id)

        self.assertEqual('component4', ticket['component'])
        self.assertEqual('cowner4', ticket['owner'])
Example #31
0
File: model.py Project: ohanar/trac
 def test_set_field_stripped(self):
     """
     Verify that whitespace around ticket fields is stripped, except for
     textarea fields.
     """
     ticket = Ticket(self.env)
     ticket['component'] = '  foo  '
     ticket['description'] = '  bar  '
     self.assertEqual('foo', ticket['component'])
     self.assertEqual('  bar  ', ticket['description'])
Example #32
0
    def test_submit_with_time_field(self):
        self.env.config.set('ticket-custom', 'timefield', 'time')
        self._insert_ticket(summary='Time fields', timefield='')
        ticket = Ticket(self.env, 1)
        args_base = {
            'submit': '*',
            'action': 'leave',
            'id': '1',
            'field_summary': ticket['summary'],
            'field_reporter': ticket['reporter'],
            'field_description': ticket['description'],
            'view_time': str(to_utimestamp(ticket['changetime']))
        }
        for f in ticket.fields:
            args_base['field_%s' % f['name']] = ticket[f['name']] or ''

        args = args_base.copy()
        args['field_timefield'] = 'invalid datetime'
        req = MockRequest(self.env,
                          method='POST',
                          path_info='/ticket/1',
                          args=args)
        self.assertTrue(self.ticket_module.match_request(req))
        self.ticket_module.process_request(req)
        warnings = req.chrome['warnings']
        self.assertNotEqual([], warnings)
        self.assertEqual(1, len(warnings))
        self.assertIn('is an invalid date, or the date format is not known.',
                      unicode(warnings[0]))
        ticket = Ticket(self.env, 1)
        self.assertIsNone(ticket['timefield'])

        args = args_base.copy()
        args['field_timefield'] = '2016-01-02T12:34:56Z'
        req = MockRequest(self.env,
                          method='POST',
                          path_info='/ticket/1',
                          args=args)
        self.assertTrue(self.ticket_module.match_request(req))
        self.assertRaises(RequestDone, self.ticket_module.process_request, req)
        ticket = Ticket(self.env, 1)
        self.assertEqual(datetime(2016, 1, 2, 12, 34, 56, tzinfo=utc),
                         ticket['timefield'])
Example #33
0
    def post_process_request(self, req, template, data, content_type):
        if req.path_info.startswith('/ticket/'):
            # In case of an invalid ticket, the data is invalid
            if not data:
                return template, data, content_type
            tkt = data['ticket']
            links = TicketLinks(self.env, tkt)

            for i in links.blocked_by:
                if Ticket(self.env, i)['status'] != 'closed':
                    add_script(req, 'mastertickets/js/disable_resolve.js')
                    break

            # Add link to depgraph if needed
            if links:
                add_ctxtnav(req, 'Depgraph', req.href.depgraph('ticket', tkt.id))

            for change in data.get('changes', {}):
                if not 'fields' in change:
                    continue
                for field, field_data in change['fields'].iteritems():
                    if field in self.fields:
                        if field_data['new'].strip():
                            new = set([int(n) for n in field_data['new'].split(',')])
                        else:
                            new = set()
                        if field_data['old'].strip():
                            old = set([int(n) for n in field_data['old'].split(',')])
                        else:
                            old = set()
                        add = new - old
                        sub = old - new
                        elms = tag()
                        if add:
                            elms.append(
                                tag.em(u', '.join([unicode(n) for n in sorted(add)]))
                            )
                            elms.append(u' added')
                        if add and sub:
                            elms.append(u'; ')
                        if sub:
                            elms.append(
                                tag.em(u', '.join([unicode(n) for n in sorted(sub)]))
                            )
                            elms.append(u' removed')
                        field_data['rendered'] = elms

        #add a link to generate a dependency graph for all the tickets in the milestone
        if req.path_info.startswith('/milestone/'):
            if not data:
                return template, data, content_type
            milestone = data['milestone']
            add_ctxtnav(req, 'Depgraph', req.href.depgraph('milestone', milestone.name))

        return template, data, content_type
Example #34
0
    def _update_tickets(self, changeset, review, status_changed):
        """Updates the tickets referenced by the given review's changeset
        with a comment of field changes.  Field changes and command execution
        may occur if specified in trac.ini and the review's changeset is the
        last one of the ticket."""
        status = review.encode(review.status).lower()

        # build comment
        comment = None
        if status_changed or review['summary']:
            if status_changed:
                comment = "Code review set to %s" % review['status']
            else:
                comment = "Code review comment"
            repos = changeset.repos
            ref = review.changeset
            disp_ref = str(repos.short_rev(review.changeset))
            if review.repo:
                ref += '/' + review.repo
                disp_ref += '/' + review.repo
            comment += ' for [changeset:"%s" %s]' % (ref, disp_ref)
            if review['summary']:
                comment += ":\n\n%s" % review['summary']

        invoked = False
        for ticket in review.tickets:
            tkt = Ticket(self.env, ticket)

            # determine ticket changes
            changes = {}
            if self._is_complete(ticket, review, failed_ok=True):
                changes = self._get_ticket_changes(tkt, status)
            # update ticket if there's a review summary or ticket changes
            if comment or changes:
                for field, value in changes.items():
                    tkt[field] = value
                tkt.save_changes(review['reviewer'], comment)

            # check to invoke command
            if not invoked and self._is_complete(ticket, review):
                self._execute_command()
                invoked = True
Example #35
0
    def validate_ticket(self, req, ticket):
        tid = ticket.id
        links = self._prepare_links(ticket)

        if req.args.get('action') == 'resolve' and \
                req.args.get('action_resolve_resolve_resolution') == 'fixed':
            for i in links.blocked_by:
                if Ticket(self.env, i)['status'] != 'closed':
                    yield None, "Ticket #%s is blocking this ticket" % i

        # Check that ticket does not have itself as a blocker
        if tid in links.blocking | links.blocked_by:
            yield 'blocked_by', "This ticket is blocking itself"
            return

        # Check that there aren't any blocked_by in blocking or their parents
        blocking = links.blocking.copy()
        while len(blocking) > 0:
            if len(links.blocked_by & blocking) > 0:
                yield 'blocked_by', "This ticket has circular dependencies"
                return
            new_blocking = set()
            for link in blocking:
                tmp_tkt = Ticket(self.env, link)
                new_blocking |= TicketLinks(self.env, tmp_tkt).blocking
            blocking = new_blocking

        for field in ('blocking', 'blockedby'):
            try:
                ids = self.NUMBERS_RE.findall(ticket[field] or '')
                for tid in ids[:]:
                    for _ in self.env.db_query("""
                            SELECT id FROM ticket WHERE id=%s
                            """, (tid,)):
                        break
                    else:
                        ids.remove(tid)
                ticket[field] = ', '.join(sorted(ids, key=lambda x: int(x)))
            except Exception, e:
                self.log.debug("MasterTickets: Error parsing %s \"%s\": %s",
                               field, ticket[field], e)
                yield field, "Not a valid list of ticket IDs"
Example #36
0
File: model.py Project: t2y/trac
    def test_can_save_ticket_without_explicit_username(self):
        ticket = Ticket(self.env)
        ticket.insert()

        ticket['summary'] = 'another summary'
        ticket.save_changes()

        for change in ticket.get_changelog():
            self.assertIsNone(change[1])
Example #37
0
File: model.py Project: t2y/trac
 def test_delete_mid_comment_inconsistent(self):
     # Make oldvalue on keywords for change 4 inconsistent. This should
     # result in no change in oldvalue when deleting change 3. The
     # oldvalue of foo should change normally.
     self.env.db_transaction("""
         UPDATE ticket_change SET oldvalue='1, 2'
         WHERE field='keywords' AND oldvalue='a, b'
         """)
     ticket = Ticket(self.env, self.id)
     self.assertChange(ticket, 4, self.t4, 'joe',
         comment=dict(author='joe', old='4', new='Comment 4'),
         keywords=dict(author='joe', old='1, 2', new='a'),
         foo=dict(author='joe', old='change3', new='change4'))
     ticket.delete_change(3)
     self.assertIsNone(ticket.get_change(3))
     self.assertEqual('a', ticket['keywords'])
     self.assertChange(ticket, 4, self.t4, 'joe',
         comment=dict(author='joe', old='4', new='Comment 4'),
         keywords=dict(author='joe', old='1, 2', new='a'),
         foo=dict(author='joe', old='change2', new='change4'))
Example #38
0
File: model.py Project: t2y/trac
    def test_modify_comment(self):
        """Check modification of a "standalone" comment"""
        ticket = Ticket(self.env, self.id)
        self.assertChange(ticket, 1, self.t1, 'jack',
            comment=dict(author='jack', old='1', new='Comment 1'))
        self.assertChange(ticket, 2, self.t2, 'john',
            owner=dict(author='john', old='john', new='jack'),
            comment=dict(author='john', old='1.2', new='Comment 2'))
        self.assertChange(ticket, 3, self.t3, 'jim',
            keywords=dict(author='jim', old='a, b, c', new='a, b'),
            comment=dict(author='jim', old='3', new='Comment 3'))

        t = self.created + timedelta(seconds=10)
        ticket.modify_comment(self._find_change(ticket, 1),
                              'joe', 'New comment 1', t)
        self.assertChange(ticket, 1, self.t1, 'jack',
            comment=dict(author='jack', old='1', new='New comment 1'),
            _comment0=dict(author='joe', old='Comment 1',
                           new=str(to_utimestamp(t))))
        self.assertEqual(t, Ticket(self.env, self.id)['changetime'])
Example #39
0
    def _get_changelog_comments(self, tid):
        changelog = Ticket(self.env, tkt_id=tid).get_changelog()
        changelog_str = ''

        for date, author, field, old, new, permanent in changelog:
            if field == 'comment' and new != None and new != '' and old != None and old != '':
                changelog_str = changelog_str + ('comment:%s %s %s\n' % (
                    old, author or '', self.formats['datetime'].restore(date)))
                changelog_str = changelog_str + new + '\n\n'

        return changelog_str
Example #40
0
 def test_remove_tags(self):
     resource = Resource('ticket', 1)
     # Anonymous lacks required permissions.
     self.assertRaises(PermissionError, self.provider.remove_resource_tags,
                       self.req, resource)
     self.req.authname = 'user'
     self.req.perm = PermissionCache(self.env, username='******')
     # Shouldn't raise an error with appropriate permission.
     self.provider.remove_resource_tags(self.req, resource, 'comment')
     tkt = Ticket(self.env, 1)
     self.assertEquals(tkt['keywords'], '')
Example #41
0
 def test_changelog(self):
     tkt_id = self._insert_ticket('Test',
                                  reporter='joe',
                                  component='foo',
                                  milestone='bar')
     ticket = Ticket(self.env, tkt_id)
     ticket['component'] = 'bar'
     ticket['milestone'] = 'foo'
     ticket.save_changes('jane', 'Testing', when=42)
     for t, author, field, old, new in ticket.get_changelog():
         self.assertEqual((42, 'jane'), (t, author))
         if field == 'component':
             self.assertEqual(('foo', 'bar'), (old, new))
         elif field == 'milestone':
             self.assertEqual(('bar', 'foo'), (old, new))
         elif field == 'comment':
             self.assertEqual(('', 'Testing'), (old, new))
         else:
             self.fail('Unexpected change (%s)' %
                       ((t, author, field, old, new), ))
Example #42
0
 def test_modify_missing_comment(self):
     """Editing a comment where the comment field is missing"""
     self.env.db_transaction("""
         DELETE FROM ticket_change WHERE field='comment' AND oldvalue='1.2'
         """)
     ticket = Ticket(self.env, self.id)
     t = self.created + timedelta(seconds=40)
     ticket.modify_comment(self._find_change(ticket, 2), 'joe',
                           'New comment 2', t)
     self.assertChange(ticket,
                       2,
                       self.t2,
                       'john',
                       owner=dict(author='john', old='john', new='jack'),
                       comment=dict(author='john',
                                    old='',
                                    new='New comment 2'),
                       _comment0=dict(author='joe',
                                      old='',
                                      new=str(to_utimestamp(t))))
Example #43
0
 def test_delete_mid_comment_by_date(self):
     ticket = Ticket(self.env, self.id)
     self.assertChange(ticket,
                       4,
                       self.t4,
                       'joe',
                       comment=dict(author='joe', old='4', new='Comment 4'),
                       keywords=dict(author='joe', old='a, b', new='a'),
                       foo=dict(author='joe', old='change3', new='change4'))
     ticket.delete_change(cdate=self.t3)
     self.assertEqual(None, ticket.get_change(cdate=self.t3))
     self.assertEqual('a', ticket['keywords'])
     self.assertChange(ticket,
                       4,
                       self.t4,
                       'joe',
                       comment=dict(author='joe', old='4', new='Comment 4'),
                       keywords=dict(author='joe', old='a, b, c', new='a'),
                       foo=dict(author='joe', old='change2', new='change4'))
     self.assertEqual(self.t4, ticket.time_changed)
Example #44
0
File: api.py Project: hanotch/trac
 def get_resource_description(self, resource, format=None, context=None,
                              **kwargs):
     if format == 'compact':
         return '#%s' % resource.id
     elif format == 'summary':
         from trac.ticket.model import Ticket
         ticket = Ticket(self.env, resource.id)
         args = [ticket[f] for f in ('summary', 'status', 'resolution',
                                     'type')]
         return self.format_summary(*args)
     return _("Ticket #%(shortname)s", shortname=resource.id)
 def test_set_owner_to_field(self):
     self.env.config.set(
         'ticket', 'workflow',
         'ConfigurableTicketWorkflow,TicketWorkflowOpOwnerField')
     self._config_set('ticket-workflow', [
         ('to-owner', '* -> assigned'),
         ('to-owner.operations', 'set_owner_to_field'),
         ('to-owner.set_owner_to_field', 'keywords'),
     ])
     tktid = self._insert_ticket(summary='set owner to field',
                                 reporter='anonymous',
                                 owner='joe',
                                 keywords='john')
     ticket = Ticket(self.env, tktid)
     req = self._post_req('to-owner', ticket)
     self.assertTrue(self.tktmod.match_request(req))
     self.assertRaises(RequestDone, self.tktmod.process_request, req)
     ticket = Ticket(self.env, tktid)
     self.assertEqual('john', ticket['owner'])
     self.assertEqual('assigned', ticket['status'])
Example #46
0
 def _get_tickets(self, oldstate, days):
     db = self.env.get_db_cnx()
     timecutoff = (int(time.time()) - float(days) * 86400) * 1000000
     cursor = db.cursor()
     cursor.execute(
         '''
                     SELECT id FROM ticket LEFT JOIN ticket_change ON (id = ticket AND field = %s) WHERE ticket.status = %s GROUP BY ticket.id
                     HAVING MAX(ticket_change.time) <= %s OR (MAX(ticket_change.time) IS NULL AND MAX(ticket.time) <= %s) ORDER BY id
                    ''', ('status', oldstate, timecutoff, timecutoff))
     for (a, ) in cursor:
         yield Ticket(self.env, a)
Example #47
0
 def _comment_ticket(self, req, tkt_id):
     tkt = Ticket(self.env, tkt_id)
     if not tkt.exists:
         raise ResourceNotFound('Ticket %s does not exist.' % tkt_id,
                                'Invalid Ticket Id')
         req.perm.require('TICKET_MODIFY', Resource('ticket', tkt.resource))
     changes = TicketModule(self.env).rendered_changelog_entries(req, tkt)
     return 'itteco_ticket_comment.html', {
         'ticket': tkt,
         'changes': changes
     }, 'text/html'
Example #48
0
 def test_remove_tags(self):
     req = MockRequest(self.env, authname='editor')
     anon_req = MockRequest(self.env, authname='anonymous')
     resource = Resource('ticket', 1)
     # Anonymous lacks required permissions.
     self.assertRaises(PermissionError, self.provider.remove_resource_tags,
                       anon_req, resource)
     # Shouldn't raise an error with appropriate permission.
     self.provider.remove_resource_tags(req, resource, 'comment')
     ticket = Ticket(self.env, 1)
     self.assertEquals(ticket['keywords'], '')
Example #49
0
 def describe_tagged_resource(self, req, resource):
     if not self.check_permission(req.perm, 'view'):
         return ''
     ticket = Ticket(self.env, resource.id)
     if ticket.exists:
         # Use the corresponding IResourceManager.
         ticket_system = TicketSystem(self.env)
         return ticket_system.get_resource_description(ticket.resource,
                                                       format='summary')
     else:
         return ''
 def test_set_owner_to_component_owner(self):
     self.env.config.set(
         'ticket', 'workflow',
         'ConfigurableTicketWorkflow,TicketWorkflowOpOwnerComponent')
     self._config_set('ticket-workflow', [
         ('to-c-owner', '* -> assigned'),
         ('to-c-owner.operations', 'set_owner_to_component_owner'),
     ])
     self._insert_component('component3', 'foo')
     tktid = self._insert_ticket(summary='set owner to component owner',
                                 reporter='anonymous',
                                 owner='joe',
                                 component='component3')
     ticket = Ticket(self.env, tktid)
     req = self._post_req('to-c-owner', ticket)
     self.assertTrue(self.tktmod.match_request(req))
     self.assertRaises(RequestDone, self.tktmod.process_request, req)
     ticket = Ticket(self.env, tktid)
     self.assertEqual('foo', ticket['owner'])
     self.assertEqual('assigned', ticket['status'])
Example #51
0
 def _setup_env_and_req(self, max_size, field_value):
     self.env.config.set('ticket-custom', 'text1', 'text')
     self.env.config.set('ticket-custom', 'text1.max_size', max_size)
     ticket = insert_ticket(self.env, summary='summary', text1='init')
     change_time = Ticket(self.env, ticket.id)['changetime']
     view_time = str(to_utimestamp(change_time))
     req = MockRequest(
         self.env, method='POST', path_info='/ticket/%d' % ticket.id,
         args={'submit': 'Submit changes', 'field_text1': field_value,
               'action': 'leave', 'view_time': view_time})
     return req
Example #52
0
File: model.py Project: t2y/trac
    def test_populate_ticket(self):
        data = {'summary': 'Hello world', 'reporter': 'john',
                'foo': 'bar', 'checkbox_cbon': '', 'cbon': 'on',
                'checkbox_cboff': ''}
        ticket = Ticket(self.env)
        ticket.populate(data)

        # Standard fields
        self.assertEqual('Hello world', ticket['summary'])
        self.assertEqual('john', ticket['reporter'])

        # An unknown field
        self.assertIsNone(ticket['bar'])

        # Custom field
        self.assertEqual('bar', ticket['foo'])

        # Custom field of type 'checkbox'
        self.assertEqual('on', ticket['cbon'])
        self.assertEqual('0', ticket['cboff'])
Example #53
0
    def _assign_milestone(self, req):
        ticket_id = int(req.args.get('ticket_id'))
        milestone = req.args.get('milestone')
        author = get_reporter_id(req, 'author')

        if milestone == '(unscheduled)':
            milestone = ''

        to_result = {}

        ticket = None
        try:
            ticket = Ticket(self.env, ticket_id)
        except:
            to_result['msg'] = "Couldn't find ticket!"

        if ticket:
            db = self.env.get_db_cnx()

            cursor = db.cursor()

            try:
                ticket['milestone'] = milestone
                ticket.save_changes(author, "")

                to_result['num_tickets'] = self._get_num_tickets(
                    cursor, milestone)
            except:
                to_result['msg'] = "Unable to assign milestone"

        data = simplejson.dumps(to_result)

        if 'msg' in to_result:
            print "error:", to_result['msg']
            req.send_response(202)
        else:
            req.send_response(200)

        req.send_header('Content-Type', 'application/json')
        req.end_headers()
        req.write(data)
Example #54
0
    def post_process_request(self, req, template, data, content_type):
        if template == 'timeline.html':
            filter_projects = self._filtered_projects(req)
            if not filter_projects:  #no filter means likely more than 1 project, so we insert the project name
                filter_projects = [
                    project[1]
                    for project in self.__SmpModel.get_all_projects()
                ]

            if filter_projects:
                filtered_events = []
                tickettypes = ("newticket", "editedticket", "closedticket",
                               "attachment", "reopenedticket")
                self._old_render_fn = []
                self._current_project = []
                self._read_idx = -1
                for event in data['events']:
                    if event['kind'] in tickettypes:
                        resource = event['kind'] == "attachment" and event[
                            'data'][0].parent or event['data'][0]
                        if resource.realm == "ticket":
                            ticket = Ticket(self.env, resource.id)
                            project = ticket.get_value_or_default('project')
                            if project and project in filter_projects:
                                if len(
                                        filter_projects
                                ) > 1:  #only if more than 1 filtered project
                                    #store the old render function and the project to be inserted
                                    self._old_render_fn.append(event['render'])
                                    self._current_project.append(project)
                                    #redirect to our new render function (which will insert the project name)
                                    event['render'] = self._render_ticket_event
                                #add to the list of displayed events
                                filtered_events.append(event)

                    else:
                        filtered_events.append(event)

                data['events'] = filtered_events

        return template, data, content_type
Example #55
0
 def setUp(self):
     self.env = EnvironmentStub(default_data=True)
     self.perm_sys = PermissionSystem(self.env)
     self.ctlr = TicketSystem(self.env).action_controllers[0]
     self.ticket = Ticket(self.env)
     self.ticket['status'] = 'new'
     self.ticket.insert()
     with self.env.db_transaction as db:
         for user in ('user1', 'user2', 'user3', 'user4'):
             db("INSERT INTO session VALUES (%s, %s, %s)", (user, 1, 0))
     permissions = [('user1', 'TICKET_EDIT_CC'),
                    ('user2', 'TICKET_EDIT_CC'),
                    ('user2', 'TICKET_BATCH_MODIFY'),
                    ('user3', 'TICKET_ADMIN'), ('user4', 'TICKET_VIEW'),
                    ('user1', 'group1'), ('user2', 'group1'),
                    ('user2', 'group2'), ('user3', 'group2'),
                    ('user4', 'group3')]
     for perm in permissions:
         self.perm_sys.grant_permission(*perm)
     self.req = MockRequest(self.env, authname='user1')
     self.expected = """\
Example #56
0
    def test_action_with_side_effects(self):
        """Actions can have operations with side effects."""
        self.env.config.set('ticket-workflow', 'buckify', '* -> *')
        self.env.config.set('ticket-workflow', 'buckify.operations',
                                               'set_owner')
        self.req.args = {}
        self.req.args['action_buckify_reassign_owner'] = 'buck'

        first_ticket_id = self._insert_ticket('Test 1', reporter='joe',
                                              owner='foo')
        second_ticket_id = self._insert_ticket('Test 2', reporter='joe')
        selected_tickets = [first_ticket_id, second_ticket_id]

        batch = BatchModifyModule(self.env)
        batch._save_ticket_changes(self.req, selected_tickets, {}, '',
                                   'buckify')

        ticket = Ticket(self.env, int(first_ticket_id))
        changes = ticket.get_changelog()
        self.assertFieldChanged(first_ticket_id, 'owner', 'buck')
        self.assertFieldChanged(second_ticket_id, 'owner', 'buck')
 def check_permission(self, action, username, resource, perm):
     if action in self.allowed_actions and \
             resource is not None and \
             resource.realm == 'ticket' and \
             resource.id is not None:
         try:
             ticket = Ticket(self.env, resource.id)
         except ResourceNotFound:
             pass
         else:
             if ticket['reporter'] == username:
                 return True
Example #58
0
 def test_modify_missing_cnum(self):
     """Editing a comment with no cnum in oldvalue"""
     self.env.db_transaction(
         "UPDATE ticket_change SET oldvalue='' WHERE oldvalue='3'")
     ticket = Ticket(self.env, self.id)
     t = self.created + timedelta(seconds=30)
     ticket.modify_comment(self._find_change(ticket, 3), 'joe',
                           'New comment 3', t)
     self.assertChange(ticket,
                       3,
                       self.t3,
                       'jim',
                       keywords=dict(author='jim',
                                     old='a, b, c',
                                     new='a, b'),
                       comment=dict(author='jim',
                                    old='',
                                    new='New comment 3'),
                       _comment0=dict(author='joe',
                                      old='Comment 3',
                                      new=str(to_utimestamp(t))))
Example #59
0
    def _reindex_ticket(self, realm, feedback, finish_fb):
        db = self.env.get_read_db()
        cursor = db.cursor()
        cursor.execute("SELECT id FROM ticket")

        def check(ticket, status):
            return (status is None
                    or ticket.values['changetime'] > to_datetime(int(status)))

        resources = (Ticket(self.env, tkt_id) for (tkt_id, ) in cursor)
        index = self.ticket_created
        return self._index(realm, resources, check, index, feedback, finish_fb)
Example #60
0
    def test_ticket_custom_field_max_size_is_zero(self):
        """Validation is skipped when max_size attribute is <= 0."""
        max_size = 0
        field_value = 'a' * 100
        req = self._setup_env_and_req(max_size, field_value)

        self.assertTrue(self.ticket_module.match_request(req))
        with self.assertRaises(RequestDone):
            self.ticket_module.process_request(req)

        self.assertEqual(0, len(req.chrome['warnings']))
        self.assertEqual(field_value, Ticket(self.env, 1)['text1'])