def testDeleteBacklogFromManager(self):
     """Test the deletion of a Backlog using the model manager"""
     model_manager = BacklogModelManager(self.env)
     backlog = model_manager.create(name='TestDeleteBacklog')
     self.assert_not_none(backlog)
     self.assert_true(backlog.exists)
     self.assert_equals('global', backlog.scope)
     # now delete it
     model_manager.delete(backlog)
     self.assert_raises(BacklogTypeError, model_manager.get, name='TestDeleteBacklog')
 def testGetModelFromManager(self):
     """Tests the get model from the manager"""
     backlog = self.teh.create_backlog('TestModelBacklog')
     self.assert_true(backlog.exists)
     # Now try to get it with the Model Manager
     model_manager = BacklogModelManager(self.env)
     same_backlog = model_manager.get(name='TestModelBacklog')
     self.assert_equals(backlog.name, same_backlog.name)
     self.assert_equals(len(backlog), len(same_backlog))
     # Now check the object identity
     self.assert_equals(id(backlog), id(same_backlog))
 def testGetModelFromManager(self):
     """Tests the get model from the manager"""
     backlog = self.teh.create_backlog('TestModelBacklog')
     self.assert_true(backlog.exists)
     # Now try to get it with the Model Manager
     model_manager = BacklogModelManager(self.env)
     same_backlog = model_manager.get(name='TestModelBacklog')
     self.assert_equals(backlog.name, same_backlog.name)
     self.assert_equals(len(backlog), len(same_backlog))
     # Now check the object identity
     self.assert_equals(id(backlog), id(same_backlog))
 def testDeleteBacklogFromManager(self):
     """Test the deletion of a Backlog using the model manager"""
     model_manager = BacklogModelManager(self.env)
     backlog = model_manager.create(name='TestDeleteBacklog')
     self.assert_not_none(backlog)
     self.assert_true(backlog.exists)
     self.assert_equals('global', backlog.scope)
     # now delete it
     model_manager.delete(backlog)
     self.assert_raises(BacklogTypeError,
                        model_manager.get,
                        name='TestDeleteBacklog')
Example #5
0
    def setUp(self):
        self.super()
        self.r1 = self.teh.create_ticket(Type.REQUIREMENT)
        self.r2 = self.teh.create_ticket(Type.REQUIREMENT)
        self.us1 = self.teh.create_ticket(Type.USER_STORY)
        self.us2 = self.teh.create_ticket(Type.USER_STORY)
        self.us3 = self.teh.create_ticket(Type.USER_STORY)
        self.t1 = self.teh.create_ticket(Type.TASK)
        self.t2 = self.teh.create_ticket(Type.TASK)
        self.r1.link_to(self.us1)
        self.r2.link_to(self.us2)
        self.r2.link_to(self.us3)
        self.tickets = [
            self.r1, self.r2, self.us1, self.us2, self.us3, self.t1, self.t2
        ]
        # The tickets should have no milestone nor story set :-)
        for t in self.tickets:
            self.assert_equals('', t[Key.MILESTONE])

        # Now create a Backlog item for each and reload it, we need a backlog
        self.pb = Backlog(self.env, Key.PRODUCT_BACKLOG)
        self.assert_not_none(self.pb, "Product Backlog not loaded...")
        self.assert_not_equals(0, len(self.pb.config.ticket_types))
        self.assert_equals(Key.PRODUCT_BACKLOG, self.pb.name,
                           "Backlog name not matching... %s" % self.pb.name)
        self.assert_equals(5, len(self.pb))
        self.milestone = self.teh.create_milestone("BacklogMilestone")
        self.sprint = self.teh.create_sprint("BacklogTestSprint",
                                             milestone="BacklogMilestone")
        self.sb = Backlog(self.env, Key.SPRINT_BACKLOG, scope=self.sprint.name)
        self.assert_equals(0, len(self.sb))
        self.assert_not_none(self.sb, "Sprint Backlog not loaded...")
        self.assert_not_equals(0, len(self.sb.config.ticket_types))
        # a BacklogItemModelManager
        self.bimm = BacklogModelManager.BacklogItemModelManager(self.env)
Example #6
0
class TestReleaseBacklog(AgiloTestCase):
    """Tests the Release Backlog"""
    def setUp(self):
        self.super()
        self.bmm = BacklogModelManager(self.env)

    def test_backlog_shows_right_tickets(self):
        """Tests the Release Backlog shows the Requirements belonging to a 
        specific Milestone"""
        sprint = self.teh.create_sprint("Release Sprint")
        release_backlog = BacklogConfiguration(self.env,
                                               name="Release Backlog",
                                               type=BacklogType.MILESTONE)
        release_backlog.ticket_types = [Type.REQUIREMENT, Type.USER_STORY]
        release_backlog.save()
        req = self.teh.create_ticket(Type.REQUIREMENT,
                                     props={Key.MILESTONE: sprint.milestone})
        # load the real backlog
        release_backlog = self.bmm.get(name="Release Backlog",
                                       scope=sprint.milestone)
        self.assert_contains(req, release_backlog)
        self.assert_length(1, release_backlog)
        # Now add 2 stories to the requirement, one planned for the sprint one
        # not, only the one assigned to the sprint should appear in the backlog
        us1 = self.teh.create_ticket(Type.USER_STORY,
                                     props={Key.SPRINT: sprint.name})
        us2 = self.teh.create_ticket(Type.USER_STORY)
        self.assert_true(us1 in release_backlog)
        self.assert_not_contains(us2, release_backlog)
        self.assert_length(1 + 1, release_backlog)
