def create_field(self, field_name, field_type, **field_options): config = AgiloConfig(self.env) ticket_custom = config.get_section('ticket-custom') ticket_custom.change_option(field_name, field_type) for (option_name, option_value) in field_options.items(): key = '%s.%s' % (field_name, option_name) ticket_custom.change_option(key, option_value) config.save() ticket_system = AgiloTicketSystem(self.env) all_known_fields = ticket_system.fieldnames(ticket_system.get_ticket_fields()) assert_contains(field_name, all_known_fields)
def create_field(self, field_name, field_type, **field_options): config = AgiloConfig(self.env) ticket_custom = config.get_section('ticket-custom') ticket_custom.change_option(field_name, field_type) for (option_name, option_value) in field_options.items(): key = '%s.%s' % (field_name, option_name) ticket_custom.change_option(key, option_value) config.save() ticket_system = AgiloTicketSystem(self.env) all_known_fields = ticket_system.fieldnames( ticket_system.get_ticket_fields()) assert_contains(field_name, all_known_fields)
def enable_burndown_filter(self): self.env.config.set( AgiloConfig.AGILO_GENERAL, 'should_reload_burndown_on_filter_change_when_filtering_by_component', True) self.enable_backlog_filter(Key.COMPONENT) assert_true(AgiloConfig(self.env).is_filtered_burndown_enabled())
def allow_link_from_to(self, from_type, to_type, save=None): # All tickets instantiated before this call will have a copy # of their allowed links, so for this call to have an effect, # the objects have to be dropped and recreated. config = AgiloConfig(self.env) assert from_type in config.get_available_types() assert to_type in config.get_available_types() section = config.get_section(AgiloConfig.AGILO_LINKS) allowed_links = section.get_list('allow') allowed_links.append('%s-%s' % (from_type, to_type)) section.change_option('allow', ', '.join(allowed_links), save=save) # Recreate all the worst caches links_configuration = LinksConfiguration(self.env) links_configuration._initialized = False links_configuration.initialize() AgiloTicketSystem(self.env).clear_cached_information()
def _upgrade_environment(self, env): # Avoid recursive imports - TestEnvHelper must not trigger anything from agilo.init import AgiloInit if not self.env.is_component_enabled(AgiloInit): return ai = AgiloInit(env) db = env.get_db_cnx() if ai.environment_needs_upgrade(db): ai.upgrade_environment(db) db.commit() AgiloConfig(env).clear_trac_component_cache()
def create_backlog(self, name='Performance Backlog', num_of_items=10, b_type=BacklogType.GLOBAL, ticket_types=[Type.REQUIREMENT, Type.USER_STORY], scope=None): """Creates a Backlog with the given parameters and returns it""" # Characteristic properties ticket_custom = AgiloConfig(self.env).get_section(AgiloConfig.TICKET_CUSTOM) char_props = {Type.REQUIREMENT: [(Key.BUSINESS_VALUE, ticket_custom.get("%s.options" % Key.BUSINESS_VALUE).split('|'))], Type.USER_STORY: [(Key.STORY_PRIORITY, ticket_custom.get("%s.options" % Key.STORY_PRIORITY).split('|')), (Key.STORY_POINTS, ticket_custom.get("%s.options" % Key.STORY_POINTS).split('|'))], Type.TASK: [(Key.REMAINING_TIME, ['12', '8', '4', '6', '2', '0'])], Type.BUG: [(Key.PRIORITY, ['minor', 'major', 'critical'])]} # creates the specified number of tickets last = None for i in range(num_of_items): t_type = ticket_types[randint(0, len(ticket_types) - 1)] t_props = dict([(prop_name, values[randint(0, len(values) - 1)]) for \ prop_name, values in char_props[t_type]]) if scope and BacklogType.LABELS.get(b_type) in \ AgiloConfig(self.env).TYPES.get(t_type): # Set the scope to the ticket t_props[BacklogType.LABELS.get(b_type)] = scope t_props[Key.SUMMARY] = 'Agilo Ticket #%d' % i actual = self.create_ticket(t_type, props=t_props) # print "Ticket(%s): %s => %s (Backlog: %s)" % \ # (actual[Key.STATUS], actual, t_props, # BacklogType.LABELS.get(b_type)) if last: if ticket_types.index(last.get_type()) > ticket_types.index(actual.get_type()): assert actual.link_to(last) else: assert last.link_to(actual) last = actual backlog = self.create_backlog_without_tickets(name, type=b_type, ticket_types=ticket_types, scope=scope) return backlog
def add_field_for_type(self, field_name, ticket_type): assert not AgiloTicket(self.env, t_type=ticket_type).is_writeable_field(field_name) config = AgiloConfig(self.env) current_fields = config.get_list(ticket_type, section=AgiloConfig.AGILO_TYPES) config.change_option(ticket_type, ', '.join(current_fields + [field_name]), section=AgiloConfig.AGILO_TYPES) config.save() assert AgiloTicket(self.env, t_type=ticket_type).is_writeable_field(field_name)
def _first_aggregated_change(self): delta = self.changes[0].delta() should_filter = AgiloConfig(self.env).is_filtered_burndown_enabled() is_filtering_by_component = self.filter_by_component is_not_component_itself = not self.changes[0].has_marker( BurndownDataConstants.COMPONENT) if should_filter and is_filtering_by_component and is_not_component_itself: by_component = self.changes[0].marker_value( BurndownDataConstants.DELTAS_BY_COMPONENT) or {} delta = by_component.get(self.filter_by_component, 0) return burndown_entry(self.changes[0].when, delta)
def add_field_for_type(self, field_name, ticket_type): assert not AgiloTicket( self.env, t_type=ticket_type).is_writeable_field(field_name) config = AgiloConfig(self.env) current_fields = config.get_list(ticket_type, section=AgiloConfig.AGILO_TYPES) config.change_option(ticket_type, ', '.join(current_fields + [field_name]), section=AgiloConfig.AGILO_TYPES) config.save() assert AgiloTicket(self.env, t_type=ticket_type).is_writeable_field(field_name)
def _discard_changes_that_do_not_match_the_filtered_component_if_neccessary( self): if not self.filter_by_component: return if not AgiloConfig(self.env).is_filtered_burndown_enabled(): raise ValueError( "Trying to filter by component %s but burndown filtering is not enabled" % self.filter_by_component) def has_component(change): return change.marker_value(BurndownDataConstants.COMPONENT) == self.filter_by_component\ or change.has_marker(BurndownDataConstants.DELTAS_BY_COMPONENT) self.changes = filter(has_component, self.changes)
def create_backlog(self, name='Performance Backlog', num_of_items=10, b_type=BacklogType.GLOBAL, ticket_types=[Type.REQUIREMENT, Type.USER_STORY], scope=None): """Creates a Backlog with the given parameters and returns it""" # Characteristic properties ticket_custom = AgiloConfig(self.env).get_section( AgiloConfig.TICKET_CUSTOM) char_props = { Type.REQUIREMENT: [(Key.BUSINESS_VALUE, ticket_custom.get("%s.options" % Key.BUSINESS_VALUE).split('|')) ], Type.USER_STORY: [(Key.STORY_PRIORITY, ticket_custom.get("%s.options" % Key.STORY_PRIORITY).split('|')), (Key.STORY_POINTS, ticket_custom.get("%s.options" % Key.STORY_POINTS).split('|'))], Type.TASK: [(Key.REMAINING_TIME, ['12', '8', '4', '6', '2', '0'])], Type.BUG: [(Key.PRIORITY, ['minor', 'major', 'critical'])] } # creates the specified number of tickets last = None for i in range(num_of_items): t_type = ticket_types[randint(0, len(ticket_types) - 1)] t_props = dict([(prop_name, values[randint(0, len(values) - 1)]) for \ prop_name, values in char_props[t_type]]) if scope and BacklogType.LABELS.get(b_type) in \ AgiloConfig(self.env).TYPES.get(t_type): # Set the scope to the ticket t_props[BacklogType.LABELS.get(b_type)] = scope t_props[Key.SUMMARY] = 'Agilo Ticket #%d' % i actual = self.create_ticket(t_type, props=t_props) # print "Ticket(%s): %s => %s (Backlog: %s)" % \ # (actual[Key.STATUS], actual, t_props, # BacklogType.LABELS.get(b_type)) if last: if ticket_types.index(last.get_type()) > ticket_types.index( actual.get_type()): assert actual.link_to(last) else: assert last.link_to(actual) last = actual backlog = self.create_backlog_without_tickets( name, type=b_type, ticket_types=ticket_types, scope=scope) return backlog
def _set_sprint_date_normalization(self, enabled): config = AgiloConfig(self.env) config.change_option('sprints_can_start_or_end_on_weekends', not enabled, section=AgiloConfig.AGILO_GENERAL) config.save()
def enable_backlog_filter(self, attribute_name): self.env.config.set(AgiloConfig.AGILO_GENERAL, 'backlog_filter_attribute', attribute_name) assert_equals(attribute_name, AgiloConfig(self.env).backlog_filter_attribute)
def set_component_marker(self, component_name): message = 'need to enable both should_reload_burndown_on_filter_change_when_filtering_by_component and backlog_filter_attribute to save burndown data by component' assert AgiloConfig(self.env).is_filtered_burndown_enabled(), message self.update_marker(BurndownDataConstants.COMPONENT, component_name)
def disable_sprint_date_normalization(self): self._set_sprint_date_normalization(False) assert AgiloConfig( self.env).sprints_can_start_or_end_on_weekends == True
def confirm_commitment_for_sprint(self, a_sprint, when=None): if AgiloConfig(self.env).is_filtered_burndown_enabled(): self.aggregate_all_changes_with_deltas_by_components(a_sprint, when=when) else: self.aggregate_all_changes(a_sprint, when=when)