def test_can_serialize_task_to_dict(self): task = AgiloTicket(self.env, t_type=Type.TASK) self.assertNotEqual('fixed', task[Key.RESOLUTION]) task[Key.SUMMARY] = 'My Summary' task.insert() expected = { # required Key.ID: task.id, Key.TYPE: Type.TASK, Key.SUMMARY: 'My Summary', Key.DESCRIPTION: '', Key.STATUS: '', Key.RESOLUTION: '', Key.REPORTER: '', Key.OWNER: '', # type specific Key.SPRINT: '', Key.REMAINING_TIME: '', Key.RESOURCES: '', # Key.Options is not used in order to reduce required data to # transfer for a backlog load. 'outgoing_links': [], 'incoming_links': [], 'time_of_last_change': to_timestamp(task.time_changed), 'ts': str(task.time_changed), } if AgiloTicketSystem.is_trac_1_0(): from trac.util.datefmt import to_utimestamp expected.update( {'view_time': str(to_utimestamp(task.time_changed))}) self.assert_equals(expected, task.as_dict())
def test_always_serialize_id_as_int(self): task = AgiloTicket(self.env, t_type=Type.TASK) task.insert() task_id = task.id task = AgiloTicket(self.env, str(task_id)) self.assert_equals(task_id, task.as_dict()['id'])
def test_can_serialize_calculated_fields(self): story = AgiloTicket(self.env, t_type=Type.USER_STORY) task = AgiloTicket(self.env, t_type=Type.TASK) task[Key.REMAINING_TIME] = '5' story.link_to(task) story.insert() self.assert_equals(5, story.as_dict()[Key.TOTAL_REMAINING_TIME])
def test_can_serialize_task_to_dict(self): task = AgiloTicket(self.env, t_type=Type.TASK) self.assertNotEqual('fixed', task[Key.RESOLUTION]) task[Key.SUMMARY] = 'My Summary' task.insert() expected = { # required Key.ID: task.id, Key.TYPE: Type.TASK, Key.SUMMARY: 'My Summary', Key.DESCRIPTION: '', Key.STATUS: '', Key.RESOLUTION: '', Key.REPORTER: '', Key.OWNER: '', # type specific Key.SPRINT: '', Key.REMAINING_TIME: '', Key.RESOURCES: '', # Key.Options is not used in order to reduce required data to # transfer for a backlog load. 'outgoing_links': [], 'incoming_links': [], 'time_of_last_change': to_timestamp(task.time_changed), 'ts': str(task.time_changed), } if AgiloTicketSystem.is_trac_1_0(): from trac.util.datefmt import to_utimestamp expected.update({'view_time': str(to_utimestamp(task.time_changed))}) self.assert_equals(expected, task.as_dict())
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_can_serialize_links(self): task = AgiloTicket(self.env, t_type=Type.TASK) task.insert() story = AgiloTicket(self.env, t_type=Type.USER_STORY) story.link_to(task) story.insert() self.assert_equals([task.id], story.as_dict()['outgoing_links']) self.assert_equals([story.id], task.as_dict()['incoming_links'])
def testCreateNewLinkedTicket(self): """Test the creation of a new linked ticket""" # Get db and handle the transaction db = self.teh.get_env().get_db_cnx() new = AgiloTicket(self.teh.get_env()) new[Key.SUMMARY] = 'This is a new ticket, never saved' new[Key.DESCRIPTION] = 'This will be created and linked in one shot ;-)' new[Key.TYPE] = Type.TASK self.assert_true(new.link_from(self.t1, db)) self.assert_not_none(new.insert(db=db)) # Now commit the link and the insert db.commit() # Check that has been linked self.assert_true(new.is_linked_from(self.t1)) self.assert_true(self.t1.is_linked_to(new)) # Now test the autoinsert and link of the agilo ticket new2 = AgiloTicket(self.teh.get_env(), t_type=Type.TASK) new2[Key.SUMMARY] = "This is a linked new ticket" new2[Key.DESCRIPTION] = "description" self.assert_true(self.t1.link_to(new2)) self.assert_true(new2.is_linked_from(self.t1)) self.assert_true(self.t1.is_linked_to(new2)) # Now test the link failure self.assert_false(new2.link_from(self.t1))
def test_can_set_basic_properties_before_creating_agilo_ticket(self): ticket = AgiloTicket(self.env) ticket[Key.TYPE] = "story" ticket[Key.SUMMARY] = "This is an AgiloTicket" ticket[Key.DESCRIPTION] = "This is the description of the ticket..." ticket_id = ticket.insert() story = AgiloTicket(self.env, ticket_id) for attribute_name in (Key.TYPE, Key.SUMMARY, Key.DESCRIPTION): self.assert_equals(ticket[attribute_name], story[attribute_name])
def test_saving_of_custom_properties_works_on_model(self): """Tests that the custom properties are saved on insert""" us = AgiloTicket(self.env) us[Key.TYPE] = Type.USER_STORY us[Key.SUMMARY] = "This is a story with 5 points" us[Key.DESCRIPTION] = "As a user..." # Now a custom property us[Key.STORY_POINTS] = '5' us_id = us.insert() # Now reload the story same_us = AgiloTicket(self.env, tkt_id=us_id) self.assert_equals(Type.USER_STORY, same_us[Key.TYPE]) self.assert_equals('5', same_us[Key.STORY_POINTS])
def test_correct_handling_of_ticket_types(self): story = AgiloTicket(self.env, t_type=Type.USER_STORY) story[Key.SUMMARY] = "This is a story..." story[Key.DESCRIPTION] = "A very nice one..." self.assert_true(self._matching_properties(story)) story.insert() self.assert_true(self._matching_properties(story)) # Not existing type should show all the properties nonex = AgiloTicket(self.env, t_type="nonex") nonex[Key.SUMMARY] = "This is a story..." nonex[Key.DESCRIPTION] = "A very nice one..." nonex.insert() self.assert_true(self._matching_properties(nonex)) # Setting type on the fly should work task = AgiloTicket(self.env, t_type=Type.TASK) task[Key.SUMMARY] = "This should be a task" self.assert_true(self._matching_properties(task)) task.insert() self.assert_true(self._matching_properties(task))
def test_do_not_stringify_none_for_ticket_properties(self): task = AgiloTicket(self.env, t_type=Type.TASK) task[Key.REMAINING_TIME] = None task.insert() task[Key.REMAINING_TIME] = 3 self.assert_none(task._old[Key.REMAINING_TIME])