Example #7
0
class TestReleaseBacklog(AgiloTestCase):
    """Tests the Release Backlog"""
    
    def setUp(self):
        self.super()
        self.bmm = BacklogModelManager(self.env)
    
    def test_backlog_shows_right_tickets(self):
        """Tests the Release Backlog shows the Requirements belonging to a 
        specific Milestone"""
        sprint = self.teh.create_sprint("Release Sprint")
        release_backlog = BacklogConfiguration(self.env, name="Release Backlog", type=BacklogType.MILESTONE)
        release_backlog.ticket_types = [Type.REQUIREMENT, Type.USER_STORY]
        release_backlog.save()
        req = self.teh.create_ticket(Type.REQUIREMENT, props={Key.MILESTONE: sprint.milestone})
        # load the real backlog
        release_backlog = self.bmm.get(name="Release Backlog", scope=sprint.milestone)
        self.assert_contains(req, release_backlog)
        self.assert_length(1, release_backlog)
        # Now add 2 stories to the requirement, one planned for the sprint one
        # not, only the one assigned to the sprint should appear in the backlog
        us1 = self.teh.create_ticket(Type.USER_STORY, props={Key.SPRINT: sprint.name})
        us2 = self.teh.create_ticket(Type.USER_STORY)
        self.assert_true(us1 in release_backlog)
        self.assert_not_contains(us2, release_backlog)
        self.assert_length(1 + 1, release_backlog)
 def testCreateModelFromManager(self):
     """Tests the creation of a new model using the Manager"""
     params = {'name': 'TestCreateBacklog'}
     model_manager = BacklogModelManager(self.env)
     backlog = model_manager.create(**params)
     self.assert_not_none(backlog)
     self.assert_true(backlog.exists)
     self.assert_equals('global', backlog.scope)
     # Now let's add a scope
     sprint = self.teh.create_sprint('ScopeSprint')
     params['name'] = 'AnotherBacklog'
     params['type'] = BacklogType.SPRINT
     params['scope'] = sprint.name
     sprint_backlog = model_manager.create(**params)
     self.assert_not_none(sprint_backlog)
     self.assert_true(sprint_backlog.exists)
     self.assert_equals(sprint.name, sprint_backlog.scope)
     self.assert_equals(BacklogType.SPRINT, sprint_backlog.config.type)
     # now trying to create a backlog twice should return None
     self.assert_none(model_manager.create(**params))
 def testCreateModelFromManager(self):
     """Tests the creation of a new model using the Manager"""
     params = {'name': 'TestCreateBacklog'}
     model_manager = BacklogModelManager(self.env)
     backlog = model_manager.create(**params)
     self.assert_not_none(backlog)
     self.assert_true(backlog.exists)
     self.assert_equals('global', backlog.scope)
     # Now let's add a scope
     sprint = self.teh.create_sprint('ScopeSprint')
     params['name'] = 'AnotherBacklog'
     params['type'] = BacklogType.SPRINT
     params['scope'] = sprint.name
     sprint_backlog = model_manager.create(**params)
     self.assert_not_none(sprint_backlog)
     self.assert_true(sprint_backlog.exists)
     self.assert_equals(sprint.name, sprint_backlog.scope)
     self.assert_equals(BacklogType.SPRINT, sprint_backlog.config.type)
     # now trying to create a backlog twice should return None
     self.assert_none(model_manager.create(**params))
    def testSelectBacklogFromManager(self):
        """Tests the select from the manager, with the order_by parameter"""
        model_manager = BacklogModelManager(self.env)
        letters = ['A', 'B', 'C']
        for letter in letters:
            backlog = model_manager.create(name='Test%sBacklog' % letter)
            self.assert_not_none(backlog)
            self.assert_true(backlog.exists)
            self.assert_equals('global', backlog.scope)
        # now select and verify that the default order is by name
        backlogs = model_manager.select()
        r_letters = [l for l in reversed(letters)]
        for backlog in backlogs:
            if backlog.name.startswith('Test'):
                letter = r_letters.pop()
                self.assert_equals('Test%sBacklog' % letter, backlog.name)

        # now sort descending by name
        backlogs = model_manager.select(order_by=['-name'])
        for backlog in backlogs:
            if backlog.name.startswith('Test'):
                letter = letters.pop()
                self.assert_equals('Test%sBacklog' % letter, backlog.name)
 def testSelectBacklogFromManager(self):
     """Tests the select from the manager, with the order_by parameter"""
     model_manager = BacklogModelManager(self.env)
     letters = ['A', 'B', 'C']
     for letter in letters:
         backlog = model_manager.create(name='Test%sBacklog' % letter)
         self.assert_not_none(backlog)
         self.assert_true(backlog.exists)
         self.assert_equals('global', backlog.scope)
     # now select and verify that the default order is by name
     backlogs = model_manager.select()
     r_letters = [l for l in reversed(letters)]
     for backlog in backlogs:
         if backlog.name.startswith('Test'):
             letter = r_letters.pop()
             self.assert_equals('Test%sBacklog' % letter, backlog.name)
     
     # now sort descending by name
     backlogs = model_manager.select(order_by=['-name'])
     for backlog in backlogs:
         if backlog.name.startswith('Test'):
             letter = letters.pop()
             self.assert_equals('Test%sBacklog' % letter, backlog.name)
Example #12
0
 def __init__(self):
     """Create a reference to the Model Manager"""
     self.manager = BacklogModelManager(self.env)
 def _invalidate_backlog_cache(self):
     BacklogModelManager(self.env).get_cache().invalidate()
Example #14
0
 def setUp(self):
     self.super()
     self.bmm = BacklogModelManager(self.env)
