def test_delete_last_comment_when_custom_field_gone(self): """Regression test for http://trac.edgewall.org/ticket/10858""" ticket = Ticket(self.env, self.id) self.assertEqual('a', ticket['keywords']) self.assertEqual('change4', ticket['foo']) # we simulate the removal of the definition of the 'foo' custom field self.env.config.remove('ticket-custom', 'foo') del TicketSystem(self.env).fields del TicketSystem(self.env).custom_fields ticket = Ticket(self.env, self.id) # t = datetime.now(utc) ticket.delete_change(cnum=4, when=t) self.assertEqual('a, b', ticket['keywords']) # 'foo' is no longer defined for the ticket self.assertEqual(None, ticket['foo']) # however, 'foo=change3' is still in the database self.assertEqual([('change3', )], self.env.db_query( """ SELECT value FROM ticket_custom WHERE ticket=%s AND name='foo' """, (self.id, ))) self.assertEqual(None, ticket.get_change(cnum=4)) self.assertNotEqual(None, ticket.get_change(cnum=3)) self.assertEqual(t, ticket.time_changed)
def test_delete_last_comment(self): ticket = Ticket(self.env, self.id) self.assertEqual("a", ticket["keywords"]) self.assertEqual("change4", ticket["foo"]) ticket.delete_change(4) self.assertEqual("a, b", ticket["keywords"]) self.assertEqual("change3", ticket["foo"]) self.assertEqual(None, ticket.get_change(4)) self.assertNotEqual(None, ticket.get_change(3)) self.assertEqual(self.t3, ticket.time_changed)
def test_delete_last_comment(self): ticket = Ticket(self.env, self.id) self.assertEqual('a', ticket['keywords']) self.assertEqual('change4', ticket['foo']) ticket.delete_change(4) self.assertEqual('a, b', ticket['keywords']) self.assertEqual('change3', ticket['foo']) self.assertEqual(None, ticket.get_change(4)) self.assertNotEqual(None, ticket.get_change(3)) self.assertEqual(self.t3, ticket.time_changed)
def test_delete_last_comment_by_date(self): ticket = Ticket(self.env, self.id) self.assertEqual('a', ticket['keywords']) self.assertEqual('change4', ticket['foo']) ticket.delete_change(cdate=self.t4) self.assertEqual('a, b', ticket['keywords']) self.assertEqual('change3', ticket['foo']) self.assertEqual(None, ticket.get_change(cdate=self.t4)) self.assertNotEqual(None, ticket.get_change(cdate=self.t3)) self.assertEqual(self.t3, ticket.time_changed)
def test_delete_last_comment(self): ticket = Ticket(self.env, self.id) self.assertEqual('a', ticket['keywords']) self.assertEqual('change4', ticket['foo']) t = datetime.now(utc) ticket.delete_change(cnum=4, when=t) self.assertEqual('a, b', ticket['keywords']) self.assertEqual('change3', ticket['foo']) self.assertEqual(None, ticket.get_change(cnum=4)) self.assertNotEqual(None, ticket.get_change(cnum=3)) self.assertEqual(t, ticket.time_changed)
def test_delete_last_comment_by_date(self): ticket = Ticket(self.env, self.id) self.assertEqual('a', ticket['keywords']) self.assertEqual('change4', ticket['foo']) t = datetime.now(utc) ticket.delete_change(cdate=self.t4, when=t) self.assertEqual('a, b', ticket['keywords']) self.assertEqual('change3', ticket['foo']) self.assertEqual(None, ticket.get_change(cdate=self.t4)) self.assertNotEqual(None, ticket.get_change(cdate=self.t3)) self.assertEqual(t, ticket.time_changed)
def test_delete_last_comment_by_date(self): ticket = Ticket(self.env, self.id) self.assertEqual('a', ticket['keywords']) self.assertEqual('change4', ticket['foo']) t = datetime.now(utc) ticket.delete_change(cdate=self.t4, when=t) self.assertEqual('a, b', ticket['keywords']) self.assertEqual('change3', ticket['foo']) self.assertIsNone(ticket.get_change(cdate=self.t4)) self.assertIsNotNone(ticket.get_change(cdate=self.t3)) self.assertEqual(t, ticket.time_changed)
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.assertEqual(None, 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'))
def send(self, from_addr, recipients, message): parsed = email.message_from_string(message) link = parsed.get('X-Trac-Ticket-URL') if link: match = self.TICKET_URI_RE.search(link) if match: tktid = match.group('tktid') cnum = match.group('cnum') if cnum is not None: cnum = int(cnum) try: ticket = Ticket(self.env, tktid) except ResourceNotFound: pass change = ticket.get_change(cnum) if change: author = change.get('author', None) fields = change.get('fields', None) if not author and fields: author = fields[0]['author'] if author and\ QuietSystem(self.env).is_quiet_mode(change['author']): return SmtpEmailSender.send(self, from_addr, recipients, message)
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. cursor = self.db.cursor() cursor.execute("UPDATE ticket_change SET oldvalue='1, 2' " "WHERE field='keywords' AND oldvalue='a, b'") self.db.commit() 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.assertEqual(None, 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"), )
def send (self, from_addr, recipients, message): parsed = email.message_from_string(message) link = parsed.get('X-Trac-Ticket-URL') if link: match = self.TICKET_URI_RE.search(link) if match: tktid = match.group('tktid') cnum = match.group('cnum') if cnum is not None: cnum = int(cnum) try: ticket = Ticket(self.env, tktid) except ResourceNotFound: pass change = ticket.get_change(cnum) if change: author = change.get('author', None) fields = change.get('fields', None) if not author and fields: author = fields[0]['author'] if author and\ QuietSystem(self.env).is_quiet_mode(change['author']): return SmtpEmailSender.send(self, from_addr, recipients, message)
def _format_comment_link(self, formatter, ns, target, label): resource = None if ':' in target: elts = target.split(':') if len(elts) == 3: cnum, realm, id = elts if cnum != 'description' and cnum and not cnum[0].isdigit(): realm, id, cnum = elts # support old comment: style id = as_int(id, None) if realm in ('bug', 'issue'): realm = 'ticket' resource = formatter.resource(realm, id) else: resource = formatter.resource cnum = target if resource and resource.id and resource.realm == self.realm and \ cnum and (cnum.isdigit() or cnum == 'description'): href = title = class_ = None if self.resource_exists(resource): from trac.ticket.model import Ticket ticket = Ticket(self.env, resource.id) if cnum != 'description' and not ticket.get_change(cnum): title = _("ticket comment does not exist") class_ = 'missing ticket' elif 'TICKET_VIEW' in formatter.perm(resource): href = formatter.href.ticket(resource.id) + \ "#comment:%s" % cnum if resource.id != formatter.resource.id: summary = self.format_summary(ticket['summary'], ticket['status'], ticket['resolution'], ticket['type']) if cnum == 'description': title = _("Description for #%(id)s: %(summary)s", id=resource.id, summary=summary) else: title = _( "Comment %(cnum)s for #%(id)s: " "%(summary)s", cnum=cnum, id=resource.id, summary=summary) class_ = ticket['status'] + ' ticket' else: title = _("Description") if cnum == 'description' \ else _("Comment %(cnum)s", cnum=cnum) class_ = 'ticket' else: title = _("no permission to view ticket") class_ = 'forbidden ticket' else: title = _("ticket does not exist") class_ = 'missing ticket' return tag.a(label, class_=class_, href=href, title=title) return label
def test_delete_mid_comment(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(3) self.assertEqual(None, 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='a, b, c', new='a'), foo=dict(author='joe', old='change2', new='change4')) self.assertEqual(self.t4, ticket.time_changed)
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)
def test_delete_last_comment_when_custom_field_gone(self): """Regression test for http://trac.edgewall.org/ticket/10858""" ticket = Ticket(self.env, self.id) self.assertEqual('a', ticket['keywords']) self.assertEqual('change4', ticket['foo']) # we simulate the removal of the definition of the 'foo' custom field self.env.config.remove('ticket-custom', 'foo') del TicketSystem(self.env).fields del TicketSystem(self.env).custom_fields ticket = Ticket(self.env, self.id) # t = datetime.now(utc) ticket.delete_change(cnum=4, when=t) self.assertEqual('a, b', ticket['keywords']) # 'foo' is no longer defined for the ticket self.assertEqual(None, ticket['foo']) # however, 'foo=change3' is still in the database self.assertEqual([('change3',)], self.env.db_query(""" SELECT value FROM ticket_custom WHERE ticket=%s AND name='foo' """, (self.id,))) self.assertEqual(None, ticket.get_change(cnum=4)) self.assertNotEqual(None, ticket.get_change(cnum=3)) self.assertEqual(t, ticket.time_changed)
def test_delete_mid_comment(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')) t = datetime.now(utc) ticket.delete_change(cnum=3, when=t) self.assertIsNone(ticket.get_change(cnum=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='a, b, c', new='a'), foo=dict(author='joe', old='change2', new='change4')) self.assertEqual(t, ticket.time_changed)
def _format_comment_link(self, formatter, ns, target, label): resource = None if ":" in target: elts = target.split(":") if len(elts) == 3: cnum, realm, id = elts if cnum != "description" and cnum and not cnum[0].isdigit(): realm, id, cnum = elts # support old comment: style id = as_int(id, None) resource = formatter.resource(realm, id) else: resource = formatter.resource cnum = target if ( resource and resource.id and resource.realm == "ticket" and cnum and (all(c.isdigit() for c in cnum) or cnum == "description") ): href = title = class_ = None if self.resource_exists(resource): from trac.ticket.model import Ticket ticket = Ticket(self.env, resource.id) if cnum != "description" and not ticket.get_change(cnum): title = _("ticket comment does not exist") class_ = "missing ticket" elif "TICKET_VIEW" in formatter.perm(resource): href = formatter.href.ticket(resource.id) + "#comment:%s" % cnum if resource.id != formatter.resource.id: if cnum == "description": title = _("Description for Ticket #%(id)s", id=resource.id) else: title = _("Comment %(cnum)s for Ticket #%(id)s", cnum=cnum, id=resource.id) class_ = ticket["status"] + " ticket" else: title = _("Description") if cnum == "description" else _("Comment %(cnum)s", cnum=cnum) class_ = "ticket" else: title = _("no permission to view ticket") class_ = "forbidden ticket" else: title = _("ticket does not exist") class_ = "missing ticket" return tag.a(label, class_=class_, href=href, title=title) return label
def test_delete_mid_comment(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(3) self.assertEqual(None, 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="a, b, c", new="a"), foo=dict(author="joe", old="change2", new="change4"), ) self.assertEqual(self.t4, ticket.time_changed)