def _hide_fields_not_configured_for_this_type(self, req, data): ticket_type = req.args[Key.TYPE] ats = AgiloTicketSystem(self.env) normalized_type = ats.normalize_type(ticket_type) data[Key.TYPE] = normalized_type fields_for_type = AgiloConfig(self.env).TYPES.get(normalized_type, []) create_perms = CoreTemplateProvider(self.env).create_permissions(req) if normalized_type in create_perms: for data_field in data['fields']: field_name = data_field[Key.NAME] if field_name == Key.TYPE: current_options = data_field.get('options', []) data_field['options'] = \ self._ticket_types_the_user_can_create_or_modify(normalized_type, current_options, create_perms) data['type_selection'] = data_field data_field[Key.SKIP] = True elif not field_name in fields_for_type: # Skip the field and the value if it's not for this type data_field[Key.SKIP] = True elif data_field[Key.SKIP] and (field_name not in MANDATORY_FIELDS): # We have to make all fields visible which belong to # this ticket type. Unfortunately, Trac just creates # a Ticket (though an AgiloTicket due to our monkey # patching) and we can't influence the instantiation # itself. # Therefore it just depends on the default ticket type # set in the environment what fields this ticket has. # Therefore some fields are marked skipped although they # should be displayed. # trac itself skips some fields because it want to have # more control over the positioning. We have to respect # that. # fs, 04.11.2008: I thought about moving this condition # to_prepare_fields where I think this code should live # but then I would have to copy all the conditions and # probably the code is here for a good reason so I'm # just adding it here. data_field[Key.SKIP] = False elif field_name == Key.OWNER and ats.restrict_owner: # we need to transform the field into a list of users ats.eventually_restrict_owner(data_field) elif len(create_perms) > 0: # Redirect to the first allowed type for the given user. first_allowed_type = create_perms[0] req.redirect(req.href.newticket(type=first_allowed_type)) else: if ticket_type not in AgiloConfig(self.env).ALIASES: raise TracError(u"Unkown type '%s'!" % ticket_type) raise TracError("You are not allowed to create a %s!" % ticket_type) return data
def _check_if_user_can_create_referenced_tickets(self, req, data): if 'ticket' not in data: data['can_create_at_least_one_referenced_type'] = False return ticket = data['ticket'] ticket_type = ticket[Key.TYPE] can_create_at_least_one_referenced_type = False for allowed_type in LinksConfiguration( self.env).get_allowed_destination_types(ticket_type): permission_name = CoreTemplateProvider( self.env).get_permission_name_to_create(allowed_type) if permission_name in req.perm: can_create_at_least_one_referenced_type = True break data[ 'can_create_at_least_one_referenced_type'] = can_create_at_least_one_referenced_type
def setUp(self): """Creates the environment stub""" self.super() t1 = self.teh.create_ticket(Type.TASK, props={'remaining_time': '12'}) self.DATA = { 'action': 'leave', 'action_controls': [('leave', 'leave', '<Fragment>', ['']), ('resolve', 'resolve', '<Fragment>', [u"The resolution will be set. Next status will be 'closed'"]), ('reassign', 'reassign', '<Fragment>', [u"The owner will change. Next status will be 'assigned'"]), ('accept', 'accept', '<Fragment>', [u"The owner will change to admin. Next status will be 'accepted'"])], 'attachments': {'attach_href': '/test0.11/attachment/ticket/4/', 'attachments': [], 'can_create': True, 'parent': None}, 'author_id': u'admin', 'change_preview': None, # Command: changes@fields(item.has_key(Key.FIELDS)):Key.TYPE:'new'|'old' 'changes': [{'author': u'admin', 'cnum': 1, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 18), 'fields': {u'description': {'new': u'Test story changed', 'old': u'Test story', 'rendered': None}, u'type': {'new': u'task', 'old': u'story'}}, # Replace 'permanent': 1}, {'author': u'admin', 'cnum': 2, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 44), 'fields': {u'type': {'new': u'story', 'old': u'task'}}, # Replace 'permanent': 1}, {'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51), 'fields': {u'description': {'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': None}}, 'permanent': 1}, {'author': u'admin', 'cnum': 4, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 34), 'fields': {u'type': {'new': u'requirement', 'old': u'story'}}, # Replace 'permanent': 1}, {'author': u'admin', 'cnum': 5, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 50), 'fields': {u'type': {'new': u'story', 'old': u'requirement'}}, # Replace 'permanent': 1}], 'cnum': 6, 'comment': None, 'context': None, 'allowed_links': {u'bug-story': [u'bug', u'story'], u'bug-task': [u'bug', u'task'], u'requirement-story': [u'requirement', u'story'], u'story-task': [u'story', u'task']}, # Replace 'available_types': [u'task', u'requirement', u'story', u'bug'], # Replace 'description_change': {'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51), 'fields': {u'description': {'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': None}}, 'permanent': 1}, 'fields': [{'label': 'Summary', 'name': 'summary', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Reporter', 'name': 'reporter', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Owner', 'name': 'owner', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Description', 'name': 'description', 'optional': False, 'options': [], 'skip': True, 'type': 'textarea'}, {'label': 'Type', 'name': 'type', 'optional': False, 'options': [u'task', u'requirement', u'story', u'bug'], # Replace 'skip': False, 'type': 'select', 'value': u'defect'}, {'label': 'Status', 'name': 'status', 'optional': True, 'options': [u'accepted', u'assigned', u'closed', u'new', u'reopened'], 'skip': True, 'type': 'radio', 'value': u''}, {'label': 'Priority', 'name': 'priority', 'optional': False, 'options': [u'blocker', u'critical', u'major', u'minor', u'trivial'], 'skip': True, 'type': 'select', 'value': u'major'}, {'label': 'Milestone', 'name': 'milestone', 'optgroups': [{'label': 'Open', 'options': [u'milestone1', u'milestone2', u'milestone3', u'milestone4']}, {'label': 'Closed', 'options': []}], 'optional': True, 'options': [], 'rendered': '<Element "a">', 'skip': False, 'type': 'select', 'value': u''}, {'label': 'Component', 'name': 'component', 'optional': False, 'options': [u'component1', u'component2'], 'skip': True, 'type': 'select', 'value': u''}, {'label': 'Version', 'name': 'version', 'optional': True, 'options': [u'2.0', u'1.0'], 'skip': True, 'type': 'select', 'value': u''}, {'label': 'Resolution', 'name': 'resolution', 'optional': True, 'options': [u'fixed', u'invalid', u'wontfix', u'duplicate', u'worksforme'], 'skip': True, 'type': 'radio', 'value': u'fixed'}, {'label': 'Keywords', 'name': 'keywords', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Cc', 'name': 'cc', 'optional': False, 'options': [], 'rendered': '', 'skip': True, 'type': 'text'}, {'custom': True, 'label': 'Linking_src', 'name': 'linking_src', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}, {'custom': True, 'label': u'Remaining Time', 'name': 'remaining_time', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}, {'custom': True, 'label': u'User Story Points', 'name': 'rd_points', 'optional': True, 'options': [u'0', u'1', u'2', u'3', u'5', u'8', u'13', u'20', u'40', u'100'], 'order': 0, 'skip': False, 'type': u'select', 'value': u''}, {'custom': True, 'label': u'References', 'name': 'o_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}, {'custom': True, 'label': u'User Story Priority', 'name': 'story_priority', 'optional': False, 'options': [u'Mandatory', u'Linear', u'Exciter'], 'order': 0, 'skip': False, 'type': u'select', 'value': u'Mandatory'}, {'custom': True, 'label': u'Business Value Points', 'name': 'businessvalue', 'optional': True, 'options': [u'100', u'200', u'300', u'500', u'800', u'1200', u'2000', u'3000'], 'order': 0, 'skip': True, 'type': u'select', 'value': u''}, {'custom': True, 'label': u'Referenced By', 'name': 'i_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}], 'may_comment_ticket': True, 'can_edit_ticket': True, 'preserve_newlines': True, 'reassign_owner': u'admin', 'replies': {}, 'replyto': None, 'resolve_resolution': None, 'ticket': t1, 'timestamp': '2008-06-13 15:27:50+00:00', 'version': None, 'row_groups': [(None, [{u'__color__': u'3', '__idx__': 0, 'cell_groups': [[{'header': {'asc': False, 'col': u'__color__', 'hidden': True, 'title': u'Color'}, 'index': 0, 'value': u'3'}, {'header': {'asc': False, 'col': u'ticket', 'hidden': False, 'title': u'Ticket'}, 'index': 1, 'value': u'4'}, {'header': {'asc': False, 'col': u'summary', 'hidden': False, 'title': u'Summary'}, 'index': 2, 'value': u'New User Story'}, {'header': {'asc': False, 'col': u'component', 'hidden': False, 'title': u'Component'}, 'index': 3, 'value': u'component1'}, {'header': {'asc': False, 'col': u'version', 'hidden': False, 'title': u'Version'}, 'index': 4, 'value': u''}, {'header': {'asc': False, 'col': u'milestone', 'hidden': False, 'title': u'Milestone'}, 'index': 5, 'value': u''}, {'header': {'asc': False, 'col': u'type', 'hidden': False, 'title': u'Type'}, 'index': 6, 'value': u'story'}]], # Replace in View Ticket 'id': u'4', 'resource': "Resource u'ticket:4'"}] )], } self.ctp = CoreTemplateProvider(self.env)
class TestCoreTemplateProvider(AgiloTestCase): """ This testcase aims to test as much as possible of the IRequestFilter implementation, given the fact that it is very complex and may introduce may issues. The IRequestFilter process the request before (PRE) and after (POST) having called the process_request() of a Trac Component. With Trac 0.11 there has been a change in the interface of the API, with it the use of Genshi complicate the things a bit, now in the data dictionary there may be any valid Python object. A sample data dictionary look the following: {'action': 'leave', 'action_controls': [('leave', 'leave', <Fragment>, ['']), ('resolve', 'resolve', <Fragment>, [u"The resolution will be set. Next status will be 'closed'"]), ('reassign', 'reassign', <Fragment>, [u"The owner will change. Next status will be 'assigned'"]), ('accept', 'accept', <Fragment>, [u"The owner will change to admin. Next status will be 'accepted'"])], 'attachments': {'attach_href': '/test0.11/attachment/ticket/4/', 'attachments': [], 'can_create': True, 'parent': <Resource u'ticket:4'>}, 'author_id': u'admin', 'change_preview': None, 'changes': [{'author': u'admin', 'cnum': 1, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 18, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'description': {'new': u'Test story changed', 'old': u'Test story', 'rendered': <Fragment>}, u'type': {'new': u'task', 'old': u'story'}}, 'permanent': 1}, {'author': u'admin', 'cnum': 2, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 44, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'type': {'new': u'story', 'old': u'task'}}, 'permanent': 1}, {'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'description': {'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': <Fragment>}}, 'permanent': 1}, {'author': u'admin', 'cnum': 4, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 34, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'type': {'new': u'requirement', 'old': u'story'}}, 'permanent': 1}, {'author': u'admin', 'cnum': 5, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 50, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'type': {'new': u'story', 'old': u'requirement'}}, 'permanent': 1}], 'cnum': 6, 'comment': None, 'context': <Context <Resource u'ticket:4'>>, 'description_change': {'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'description': {'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': <Fragment>}}, 'permanent': 1}, 'fields': [{'label': 'Summary', 'name': 'summary', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Reporter', 'name': 'reporter', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Owner', 'name': 'owner', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Description', 'name': 'description', 'optional': False, 'options': [], 'skip': True, 'type': 'textarea'}, {'label': 'Type', 'name': 'type', 'optional': False, 'options': [u'task', u'requirement', u'story', u'bug'], 'skip': False, 'type': 'select', 'value': u'defect'}, {'label': 'Status', 'name': 'status', 'optional': True, 'options': [u'accepted', u'assigned', u'closed', u'new', u'reopened'], 'skip': True, 'type': 'radio', 'value': u''}, {'label': 'Priority', 'name': 'priority', 'optional': False, 'options': [u'blocker', u'critical', u'major', u'minor', u'trivial'], 'skip': True, 'type': 'select', 'value': u'major'}, {'label': 'Milestone', 'name': 'milestone', 'optgroups': [{'label': 'Open', 'options': [u'milestone1', u'milestone2', u'milestone3', u'milestone4']}, {'label': 'Closed', 'options': []}], 'optional': True, 'options': [], 'rendered': <Element "a">, 'skip': False, 'type': 'select', 'value': u''}, {'label': 'Component', 'name': 'component', 'optional': False, 'options': [u'component1', u'component2'], 'skip': True, 'type': 'select', 'value': u''}, {'label': 'Version', 'name': 'version', 'optional': True, 'options': [u'2.0', u'1.0'], 'skip': True, 'type': 'select', 'value': u''}, {'label': 'Resolution', 'name': 'resolution', 'optional': True, 'options': [u'fixed', u'invalid', u'wontfix', u'duplicate', u'worksforme'], 'skip': True, 'type': 'radio', 'value': u'fixed'}, {'label': 'Keywords', 'name': 'keywords', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Cc', 'name': 'cc', 'optional': False, 'options': [], 'rendered': '', 'skip': True, 'type': 'text'}, {'custom': True, 'label': u'Remaining Time', 'name': 'remaining_time', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}, {'custom': True, 'label': u'User Story Points', 'name': 'rd_points', 'optional': True, 'options': [u'0', u'1', u'2', u'3', u'5', u'8', u'13', u'20', u'40', u'100'], 'order': 0, 'skip': False, 'type': u'select', 'value': u''}, {'custom': True, 'label': u'References', 'name': 'o_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}, {'custom': True, 'label': u'User Story Priority', 'name': 'story_priority', 'optional': False, 'options': [u'Mandatory', u'Linear', u'Exciter'], 'order': 0, 'skip': False, 'type': u'select', 'value': u'Mandatory'}, {'custom': True, 'label': u'Business Value Points', 'name': 'businessvalue', 'optional': True, 'options': [u'100', u'200', u'300', u'500', u'800', u'1200', u'2000', u'3000'], 'order': 0, 'skip': True, 'type': u'select', 'value': u''}, {'custom': True, 'label': u'Referenced By', 'name': 'i_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}], 'may_comment_ticket': True, 'can_edit_ticket': True, 'preserve_newlines': True, 'reassign_owner': u'admin', 'replies': {}, 'replyto': None, 'resolve_resolution': None, 'ticket': <AgiloTicket #4 (story)>, 'timestamp': '2008-06-13 15:27:50+00:00', 'version': None} This example is used also for testing and is based on a pprint of a regular Trac ticket. """ def setUp(self): """Creates the environment stub""" self.super() t1 = self.teh.create_ticket(Type.TASK, props={'remaining_time': '12'}) self.DATA = { 'action': 'leave', 'action_controls': [('leave', 'leave', '<Fragment>', ['']), ('resolve', 'resolve', '<Fragment>', [u"The resolution will be set. Next status will be 'closed'"]), ('reassign', 'reassign', '<Fragment>', [u"The owner will change. Next status will be 'assigned'"]), ('accept', 'accept', '<Fragment>', [u"The owner will change to admin. Next status will be 'accepted'"])], 'attachments': {'attach_href': '/test0.11/attachment/ticket/4/', 'attachments': [], 'can_create': True, 'parent': None}, 'author_id': u'admin', 'change_preview': None, # Command: changes@fields(item.has_key(Key.FIELDS)):Key.TYPE:'new'|'old' 'changes': [{'author': u'admin', 'cnum': 1, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 18), 'fields': {u'description': {'new': u'Test story changed', 'old': u'Test story', 'rendered': None}, u'type': {'new': u'task', 'old': u'story'}}, # Replace 'permanent': 1}, {'author': u'admin', 'cnum': 2, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 44), 'fields': {u'type': {'new': u'story', 'old': u'task'}}, # Replace 'permanent': 1}, {'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51), 'fields': {u'description': {'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': None}}, 'permanent': 1}, {'author': u'admin', 'cnum': 4, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 34), 'fields': {u'type': {'new': u'requirement', 'old': u'story'}}, # Replace 'permanent': 1}, {'author': u'admin', 'cnum': 5, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 50), 'fields': {u'type': {'new': u'story', 'old': u'requirement'}}, # Replace 'permanent': 1}], 'cnum': 6, 'comment': None, 'context': None, 'allowed_links': {u'bug-story': [u'bug', u'story'], u'bug-task': [u'bug', u'task'], u'requirement-story': [u'requirement', u'story'], u'story-task': [u'story', u'task']}, # Replace 'available_types': [u'task', u'requirement', u'story', u'bug'], # Replace 'description_change': {'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51), 'fields': {u'description': {'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': None}}, 'permanent': 1}, 'fields': [{'label': 'Summary', 'name': 'summary', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Reporter', 'name': 'reporter', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Owner', 'name': 'owner', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Description', 'name': 'description', 'optional': False, 'options': [], 'skip': True, 'type': 'textarea'}, {'label': 'Type', 'name': 'type', 'optional': False, 'options': [u'task', u'requirement', u'story', u'bug'], # Replace 'skip': False, 'type': 'select', 'value': u'defect'}, {'label': 'Status', 'name': 'status', 'optional': True, 'options': [u'accepted', u'assigned', u'closed', u'new', u'reopened'], 'skip': True, 'type': 'radio', 'value': u''}, {'label': 'Priority', 'name': 'priority', 'optional': False, 'options': [u'blocker', u'critical', u'major', u'minor', u'trivial'], 'skip': True, 'type': 'select', 'value': u'major'}, {'label': 'Milestone', 'name': 'milestone', 'optgroups': [{'label': 'Open', 'options': [u'milestone1', u'milestone2', u'milestone3', u'milestone4']}, {'label': 'Closed', 'options': []}], 'optional': True, 'options': [], 'rendered': '<Element "a">', 'skip': False, 'type': 'select', 'value': u''}, {'label': 'Component', 'name': 'component', 'optional': False, 'options': [u'component1', u'component2'], 'skip': True, 'type': 'select', 'value': u''}, {'label': 'Version', 'name': 'version', 'optional': True, 'options': [u'2.0', u'1.0'], 'skip': True, 'type': 'select', 'value': u''}, {'label': 'Resolution', 'name': 'resolution', 'optional': True, 'options': [u'fixed', u'invalid', u'wontfix', u'duplicate', u'worksforme'], 'skip': True, 'type': 'radio', 'value': u'fixed'}, {'label': 'Keywords', 'name': 'keywords', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Cc', 'name': 'cc', 'optional': False, 'options': [], 'rendered': '', 'skip': True, 'type': 'text'}, {'custom': True, 'label': 'Linking_src', 'name': 'linking_src', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}, {'custom': True, 'label': u'Remaining Time', 'name': 'remaining_time', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}, {'custom': True, 'label': u'User Story Points', 'name': 'rd_points', 'optional': True, 'options': [u'0', u'1', u'2', u'3', u'5', u'8', u'13', u'20', u'40', u'100'], 'order': 0, 'skip': False, 'type': u'select', 'value': u''}, {'custom': True, 'label': u'References', 'name': 'o_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}, {'custom': True, 'label': u'User Story Priority', 'name': 'story_priority', 'optional': False, 'options': [u'Mandatory', u'Linear', u'Exciter'], 'order': 0, 'skip': False, 'type': u'select', 'value': u'Mandatory'}, {'custom': True, 'label': u'Business Value Points', 'name': 'businessvalue', 'optional': True, 'options': [u'100', u'200', u'300', u'500', u'800', u'1200', u'2000', u'3000'], 'order': 0, 'skip': True, 'type': u'select', 'value': u''}, {'custom': True, 'label': u'Referenced By', 'name': 'i_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}], 'may_comment_ticket': True, 'can_edit_ticket': True, 'preserve_newlines': True, 'reassign_owner': u'admin', 'replies': {}, 'replyto': None, 'resolve_resolution': None, 'ticket': t1, 'timestamp': '2008-06-13 15:27:50+00:00', 'version': None, 'row_groups': [(None, [{u'__color__': u'3', '__idx__': 0, 'cell_groups': [[{'header': {'asc': False, 'col': u'__color__', 'hidden': True, 'title': u'Color'}, 'index': 0, 'value': u'3'}, {'header': {'asc': False, 'col': u'ticket', 'hidden': False, 'title': u'Ticket'}, 'index': 1, 'value': u'4'}, {'header': {'asc': False, 'col': u'summary', 'hidden': False, 'title': u'Summary'}, 'index': 2, 'value': u'New User Story'}, {'header': {'asc': False, 'col': u'component', 'hidden': False, 'title': u'Component'}, 'index': 3, 'value': u'component1'}, {'header': {'asc': False, 'col': u'version', 'hidden': False, 'title': u'Version'}, 'index': 4, 'value': u''}, {'header': {'asc': False, 'col': u'milestone', 'hidden': False, 'title': u'Milestone'}, 'index': 5, 'value': u''}, {'header': {'asc': False, 'col': u'type', 'hidden': False, 'title': u'Type'}, 'index': 6, 'value': u'story'}]], # Replace in View Ticket 'id': u'4', 'resource': "Resource u'ticket:4'"}] )], } self.ctp = CoreTemplateProvider(self.env) def tearDown(self): self.teh.delete_created_tickets() self.super() def alias_values(self): return AgiloConfig(self.env).ALIASES.values() def testReplaceInFields(self): """Tests the replace of the type alias into the fields""" ALIAS_KEYS = ["'fields'@'options'(item[Key.NAME]==Key.TYPE)"] self.ctp._substitute_ticket_types_with_aliases_in_genshi_data(self.DATA, ALIAS_KEYS) for f in self.DATA['fields']: if f.has_key('name') and f['name'] == 'type': self.assert_equals(sorted(f['options']), sorted(self.alias_values())) def testReplaceInChanges(self): """Tests the replace of the type alias into the changes""" ALIAS_KEYS = ["'changes'@'fields'(item.has_key(Key.FIELDS)):Key.TYPE:'new'|'old'"] self.ctp._substitute_ticket_types_with_aliases_in_genshi_data(self.DATA, ALIAS_KEYS) for change in self.DATA['changes']: if change.has_key(Key.TYPE): self.assert_true(change[Key.TYPE]['new'] in self.alias_values()) self.assert_true(change[Key.TYPE]['old'] in self.alias_values()) def testReplaceInAdminInterface(self): """Tests the replace in the Admin interface""" ALIAS_KEYS = ["'available_types'", "'allowed_links':'*'"] self.ctp._substitute_ticket_types_with_aliases_in_genshi_data(self.DATA, ALIAS_KEYS) for ltype in self.DATA['available_types']: self.assert_true(ltype in self.alias_values()) for alinks in self.DATA['allowed_links'].values(): for al in alinks: self.assert_true(al in self.alias_values()) def testReplaceInViewTicketReport(self): """Tests the replace in the Report from View Ticket""" ALIAS_KEYS = ["'row_groups',0,1@'cell_groups',0@'value'(item['header']['title']=='Type')"] self.ctp._substitute_ticket_types_with_aliases_in_genshi_data(self.DATA, ALIAS_KEYS) for key, rows in self.DATA['row_groups']: for r in rows: for v in r['cell_groups']: for l in v: if l['header']['title'] == 'Type': self.assert_true(l['value'] in self.alias_values())
def can_create_at_least_one_referenced_type(ticket_type): for allowed_type in LinksConfiguration(self.env).get_allowed_destination_types(ticket_type): permission_name = CoreTemplateProvider(self.env).get_permission_name_to_create(allowed_type) if permission_name in perm: return True return False
def setUp(self): """Creates the environment stub""" self.super() t1 = self.teh.create_ticket(Type.TASK, props={'remaining_time': '12'}) self.DATA = { 'action': 'leave', 'action_controls': [('leave', 'leave', '<Fragment>', ['']), ('resolve', 'resolve', '<Fragment>', [u"The resolution will be set. Next status will be 'closed'"]), ('reassign', 'reassign', '<Fragment>', [u"The owner will change. Next status will be 'assigned'"]), ('accept', 'accept', '<Fragment>', [ u"The owner will change to admin. Next status will be 'accepted'" ])], 'attachments': { 'attach_href': '/test0.11/attachment/ticket/4/', 'attachments': [], 'can_create': True, 'parent': None }, 'author_id': u'admin', 'change_preview': None, # Command: changes@fields(item.has_key(Key.FIELDS)):Key.TYPE:'new'|'old' 'changes': [ { 'author': u'admin', 'cnum': 1, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 18), 'fields': { u'description': { 'new': u'Test story changed', 'old': u'Test story', 'rendered': None }, u'type': { 'new': u'task', 'old': u'story' } }, # Replace 'permanent': 1 }, { 'author': u'admin', 'cnum': 2, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 44), 'fields': { u'type': { 'new': u'story', 'old': u'task' } }, # Replace 'permanent': 1 }, { 'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51), 'fields': { u'description': { 'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': None } }, 'permanent': 1 }, { 'author': u'admin', 'cnum': 4, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 34), 'fields': { u'type': { 'new': u'requirement', 'old': u'story' } }, # Replace 'permanent': 1 }, { 'author': u'admin', 'cnum': 5, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 50), 'fields': { u'type': { 'new': u'story', 'old': u'requirement' } }, # Replace 'permanent': 1 } ], 'cnum': 6, 'comment': None, 'context': None, 'allowed_links': { u'bug-story': [u'bug', u'story'], u'bug-task': [u'bug', u'task'], u'requirement-story': [u'requirement', u'story'], u'story-task': [u'story', u'task'] }, # Replace 'available_types': [u'task', u'requirement', u'story', u'bug'], # Replace 'description_change': { 'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51), 'fields': { u'description': { 'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': None } }, 'permanent': 1 }, 'fields': [ { 'label': 'Summary', 'name': 'summary', 'optional': False, 'options': [], 'skip': True, 'type': 'text' }, { 'label': 'Reporter', 'name': 'reporter', 'optional': False, 'options': [], 'skip': True, 'type': 'text' }, { 'label': 'Owner', 'name': 'owner', 'optional': False, 'options': [], 'skip': True, 'type': 'text' }, { 'label': 'Description', 'name': 'description', 'optional': False, 'options': [], 'skip': True, 'type': 'textarea' }, { 'label': 'Type', 'name': 'type', 'optional': False, 'options': [u'task', u'requirement', u'story', u'bug'], # Replace 'skip': False, 'type': 'select', 'value': u'defect' }, { 'label': 'Status', 'name': 'status', 'optional': True, 'options': [u'accepted', u'assigned', u'closed', u'new', u'reopened'], 'skip': True, 'type': 'radio', 'value': u'' }, { 'label': 'Priority', 'name': 'priority', 'optional': False, 'options': [u'blocker', u'critical', u'major', u'minor', u'trivial'], 'skip': True, 'type': 'select', 'value': u'major' }, { 'label': 'Milestone', 'name': 'milestone', 'optgroups': [{ 'label': 'Open', 'options': [ u'milestone1', u'milestone2', u'milestone3', u'milestone4' ] }, { 'label': 'Closed', 'options': [] }], 'optional': True, 'options': [], 'rendered': '<Element "a">', 'skip': False, 'type': 'select', 'value': u'' }, { 'label': 'Component', 'name': 'component', 'optional': False, 'options': [u'component1', u'component2'], 'skip': True, 'type': 'select', 'value': u'' }, { 'label': 'Version', 'name': 'version', 'optional': True, 'options': [u'2.0', u'1.0'], 'skip': True, 'type': 'select', 'value': u'' }, { 'label': 'Resolution', 'name': 'resolution', 'optional': True, 'options': [ u'fixed', u'invalid', u'wontfix', u'duplicate', u'worksforme' ], 'skip': True, 'type': 'radio', 'value': u'fixed' }, { 'label': 'Keywords', 'name': 'keywords', 'optional': False, 'options': [], 'skip': True, 'type': 'text' }, { 'label': 'Cc', 'name': 'cc', 'optional': False, 'options': [], 'rendered': '', 'skip': True, 'type': 'text' }, { 'custom': True, 'label': 'Linking_src', 'name': 'linking_src', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u'' }, { 'custom': True, 'label': u'Remaining Time', 'name': 'remaining_time', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u'' }, { 'custom': True, 'label': u'User Story Points', 'name': 'rd_points', 'optional': True, 'options': [ u'0', u'1', u'2', u'3', u'5', u'8', u'13', u'20', u'40', u'100' ], 'order': 0, 'skip': False, 'type': u'select', 'value': u'' }, { 'custom': True, 'label': u'References', 'name': 'o_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u'' }, { 'custom': True, 'label': u'User Story Priority', 'name': 'story_priority', 'optional': False, 'options': [u'Mandatory', u'Linear', u'Exciter'], 'order': 0, 'skip': False, 'type': u'select', 'value': u'Mandatory' }, { 'custom': True, 'label': u'Business Value Points', 'name': 'businessvalue', 'optional': True, 'options': [ u'100', u'200', u'300', u'500', u'800', u'1200', u'2000', u'3000' ], 'order': 0, 'skip': True, 'type': u'select', 'value': u'' }, { 'custom': True, 'label': u'Referenced By', 'name': 'i_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u'' } ], 'may_comment_ticket': True, 'can_edit_ticket': True, 'preserve_newlines': True, 'reassign_owner': u'admin', 'replies': {}, 'replyto': None, 'resolve_resolution': None, 'ticket': t1, 'timestamp': '2008-06-13 15:27:50+00:00', 'version': None, 'row_groups': [( None, [{ u'__color__': u'3', '__idx__': 0, 'cell_groups': [[{ 'header': { 'asc': False, 'col': u'__color__', 'hidden': True, 'title': u'Color' }, 'index': 0, 'value': u'3' }, { 'header': { 'asc': False, 'col': u'ticket', 'hidden': False, 'title': u'Ticket' }, 'index': 1, 'value': u'4' }, { 'header': { 'asc': False, 'col': u'summary', 'hidden': False, 'title': u'Summary' }, 'index': 2, 'value': u'New User Story' }, { 'header': { 'asc': False, 'col': u'component', 'hidden': False, 'title': u'Component' }, 'index': 3, 'value': u'component1' }, { 'header': { 'asc': False, 'col': u'version', 'hidden': False, 'title': u'Version' }, 'index': 4, 'value': u'' }, { 'header': { 'asc': False, 'col': u'milestone', 'hidden': False, 'title': u'Milestone' }, 'index': 5, 'value': u'' }, { 'header': { 'asc': False, 'col': u'type', 'hidden': False, 'title': u'Type' }, 'index': 6, 'value': u'story' }]], # Replace in View Ticket 'id': u'4', 'resource': "Resource u'ticket:4'" }])], } self.ctp = CoreTemplateProvider(self.env)
class TestCoreTemplateProvider(AgiloTestCase): """ This testcase aims to test as much as possible of the IRequestFilter implementation, given the fact that it is very complex and may introduce may issues. The IRequestFilter process the request before (PRE) and after (POST) having called the process_request() of a Trac Component. With Trac 0.11 there has been a change in the interface of the API, with it the use of Genshi complicate the things a bit, now in the data dictionary there may be any valid Python object. A sample data dictionary look the following: {'action': 'leave', 'action_controls': [('leave', 'leave', <Fragment>, ['']), ('resolve', 'resolve', <Fragment>, [u"The resolution will be set. Next status will be 'closed'"]), ('reassign', 'reassign', <Fragment>, [u"The owner will change. Next status will be 'assigned'"]), ('accept', 'accept', <Fragment>, [u"The owner will change to admin. Next status will be 'accepted'"])], 'attachments': {'attach_href': '/test0.11/attachment/ticket/4/', 'attachments': [], 'can_create': True, 'parent': <Resource u'ticket:4'>}, 'author_id': u'admin', 'change_preview': None, 'changes': [{'author': u'admin', 'cnum': 1, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 18, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'description': {'new': u'Test story changed', 'old': u'Test story', 'rendered': <Fragment>}, u'type': {'new': u'task', 'old': u'story'}}, 'permanent': 1}, {'author': u'admin', 'cnum': 2, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 44, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'type': {'new': u'story', 'old': u'task'}}, 'permanent': 1}, {'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'description': {'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': <Fragment>}}, 'permanent': 1}, {'author': u'admin', 'cnum': 4, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 34, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'type': {'new': u'requirement', 'old': u'story'}}, 'permanent': 1}, {'author': u'admin', 'cnum': 5, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 50, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'type': {'new': u'story', 'old': u'requirement'}}, 'permanent': 1}], 'cnum': 6, 'comment': None, 'context': <Context <Resource u'ticket:4'>>, 'description_change': {'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51, tzinfo=<FixedOffset "UTC" 0:00:00>), 'fields': {u'description': {'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': <Fragment>}}, 'permanent': 1}, 'fields': [{'label': 'Summary', 'name': 'summary', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Reporter', 'name': 'reporter', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Owner', 'name': 'owner', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Description', 'name': 'description', 'optional': False, 'options': [], 'skip': True, 'type': 'textarea'}, {'label': 'Type', 'name': 'type', 'optional': False, 'options': [u'task', u'requirement', u'story', u'bug'], 'skip': False, 'type': 'select', 'value': u'defect'}, {'label': 'Status', 'name': 'status', 'optional': True, 'options': [u'accepted', u'assigned', u'closed', u'new', u'reopened'], 'skip': True, 'type': 'radio', 'value': u''}, {'label': 'Priority', 'name': 'priority', 'optional': False, 'options': [u'blocker', u'critical', u'major', u'minor', u'trivial'], 'skip': True, 'type': 'select', 'value': u'major'}, {'label': 'Milestone', 'name': 'milestone', 'optgroups': [{'label': 'Open', 'options': [u'milestone1', u'milestone2', u'milestone3', u'milestone4']}, {'label': 'Closed', 'options': []}], 'optional': True, 'options': [], 'rendered': <Element "a">, 'skip': False, 'type': 'select', 'value': u''}, {'label': 'Component', 'name': 'component', 'optional': False, 'options': [u'component1', u'component2'], 'skip': True, 'type': 'select', 'value': u''}, {'label': 'Version', 'name': 'version', 'optional': True, 'options': [u'2.0', u'1.0'], 'skip': True, 'type': 'select', 'value': u''}, {'label': 'Resolution', 'name': 'resolution', 'optional': True, 'options': [u'fixed', u'invalid', u'wontfix', u'duplicate', u'worksforme'], 'skip': True, 'type': 'radio', 'value': u'fixed'}, {'label': 'Keywords', 'name': 'keywords', 'optional': False, 'options': [], 'skip': True, 'type': 'text'}, {'label': 'Cc', 'name': 'cc', 'optional': False, 'options': [], 'rendered': '', 'skip': True, 'type': 'text'}, {'custom': True, 'label': u'Remaining Time', 'name': 'remaining_time', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}, {'custom': True, 'label': u'User Story Points', 'name': 'rd_points', 'optional': True, 'options': [u'0', u'1', u'2', u'3', u'5', u'8', u'13', u'20', u'40', u'100'], 'order': 0, 'skip': False, 'type': u'select', 'value': u''}, {'custom': True, 'label': u'References', 'name': 'o_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}, {'custom': True, 'label': u'User Story Priority', 'name': 'story_priority', 'optional': False, 'options': [u'Mandatory', u'Linear', u'Exciter'], 'order': 0, 'skip': False, 'type': u'select', 'value': u'Mandatory'}, {'custom': True, 'label': u'Business Value Points', 'name': 'businessvalue', 'optional': True, 'options': [u'100', u'200', u'300', u'500', u'800', u'1200', u'2000', u'3000'], 'order': 0, 'skip': True, 'type': u'select', 'value': u''}, {'custom': True, 'label': u'Referenced By', 'name': 'i_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u''}], 'may_comment_ticket': True, 'can_edit_ticket': True, 'preserve_newlines': True, 'reassign_owner': u'admin', 'replies': {}, 'replyto': None, 'resolve_resolution': None, 'ticket': <AgiloTicket #4 (story)>, 'timestamp': '2008-06-13 15:27:50+00:00', 'version': None} This example is used also for testing and is based on a pprint of a regular Trac ticket. """ def setUp(self): """Creates the environment stub""" self.super() t1 = self.teh.create_ticket(Type.TASK, props={'remaining_time': '12'}) self.DATA = { 'action': 'leave', 'action_controls': [('leave', 'leave', '<Fragment>', ['']), ('resolve', 'resolve', '<Fragment>', [u"The resolution will be set. Next status will be 'closed'"]), ('reassign', 'reassign', '<Fragment>', [u"The owner will change. Next status will be 'assigned'"]), ('accept', 'accept', '<Fragment>', [ u"The owner will change to admin. Next status will be 'accepted'" ])], 'attachments': { 'attach_href': '/test0.11/attachment/ticket/4/', 'attachments': [], 'can_create': True, 'parent': None }, 'author_id': u'admin', 'change_preview': None, # Command: changes@fields(item.has_key(Key.FIELDS)):Key.TYPE:'new'|'old' 'changes': [ { 'author': u'admin', 'cnum': 1, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 18), 'fields': { u'description': { 'new': u'Test story changed', 'old': u'Test story', 'rendered': None }, u'type': { 'new': u'task', 'old': u'story' } }, # Replace 'permanent': 1 }, { 'author': u'admin', 'cnum': 2, 'comment': '', 'date': datetime.datetime(2008, 6, 12, 18, 26, 44), 'fields': { u'type': { 'new': u'story', 'old': u'task' } }, # Replace 'permanent': 1 }, { 'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51), 'fields': { u'description': { 'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': None } }, 'permanent': 1 }, { 'author': u'admin', 'cnum': 4, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 34), 'fields': { u'type': { 'new': u'requirement', 'old': u'story' } }, # Replace 'permanent': 1 }, { 'author': u'admin', 'cnum': 5, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 15, 27, 50), 'fields': { u'type': { 'new': u'story', 'old': u'requirement' } }, # Replace 'permanent': 1 } ], 'cnum': 6, 'comment': None, 'context': None, 'allowed_links': { u'bug-story': [u'bug', u'story'], u'bug-task': [u'bug', u'task'], u'requirement-story': [u'requirement', u'story'], u'story-task': [u'story', u'task'] }, # Replace 'available_types': [u'task', u'requirement', u'story', u'bug'], # Replace 'description_change': { 'author': u'admin', 'cnum': 3, 'comment': '', 'date': datetime.datetime(2008, 6, 13, 8, 54, 51), 'fields': { u'description': { 'new': u'Test story changed...', 'old': u'Test story changed', 'rendered': None } }, 'permanent': 1 }, 'fields': [ { 'label': 'Summary', 'name': 'summary', 'optional': False, 'options': [], 'skip': True, 'type': 'text' }, { 'label': 'Reporter', 'name': 'reporter', 'optional': False, 'options': [], 'skip': True, 'type': 'text' }, { 'label': 'Owner', 'name': 'owner', 'optional': False, 'options': [], 'skip': True, 'type': 'text' }, { 'label': 'Description', 'name': 'description', 'optional': False, 'options': [], 'skip': True, 'type': 'textarea' }, { 'label': 'Type', 'name': 'type', 'optional': False, 'options': [u'task', u'requirement', u'story', u'bug'], # Replace 'skip': False, 'type': 'select', 'value': u'defect' }, { 'label': 'Status', 'name': 'status', 'optional': True, 'options': [u'accepted', u'assigned', u'closed', u'new', u'reopened'], 'skip': True, 'type': 'radio', 'value': u'' }, { 'label': 'Priority', 'name': 'priority', 'optional': False, 'options': [u'blocker', u'critical', u'major', u'minor', u'trivial'], 'skip': True, 'type': 'select', 'value': u'major' }, { 'label': 'Milestone', 'name': 'milestone', 'optgroups': [{ 'label': 'Open', 'options': [ u'milestone1', u'milestone2', u'milestone3', u'milestone4' ] }, { 'label': 'Closed', 'options': [] }], 'optional': True, 'options': [], 'rendered': '<Element "a">', 'skip': False, 'type': 'select', 'value': u'' }, { 'label': 'Component', 'name': 'component', 'optional': False, 'options': [u'component1', u'component2'], 'skip': True, 'type': 'select', 'value': u'' }, { 'label': 'Version', 'name': 'version', 'optional': True, 'options': [u'2.0', u'1.0'], 'skip': True, 'type': 'select', 'value': u'' }, { 'label': 'Resolution', 'name': 'resolution', 'optional': True, 'options': [ u'fixed', u'invalid', u'wontfix', u'duplicate', u'worksforme' ], 'skip': True, 'type': 'radio', 'value': u'fixed' }, { 'label': 'Keywords', 'name': 'keywords', 'optional': False, 'options': [], 'skip': True, 'type': 'text' }, { 'label': 'Cc', 'name': 'cc', 'optional': False, 'options': [], 'rendered': '', 'skip': True, 'type': 'text' }, { 'custom': True, 'label': 'Linking_src', 'name': 'linking_src', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u'' }, { 'custom': True, 'label': u'Remaining Time', 'name': 'remaining_time', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u'' }, { 'custom': True, 'label': u'User Story Points', 'name': 'rd_points', 'optional': True, 'options': [ u'0', u'1', u'2', u'3', u'5', u'8', u'13', u'20', u'40', u'100' ], 'order': 0, 'skip': False, 'type': u'select', 'value': u'' }, { 'custom': True, 'label': u'References', 'name': 'o_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u'' }, { 'custom': True, 'label': u'User Story Priority', 'name': 'story_priority', 'optional': False, 'options': [u'Mandatory', u'Linear', u'Exciter'], 'order': 0, 'skip': False, 'type': u'select', 'value': u'Mandatory' }, { 'custom': True, 'label': u'Business Value Points', 'name': 'businessvalue', 'optional': True, 'options': [ u'100', u'200', u'300', u'500', u'800', u'1200', u'2000', u'3000' ], 'order': 0, 'skip': True, 'type': u'select', 'value': u'' }, { 'custom': True, 'label': u'Referenced By', 'name': 'i_links', 'optional': False, 'options': [], 'order': 0, 'skip': True, 'type': u'text', 'value': u'' } ], 'may_comment_ticket': True, 'can_edit_ticket': True, 'preserve_newlines': True, 'reassign_owner': u'admin', 'replies': {}, 'replyto': None, 'resolve_resolution': None, 'ticket': t1, 'timestamp': '2008-06-13 15:27:50+00:00', 'version': None, 'row_groups': [( None, [{ u'__color__': u'3', '__idx__': 0, 'cell_groups': [[{ 'header': { 'asc': False, 'col': u'__color__', 'hidden': True, 'title': u'Color' }, 'index': 0, 'value': u'3' }, { 'header': { 'asc': False, 'col': u'ticket', 'hidden': False, 'title': u'Ticket' }, 'index': 1, 'value': u'4' }, { 'header': { 'asc': False, 'col': u'summary', 'hidden': False, 'title': u'Summary' }, 'index': 2, 'value': u'New User Story' }, { 'header': { 'asc': False, 'col': u'component', 'hidden': False, 'title': u'Component' }, 'index': 3, 'value': u'component1' }, { 'header': { 'asc': False, 'col': u'version', 'hidden': False, 'title': u'Version' }, 'index': 4, 'value': u'' }, { 'header': { 'asc': False, 'col': u'milestone', 'hidden': False, 'title': u'Milestone' }, 'index': 5, 'value': u'' }, { 'header': { 'asc': False, 'col': u'type', 'hidden': False, 'title': u'Type' }, 'index': 6, 'value': u'story' }]], # Replace in View Ticket 'id': u'4', 'resource': "Resource u'ticket:4'" }])], } self.ctp = CoreTemplateProvider(self.env) def tearDown(self): self.teh.delete_created_tickets() self.super() def alias_values(self): return AgiloConfig(self.env).ALIASES.values() def testReplaceInFields(self): """Tests the replace of the type alias into the fields""" ALIAS_KEYS = ["'fields'@'options'(item[Key.NAME]==Key.TYPE)"] self.ctp._substitute_ticket_types_with_aliases_in_genshi_data( self.DATA, ALIAS_KEYS) for f in self.DATA['fields']: if f.has_key('name') and f['name'] == 'type': self.assert_equals(sorted(f['options']), sorted(self.alias_values())) def testReplaceInChanges(self): """Tests the replace of the type alias into the changes""" ALIAS_KEYS = [ "'changes'@'fields'(item.has_key(Key.FIELDS)):Key.TYPE:'new'|'old'" ] self.ctp._substitute_ticket_types_with_aliases_in_genshi_data( self.DATA, ALIAS_KEYS) for change in self.DATA['changes']: if change.has_key(Key.TYPE): self.assert_true( change[Key.TYPE]['new'] in self.alias_values()) self.assert_true( change[Key.TYPE]['old'] in self.alias_values()) def testReplaceInAdminInterface(self): """Tests the replace in the Admin interface""" ALIAS_KEYS = ["'available_types'", "'allowed_links':'*'"] self.ctp._substitute_ticket_types_with_aliases_in_genshi_data( self.DATA, ALIAS_KEYS) for ltype in self.DATA['available_types']: self.assert_true(ltype in self.alias_values()) for alinks in self.DATA['allowed_links'].values(): for al in alinks: self.assert_true(al in self.alias_values()) def testReplaceInViewTicketReport(self): """Tests the replace in the Report from View Ticket""" ALIAS_KEYS = [ "'row_groups',0,1@'cell_groups',0@'value'(item['header']['title']=='Type')" ] self.ctp._substitute_ticket_types_with_aliases_in_genshi_data( self.DATA, ALIAS_KEYS) for key, rows in self.DATA['row_groups']: for r in rows: for v in r['cell_groups']: for l in v: if l['header']['title'] == 'Type': self.assert_true(l['value'] in self.alias_values())
def user_may_create(self, req, child_type): creation_permission = CoreTemplateProvider( self.env).get_permission_name_to_create action = creation_permission(child_type) return req.perm.has_permission(action)