Example #15
0
class TestSprintBacklog(AgiloTestCase):
    """Specific tests for the Sprint Backlog"""

    def setUp(self):
        self.super()
        self.bmm = BacklogModelManager(self.env)
    
    def test_tickets_from_other_sprint_not_appearing(self):
        """
        Tests that tasks created for other sprints are not appearing in the
        sprint backlog, see bug #345
        (https://dev.agile42.com/ticket/345)
        """
        s = self.teh.create_sprint("Test")
        sb = self.teh.create_backlog("Sprint Backlog", 
                                     num_of_items=100,
                                     ticket_types=[Type.USER_STORY, Type.TASK],
                                     b_type=BacklogType.SPRINT, 
                                     scope=s.name)
        self.assert_length(100, sb)
        # get a ticket from the backlog and check that it is planned for the sprint
        self.assert_equals(s.name, sb[10][Key.SPRINT])
        # Now add an extra ticket
        task = self.teh.create_ticket(Type.TASK, props={Key.SPRINT: s.name,
                                                        Key.REMAINING_TIME: '2'})
        self.assert_length(101, sb)
        self.assert_contains(task, sb)
        # Now remove the ticket explicitly and check if the sprint field is set
        # to None
        self.teh.move_changetime_to_the_past([task])
        sb.remove(task)
        self.assert_not_contains(task, sb)
        # reload task and backlog, the remove should have saved the task
        task = self.teh.load_ticket(task)
        self.assert_not_contains(task, sb)
        self.assert_equals('', task[Key.SPRINT])
        # Now move the ticket to another sprint
        s2 = self.teh.create_sprint("Another Sprint")
        task[Key.SPRINT] = s2.name
        task.save_changes('tester', 'Moved to sprint %s' % s2.name, 
                          when=now() + timedelta(seconds=1))
        self.assert_equals(s2.name, task[Key.SPRINT])
        # Now should not be in the backlog anymore
        self.assert_not_contains(task, sb)
        # Now change sprint again, twice
        task[Key.SPRINT] = s.name
        task.save_changes('tester', 'Moved to sprint %s' % s.name, 
                          when=now() + timedelta(seconds=2))
        self.assert_contains(task, sb)
        # again
        task[Key.SPRINT] = s2.name
        task.save_changes('tester', 'Moved to sprint %s' % s2.name, 
                          when=now() + timedelta(seconds=3))
        self.assert_equals(s2.name, task[Key.SPRINT])
        # Now should not be in the backlog anymore
        self.assert_not_contains(task, sb)
    
    def test_referenced_requirements_are_displayed_in_the_sprint_backlog(self):
        """Test that referenced requirements are shown in the sprint backlog 
        even if they are planned for a milestone."""
        milestone = self.teh.create_milestone('1.0')
        sprint = self.teh.create_sprint("First Sprint")
        backlog_name = 'My Backlog'
        my_backlog = BacklogConfiguration(self.env, name=backlog_name, type=BacklogType.SPRINT)
        my_backlog.ticket_types=[Type.USER_STORY, Type.TASK, Type.REQUIREMENT]
        my_backlog.save()
        req = self.teh.create_ticket(Type.REQUIREMENT, {Key.SUMMARY: 'Requirement', Key.MILESTONE: milestone.name})
        story = self.teh.create_ticket(Type.USER_STORY, {Key.SUMMARY: 'Story', Key.SPRINT: sprint.name})
        req.link_to(story)
        
        backlog = self.bmm.get(name=backlog_name, scope=sprint.name)
        self.assert_length(2, backlog)
Example #16
0
 def setUp(self):
     self.super()
     self.bmm = BacklogModelManager(self.env)
     # Creates and It's me backlog
     its_me = self.teh.create_sprint("It's me")
     self.assert_true(its_me.exists)
Example #17
0
 def setUp(self):
     self.super()
     self.bmm = BacklogModelManager(self.env)
Example #18
0
class TestSprintBacklog(AgiloTestCase):
    """Specific tests for the Sprint Backlog"""
    def setUp(self):
        self.super()
        self.bmm = BacklogModelManager(self.env)

    def test_tickets_from_other_sprint_not_appearing(self):
        """
        Tests that tasks created for other sprints are not appearing in the
        sprint backlog, see bug #345
        (https://dev.agile42.com/ticket/345)
        """
        s = self.teh.create_sprint("Test")
        sb = self.teh.create_backlog("Sprint Backlog",
                                     num_of_items=100,
                                     ticket_types=[Type.USER_STORY, Type.TASK],
                                     b_type=BacklogType.SPRINT,
                                     scope=s.name)
        self.assert_length(100, sb)
        # get a ticket from the backlog and check that it is planned for the sprint
        self.assert_equals(s.name, sb[10][Key.SPRINT])
        # Now add an extra ticket
        task = self.teh.create_ticket(Type.TASK,
                                      props={
                                          Key.SPRINT: s.name,
                                          Key.REMAINING_TIME: '2'
                                      })
        self.assert_length(101, sb)
        self.assert_contains(task, sb)
        # Now remove the ticket explicitly and check if the sprint field is set
        # to None
        self.teh.move_changetime_to_the_past([task])
        sb.remove(task)
        self.assert_not_contains(task, sb)
        # reload task and backlog, the remove should have saved the task
        task = self.teh.load_ticket(task)
        self.assert_not_contains(task, sb)
        self.assert_equals('', task[Key.SPRINT])
        # Now move the ticket to another sprint
        s2 = self.teh.create_sprint("Another Sprint")
        task[Key.SPRINT] = s2.name
        task.save_changes('tester',
                          'Moved to sprint %s' % s2.name,
                          when=now() + timedelta(seconds=1))
        self.assert_equals(s2.name, task[Key.SPRINT])
        # Now should not be in the backlog anymore
        self.assert_not_contains(task, sb)
        # Now change sprint again, twice
        task[Key.SPRINT] = s.name
        task.save_changes('tester',
                          'Moved to sprint %s' % s.name,
                          when=now() + timedelta(seconds=2))
        self.assert_contains(task, sb)
        # again
        task[Key.SPRINT] = s2.name
        task.save_changes('tester',
                          'Moved to sprint %s' % s2.name,
                          when=now() + timedelta(seconds=3))
        self.assert_equals(s2.name, task[Key.SPRINT])
        # Now should not be in the backlog anymore
        self.assert_not_contains(task, sb)

    def test_referenced_requirements_are_displayed_in_the_sprint_backlog(self):
        """Test that referenced requirements are shown in the sprint backlog 
        even if they are planned for a milestone."""
        milestone = self.teh.create_milestone('1.0')
        sprint = self.teh.create_sprint("First Sprint")
        backlog_name = 'My Backlog'
        my_backlog = BacklogConfiguration(self.env,
                                          name=backlog_name,
                                          type=BacklogType.SPRINT)
        my_backlog.ticket_types = [
            Type.USER_STORY, Type.TASK, Type.REQUIREMENT
        ]
        my_backlog.save()
        req = self.teh.create_ticket(Type.REQUIREMENT, {
            Key.SUMMARY: 'Requirement',
            Key.MILESTONE: milestone.name
        })
        story = self.teh.create_ticket(Type.USER_STORY, {
            Key.SUMMARY: 'Story',
            Key.SPRINT: sprint.name
        })
        req.link_to(story)

        backlog = self.bmm.get(name=backlog_name, scope=sprint.name)
        self.assert_length(2, backlog)
