def copy_milestone(source_env, dest_env, name, dest_db=None): # In case a string gets passed in if not isinstance(source_env, Environment): source_env = _open_environment(source_env) if not isinstance(dest_env, Environment): dest_env = _open_environment(dest_env) # Log message source_env.log.info('DatamoverPlugin: Moving milestone %s to the environment at %s', name, dest_env.path) dest_env.log.info('DatamoverPlugin: Moving milestone %s from the environment at %s', name, source_env.path) # Open databases source_db = source_env.get_db_cnx() source_cursor = source_db.cursor() handle_commit = True if not dest_db: dest_db, handle_commit = dest_env.get_db_cnx(), False dest_cursor = dest_db.cursor() # Remove the milestone from the destination try: dest_milestone = Milestone(dest_env, name, db=dest_db) dest_milestone.delete(retarget_to=name, db=dest_db) except TracError: pass # Copy each entry in the milestone table source_cursor.execute('SELECT * FROM milestone WHERE name=%s',(name,)) for row in source_cursor: milestone_data = dict(zip([d[0] for d in source_cursor.description], row)) q = make_query(milestone_data, 'milestone') dest_cursor.execute(*q) if handle_commit: dest_db.commit()
def test_save_milestone(self): map = MilestoneAdminPanel(self.env) old_name = 'milestone2' new_name = 'mile stone 6' milestone = Milestone(self.env, old_name) self.assertEqual(old_name, milestone.name) req = MockRequest(self.env, method='POST', args={ 'name': ' milestone1 ', 'save': True }) with self.assertRaises(ResourceExistsError) as cm: map.render_admin_panel(req, 'ticket', 'milestone', old_name) self.assertIn('Milestone "milestone1" already exists', unicode(cm.exception)) req = MockRequest(self.env, method='POST', args={ 'name': ' mile \t stone \t 6 ', 'save': True }) self.assertRaises(RequestDone, map.render_admin_panel, req, 'ticket', 'milestone', old_name) self.assertIn('Your changes have been saved.', req.chrome['notices']) milestone = Milestone(self.env, new_name) self.assertEqual(new_name, milestone.name) self.assertRaises(ResourceNotFound, map.render_admin_panel, req, 'ticket', 'milestone', old_name) self.assertRaises(ResourceNotFound, Milestone, self.env, old_name)
def process_request(self, req): milestone_id = req.args.get('id') req.perm('milestone', milestone_id).require('MILESTONE_VIEW') add_link(req, 'up', req.href.roadmap(), _('Roadmap')) action = req.args.get('action', 'view') try: milestone = Milestone(self.env, milestone_id) except ResourceNotFound: if 'MILESTONE_CREATE' not in req.perm('milestone', milestone_id): raise milestone = Milestone(self.env, None) milestone.name = milestone_id action = 'edit' # rather than 'new' so that it works for POST/save if req.method == 'POST': if req.args.has_key('cancel'): if milestone.exists: req.redirect(req.href.milestone(milestone.name)) else: req.redirect(req.href.roadmap()) elif action == 'edit': return self._do_save(req, milestone) elif action == 'delete': self._do_delete(req, milestone) elif action in ('new', 'edit'): return self._render_editor(req, milestone) elif action == 'delete': return self._render_confirm(req, milestone) if not milestone.name: req.redirect(req.href.roadmap()) return self._render_view(req, milestone)
def process_request(self, req): milestone_id = req.args.get('id') req.perm('milestone', milestone_id).require('MILESTONE_VIEW') add_link(req, 'up', req.href.roadmap(), _('Roadmap')) action = req.args.get('action', 'view') try: milestone = Milestone(self.env, milestone_id) except ResourceNotFound: if 'MILESTONE_CREATE' not in req.perm('milestone', milestone_id): raise milestone = Milestone(self.env, None) milestone.name = milestone_id action = 'edit' # rather than 'new' so that it works for POST/save if req.method == 'POST': if 'cancel' in req.args: if milestone.exists: req.redirect(req.href.milestone(milestone.name)) else: req.redirect(req.href.roadmap()) elif action == 'edit': return self._do_save(req, milestone) elif action == 'delete': self._do_delete(req, milestone) elif action in ('new', 'edit'): return self._render_editor(req, milestone) elif action == 'delete': return self._render_confirm(req, milestone) if not milestone.name: req.redirect(req.href.roadmap()) return self._render_view(req, milestone)
def test_reset_milestone(self): self.env.config.set('ticket', 'workflow', 'ConfigurableTicketWorkflow,TicketWorkflowOpResetMilestone') self._config_set('ticket-workflow', [ ('reset-milestone', '* -> *'), ('reset-milestone.operations', 'reset_milestone'), ]) tktid = self._insert_ticket(when=datetime(2017, 3, 9, tzinfo=utc), summary='reset milestone', milestone='milestone1', reporter='anonymous', owner='joe') ticket = Ticket(self.env, tktid) req = self._post_req('reset-milestone', ticket) self.assertTrue(self.tktmod.match_request(req)) self.assertRaises(RequestDone, self.tktmod.process_request, req) ticket = Ticket(self.env, tktid) self.assertEqual('milestone1', ticket['milestone']) milestone = Milestone(self.env, ticket['milestone']) milestone.completed = datetime(2017, 3, 8, tzinfo=utc) milestone.update() req = self._post_req('reset-milestone', ticket) self.assertTrue(self.tktmod.match_request(req)) self.assertRaises(RequestDone, self.tktmod.process_request, req) ticket = Ticket(self.env, tktid) self.assertEqual('', ticket['milestone']) ticket['milestone'] = 'unknown-milestone' ticket.save_changes(when=datetime(2017, 3, 8, 1, tzinfo=utc)) req = self._post_req('reset-milestone', ticket) self.assertTrue(self.tktmod.match_request(req)) self.assertRaises(RequestDone, self.tktmod.process_request, req) ticket = Ticket(self.env, tktid) self.assertEqual('unknown-milestone', ticket['milestone'])
def test_delete_milestone(self): self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')") milestone = Milestone(self.env, 'Test') milestone.delete() self.assertEqual(False, milestone.exists) self.assertEqual( [], self.env.db_query("SELECT * FROM milestone WHERE name='Test'"))
def test_update_milestone_without_name(self): cursor = self.db.cursor() cursor.execute("INSERT INTO milestone (name) VALUES ('Test')") cursor.close() milestone = Milestone(self.env, 'Test') milestone.name = None self.assertRaises(AssertionError, milestone.update)
def test_update_milestone_without_name(self): cursor = self.db.cursor() cursor.execute("INSERT INTO milestone (name) VALUES ('Test')") cursor.close() milestone = Milestone(self.env, 'Test') milestone.name = None self.assertRaises(TracError, milestone.update)
def test_delete_milestone(self): self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')") milestone = Milestone(self.env, 'Test') milestone.delete() self.assertEqual(False, milestone.exists) self.assertEqual([], self.env.db_query("SELECT * FROM milestone WHERE name='Test'"))
def test_create_milestone(self): milestone = Milestone(self.env) milestone.name = 'Test' milestone.insert() cursor = self.db.cursor() cursor.execute("SELECT name,due,completed,description FROM milestone " "WHERE name='Test'") self.assertEqual(('Test', 0, 0, ''), cursor.fetchone())
def test_delete_milestone(self): cursor = self.db.cursor() cursor.execute("INSERT INTO milestone (name) VALUES ('Test')") cursor.close() milestone = Milestone(self.env, 'Test') milestone.delete() cursor = self.db.cursor() cursor.execute("SELECT * FROM milestone WHERE name='Test'") self.assertEqual(None, cursor.fetchone())
def ticket_changed(self, ticket, comment, author, old_values): old_summary = old_values.get('summary') if ticket['type']==milestone_ticket_type \ and old_summary \ and ticket['summary'] != old_summary: try: milestone = Milestone(self.env, old_summary) if milestone.exists: milestone.name = ticket['summary'] milestone.update() except ResourceNotFound: pass
def milestone_setup(tc): from datetime import datetime from trac.util.datefmt import utc boo = Milestone(tc.env) boo.name = 'boo' boo.completed = boo.due = None boo.insert() roo = Milestone(tc.env) roo.name = 'roo' roo.completed = datetime.now(utc) roo.due = None roo.insert()
def test_delete_milestone_retarget_tickets(self): self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')") tkt1 = Ticket(self.env) tkt1.populate({'summary': 'Foo', 'milestone': 'Test'}) tkt1.insert() tkt2 = Ticket(self.env) tkt2.populate({'summary': 'Bar', 'milestone': 'Test'}) tkt2.insert() milestone = Milestone(self.env, 'Test') milestone.delete(retarget_to='Other') self.assertEqual(False, milestone.exists) self.assertEqual('Other', Ticket(self.env, tkt1.id)['milestone']) self.assertEqual('Other', Ticket(self.env, tkt2.id)['milestone'])
def _go_graph(self, req): #search all artifacts. artifacts = ArtifactManager.find_all(self.env) milestones = [m for m in Milestone.select(self.env) if 'MILESTONE_VIEW' in req.perm(m.resource)] #add artifacts to milestone. for m in milestones: artifacts_of_m = [artifact for artifact in artifacts if artifact.milestone == m.name] setattr(m, 'artifacts', artifacts_of_m) manager = SCMManager(self.env, req) nodes = manager.artifacts_to_nodes(artifacts) roots = manager.get_roots(nodes) gm = GraphManager(self.env) nodes = gm.to_graphnode(roots) gm.to_s(nodes) graph = gm.to_graphviz(nodes, milestones) self.env.log.info('graphviz graph:\n%s' % graph) data = {'milestones':milestones, 'artifacts':artifacts, 'graph':graph} return 'releaseartifactgraph.html', data, None
def _render_editor(self, req, milestone): # Suggest a default due time of 18:00 in the user's timezone now = datetime.now(req.tz) default_due = datetime(now.year, now.month, now.day, 18) if now.hour > 18: default_due += timedelta(days=1) default_due = to_datetime(default_due, req.tz) data = { 'milestone': milestone, 'datetime_hint': get_datetime_format_hint(req.lc_time), 'default_due': default_due, 'milestone_groups': [], } if milestone.exists: req.perm(milestone.resource).require('MILESTONE_MODIFY') milestones = [ m for m in Milestone.select(self.env) if m.name != milestone.name and 'MILESTONE_VIEW' in req.perm(m.resource) ] data['milestone_groups'] = group_milestones( milestones, 'TICKET_ADMIN' in req.perm) else: req.perm(milestone.resource).require('MILESTONE_CREATE') chrome = Chrome(self.env) chrome.add_jquery_ui(req) chrome.add_wiki_toolbars(req) return 'milestone_edit.html', data, None
def test_complete_milestone_retarget_tickets(self): name = 'milestone1' target = 'milestone2' insert_ticket(self.env, summary='Ticket 1', milestone=name) insert_ticket(self.env, summary='Ticket 2', milestone=name) ps = PermissionSystem(self.env) ps.grant_permission('user1', 'TICKET_ADMIN') ps.grant_permission('user1', 'MILESTONE_MODIFY') req = MockRequest(self.env, authname='user1', method='POST', path_info='/admin/ticket/milestones/%s' % name, args=dict(action='edit', save='Submit changes', name=name, description='', retarget='on', target=target, comment='', completed='on', completeddate='May 20, 2020, 9:07:52 PM')) mod = AdminModule(self.env) self.assertTrue(mod.match_request(req)) with self.assertRaises(RequestDone): mod.process_request(req) self.assertEqual(2, len(req.chrome['notices'])) self.assertEqual( 'The open tickets associated with milestone "milestone1" ' 'have been retargeted to milestone "milestone2".', req.chrome['notices'][0]) self.assertEqual('Your changes have been saved.', req.chrome['notices'][1]) self.assertEqual([], req.chrome['warnings']) self.assertEqual(['303 See Other'], req.status_sent) self.assertEqual('http://example.org/trac.cgi/admin/ticket/milestones', req.headers_sent['Location']) self.assertTrue(Milestone(self.env, name).is_completed) self.assertEqual(target, Ticket(self.env, 1)['milestone']) self.assertEqual(target, Ticket(self.env, 2)['milestone'])
def get_ticket_changes(self, req, ticket, action): if action == 'resolve' and \ req.args and 'action_resolve_resolve_resolution' in req.args: old_milestone = ticket._old.get('milestone') or None user_milestone = ticket['milestone'] or None # If there's no user defined milestone, we try to set it # using the defined resolution -> milestone mapping. if old_milestone is None: new_status = req.args['action_resolve_resolve_resolution'] new_milestone = self.__get_new_milestone( ticket, action, new_status) # ... but we don't reset it to None unless it was None if new_milestone is not None or user_milestone is None: try: Milestone(self.env, new_milestone) except ResourceNotFound: add_warning( req, _("Milestone %(name)s does " "not exist.", name=new_milestone)) else: self.log.info('changed milestone from %s to %s', old_milestone, new_milestone) return {'milestone': new_milestone} return {}
def render_ticket_action_control(self, req, ticket, action): actions = ConfigurableTicketWorkflow(self.env).actions label = actions[action]['label'] res_ms = self.__get_resolution_milestone_dict(ticket, action) resolutions = '' milestone = None for i, resolution in enumerate(res_ms): if i > 0: resolutions = "%s, '%s'" % (resolutions, resolution) else: resolutions = "'%s'" % resolution milestone = res_ms[resolution] hint = None if res_ms: try: Milestone(self.env, milestone) except ResourceNotFound: pass else: hint = _( "For resolution %(resolutions)s the milestone will " "be set to '%(milestone)s'.", resolutions=resolutions, milestone=milestone) return label, None, hint
def select(env, include_completed=True, db=None): if not db: db = env.get_db_cnx() milestones = [ StructuredMilestone(env, milestone) \ for milestone in Milestone.select(env, include_completed, db)] return StructuredMilestone.reorganize(milestones)
def _render_editor(self, req, milestone): data = { 'milestone': milestone, 'datetime_hint': get_datetime_format_hint(req.lc_time), 'default_due': self.get_default_due(req), 'milestone_groups': [], } if milestone.exists: req.perm(milestone.resource).require('MILESTONE_MODIFY') milestones = [m for m in Milestone.select(self.env) if m.name != milestone.name and 'MILESTONE_VIEW' in req.perm(m.resource)] data['milestone_groups'] = \ group_milestones(milestones, 'TICKET_ADMIN' in req.perm) data['num_open_tickets'] = \ get_num_tickets_for_milestone(self.env, milestone, exclude_closed=True) data['retarget_to'] = self.default_retarget_to else: req.perm(milestone.resource).require('MILESTONE_CREATE') if milestone.name: add_notice(req, _("Milestone %(name)s does not exist. You " "can create it here.", name=milestone.name)) chrome = Chrome(self.env) chrome.add_jquery_ui(req) chrome.add_wiki_toolbars(req) add_stylesheet(req, 'common/css/roadmap.css') return 'milestone_edit.html', data
def test_update_milestone_update_tickets(self): self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')") tkt1 = Ticket(self.env) tkt1.populate({'summary': 'Foo', 'milestone': 'Test'}) tkt1.insert() tkt2 = Ticket(self.env) tkt2.populate({'summary': 'Bar', 'milestone': 'Test'}) tkt2.insert() milestone = Milestone(self.env, 'Test') milestone.name = 'Testing' milestone.update() self.assertEqual('Testing', Ticket(self.env, tkt1.id)['milestone']) self.assertEqual('Testing', Ticket(self.env, tkt2.id)['milestone'])
def test_new_milestone(self): milestone = Milestone(self.env) self.assertEqual(False, milestone.exists) self.assertEqual(None, milestone.name) self.assertEqual(0, milestone.due) self.assertEqual(0, milestone.completed) self.assertEqual('', milestone.description)
def _render_editor(self, req, milestone): # Suggest a default due time of 18:00 in the user's timezone now = datetime.now(req.tz) default_due = datetime(now.year, now.month, now.day, 18) if now.hour > 18: default_due += timedelta(days=1) default_due = to_datetime(default_due, req.tz) data = { 'milestone': milestone, 'datetime_hint': get_datetime_format_hint(req.lc_time), 'default_due': default_due, 'milestone_groups': [], } if milestone.exists: req.perm(milestone.resource).require('MILESTONE_MODIFY') milestones = [m for m in Milestone.select(self.env) if m.name != milestone.name and 'MILESTONE_VIEW' in req.perm(m.resource)] data['milestone_groups'] = group_milestones(milestones, 'TICKET_ADMIN' in req.perm) else: req.perm(milestone.resource).require('MILESTONE_CREATE') if milestone.name: add_notice(req, _("Milestone %(name)s does not exist. You can" " create it here.", name=milestone.name)) chrome = Chrome(self.env) chrome.add_jquery_ui(req) chrome.add_wiki_toolbars(req) return 'milestone_edit.html', data, None
def _render_editor(self, req, milestone): data = { 'milestone': milestone, 'datetime_hint': get_datetime_format_hint(req.lc_time), 'default_due': self.get_default_due(req), 'milestone_groups': [], } if milestone.exists: req.perm(milestone.resource).require('MILESTONE_MODIFY') milestones = [m for m in Milestone.select(self.env) if m.name != milestone.name and 'MILESTONE_VIEW' in req.perm(m.resource)] data['milestone_groups'] = group_milestones(milestones, 'TICKET_ADMIN' in req.perm) data['num_open_tickets'] = milestone \ .get_num_tickets(exclude_closed=True) data['retarget_to'] = self.default_retarget_to else: req.perm(milestone.resource).require('MILESTONE_CREATE') if milestone.name: add_notice(req, _("Milestone %(name)s does not exist. You can" " create it here.", name=milestone.name)) chrome = Chrome(self.env) chrome.add_jquery_ui(req) chrome.add_wiki_toolbars(req) add_stylesheet(req, 'common/css/roadmap.css') return 'milestone_edit.html', data, None
def test_delete_milestone_retarget_tickets(self): cursor = self.db.cursor() cursor.execute("INSERT INTO milestone (name) VALUES ('Test')") cursor.close() tkt1 = Ticket(self.env) tkt1.populate({'summary': 'Foo', 'milestone': 'Test'}) tkt1.insert() tkt2 = Ticket(self.env) tkt2.populate({'summary': 'Bar', 'milestone': 'Test'}) tkt2.insert() milestone = Milestone(self.env, 'Test') milestone.delete(retarget_to='Other') self.assertEqual('Other', Ticket(self.env, tkt1.id)['milestone']) self.assertEqual('Other', Ticket(self.env, tkt2.id)['milestone'])
def test_rename_milestone_retarget_tickets(self): self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')") tkt1 = self._insert_ticket(status='new', summary='Foo', milestone='Test') tkt2 = self._insert_ticket(status='new', summary='Bar', milestone='Test') self._update_ticket(tkt2, status='closed', resolution='fixed') milestone = Milestone(self.env, 'Test') milestone.name = 'Testing' milestone.update() tkt1 = Ticket(self.env, tkt1.id) tkt2 = Ticket(self.env, tkt2.id) self.assertEqual('Testing', tkt1['milestone']) self.assertEqual('Testing', tkt2['milestone']) self.assertEqual(tkt1['changetime'], tkt2['changetime']) self.assertNotEqual(self.updated_at, tkt1['changetime'])
def default_retarget_to(self): if self._default_retarget_to and \ not any(self._default_retarget_to == m.name for m in Milestone.select(self.env)): self.log.warn('Milestone "%s" does not exist. Update the ' '"default_retarget_to" option in the [milestone] ' 'section of trac.ini', self._default_retarget_to) return self._default_retarget_to
def _reindex_milestone(self, realm, feedback, finish_fb): resources = Milestone.select(self.env) def check(milestone, check): return True index = self.milestone_created return self._index(realm, resources, check, index, feedback, finish_fb)
def _format_link(self, formatter, ns, name, label): name, query, fragment = formatter.split_link(name) href = formatter.href.mdashboard(name) + query + fragment try: milestone = Milestone(self.env, name, formatter.db) except TracError: milestone = Milestone(self.env) # Note: this should really not be needed, exists should simply be false # if the milestone doesn't exist in the db if milestone.exists: closed = milestone.completed and 'closed ' or '' return tag.a(label, class_='%smilestone' % closed, href=href) else: return tag.a(label, class_='missing milestone', href=href, rel="nofollow")
def _reindex_milestone(self, realm, feedback, finish_fb): resources = Milestone.select(self.env) def check(milestone, check): return True index = self._index_milestone return self._index(realm, resources, check, index, feedback, finish_fb)
def testBacklogForMultipleSprint(self): """Tests a Backlog associated to a Sprint with multiple sprints""" # Creates a Milestone m = Milestone(self.env) m.name = "Milestone 1" m.insert() # Create 2 Sprints sprint1 = self.teh.create_sprint( name="Sprint 1", start=to_datetime(t=None), duration=20, milestone=m.name) sprint2 = self.teh.create_sprint( name="Sprint 2", start=to_datetime(t=None), duration=20, milestone=m.name) # Create some tickets s1 = self.teh.create_ticket(Type.USER_STORY, props={Key.STORY_POINTS: '3', Key.SPRINT: sprint1.name}) self.assert_true(s1.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '4', Key.SPRINT: sprint1.name}))) self.assert_true(s1.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '8', Key.SPRINT: sprint1.name}))) self.assert_true(s1.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '4'}))) s2 = self.teh.create_ticket(Type.USER_STORY, props={Key.STORY_POINTS: '5', Key.SPRINT: sprint2.name}) self.assert_true(s2.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '2', Key.SPRINT: sprint2.name}))) self.assert_true(s2.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '3'}))) # Creates the Backlog bound to the Sprint backlog = BacklogConfiguration(self.env, name="Sprint-Backlog", type=BacklogType.SPRINT) backlog.ticket_types = [Type.USER_STORY, Type.TASK] backlog.save() # The Backlog should contains only the items planned for the Sprint, and with parents # planned for the Sprint too backlog1 = self.bmm.get(name="Sprint-Backlog", scope=sprint1.name) self.assert_length(3, backlog1) backlog2 = self.bmm.get(name="Sprint-Backlog", scope=sprint2.name) self.assert_length(2, backlog2)
def test_get_ticket_fields_milestone_rename(self): """Cached ticket fields are updated when milestone is renamed.""" fields = self.ticket_system.get_ticket_fields() milestone_field = self._get_ticket_field('milestone') m2 = Milestone(self.env, 'milestone2') m2.name = 'milestone5' m2.update() updated_fields = self.ticket_system.get_ticket_fields() updated_milestone_field = self._get_ticket_field('milestone') self.assertNotEqual(fields, updated_fields) self.assertEqual(['milestone1', 'milestone2', 'milestone3', 'milestone4'], milestone_field['options']) self.assertEqual(['milestone1', 'milestone3', 'milestone4', 'milestone5'], updated_milestone_field['options'])
def task(add): """the thread task - either we are discovering or adding events""" with lock: env = ProductEnvironment(self.global_env, self.default_product) if add: name = 'milestone_from_' + threading.current_thread().name milestone = Milestone(env) milestone.name = name milestone.insert() else: # collect the names of milestones reported by Milestone and # directly from the db - as sets to ease comparison later results.append({ 'from_t': set([m.name for m in Milestone.select(env)]), 'from_db': set( [v[0] for v in self.env.db_query( "SELECT name FROM milestone")])})
def test_existing_milestone(self): self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')") milestone = Milestone(self.env, 'Test') self.assertTrue(milestone.exists) self.assertEqual('Test', milestone.name) self.assertIsNone(milestone.due) self.assertIsNone(milestone.completed) self.assertEqual('', milestone.description)
def test_update_milestone_update_tickets(self): cursor = self.db.cursor() cursor.execute("INSERT INTO milestone (name) VALUES ('Test')") cursor.close() tkt1 = Ticket(self.env) tkt1.populate({'summary': 'Foo', 'milestone': 'Test'}) tkt1.insert() tkt2 = Ticket(self.env) tkt2.populate({'summary': 'Bar', 'milestone': 'Test'}) tkt2.insert() milestone = Milestone(self.env, 'Test') milestone.name = 'Testing' milestone.update() self.assertEqual('Testing', Ticket(self.env, tkt1.id)['milestone']) self.assertEqual('Testing', Ticket(self.env, tkt2.id)['milestone'])
def test_move_tickets(self): self.env.db_transaction.executemany( "INSERT INTO milestone (name) VALUES (%s)", [('Test',), ('Testing',)]) tkt1 = self._insert_ticket(status='new', summary='Foo', milestone='Test') tkt2 = self._insert_ticket(status='new', summary='Bar', milestone='Test') self._update_ticket(tkt2, status='closed', resolution='fixed') milestone = Milestone(self.env, 'Test') milestone.move_tickets('Testing', 'anonymous', 'Move tickets') tkt1 = Ticket(self.env, tkt1.id) tkt2 = Ticket(self.env, tkt2.id) self.assertEqual('Testing', tkt1['milestone']) self.assertEqual('Testing', tkt2['milestone']) self.assertEqual(tkt1['changetime'], tkt2['changetime']) self.assertNotEqual(self.updated_at, tkt1['changetime'])
def test_delete_milestone_retarget_tickets(self): cursor = self.db.cursor() cursor.execute("INSERT INTO milestone (name) VALUES ('Test')") cursor.close() tkt1 = Ticket(self.env) tkt1.populate({"summary": "Foo", "milestone": "Test"}) tkt1.insert() tkt2 = Ticket(self.env) tkt2.populate({"summary": "Bar", "milestone": "Test"}) tkt2.insert() milestone = Milestone(self.env, "Test") milestone.delete(retarget_to="Other") self.assertEqual(False, milestone.exists) self.assertEqual("Other", Ticket(self.env, tkt1.id)["milestone"]) self.assertEqual("Other", Ticket(self.env, tkt2.id)["milestone"])
def test_select_milestones(self): self.env.db_transaction.executemany( "INSERT INTO milestone (name) VALUES (%s)", [('1.0', ), ('2.0', )]) milestones = list(Milestone.select(self.env)) self.assertEqual('1.0', milestones[0].name) assert milestones[0].exists self.assertEqual('2.0', milestones[1].name) assert milestones[1].exists
def test_update_milestone_update_tickets(self): cursor = self.db.cursor() cursor.execute("INSERT INTO milestone (name) VALUES ('Test')") cursor.close() tkt1 = Ticket(self.env) tkt1.populate({"summary": "Foo", "milestone": "Test"}) tkt1.insert() tkt2 = Ticket(self.env) tkt2.populate({"summary": "Bar", "milestone": "Test"}) tkt2.insert() milestone = Milestone(self.env, "Test") milestone.name = "Testing" milestone.update() self.assertEqual("Testing", Ticket(self.env, tkt1.id)["milestone"]) self.assertEqual("Testing", Ticket(self.env, tkt2.id)["milestone"])
def _modify_resource_breadcrumb(self, req, template, data, content_type, is_active): """Provides logic for breadcrumb resource permissions """ if data and ('ticket' in data.keys()) and data['ticket'].exists: data['resourcepath_template'] = 'bh_path_ticket.html' # determine path permissions for resname, permname in [('milestone', 'MILESTONE_VIEW'), ('product', 'PRODUCT_VIEW')]: res = Resource(resname, data['ticket'][resname]) data['path_show_' + resname] = permname in req.perm(res) # add milestone list + current milestone to the breadcrumb data['milestone_list'] = [m.name for m in Milestone.select(self.env)] mname = data['ticket']['milestone'] if mname: data['milestone'] = Milestone(self.env, mname)
def _modify_roadmap_page(self, req, template, data, content_type, is_active): """Insert roadmap.css + products breadcrumb """ add_stylesheet(req, 'dashboard/css/roadmap.css') self._add_products_general_breadcrumb(req, template, data, content_type, is_active) data['milestone_list'] = [m.name for m in Milestone.select(self.env)] req.chrome['ctxtnav'] = []
def test_select_milestones(self): cursor = self.db.cursor() cursor.executemany("INSERT INTO milestone (name) VALUES (%s)", [("1.0",), ("2.0",)]) cursor.close() milestones = list(Milestone.select(self.env)) self.assertEqual("1.0", milestones[0].name) assert milestones[0].exists self.assertEqual("2.0", milestones[1].name) assert milestones[1].exists
def test_delete_milestone(self): self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')") tkt1 = self._insert_ticket(status='new', summary='Foo', milestone='Test') tkt2 = self._insert_ticket(status='new', summary='Bar', milestone='Test') self._update_ticket(tkt2, status='closed', resolution='fixed') milestone = Milestone(self.env, 'Test') milestone.delete() self.assertFalse(milestone.exists) self.assertEqual([], self.env.db_query("SELECT * FROM milestone WHERE name='Test'")) tkt1 = Ticket(self.env, tkt1.id) tkt2 = Ticket(self.env, tkt2.id) self.assertEqual('', tkt1['milestone']) self.assertEqual('', tkt2['milestone']) self.assertEqual(tkt1['changetime'], tkt2['changetime']) self.assertNotEqual(self.updated_at, tkt1['changetime'])
def test_select_milestones(self): self.env.db_transaction.executemany( "INSERT INTO milestone (name) VALUES (%s)", [('1.0',), ('2.0',)]) milestones = list(Milestone.select(self.env)) self.assertEqual('1.0', milestones[0].name) assert milestones[0].exists self.assertEqual('2.0', milestones[1].name) assert milestones[1].exists
def test_delete_milestone_retarget_tickets(self): self.env.db_transaction.executemany( "INSERT INTO milestone (name) VALUES (%s)", [('Test',), ('Other',)]) tkt1 = self._insert_ticket(status='new', summary='Foo', milestone='Test') tkt2 = self._insert_ticket(status='new', summary='Bar', milestone='Test') self._update_ticket(tkt2, status='closed', resolution='fixed') milestone = Milestone(self.env, 'Test') milestone.delete(retarget_to='Other') self.assertFalse(milestone.exists) tkt1 = Ticket(self.env, tkt1.id) tkt2 = Ticket(self.env, tkt2.id) self.assertEqual('Other', tkt1['milestone']) self.assertEqual('Other', tkt2['milestone']) self.assertEqual(tkt1['changetime'], tkt2['changetime']) self.assertNotEqual(self.updated_at, tkt1['changetime'])
def test_get_ticket_fields_milestone_update_due(self): """Cached ticket fields are updated when milestone due date is changed. """ fields = self.ticket_system.get_ticket_fields() milestone_field = self._get_ticket_field('milestone') m2 = Milestone(self.env, 'milestone2') m2.due = datetime.now(utc) m2.update() updated_fields = self.ticket_system.get_ticket_fields() updated_milestone_field = self._get_ticket_field('milestone') self.assertNotEqual(fields, updated_fields) self.assertEqual(['milestone1', 'milestone2', 'milestone3', 'milestone4'], milestone_field['options']) self.assertEqual(['milestone2', 'milestone1', 'milestone3', 'milestone4'], updated_milestone_field['options'])
def list_view(self, req, cat, page): data = { 'view': 'list', 'sprints': self.sm.select(), 'format_datetime' : datefmt.format_datetime, 'date_hint' : datefmt.get_date_format_hint(), 'datetime_hint' : datefmt.get_datetime_format_hint(), 'milestones' : [m.name for m in Milestone.select(self.env)], } data.update(req.args) return 'agilo_admin_sprint.html', data
def _render_confirm(self, req, milestone): req.perm(milestone.resource).require('MILESTONE_DELETE') milestones = [m for m in Milestone.select(self.env) if m.name != milestone.name and 'MILESTONE_VIEW' in req.perm(m.resource)] data = { 'milestone': milestone, 'milestone_groups': group_milestones(milestones, 'TICKET_ADMIN' in req.perm) } return 'milestone_delete.html', data, None