def _set_restrict_owner_option(self, new_value): env = self._testenv.get_trac_environment() agilo_config = AgiloConfig(env) old_value = agilo_config.get_bool('restrict_owner', 'ticket') agilo_config.change_option('restrict_owner', new_value, section='ticket', save=True) return old_value
def test_changing_type_restore_correct_fields(self): """Tests that changing a ticket type restores the correct fields for that type""" t = AgiloTicket(self.env, t_type=Type.TASK) self.assert_true(self._matching_properties(t)) # Now change that to a story t[Key.TYPE] = Type.USER_STORY self.assert_true(self._matching_properties(t)) # Now reload config and change to bug ac = AgiloConfig(self.env) ac.reload() t[Key.TYPE] = Type.BUG self.assert_true(self._matching_properties(t)) # Now add a field on the fly and see if it is adapting to it agilo_types = ac.get_section(ac.AGILO_TYPES) ticket_custom = ac.get_section(ac.TICKET_CUSTOM) ticket_custom.change_option('customer', 'text') ticket_custom.change_option('customer.label', 'Customer') fields = agilo_types.get_list(Type.BUG) fields.append('customer') # notice the save to force the reload of the config agilo_types.change_option('story', ','.join(fields), save=True) t[Key.TYPE] = Type.USER_STORY self.assert_true('customer' in t.fields_for_type, \ "No 'customer' in %s" % t.fields_for_type) t['customer'] = 'My Own Customer' self.assert_true(self._matching_properties(t)) t.insert() self.assert_true(self._matching_properties(t)) self.assert_equals('My Own Customer', t['customer'])
def test_do_not_sets_default_logo_if_changed(self): test_src = 'my_logo' agilo_config = AgiloConfig(self.env) header_logo = agilo_config.get_section('header_logo') header_logo.change_option('src', test_src) self.assert_equals(test_src, header_logo.get('src')) set_default_agilo_logo(agilo_config) self.assert_equals(test_src, header_logo.get('src'))
def set_sprint_can_start_or_end_on_weekends(self): # The sprint must be running only for exactly one day, otherwise # confirm commitment is not possible anymore (and the total capacity # might be different) env = self.testenv.get_trac_environment() config = AgiloConfig(env) config.change_option('sprints_can_start_or_end_on_weekends', True, section='agilo-general') config.save()
def _set_default_type(self, new_value): agilo_config = AgiloConfig(self.env) old_value = agilo_config.get('default_type', 'ticket') agilo_config.change_option('default_type', new_value, section='ticket', save=True) return old_value
def setUp(self): self.super() links = AgiloConfig(self.env).get_section(AgiloConfig.AGILO_LINKS) links.change_option(LinkOption.ALLOW, 'story-task, bug-task, bug-story') # Creates tickets self.t1 = self.teh.create_ticket(Type.USER_STORY, props={Key.SUMMARY: u"User Story"}) self.t2 = self.teh.create_ticket(Type.TASK, props={Key.SUMMARY: u"First Task"}) self.t3 = self.teh.create_ticket(Type.TASK, props={Key.SUMMARY: u"Second Task"}) self.linksearch = LinksSearchModule(self.env)
def _reset_properly_query_and_report_modules(env): # Reset the properties of query module and report in the trac.ini, in old # agilo was required to remove the original from trac, now we have to make # sure that they are reset again, cause the patching is done in AgiloConfig. ac = AgiloConfig(env) components = ac.get_section("components") # even if they would be set to enabled, removing them wouldn't change the # behavior components.remove_option("trac.ticket.query.querymodule") components.remove_option("trac.ticket.report.reportmodule") components.save()
def _reset_properly_query_and_report_modules(env): # Reset the properties of query module and report in the trac.ini, in old # agilo was required to remove the original from trac, now we have to make # sure that they are reset again, cause the patching is done in AgiloConfig. ac = AgiloConfig(env) components = ac.get_section('components') # even if they would be set to enabled, removing them wouldn't change the # behavior components.remove_option('trac.ticket.query.querymodule') components.remove_option('trac.ticket.report.reportmodule') components.save()
def testCanDisableSprintStartDateNormalization(self): config = AgiloConfig(self.env).get_section(AgiloConfig.AGILO_GENERAL) option_name = 'sprints_can_start_or_end_on_weekends' self.assert_false(config.get_bool(option_name)) config.change_option(option_name, True, save=True) self.assert_true(AgiloConfig(self.env).sprints_can_start_or_end_on_weekends) start = datetime(2009, 05, 30, tzinfo=utc) sprint = self.teh.create_sprint('Foo', start=start) self.assert_equals(start, sprint.start) self.assert_equals(utc, sprint.start.tzinfo)
def list_save_view(self, req, cat, page): """Stores general preferences for agilo""" use_days = (req.args.get('use_days') == 'True') # sets the days option config = AgiloConfig(self.env) # REFACT: Actually we could use config.use_days = use_days but then # we don't have any control when the config is actually written... config.change_option(Key.USE_DAYS, use_days, 'agilo-general', save=False) # Save only once self.config.save() req.redirect(req.href.admin(cat, page))
def setUp(self): self.super() self.tester.login_as(Usernames.admin) components = AgiloConfig(self.env).get_section('components') components.change_option("tracrpc.*", 'enabled') components.save() self.ticket1_id = self.tester.create_new_agilo_task('foo', 'abc') self.ticket2_id = self.tester.create_new_agilo_task('bar', 'def')
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 test_safe_custom_fields(self): """Tests that the defined custom fields are safe""" ticket_custom = \ AgiloConfig(self.env).get_section(AgiloConfig.TICKET_CUSTOM) custom_fields = ticket_custom.get_options_matching_re('^[^.]+$') tfw = FieldsWrapper(self.env, AgiloTicketSystem(self.env).get_ticket_fields(), Type.TASK) for f in tfw: if f[Key.NAME] in custom_fields: self.assert_true(f[Key.CUSTOM], "%s should be custom!!!" % f[Key.NAME])
def runTest(self): self._tester.login_as(Usernames.admin) fieldname = 'remaining_time' self._tester.modify_custom_field(fieldname, value='5') self._tester.modify_custom_field(fieldname, value='') url = '%s/admin/agilo/fields/%s' % (self._tester.url, fieldname) tc.go(url) tc.find('<input type="text" name="value" value=""') env = self._testenv.get_trac_environment() config = AgiloConfig(env).get_section(AgiloConfig.TICKET_CUSTOM) self.assertEqual(None, config.get('remaining_time.value'))
def agilo_was_installed(self): try: from acct_mgr.web_ui import EmailVerificationModule except ImportError: return if not self.env.is_component_enabled(EmailVerificationModule): return components = AgiloConfig(self.env).get_section('components') if self.was_email_verification_enabled_explicitely(components): return components.change_option(self.name_emailverificationmodule(), 'disabled') components.save()
def testTimeRenderer(self): """Tests the time renderer""" task = self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '2.5'}) r = Renderer(task, Key.REMAINING_TIME) # force hours AgiloConfig(self.teh.get_env()).use_days = False self.assert_equals('2.5h', r()) self.assert_equals('2.5h', '%s' % r) # force days AgiloConfig(self.teh.get_env()).use_days = True self.assert_equals('2.5d', r()) self.assert_equals('2.5d', '%s' % r)
def test_reload_config(self): """Tests the reload of the config""" types = AgiloConfig(self.env).get_section(AgiloConfig.AGILO_TYPES) # Add a ticket type types.change_option('my_type', ', '.join([Key.PRIORITY, Key.COMPONENT])) types.change_option('my_type.alias', 'My Type') types.save() self.assert_true('my_type' in AgiloConfig(self.env).ALIASES, "Type not found in aliases, AgiloConfig not reloaded?")
def initialize_agilo(self, project_name, db_url, svn_repo, demo=False): try: self.do_initenv( '%s %s %s %s' % (project_name, db_url, 'svn', svn_repo or 'somewhere')) # Now add agilo and the template path env = Environment(self.envname) ac = AgiloConfig(env) if not svn_repo: # remove the fake from the config ac.change_option('repository_dir', '', 'trac') # sets the restric_owner option ac.change_option('restrict_owner', 'true', 'ticket') # this is also saving the config ac.enable_agilo() # update wiki wiki = WikiPage(env, name='WikiStart') wiki.text = agilo_wiki wiki.save('admin', 'Updated to Agilo', '127.0.0.1') # reset the env self.env_set(envname=self.envname, env=env) # Now initialize Agilo self.do_upgrade('upgrade --no-backup') # Now create the demo if needed if demo: try: from create_demo_data import _create_demo_data _create_demo_data(env) except ImportError, e: env.log.error(exception_to_unicode(e)) except: pass
class InstallationTest(AgiloTestCase): """Tests agilo installation process, calling the main init method""" def setUp(self): self.super() self.config = AgiloConfig(self.env) def test_initialization_adds_agilo_policy(self): self.assert_equals( self.config.get('permission_policies', section='trac'), u'AgiloPolicy, DefaultPermissionPolicy, LegacyAttachmentPolicy') def test_initialization_set_templates_dir(self): template_path = self.config.get('templates_dir', section='inherit') self.assert_true(template_path.find('templates') > -1)
class InstallationTest(AgiloTestCase): """Tests agilo installation process, calling the main init method""" def setUp(self): self.super() self.config = AgiloConfig(self.env) def test_initialization_adds_agilo_policy(self): self.assert_equals(self.config.get('permission_policies', section='trac'), u'AgiloPolicy, DefaultPermissionPolicy, LegacyAttachmentPolicy') def test_initialization_set_templates_dir(self): template_path = self.config.get('templates_dir', section='inherit') self.assert_true(template_path.find('templates') > -1)
def test_raises_if_wrong_unit_is_used(self): task_id = self.teh.create_task().id config = AgiloConfig(self.env) config.use_days = True parsed = [('rem', "%s" % task_id, '3d')] self.assert_equals(parsed, self.parse('rem #%s:3d' % task_id)) exception = self.assert_raises(InvalidAttributeError, self.parse, 'rem #%s:3h' % task_id) self.assert_true('Wrong unit used in remaining time' in exception.args[0]) config.use_days = False parsed = [('rem', "%s" % task_id, '3h')] self.assert_equals(parsed, self.parse('rem #%s:3h' % task_id)) exception = self.assert_raises(InvalidAttributeError, self.parse, 'rem #%s:3d' % task_id) self.assert_true('Wrong unit used in remaining time' in exception.args[0])
def environment_created(self): for table in db_default.schema: create_table(self.env, table) cache_manager = HttpRequestCacheManager(self.env) po_manager = PersistentObjectManager(self.env) for manager in cache_manager.managers: model_class = manager.for_model() if issubclass(model_class, PersistentObject): module_name = model_class.__module__ # We don't want to create tables for dummy classes automatically # but the test finder may load some of these managers so we # need to exclude them here. if ('tests.' not in module_name): po_manager.create_table(model_class) # Need to create Agilo types in the database before writing to the # configuration - otherwise we get a warning during config setup (you'll # see it in every test case during setUp) db_default.create_default_types(self.env) initialize_config(self.env, __CONFIG_PROPERTIES__) db_default.create_default_backlogs(self.env) super(AgiloInit, self).environment_created() for listener in self.setup_listeners: listener.agilo_was_installed() # Reload the AgiloConfig to make sure all the changes have been updated AgiloConfig(self.env).reload() info(self, 'Agilo environment initialized')
def testTimeRendererWithIntegers(self): task = self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '2'}) r = Renderer(task, Key.REMAINING_TIME) # force hours AgiloConfig(self.teh.get_env()).use_days = False self.assert_equals('2.0h', r())
def _prepare_fields(self, req, ticket, field_changes=None): """Set specific renderer for the ticket fields""" fields = super(AgiloTicketModule, self)._prepare_fields(req, ticket) if not AgiloConfig(self.env).is_agilo_enabled: return fields from agilo.scrum import SprintController sp_controller = SprintController(self.env) for field in fields: field[Key.RENDERED] = self._rendered_ticket_value(ticket, field) # makes the nice Sprint pulldown to emulate the milestone one if field[Key.NAME] == Key.SPRINT: get_options = SprintController.GetSprintOptionListCommand( self.env, sprint_names=field[Key.OPTIONS]) closed, running, to_start = sp_controller.process_command( get_options) field[Key.OPTIONS] = [] field[Key.OPTIONS_GROUP] = [ { Key.LABEL: _('Running (by Start Date)'), Key.OPTIONS: running }, { Key.LABEL: _('To Start (by Start Date)'), Key.OPTIONS: to_start }, { Key.LABEL: _('Closed (by Start Date)'), Key.OPTIONS: closed }, ] return fields
def _filter_info(self): config = AgiloConfig(self.env) if not config.backlog_filter_attribute: return dict() return dict(should_filter_by_attribute=config.backlog_filter_attribute, should_reload_burndown_on_filter_change_when_filtering_by_component= \ config.should_reload_burndown_on_filter_change_when_filtering_by_component)
def detail_view(self, req, cat, page, name, backlog_config=None): backlog_config = self._backlog_config_with_changed_ticket_types( req, cat, page, name, backlog_config=backlog_config) # REFACT: Maybe we should use JSON here rather than xml? if ajax.is_ajax(req): # we got called by an Ajax request -> get available fields fields_for_selected_types = backlog_config.columns_as_fields( all_fields=False) items = [field[Key.NAME] for field in fields_for_selected_types] return 'ajax_response.xml', {'items': items} # TODO: Go for ticket configuration agilo_config = AgiloConfig(self.env) data = { 'view': 'detail', 'backlog': backlog_config, 'backlog_types': BacklogType.LABELS, 't_types': [(t_type, t_type in backlog_config.ticket_types, agilo_config.ALIASES.get(t_type, t_type)) for t_type in agilo_config.TYPES.keys()], 'fields': backlog_config.columns_as_fields(all_fields=True), } add_script(req, 'agilo/js/backlog_admin.js') add_script(req, 'common/js/wikitoolbar.js') return 'agilo_admin_backlog.html', data
def is_email_verification_enabled(env): AgiloConfig(env).clear_trac_component_cache() try: from acct_mgr.web_ui import EmailVerificationModule return env.is_component_enabled(EmailVerificationModule) except ImportError: return None
def _all_field_names(self): all_field_names = set() ticket_configuration = AgiloConfig(self.env).ticket_configuration for field_names in ticket_configuration.fieldnames_per_type.values(): for field_name in field_names: all_field_names.add(field_name) return all_field_names
def config_reloaded(self): """Recreate mapping dictionaries when needed""" config = AgiloConfig(self.env) if config.ALIASES is not None: self._alias_to_type = dict( zip(config.ALIASES.values(), config.ALIASES.keys())) self.cp = CommandParser(self.env, config.ALIASES, self._alias_to_type)
def _filter_by(self, data): filter_by = None if AgiloConfig( self.env ).should_reload_burndown_on_filter_change_when_filtering_by_component: filter_by = data.get('filter_by') return filter_by
def _all_configured_ticket_fields(self): field_names = set() ticket_config = AgiloConfig(self.env).ticket_configuration for field_names_for_type in ticket_config.fieldnames_per_type.values(): for field_name in field_names_for_type: field_names.add(field_name) return list(field_names)
def test_doesnt_overwrite_custom_favicons(self): custom_favicon = 'fnord' project_section = AgiloConfig(self.env).get_section('project') project_section.change_option('icon', custom_favicon) self.assert_equals(custom_favicon, project_section.get('icon')) initialize_config(self.env, {}) project_section = AgiloConfig(self.env).get_section('project') self.assert_equals(custom_favicon, project_section.get('icon'))
def _days_to_remove_from_burndown(self, sprint, viewer_timezone): if not AgiloConfig(self.env).burndown_should_show_working_days_only: return [] if sprint.team is None: return [] days_to_remove = sprint.team.capacity(viewer_timezone).days_without_capacity_in_interval(sprint.start, sprint.end) return days_to_remove
def _set_duration(self, value): """Sets the duration of the Sprint and recalculates the end Date""" if value is not None: week_days_off = None if AgiloConfig(self.env).sprints_can_start_or_end_on_weekends: week_days_off = [] self.end = add_to_date(self.start, value, week_days_off=week_days_off) debug(self, "Setting Sprint end date to: %s" % self.end)
def test_can_extract_remaining_time_with_unit(self): task_id = self.teh.create_task().id parsed = [('rem', "%s" % task_id, '3h')] self.assert_equals(parsed, self.parse('rem #%s:3h' % task_id)) AgiloConfig(self.env).use_days = True parsed = [('TIME', "%s" % task_id, '3d')] self.assert_equals(parsed, self.parse('TIME #%s:3d' % task_id))
def initialize_agilo(self, project_name, db_url, svn_repo, demo=False): try: self.do_initenv('%s %s %s %s' % (project_name, db_url, 'svn', svn_repo or 'somewhere')) # Now add agilo and the template path env = Environment(self.envname) ac = AgiloConfig(env) if not svn_repo: # remove the fake from the config ac.change_option('repository_dir', '', 'trac') # sets the restric_owner option ac.change_option('restrict_owner', 'true', 'ticket') # this is also saving the config ac.enable_agilo() # update wiki wiki = WikiPage(env, name='WikiStart') wiki.text = agilo_wiki wiki.save('admin', 'Updated to Agilo', '127.0.0.1') # reset the env self.env_set(envname=self.envname, env=env) # Now initialize Agilo self.do_upgrade('upgrade --no-backup') # Now create the demo if needed if demo: try: from create_demo_data import _create_demo_data _create_demo_data(env) except ImportError, e: env.log.error(exception_to_unicode(e)) except: pass
def remove_all_account_manager_components_from_config(self): env = self._testenv.get_trac_environment() components = AgiloConfig(env).get_section('components') for name in components.get_options_by_prefix('acct_mgr', chop_prefix=False): components.remove_option(name, save=False) components.save()
def _update_configuration(env): my_config = copy(__CONFIG_PROPERTIES__) del my_config[AgiloConfig.AGILO_LINKS] del my_config[AgiloConfig.AGILO_TYPES] initialize_config(env, my_config) config = AgiloConfig(env).tc # Only the trac config wrapper _update_agilo_types(config) _update_calculated_properties(config, env)
def render(self): """Returns the rendered property with a d or h""" if self.value_is_a_number() or isinstance(self.value, (float, int, Decimal)): if AgiloConfig(self.env).use_days: return u"%sd" % round(float(self.value), 2) else: return u"%sh" % round(float(self.value), 1) return self.value
def initialize(self): """Initialize the links configuration from the give config key""" self._currently_initializing = True # Prevent recursive imports (AgiloConfig needs to import the ticket # module) from agilo.utils.config import AgiloConfig if self._initialized and AgiloConfig(self.env).is_agilo_enabled: return links = AgiloConfig(self.env).get_section(AgiloConfig.AGILO_LINKS) for pair in links.get_list(LinkOption.ALLOW): if pair.find('-') == -1: continue self._parse_option(pair, links) # Set to initialized self._initialized = True self._currently_initializing = False
def test_fields_for_task(self): """Tests how the FieldsWrapper respond with a task type""" ticket_system = AgiloTicketSystem(self.env) tfw = FieldsWrapper(self.env, ticket_system.get_ticket_fields(), Type.TASK) expected_fields_for_task = AgiloConfig(self.env).TYPES.get(Type.TASK) # Try to check the keys field_wrapper_names = map(lambda field: field[Key.NAME], tfw) # it is added by the ticket system to store sprint # scope synchronous with milestone field_wrapper_names.remove(Key.MILESTONE) expected_fields_for_task.remove('id') if not ticket_system.is_trac_012(): # in Trac 0.11, time fields are magic field_wrapper_names.append('changetime') field_wrapper_names.append('time') self.assert_equals(sorted(expected_fields_for_task), sorted(field_wrapper_names))
def populate_with_sprint_data(self, sprint_name): """Populate the chart with sprint statistics""" cmd_stats = SprintController.GetTicketsStatisticsCommand(self.env, sprint=sprint_name) tickets_stats = SprintController(self.env).process_command(cmd_stats) planned, closed, total, labels = [], [], [], [] aliases = AgiloConfig(self.env).ALIASES for i, t_type in enumerate(tickets_stats): nr_planned, nr_in_progress, nr_closed = tickets_stats[t_type] planned.append((i, nr_planned)) closed.append((i, nr_closed)) nr_total = nr_planned + nr_in_progress + nr_closed total.append((i, nr_total)) alias = aliases.get(t_type, t_type) labels.append((i, alias)) self.data.update( dict(sprint_name=sprint_name, labels=labels, planned=planned, closed=closed, total=total) )
def _create_custom_ticket_type(self, type_name, field_names): custom_type = TicketType(self.env) custom_type.name = type_name custom_type.insert() config = AgiloConfig(self.env) config.change_option(type_name, field_names, section=AgiloConfig.AGILO_TYPES) config.reload() self.assert_true(type_name in config.get_available_types())
def test_handles_types_with_dashes(self): from_type = 'with-dashes' to_type = 'bug' custom_type = TicketType(self.env) custom_type.name = from_type custom_type.insert() config = AgiloConfig(self.env) config.change_option(from_type, "", section=AgiloConfig.AGILO_TYPES) config.reload() self.assert_true(from_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=True) self.links_configuration = LinksConfiguration(self.env) self.assert_equals(self.links_configuration.get_alloweds(from_type)[0].dest_type, to_type)
def runTest(self): env = self._testenv.get_trac_environment() config = AgiloConfig(env).get_section(AgiloConfig.AGILO_LINKS) option_name = '%s.calculate' % Type.REQUIREMENT configured_properties = config.get_list(option_name) broken_definition = 'sum:get_outgoing.blubber' configured_properties.append(broken_definition) config.change_option(option_name, ', '.join(configured_properties)) config.save() self._tester.login_as(Usernames.admin) page_url = self._tester.url + '/admin/agilo/types/%s' % Type.REQUIREMENT tc.go(page_url) tc.code(200) html = tc.show() assert "sum:get_outgoing.rd_points|type=story|story_priority=Mandatory" in html assert 'blubber' not in html
def test_agilo_with_parallel_environments(self): """ Tests agilo in parallel with two different environment, one with and one without agilo """ ac_agilo = AgiloConfig(self.env) ac_agilo.enable_agilo() env_no_agilo = TestEnvHelper(env_key=self.env_key) ac_no_agilo = AgiloConfig(env_no_agilo.get_env()) ac_no_agilo.disable_agilo() # Now we have two environment in the same python VM agilo_ticket = self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '2'}) self.assert_true(isinstance(agilo_ticket, AgiloTicket), "Got the wrong type: %s" % type(agilo_ticket)) non_agilo_ticket = env_no_agilo.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '2'}) self.assert_true(hasattr(agilo_ticket, '_calculated')) self.assert_false(hasattr(non_agilo_ticket, '_calculated'))
def sprints_can_start_and_end_anytime(self): config = AgiloConfig(self.env) config.change_option('sprints_can_start_or_end_on_weekends', True, section='agilo-general') config.save()
def setUp(self): self.super() self.config = AgiloConfig(self.env)
def set_cascade_delete_story_task(self): env = self.testenv.get_trac_environment() config = AgiloConfig(env) config.change_option('delete', 'task-story', section='agilo-links') config.save()
def _get_number_of_custom_fields(self): env = self._testenv.get_trac_environment() config = AgiloConfig(env).get_section(AgiloConfig.TICKET_CUSTOM) last = len(config.get_options_matching_re('^[^.]+$')) - 1 return last