Example #19
0
 def setUp(self):
     self.super()
     self.bmm = BacklogModelManager(self.env)
     # Creates and It's me backlog
     its_me = self.teh.create_sprint("It's me")
     self.assert_true(its_me.exists)
Example #20
0
class TestBacklog(AgiloTestCase):
    """Tests for the Backlog class"""
    def setUp(self):
        self.super()
        self.bmm = BacklogModelManager(self.env)
        # Creates and It's me backlog
        its_me = self.teh.create_sprint("It's me")
        self.assert_true(its_me.exists)

    def _create_sprint_backlog(self):
        """Creates stories and tasks for a Sprint Backlog and returns the Backlog"""
        sprint = self.teh.create_sprint("Test")
        s1 = self.teh.create_ticket(Type.USER_STORY,
                                    props={
                                        Key.STORY_POINTS: '3',
                                        Key.SPRINT: sprint.name
                                    })
        self.assert_true(
            s1.link_to(
                self.teh.create_ticket(Type.TASK,
                                       props={
                                           Key.REMAINING_TIME: '4',
                                           Key.SPRINT: sprint.name
                                       })))
        self.assert_true(
            s1.link_to(
                self.teh.create_ticket(Type.TASK,
                                       props={
                                           Key.REMAINING_TIME: '8',
                                           Key.SPRINT: sprint.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: sprint.name
                                    })
        self.assert_true(
            s2.link_to(
                self.teh.create_ticket(Type.TASK,
                                       props={
                                           Key.REMAINING_TIME: '2',
                                           Key.SPRINT: sprint.name
                                       })))
        self.assert_true(
            s2.link_to(
                self.teh.create_ticket(Type.TASK,
                                       props={Key.REMAINING_TIME: '3'})))
        sprint_backlog = self.bmm.get(name="Sprint Backlog", scope=sprint.name)
        self.assert_contains(s1, sprint_backlog)
        self.assert_contains(s2, sprint_backlog)
        self.assert_length(5, sprint_backlog)
        return sprint_backlog

    def _create_product_backlog(self):
        """Creates Requirements and Stories for a Product Backlog and returns the Backlog"""
        def _create_story(props):
            """Creates a ticket of type story and returns it"""
            return self.teh.create_ticket(Type.USER_STORY, props=props)

        r1 = self.teh.create_ticket(Type.REQUIREMENT,
                                    props={Key.BUSINESS_VALUE: '3000'})
        self.assert_true(
            r1.link_to(_create_story({Key.STORY_PRIORITY: 'Linear'})))
        self.assert_true(
            r1.link_to(_create_story({Key.STORY_PRIORITY: 'Exciter'})))
        self.assert_true(
            r1.link_to(_create_story({Key.STORY_PRIORITY: 'Mandatory'})))
        r2 = self.teh.create_ticket(Type.REQUIREMENT,
                                    props={Key.BUSINESS_VALUE: '1200'})
        self.assert_true(
            r2.link_to(_create_story({Key.STORY_PRIORITY: 'Mandatory'})))
        self.assert_true(
            r2.link_to(_create_story({Key.STORY_PRIORITY: 'Exciter'})))
        r3 = self.teh.create_ticket(Type.REQUIREMENT,
                                    props={Key.BUSINESS_VALUE: '2000'})
        self.assert_true(
            r3.link_to(_create_story({Key.STORY_PRIORITY: 'Mandatory'})))
        r4 = self.teh.create_ticket(Type.REQUIREMENT,
                                    props={Key.BUSINESS_VALUE: '800'})
        self.assert_true(
            r4.link_to(_create_story({Key.STORY_PRIORITY: 'Linear'})))
        r5 = self.teh.create_ticket(Type.REQUIREMENT,
                                    props={Key.BUSINESS_VALUE: '3000'})
        self.assert_true(
            r5.link_to(_create_story({Key.STORY_PRIORITY: 'Exciter'})))
        self.assert_true(
            r5.link_to(_create_story({Key.STORY_PRIORITY: 'Mandatory'})))
        product_backlog = self.bmm.get(name="Product Backlog")
        self.assert_equals(len(product_backlog), 14)
        return product_backlog

    def testBacklogAsDictDecorator(self):
        """Tests that the Backlog car return itself with the Dict
        Decorator"""

    def testBacklogCreation(self):
        """Tests the creation of a Backlog"""
        global_backlog = BacklogConfiguration(self.env, name="Global Backlog")
        global_backlog.ticket_types = [Type.REQUIREMENT]
        global_backlog.save()
        # Now reload the same backlog and check that the type and order are kept
        b1 = self.bmm.get(name="Global Backlog")
        self.assert_equals(b1.ticket_types, [Type.REQUIREMENT])

    def testProductBacklogItems(self):
        """Tests the creation of a Global Backlog and add some Items to it"""
        backlog = BacklogConfiguration(self.env, name="Global Backlog")
        backlog.ticket_types = [Type.REQUIREMENT]
        backlog.save()
        # Create some tickets and add them to the Backlog
        b = self.bmm.get(name="Global Backlog")
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '3000'}))
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '1200'}))
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '2000'}))
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '800'}))
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '3000'}))
        # Now test that the ticket are sorted by the defined Key
        ref = 3000
        self.assert_equals(5, len(b), 'Wrong number of tickets in this (%s) Backlog!' % \
                                      len(b))
        # Now load it again, and verify that the order is still ok
        b1 = self.bmm.get(name="Global Backlog")
        self.assert_true(
            len(b1) > 0, 'There is no ticket associated to this Backlog!')

    def testMoveItemInBacklog(self):
        """Test the movement of an item into the backlog, change the position"""
        backlog = BacklogConfiguration(self.env, name="Global Backlog")
        backlog.ticket_types = [Type.REQUIREMENT]
        backlog.save()
        # Create some tickets and add them to the Backlog
        b = self.bmm.get(name="Global Backlog")
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '3000'}))
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '1200'}))
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '2000'}))
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '800'}))
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '3000'}))
        b1 = self.bmm.get(name="Global Backlog")
        t2000 = None
        for b in b1:
            #print "b: %s" % type(b)
            if int(b.ticket[Key.BUSINESS_VALUE]) == 2000:
                t2000 = b
                break
        self.assert_not_none(t2000)
        new_pos = b1.insert(0, t2000)
        self.assert_equals(new_pos, 0)
        # Now try to move a normal ticket and not a BacklogItem
        t2000 = self.teh.load_ticket(t_id=t2000.ticket.id)
        b1.insert(1, t2000)
        self.assert_equals(t2000, b1[1].ticket)

    def testBacklogPositionPersistence(self):
        """Tests the Backlog position persistence of items, after being saved and reloaded"""
        backlog = BacklogConfiguration(self.env, name="Global Backlog")
        backlog.ticket_types = [Type.REQUIREMENT]
        backlog.save()

        # Create some tickets and add them to the Backlog
        b = self.bmm.get(name="Global Backlog")
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '3000'}))
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '1200'}))
        b.add(
            self.teh.create_ticket(Type.REQUIREMENT,
                                   props={Key.BUSINESS_VALUE: '2000'}))
        # Now reload the backlog, move the item in pos 2 to 1, save and reload
        b1 = self.bmm.get(name="Global Backlog")
        self.assert_equals(3, len(b1))
        t1200 = b1[1]
        b1.insert(0, t1200)
        # reload the backlgo and verify that the item is in position 0
        b2 = self.bmm.get(name='Global Backlog')
        self.assert_equals(t1200.ticket.id, b2[0].ticket.id)
        self.assert_equals(0, b2[0].pos)

    def testBacklogWithItemNotAdded(self):
        """Tests the Backlog with Items that have not been explicitly added"""
        backlog = BacklogConfiguration(self.env, name="Global Backlog")
        backlog.ticket_types = [Type.REQUIREMENT]
        backlog.save()
        # Create some tickets and add them to the Backlog
        b = self.bmm.get(name="Global Backlog")
        t1 = self.teh.create_ticket(Type.REQUIREMENT,
                                    props={Key.BUSINESS_VALUE: '3000'})
        t_no = self.teh.create_ticket(Type.USER_STORY,
                                      props={Key.STORY_POINTS: '13'})
        t2 = self.teh.create_ticket(Type.REQUIREMENT,
                                    props={Key.BUSINESS_VALUE: '1200'})
        b1 = self.bmm.get(name="Global Backlog")
        # Test that a belonging ticket is really belonging
        self.assert_contains(t2, b1)
        # Test if the external ticket, has been loaded into the Backlog
        self.assert_contains(t1, b1)
        # Test that the t_no, User Story is also not in the Backlog
        self.assert_not_contains(t_no, b1)

    def testBacklogWithHierarchicalItems(self):
        """Tests the Backlog with multiple hierarchical types"""
        # Create 2 requirements and link 2 stories each
        r1 = self.teh.create_ticket(Type.REQUIREMENT,
                                    props={Key.BUSINESS_VALUE: '2000'})
        self.assert_true(
            r1.link_to(
                self.teh.create_ticket(Type.USER_STORY,
                                       props={Key.STORY_PRIORITY: 'Linear'})))
        self.assert_true(
            r1.link_to(
                self.teh.create_ticket(Type.USER_STORY,
                                       props={Key.STORY_PRIORITY:
                                              'Mandatory'})))
        r2 = self.teh.create_ticket(Type.REQUIREMENT,
                                    props={Key.BUSINESS_VALUE: '3000'})
        self.assert_true(
            r2.link_to(
                self.teh.create_ticket(Type.USER_STORY,
                                       props={Key.STORY_PRIORITY: 'Exciter'})))
        self.assert_true(
            r2.link_to(
                self.teh.create_ticket(Type.USER_STORY,
                                       props={Key.STORY_PRIORITY: 'Linear'})))
        # Now create a Backlog with both type and lets' verify that the tickets are there
        backlog = BacklogConfiguration(self.env, name="Global Backlog")
        backlog.ticket_types = [Type.REQUIREMENT, Type.USER_STORY]
        backlog.save()
        b = self.bmm.get(name="Global Backlog")
        self.assert_equals(6, len(b))
        self.assert_contains(r1, b)
        for at in r1.get_outgoing():
            self.assert_contains(at, b)
        self.assert_contains(r1, b)
        for at in r2.get_outgoing():
            self.assert_contains(at, b)

    def testBacklogForSprint(self):
        """Tests a Backlog associated to a Sprint"""
        # Creates a Milestone
        m = Milestone(self.env)
        m.name = "Milestone 1"
        m.insert()
        # Create a Sprint
        sprint = self.teh.create_sprint(name="Sprint 1",
                                        start=to_datetime(t=None),
                                        duration=20,
                                        milestone=m.name)
        # Create some tickets
        # s1(s) -> t1(s)
        #       -> t2(s)
        #       -> t3
        # s2    -> t4(s)
        #       -> t5
        s1 = self.teh.create_ticket(Type.USER_STORY,
                                    props={
                                        Key.STORY_POINTS: '3',
                                        Key.SPRINT: sprint.name
                                    })
        self.assert_equals(s1[Key.SPRINT], sprint.name)
        self.assert_true(
            s1.link_to(
                self.teh.create_ticket(Type.TASK,
                                       props={
                                           Key.REMAINING_TIME: '4',
                                           Key.SPRINT: sprint.name
                                       })))
        self.assert_true(
            s1.link_to(
                self.teh.create_ticket(Type.TASK,
                                       props={
                                           Key.REMAINING_TIME: '8',
                                           Key.SPRINT: sprint.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'})
        self.assert_true(
            s2.link_to(
                self.teh.create_ticket(Type.TASK,
                                       props={
                                           Key.REMAINING_TIME: '2',
                                           Key.SPRINT: sprint.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
        backlog = self.bmm.get(name="Sprint-Backlog", scope=sprint.name)
        self.assert_length(5, backlog)

    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 testGlobalBacklogWithStrictOption(self):
        """Tests a global backlog with the Strict option"""
        backlog = BacklogConfiguration(self.env, name="Bug-Backlog")
        backlog.ticket_types = [Type.BUG, Type.TASK]
        backlog.save()
        # Build a hierarchy of Bug tasks
        b1 = self.teh.create_ticket(Type.BUG)
        t1 = self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '3'})
        t2 = self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '7'})
        # Link the Bug only with one task
        self.assert_true(b1.link_to(t1))
        self.assert_equals('', b1[Key.SPRINT])
        # Standard trac fields must not be None (see property change rendering
        # for ticket preview)
        self.assert_equals('', b1[Key.MILESTONE])
        self.assert_equals(Type.BUG, b1[Key.TYPE])
        self.assert_equals('', t1[Key.SPRINT])
        self.assert_equals('', t1[Key.MILESTONE])
        self.assert_equals('', t2[Key.SPRINT])
        self.assert_equals('', t2[Key.MILESTONE])

        # Now load the backlog, and check that even with strict
        # a global backlog shows all the tickets
        b = self.bmm.get(name="Bug-Backlog")
        if len(b) != 3:
            print_backlog(b)
            self.fail("Backlog count wrong! %s != 3" % \
                       len(b))
        # Now links also the second task
        self.assert_true(b1.link_to(t2))
        # Now reload the backlog and check if the second task is there too
        self.assert_length(3, b)
        # Now plan the a task for a sprint so that should disappear from the
        # backlog
        s = self.teh.create_sprint("Test")
        t1[Key.SPRINT] = s.name
        self.assert_true(t1.save_changes('Tester', 'Planned...'))
        self.assert_length(2, b)

    def testScopedBacklogWithClosedTicket(self):
        """Tests if a scoped backlog loads also closed tickets"""

        sprint1 = self.teh.create_sprint("Sprint Scoped")
        sprint1.save()
        # Creates the Backlog bound to a scope (Sprint)
        backlog = BacklogConfiguration(self.env,
                                       name="Scoped-Backlog",
                                       type=BacklogType.SPRINT)
        backlog.ticket_types = [Type.USER_STORY, Type.TASK]
        backlog.save()
        # Create 1 ticket
        task = self.teh.create_ticket(Type.TASK,
                                      props={
                                          Key.REMAINING_TIME: '12',
                                          Key.SPRINT: sprint1.name
                                      })
        # Force reload
        backlog = self.bmm.get(name="Scoped-Backlog", scope=sprint1.name)
        self.assert_true(task in backlog)
        self.assert_equals(len(backlog), 1)
        task[Key.STATUS] = Status.CLOSED
        task.save_changes('tester', 'Changed Status')
        # Now should still be there even if closed, because the backlog is scoped
        self.assert_true(task in backlog)
        self.assert_equals(len(backlog), 1)

    def testDeleteBacklog(self):
        """Tests the deletion of a Backlog"""
        backlog = BacklogConfiguration(self.env, name="Delete-Backlog")
        backlog.ticket_types = [Type.USER_STORY, Type.TASK]
        backlog.save()
        # Test that the backlog exists
        try:
            b2 = self.bmm.get(name="Delete-Backlog")
            self.assert_true(b2.delete())
        except Exception, e:
            print "Error: %s" % unicode(e)
            self.fail("Not able to load backlog!!!")
        try:
            b2 = self.bmm.get(self.env, "Delete-Backlog")
            self.fail("The Backlog was not deleted!!!")
        except:
            self.assert_true(True)
Example #21
0
class TestBacklog(AgiloTestCase):
    """Tests for the Backlog class"""
    
    def setUp(self):
        self.super()
        self.bmm = BacklogModelManager(self.env)
        # Creates and It's me backlog
        its_me = self.teh.create_sprint("It's me")
        self.assert_true(its_me.exists)

    def _create_sprint_backlog(self):
        """Creates stories and tasks for a Sprint Backlog and returns the Backlog"""
        sprint = self.teh.create_sprint("Test")
        s1 = self.teh.create_ticket(Type.USER_STORY, 
                                    props={Key.STORY_POINTS: '3', 
                                           Key.SPRINT: sprint.name})
        self.assert_true(s1.link_to(self.teh.create_ticket(Type.TASK, 
                                                           props={Key.REMAINING_TIME: '4',
                                                                  Key.SPRINT: sprint.name})))
        self.assert_true(s1.link_to(self.teh.create_ticket(Type.TASK,
                                                           props={Key.REMAINING_TIME: '8',
                                                                  Key.SPRINT: sprint.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: sprint.name})
        self.assert_true(s2.link_to(self.teh.create_ticket(Type.TASK, 
                                                           props={Key.REMAINING_TIME: '2',
                                                                  Key.SPRINT: sprint.name})))
        self.assert_true(s2.link_to(self.teh.create_ticket(Type.TASK, 
                                                           props={Key.REMAINING_TIME: '3'})))
        sprint_backlog = self.bmm.get(name="Sprint Backlog", scope=sprint.name)
        self.assert_contains(s1, sprint_backlog)
        self.assert_contains(s2, sprint_backlog)
        self.assert_length(5, sprint_backlog)
        return sprint_backlog
    
    def _create_product_backlog(self):
        """Creates Requirements and Stories for a Product Backlog and returns the Backlog"""
        def _create_story(props):
            """Creates a ticket of type story and returns it"""
            return self.teh.create_ticket(Type.USER_STORY, props=props)
        
        r1 = self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '3000'})
        self.assert_true(r1.link_to(_create_story({Key.STORY_PRIORITY: 'Linear'})))
        self.assert_true(r1.link_to(_create_story({Key.STORY_PRIORITY: 'Exciter'})))
        self.assert_true(r1.link_to(_create_story({Key.STORY_PRIORITY: 'Mandatory'})))
        r2 = self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '1200'})
        self.assert_true(r2.link_to(_create_story({Key.STORY_PRIORITY: 'Mandatory'})))
        self.assert_true(r2.link_to(_create_story({Key.STORY_PRIORITY: 'Exciter'})))
        r3 = self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '2000'})
        self.assert_true(r3.link_to(_create_story({Key.STORY_PRIORITY: 'Mandatory'})))
        r4 = self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '800'})
        self.assert_true(r4.link_to(_create_story({Key.STORY_PRIORITY: 'Linear'})))
        r5 = self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '3000'})
        self.assert_true(r5.link_to(_create_story({Key.STORY_PRIORITY: 'Exciter'})))
        self.assert_true(r5.link_to(_create_story({Key.STORY_PRIORITY: 'Mandatory'})))
        product_backlog = self.bmm.get(name="Product Backlog")
        self.assert_equals(len(product_backlog), 14)
        return product_backlog
    
    def testBacklogAsDictDecorator(self):
        """Tests that the Backlog car return itself with the Dict
        Decorator"""
    
    def testBacklogCreation(self):
        """Tests the creation of a Backlog"""
        global_backlog = BacklogConfiguration(self.env, name="Global Backlog")
        global_backlog.ticket_types = [Type.REQUIREMENT]
        global_backlog.save()
        # Now reload the same backlog and check that the type and order are kept
        b1 = self.bmm.get(name="Global Backlog")
        self.assert_equals(b1.ticket_types, [Type.REQUIREMENT])
    
    def testProductBacklogItems(self):
        """Tests the creation of a Global Backlog and add some Items to it"""
        backlog = BacklogConfiguration(self.env, name="Global Backlog")
        backlog.ticket_types = [Type.REQUIREMENT]
        backlog.save()
        # Create some tickets and add them to the Backlog
        b = self.bmm.get(name="Global Backlog")
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '3000'}))
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '1200'}))
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '2000'}))
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '800'}))
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '3000'}))
        # Now test that the ticket are sorted by the defined Key
        ref = 3000
        self.assert_equals(5, len(b), 'Wrong number of tickets in this (%s) Backlog!' % \
                                      len(b))
        # Now load it again, and verify that the order is still ok
        b1 = self.bmm.get(name="Global Backlog")
        self.assert_true(len(b1) > 0, 'There is no ticket associated to this Backlog!')

    def testMoveItemInBacklog(self):
        """Test the movement of an item into the backlog, change the position"""
        backlog = BacklogConfiguration(self.env, name="Global Backlog")
        backlog.ticket_types=[Type.REQUIREMENT]
        backlog.save()
        # Create some tickets and add them to the Backlog
        b = self.bmm.get(name="Global Backlog")
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '3000'}))
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '1200'}))
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '2000'}))
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '800'}))
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '3000'}))
        b1 = self.bmm.get(name="Global Backlog")
        t2000 = None
        for b in b1:
            #print "b: %s" % type(b)
            if int(b.ticket[Key.BUSINESS_VALUE]) == 2000:
                t2000 = b
                break
        self.assert_not_none(t2000)
        new_pos = b1.insert(0, t2000)
        self.assert_equals(new_pos, 0)
        # Now try to move a normal ticket and not a BacklogItem
        t2000 = self.teh.load_ticket(t_id=t2000.ticket.id)
        b1.insert(1, t2000)
        self.assert_equals(t2000, b1[1].ticket)

    def testBacklogPositionPersistence(self):
        """Tests the Backlog position persistence of items, after being saved and reloaded"""
        backlog = BacklogConfiguration(self.env, name="Global Backlog")
        backlog.ticket_types=[Type.REQUIREMENT]
        backlog.save()

        # Create some tickets and add them to the Backlog
        b = self.bmm.get(name="Global Backlog")
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '3000'}))
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '1200'}))
        b.add(self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '2000'}))
        # Now reload the backlog, move the item in pos 2 to 1, save and reload
        b1 = self.bmm.get(name="Global Backlog")
        self.assert_equals(3, len(b1))
        t1200 = b1[1]
        b1.insert(0, t1200)
        # reload the backlgo and verify that the item is in position 0
        b2 = self.bmm.get(name='Global Backlog')
        self.assert_equals(t1200.ticket.id, b2[0].ticket.id)
        self.assert_equals(0, b2[0].pos)
        
    def testBacklogWithItemNotAdded(self):
        """Tests the Backlog with Items that have not been explicitly added"""
        backlog = BacklogConfiguration(self.env, name="Global Backlog")
        backlog.ticket_types=[Type.REQUIREMENT]
        backlog.save()
        # Create some tickets and add them to the Backlog
        b = self.bmm.get(name="Global Backlog")
        t1 = self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '3000'})
        t_no = self.teh.create_ticket(Type.USER_STORY, props={Key.STORY_POINTS: '13'})
        t2 = self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '1200'})
        b1 = self.bmm.get(name="Global Backlog")
        # Test that a belonging ticket is really belonging
        self.assert_contains(t2, b1)
        # Test if the external ticket, has been loaded into the Backlog
        self.assert_contains(t1, b1)
        # Test that the t_no, User Story is also not in the Backlog
        self.assert_not_contains(t_no, b1)
    
    def testBacklogWithHierarchicalItems(self):
        """Tests the Backlog with multiple hierarchical types"""
        # Create 2 requirements and link 2 stories each
        r1 = self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '2000'})
        self.assert_true(r1.link_to(self.teh.create_ticket(Type.USER_STORY, 
                                                          props={Key.STORY_PRIORITY: 'Linear'})))
        self.assert_true(r1.link_to(self.teh.create_ticket(Type.USER_STORY, 
                                                          props={Key.STORY_PRIORITY: 'Mandatory'})))
        r2 = self.teh.create_ticket(Type.REQUIREMENT, props={Key.BUSINESS_VALUE: '3000'})
        self.assert_true(r2.link_to(self.teh.create_ticket(Type.USER_STORY, 
                                                          props={Key.STORY_PRIORITY: 'Exciter'})))
        self.assert_true(r2.link_to(self.teh.create_ticket(Type.USER_STORY, 
                                                          props={Key.STORY_PRIORITY: 'Linear'})))
        # Now create a Backlog with both type and lets' verify that the tickets are there
        backlog = BacklogConfiguration(self.env, name="Global Backlog")
        backlog.ticket_types=[Type.REQUIREMENT, Type.USER_STORY]
        backlog.save()
        b = self.bmm.get(name="Global Backlog")
        self.assert_equals(6, len(b))
        self.assert_contains(r1, b)
        for at in r1.get_outgoing():
            self.assert_contains(at, b)
        self.assert_contains(r1, b)
        for at in r2.get_outgoing():
            self.assert_contains(at, b)
        
    def testBacklogForSprint(self):
        """Tests a Backlog associated to a Sprint"""
        # Creates a Milestone
        m = Milestone(self.env)
        m.name = "Milestone 1"
        m.insert()
        # Create a Sprint
        sprint = self.teh.create_sprint( 
                        name="Sprint 1", 
                        start=to_datetime(t=None), 
                        duration=20,
                        milestone=m.name)
        # Create some tickets
        # s1(s) -> t1(s)
        #       -> t2(s)
        #       -> t3
        # s2    -> t4(s)
        #       -> t5 
        s1 = self.teh.create_ticket(Type.USER_STORY, props={Key.STORY_POINTS: '3', 
                                                            Key.SPRINT: sprint.name})
        self.assert_equals(s1[Key.SPRINT], sprint.name)
        self.assert_true(s1.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '4',
                                                                             Key.SPRINT: sprint.name})))
        self.assert_true(s1.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '8',
                                                                             Key.SPRINT: sprint.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'})
        self.assert_true(s2.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: '2',
                                                                             Key.SPRINT: sprint.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
        backlog = self.bmm.get(name="Sprint-Backlog", scope=sprint.name)
        self.assert_length(5, backlog)
        
    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 testGlobalBacklogWithStrictOption(self):
        """Tests a global backlog with the Strict option"""
        backlog = BacklogConfiguration(self.env, name="Bug-Backlog")
        backlog.ticket_types=[Type.BUG, Type.TASK]
        backlog.save()
        # Build a hierarchy of Bug tasks
        b1 = self.teh.create_ticket(Type.BUG)
        t1 = self.teh.create_ticket(Type.TASK, 
                                    props={Key.REMAINING_TIME: '3'})
        t2 = self.teh.create_ticket(Type.TASK, 
                                    props={Key.REMAINING_TIME: '7'})
        # Link the Bug only with one task
        self.assert_true(b1.link_to(t1))
        self.assert_equals('', b1[Key.SPRINT])
        # Standard trac fields must not be None (see property change rendering
        # for ticket preview)
        self.assert_equals('', b1[Key.MILESTONE])
        self.assert_equals(Type.BUG, b1[Key.TYPE])
        self.assert_equals('', t1[Key.SPRINT])
        self.assert_equals('', t1[Key.MILESTONE])
        self.assert_equals('', t2[Key.SPRINT])
        self.assert_equals('', t2[Key.MILESTONE])
        
        # Now load the backlog, and check that even with strict
        # a global backlog shows all the tickets
        b = self.bmm.get(name="Bug-Backlog")
        if len(b) != 3:
            print_backlog(b)
            self.fail("Backlog count wrong! %s != 3" % \
                       len(b))
        # Now links also the second task
        self.assert_true(b1.link_to(t2))
        # Now reload the backlog and check if the second task is there too
        self.assert_length(3, b)
        # Now plan the a task for a sprint so that should disappear from the
        # backlog
        s = self.teh.create_sprint("Test")
        t1[Key.SPRINT] = s.name
        self.assert_true(t1.save_changes('Tester', 'Planned...'))
        self.assert_length(2, b)
    
    def testScopedBacklogWithClosedTicket(self):
        """Tests if a scoped backlog loads also closed tickets"""
        
        sprint1 = self.teh.create_sprint("Sprint Scoped")
        sprint1.save()
        # Creates the Backlog bound to a scope (Sprint)
        backlog = BacklogConfiguration(self.env, name="Scoped-Backlog", type=BacklogType.SPRINT)
        backlog.ticket_types = [Type.USER_STORY, Type.TASK]
        backlog.save()
        # Create 1 ticket
        task = self.teh.create_ticket(Type.TASK, 
                                      props={Key.REMAINING_TIME: '12',
                                             Key.SPRINT: sprint1.name})
        # Force reload
        backlog = self.bmm.get(name="Scoped-Backlog", 
                               scope=sprint1.name)
        self.assert_true(task in backlog)
        self.assert_equals(len(backlog), 1)
        task[Key.STATUS] = Status.CLOSED
        task.save_changes('tester', 'Changed Status')
        # Now should still be there even if closed, because the backlog is scoped
        self.assert_true(task in backlog)
        self.assert_equals(len(backlog), 1)
        
    def testDeleteBacklog(self):
        """Tests the deletion of a Backlog"""
        backlog = BacklogConfiguration(self.env, name="Delete-Backlog") 
        backlog.ticket_types=[Type.USER_STORY, Type.TASK]
        backlog.save()
        # Test that the backlog exists
        try:
            b2 = self.bmm.get(name="Delete-Backlog")
            self.assert_true(b2.delete())
        except Exception, e:
            print "Error: %s" % unicode(e)
            self.fail("Not able to load backlog!!!")
        try:
            b2 = self.bmm.get(self.env, "Delete-Backlog")
            self.fail("The Backlog was not deleted!!!")
        except:
            self.assert_true(True)
Example #22
0
 def backlog(self):
     from agilo.scrum.backlog.model import BacklogModelManager
     return BacklogModelManager(self.env).get(name=self.name, scope=Key.SPRINT)