예제 #1
0
파일: team_test.py 프로젝트: nagyist/agilo
 def test_team_with_capacity_on_every_day_has_no_empty_days(self):
     team, member1 = self.team_with_one_member()
     member1.capacity = [1] * 7
     member1.save()
     start = now() - timedelta(days=7)
     end = now()
     self.assert_length(0, team.capacity().days_without_capacity_in_interval(start, end))
예제 #2
0
 def runTest(self):
     self._tester.login_as(Usernames.admin)
     # Create the milestone first
     self._tester.create_milestone('milestone2')
     
     # get sprint listing, should be empty
     page_url = self._tester.url + '/admin/agilo/sprints'
     tc.go(page_url)
     tc.url(page_url)
     tc.code(200)
     
     # add new sprint
     sprint_start = normalize_date(now())
     sprint_name = 'Test sprint'
     tc.formvalue('addsprint', 'name', sprint_name)
     tc.formvalue('addsprint', 'start', format_datetime(sprint_start, format='iso8601'))
     tc.formvalue('addsprint', 'duration', '1')
     tc.formvalue('addsprint', 'milestone', 'milestone2')
     tc.submit('add')
     # add redirects to list view, new sprint should be in there
     tc.find(sprint_name)
     # go to detail page
     tc.go("%s/%s" % (page_url, quote(sprint_name)))
     # see if milestone is set correctly
     tc.find('<option selected="selected">\s*milestone2')
     
     # test setting end date, not duration
     tc.formvalue('modcomp', 'description', '[http://www.example.com]')
     tomorrow = sprint_start + timedelta(days=1)
     tc.formvalue('modcomp', 'end', format_datetime(tomorrow, format='iso8601'))
     tc.formvalue('modcomp', 'duration', '')
     tc.submit('save')
     tc.url(page_url)
     
     # duration of the new sprint should be 2
     tc.find('"duration">2</td>')
     
     # --- test invalid values when adding sprint ---
     # no values, should redirect to list view
     tc.formvalue('addsprint', 'name', '')
     tc.submit('add')
     tc.url(page_url)
     
     # invalid date, should throw an error
     tc.formvalue('addsprint', 'name', 'Testsprint 2')
     tc.formvalue('addsprint', 'start', '2008 May 13')
     tc.formvalue('addsprint', 'duration', '1')
     tc.submit('add')
     tc.find('Error: Invalid Date')
     
     # no end date or duration
     tc.go(page_url)
     tc.formvalue('addsprint', 'name', 'Testsprint 2')
     yesterday = now() - timedelta(days=3)
     tc.formvalue('addsprint', 'start', 
                  format_datetime(yesterday, format='iso8601'))
     tc.submit('add')
     tc.url(page_url)
예제 #3
0
파일: team_test.py 프로젝트: nagyist/agilo
 def test_team_not_working_on_weekends_has_no_capacity_on_weekends(self):
     team = self._create_team_with_weekends_off()
     # exactly one week so we're sure that this interval covers two non-working days
     start = now() - timedelta(days=7)
     end = now()
     days_without_capacity = team.capacity().days_without_capacity_in_interval(start, end)
     self.assert_length(2, days_without_capacity)
     self.assert_equals(0, days_without_capacity[0].hour)
     self.assert_equals(0, days_without_capacity[0].minute)
예제 #4
0
 def test_ideal_burndown_doesnt_raise_division_by_Zero_exception(self):
     commitment_when =  now() - timedelta(days=2)
     capacities = [
         (now() - timedelta(days=3), 1.0),
         (commitment_when, 0.0),
         (now() - timedelta(days=1), 0.0),
         (now(), 0.0)
     ]
     self.assert_equals([0,0,0], self._ideal_burndown(2, commitment_when=commitment_when,capacities=capacities))
예제 #5
0
 def test_can_compute_points_with_datetimes(self):
     two_days_ago = now() - timedelta(days=2)
     one_day_ago = now() - timedelta(days=1)
     today = now()
     line = Line.from_two_points(Point(two_days_ago, 1), Point(one_day_ago, 2))
     expected = Point(today, 3)
     actual = line.point_from_x(today)
     self.assert_equals(expected.x, actual.x)
     self.assert_almost_equals(expected.y, actual.y, max_delta=0.1)
 def _create_remaining_times(self):
     self._create_sprint_with_team()
     self._remaining_time(3, self.sprint.start, Key.COMPONENT, 'foo')
     self._remaining_time(6, self.sprint.start, Key.COMPONENT, 'bar')
     self._remaining_time(9, self.sprint.start)
     self._simulate_confirm_commitment(self.sprint.start)
     self._remaining_time(-2, now(), Key.COMPONENT, 'foo')
     self._remaining_time(-4, now(), Key.COMPONENT, 'bar')
     self._remaining_time(-6, now())
예제 #7
0
 def test_ideal_burndown_doesnt_raise_division_by_Zero_exception(self):
     commitment_when = now() - timedelta(days=2)
     capacities = [(now() - timedelta(days=3), 1.0), (commitment_when, 0.0),
                   (now() - timedelta(days=1), 0.0), (now(), 0.0)]
     self.assert_equals([0, 0, 0],
                        self._ideal_burndown(
                            2,
                            commitment_when=commitment_when,
                            capacities=capacities))
 def _create_remaining_times(self):
     self._create_sprint_with_team()
     self._remaining_time(3, self.sprint.start, Key.COMPONENT, 'foo')
     self._remaining_time(6, self.sprint.start, Key.COMPONENT, 'bar')
     self._remaining_time(9, self.sprint.start)
     self._simulate_confirm_commitment(self.sprint.start)
     self._remaining_time(-2, now(), Key.COMPONENT, 'foo')
     self._remaining_time(-4, now(), Key.COMPONENT, 'bar')
     self._remaining_time(-6, now())
예제 #9
0
 def _get_today_data(self, start, end, tz):
     if not (start <= now(tz) <= end):
         return []
     
     # Now is already calculated in the given timezone so we have to get
     # the midnight in that timezone, shifted to UTC time
     # TODO: this is being shifted later, does midnight suffice?
     today_midnight = midnight_with_utc_shift(now(tz))
     return [DayMarker(today_midnight)]
예제 #10
0
 def _request_with_valid_sprint_data(self):
     start = format_date(now())
     end = format_date(now() + timedelta(10))
     req = self.teh.mock_request()
     req.args = dict(name=self.sprint_name(),
                     add=True,
                     start=start,
                     end=end,
                     milestone="Test milestone fnord")
     return req
예제 #11
0
 def test_can_compute_points_with_datetimes(self):
     two_days_ago = now() - timedelta(days=2)
     one_day_ago = now() - timedelta(days=1)
     today = now()
     line = Line.from_two_points(Point(two_days_ago, 1),
                                 Point(one_day_ago, 2))
     expected = Point(today, 3)
     actual = line.point_from_x(today)
     self.assert_equals(expected.x, actual.x)
     self.assert_almost_equals(expected.y, actual.y, max_delta=0.1)
예제 #12
0
 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)
예제 #13
0
    def setUp(self):
        self.super()
        self.teh.disable_sprint_date_normalization()
        self.sprint = self.teh.create_sprint(name='Sprint 1',
                                             start=now() - timedelta(days=3),
                                             end=now() + timedelta(days=3))
        # already enteres a remaining time!
        self.task = self.teh.create_task(remaining_time=5,
                                         sprint=self.sprint.name)

        self.assert_true(self.sprint.is_currently_running)
예제 #14
0
 def testUTCDatetimeValidator(self):
     """Tests the UTCDatetimeValidator"""
     val = validator.UTCDatetimeValidator(None)
     utc_now = now(tz=utc)
     self.assert_equals(utc_now, val.validate(utc_now))
     # No UTC datetime
     self.assert_raises(validator.ValidationError, val.validate, now())
     # No datetime
     self.assert_raises(validator.ValidationError, val.validate, 0)
     # should allow None, it is not Mandatory
     self.assert_none(val.validate(None))
예제 #15
0
 def _ideal_burndown(self, commitment, commitment_when=None, capacities=None):
     commitment_when = commitment_when or now() - timedelta(days=3)
     if capacities is None:
         capacities = [
             (now() - timedelta(days=3), 6.0),
             (now() - timedelta(days=2), 4.0),
             (now() - timedelta(days=1), 2.0),
             (now(), 0)
         ]
     first_burndown = ValueObject(when=commitment_when, remaining_time=commitment)
     ideal_burndown = calculate_ideal_burndown(capacities, first_burndown, self.sprint)
     return [remaining for (when, remaining) in ideal_burndown]
예제 #16
0
 def _ideal_burndown(self,
                     commitment,
                     commitment_when=None,
                     capacities=None):
     commitment_when = commitment_when or now() - timedelta(days=3)
     if capacities is None:
         capacities = [(now() - timedelta(days=3), 6.0),
                       (now() - timedelta(days=2), 4.0),
                       (now() - timedelta(days=1), 2.0), (now(), 0)]
     first_burndown = ValueObject(when=commitment_when,
                                  remaining_time=commitment)
     ideal_burndown = calculate_ideal_burndown(capacities, first_burndown,
                                               self.sprint)
     return [remaining for (when, remaining) in ideal_burndown]
예제 #17
0
 def test_easy_generation_of_burndown_entries(self):
     actual = BurndownDataChange(self.env).update_values(
         type='fnord', scope=self.sprint.name, when=now(), delta=3)
     expected = self.create_change(type='fnord',
                                   scope=self.sprint.name,
                                   when=now())
     expected.set_delta(3)
     self.assert_equals(expected.type, actual.type)
     self.assert_equals(expected.scope, actual.scope)
     self.assert_almost_equals(expected.when,
                               actual.when,
                               max_delta=timedelta(seconds=2))
     self.assert_equals(expected.delta(), actual.delta())
     self.assert_equals(expected.markers(), actual.markers())
예제 #18
0
 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)
예제 #19
0
 def runTest(self):
     team_name = 'team_for_capacity_saving'
     member_name = 'Team member_name'
     sprint_name = 'capacity_saving_sprint'
     
     self._tester.login_as(Usernames.admin)
     self._tester.create_new_team(team_name)
     self._tester.add_member_to_team(team_name, member_name)
     sprint_start = now()
     self._tester.create_sprint_via_admin(sprint_name, start=sprint_start, team=team_name)
     
     # having tasks with remaining time which were not assigned to a specific
     # user triggered another bug on the team page.
     attributes = dict(sprint=sprint_name, remaining_time='12')
     self._tester.create_new_agilo_task('Not assigned Task', **attributes)
     
     self._tester.login_as(Usernames.scrum_master)
     self._tester.go_to_team_page(team_name, sprint_name)
     team_page_url = tc.get_browser().get_url()
     
     day_ordinal = (sprint_start + timedelta(days=3)).toordinal()
     input_name = 'ts_%s_%d' % (member_name, day_ordinal)
     tc.formvalue('team_capacity_form', input_name, '2')
     tc.submit('save')
     tc.code(200)
     tc.url(team_page_url)
예제 #20
0
 def test_continues_straight_line_if_two_values_are_closer_together_than_the_interval_are_given(self):
     until = now()
     first = burndown_entry(until - timedelta(minutes=10), 10)
     second = burndown_entry(until - timedelta(minutes=5), 5)
     extrapolation = self.generator.calculate([first, second], until)
     self.assert_length(2, extrapolation)
     self.assert_equals([burndown_entry(second.when, 5), burndown_entry(until, 0)], extrapolation)
예제 #21
0
파일: team_test.py 프로젝트: nagyist/agilo
 def test_days_without_capacity_respect_given_timestamp(self):
     team = self._create_team_with_weekends_off()
     end = now(utc)
     start = end - timedelta(days=7)
     bangkok_tz = get_timezone('GMT +7:00')
     days_without_capacity = team.capacity(bangkok_tz).days_without_capacity_in_interval(start, end)
     self.assert_equals(bangkok_tz, days_without_capacity[0].tzinfo)
 def setUp(self):
     self.super()
     self.task = self.teh.create_ticket(Type.TASK)
     self.task.last_changed = now() - timedelta(seconds=3)
     self.req = self.teh.mock_request(username='******',
                                      args={'ticket_id': self.task.id},
                                      method='POST')
예제 #23
0
파일: web_ui.py 프로젝트: djangsters/agilo
 def pre_process_request(self, req, handler):
     """
     Modifies the data of an HTTP request and substitutes type aliases
     with ticket type names.
     Always returns the request handler unchanged.
     """
     # Performance measurement
     setattr(req, START_TIME, now())
     
     #substitute aliases with ticket types in request arguments
     for typedef in self.TYPE_KEYS:
         if req.args.has_key(typedef):
             typedef_obj = req.args.get(typedef)
             if isinstance(typedef_obj, list):
                 req.args[typedef] = list() # We need a new list
                 for td in typedef_obj:
                     if self._alias_to_type.has_key(td):
                         req.args[typedef].append(self._alias_to_type[td])
                     else:
                         req.args[typedef].append(td)
             elif self._alias_to_type.has_key(req.args[typedef]):
                 # print "!!! Replacing %s with %s" % (req.args[typedef], 
                 #                                     self._alias_to_type[req.args[typedef]])
                 req.args[typedef] = self._alias_to_type[req.args[typedef]]
     return handler
예제 #24
0
파일: web_ui.py 프로젝트: nagyist/agilo
    def pre_process_request(self, req, handler):
        """
        Modifies the data of an HTTP request and substitutes type aliases
        with ticket type names.
        Always returns the request handler unchanged.
        """
        # Performance measurement
        setattr(req, START_TIME, now())

        #substitute aliases with ticket types in request arguments
        for typedef in self.TYPE_KEYS:
            if req.args.has_key(typedef):
                typedef_obj = req.args.get(typedef)
                if isinstance(typedef_obj, list):
                    req.args[typedef] = list()  # We need a new list
                    for td in typedef_obj:
                        if self._alias_to_type.has_key(td):
                            req.args[typedef].append(self._alias_to_type[td])
                        else:
                            req.args[typedef].append(td)
                elif self._alias_to_type.has_key(req.args[typedef]):
                    # print "!!! Replacing %s with %s" % (req.args[typedef],
                    #                                     self._alias_to_type[req.args[typedef]])
                    req.args[typedef] = self._alias_to_type[req.args[typedef]]
        return handler
예제 #25
0
 def testTeamMetricsChartContainsAllMetricsDataForMultipleSeries(self):
     self.env.compmgr.enabled[MetricsChartGenerator] = True
     today = now()
     self._add_metrics(self.sprint, **{Key.VELOCITY: 10})
     start_sprint2 = today - timedelta(days=30)
     sprint2 = self.teh.create_sprint(name='Sprint 2', start=start_sprint2, 
                                      duration=20, team=self.sprint.team)
     self._add_metrics(sprint2, **{Key.ESTIMATED_VELOCITY: 7})
     start_sprint3 = today - 2 * timedelta(days=30)
     sprint3 = self.teh.create_sprint(name='Sprint 3', start=start_sprint3,
                                      duration=20, team=self.sprint.team)
     self._add_metrics(sprint3, **{Key.VELOCITY: 5})
     self._add_metrics(sprint3, **{Key.ESTIMATED_VELOCITY: 9})
     
     widget = ChartGenerator(self.env).get_chartwidget(ChartType.TEAM_METRICS, 
                   team_name=self.sprint.team.name, metric_names=[Key.ESTIMATED_VELOCITY, Key.VELOCITY])
     self.assert_equals(['Sprint 3', 'Sprint 2', self.sprint.name], widget.data['sprint_names'])
     metrics = widget.data['metrics']
     self.assert_equals(2, len(metrics))
     
     velocity_label, velocity_data = metrics[0]
     self.assert_equals(get_label(Key.ESTIMATED_VELOCITY), velocity_label)
     self.assert_equals([(0, 9), (1, 7)], velocity_data)
     
     velocity_label, velocity_data = metrics[1]
     self.assert_equals(get_label(Key.VELOCITY), velocity_label)
     self.assert_equals([(0, 5), (2, 10)], velocity_data)
예제 #26
0
 def test_can_ignore_tasks_without_sprint(self):
     self.task = self.teh.create_task()
     self.inject_remaining_time(now(), 42)
     self.perform_upgrade(db6.do_upgrade)
     
     rows = self.burndown_changes()
     self.assert_length(0, rows)
예제 #27
0
 def testSprintWithTimezoneDifference(self):
     """Tests the sprint creation and manipulation with Timezone
     differences"""
     # Create a Sprint from Berlin with Daylight risk in Summer
     berlin_tz = get_timezone('GMT +2:00') # 'Europe/Berlin'
     start_in_berlin = normalize_date(now(tz=berlin_tz))
     cmd_create = SprintController.CreateSprintCommand(self.env,
                                                       name='TimezoneSprint',
                                                       milestone='MyRelease',
                                                       team=self.team.name,
                                                       start=start_in_berlin,
                                                       duration=15)
     sprint = self.controller.process_command(cmd_create)
     # now reload the sprint and check if the date is still valid
     # and has been correctly saved... but we will read from San
     # Francisco
     sf_tz = get_timezone('GMT -7:00') # 'US/Pacific'
     # obvious, but you never know what pytz timezone does with the
     # daylight saving.
     self.assert_equals(start_in_berlin, 
                      start_in_berlin.astimezone(sf_tz))
     
     # check that the sprint.start is in UTC timezone
     self.assert_equals(timedelta(0), sprint.start.utcoffset())
     self.assert_equals(start_in_berlin, 
                      sprint.start.astimezone(berlin_tz))
     # now we read it as UTC and we create a SF timezone datetime
     start_in_sf = sprint.start.astimezone(sf_tz)
     # Python should compare the UTC value of the datetimes
     self.assert_equals(start_in_berlin, start_in_sf)
예제 #28
0
    def test_can_create_sprints_for_milestones_with_slash_in_name(self):
        self.teh.create_milestone("milestone/fnord")
        req = self.teh.mock_request(Usernames.product_owner)

        req.args = dict(add='add', sprint_name='fnord', start=format_date(now()),
                        duration=10, milestone="milestone/fnord")
        self.assert_raises(RequestDone, self.view.do_post, req)
예제 #29
0
    def testSprintWithTimezoneDifference(self):
        """Tests the sprint creation and manipulation with Timezone
        differences"""
        # Create a Sprint from Berlin with Daylight risk in Summer
        berlin_tz = get_timezone('GMT +2:00')  # 'Europe/Berlin'
        start_in_berlin = normalize_date(now(tz=berlin_tz))
        cmd_create = SprintController.CreateSprintCommand(
            self.env,
            name='TimezoneSprint',
            milestone='MyRelease',
            team=self.team.name,
            start=start_in_berlin,
            duration=15)
        sprint = self.controller.process_command(cmd_create)
        # now reload the sprint and check if the date is still valid
        # and has been correctly saved... but we will read from San
        # Francisco
        sf_tz = get_timezone('GMT -7:00')  # 'US/Pacific'
        # obvious, but you never know what pytz timezone does with the
        # daylight saving.
        self.assert_equals(start_in_berlin, start_in_berlin.astimezone(sf_tz))

        # check that the sprint.start is in UTC timezone
        self.assert_equals(timedelta(0), sprint.start.utcoffset())
        self.assert_equals(start_in_berlin, sprint.start.astimezone(berlin_tz))
        # now we read it as UTC and we create a SF timezone datetime
        start_in_sf = sprint.start.astimezone(sf_tz)
        # Python should compare the UTC value of the datetimes
        self.assert_equals(start_in_berlin, start_in_sf)
예제 #30
0
 def setUp(self):
     self.super()
     self.start = normalize_date(now())
     duration = timedelta(days=20)
     self.end = normalize_date(self.start + duration)
     self.manager = SprintModelManager(self.env)
     self.tmm = TeamMemberModelManager(self.env)
예제 #31
0
    def create_sprint(self, name, start=None, end=None, duration=20,
                      milestone=None, team=None):
        """Creates a Sprint for the given milestone, if doesn't exists, first
        it creates a Milestone"""
        # If the start day is set to today, the sprint will
        # normalize it to 9:00am of the start day and all the tests
        # will fail, till 9:00am in the morning...
        if start is None:
            # we set hours to 0 so will be normalized to 9am at any
            # time of the day, when running tests.
            start = (now(tz=utc) - timedelta(days=3)).replace(hour=0)
        if milestone is None:
            milestone = self.create_milestone('Milestone for %s' % name)
        # It should automatically load the existing Sprint if already there
        if isinstance(milestone, Milestone):
            milestone = milestone.name
        sprint_controller = SprintController(self.env)
        if start is not None:
            start = shift_to_utc(start)
        if end is not None:
            end = shift_to_utc(end)
        create_sprint_command = SprintController.CreateSprintCommand(self.env, name=name, start=start,
                                                                     end=end, duration=duration, milestone=milestone)
        create_sprint_command.native = True
        sprint = sprint_controller.process_command(create_sprint_command)

        assert sprint is not None
        if team is not None:
            if isinstance(team, basestring):
                team = self.create_team(name=team)
            sprint.team = team
            sprint.save()
        return sprint
예제 #32
0
 def _get_remaining_time_now(self, env, sprint):
     from agilo.scrum import SprintController
     cmd_class = SprintController.GetTotalRemainingTimeCommand
     cmd_tot_rem_time = cmd_class(env, sprint=sprint, day=now(tz=utc), 
                                  tickets=self.tickets)
     commitment = SprintController(env).process_command(cmd_tot_rem_time)
     return commitment
예제 #33
0
    def _record_value_change(self,
                             sprint,
                             point_change,
                             component=None,
                             fieldname=Key.REMAINING_TIME):
        if fieldname == Key.STORY_POINTS:
            change = BurndownDataChange.remaining_points_entry(
                self.env, point_change, sprint, now())
        else:
            change = BurndownDataChange.remaining_time_entry(
                self.env, point_change, sprint, now())

        if component is not None and AgiloConfig(
                self.env).is_filtered_burndown_enabled():
            change.update_marker(Key.COMPONENT, component)
        change.save()
예제 #34
0
 def test_can_not_confirm_if_sprint_started_more_than_one_day_ago(self):
     self.teh.disable_sprint_date_normalization()
     team = self.teh.create_team('A-Team')
     two_days_ago = now() - timedelta(days=2)
     sprint = self.teh.create_sprint('Sprint', start=two_days_ago, team=team)
     
     self.assert_false(self.policy_decision(sprint.resource()))
예제 #35
0
 def testStoreRemainingTimeAsTimestamp(self):
     task = self.teh.create_ticket(Type.TASK)
     task[Key.REMAINING_TIME] = '5'
     task.save_changes(None, None)
     
     an_hour_before = now() - timedelta(hours=1)
     half_an_hour_before = now() - timedelta(minutes=30)
     
     remaining = RemainingTime(self.env, task)
     remaining.set_remaining_time(3, day=an_hour_before)
     
     self.assert_equals(5, remaining.get_remaining_time())
     self.assert_equals(5, remaining.get_remaining_time(now()))
     self.assert_equals(3, remaining.get_remaining_time(half_an_hour_before))
     self.assert_equals(3, remaining.get_remaining_time(an_hour_before))
     self.assert_equals(0, remaining.get_remaining_time(yesterday()))
예제 #36
0
 def setUp(self):
     self.super()
     self.start = normalize_date(now())
     duration = timedelta(days=20)
     self.end = normalize_date(self.start + duration)
     self.manager = SprintModelManager(self.env)
     self.tmm = TeamMemberModelManager(self.env)
예제 #37
0
 def testSprintIsNotCurrentlyRunningAfterSprintEnd(self):
     today = now()
     sprint_start = today - timedelta(days=20)
     sprint = self.teh.create_sprint("Test", start=sprint_start)
     sprint.end = today - timedelta(days=10)
     # Sprint ended ten days before today
     self.assert_false(sprint.is_currently_running)
     self.assert_true(sprint.is_closed)
예제 #38
0
 def testSprintIsNotCurrentlyRunningAfterSprintEnd(self):
     today = now()
     sprint_start = today - timedelta(days=20)
     sprint = self.teh.create_sprint("Test", start=sprint_start)
     sprint.end = today - timedelta(days=10)
     # Sprint ended ten days before today
     self.assert_false(sprint.is_currently_running)
     self.assert_true(sprint.is_closed)
예제 #39
0
 def test_can_extend_series_till_specified_time(self):
     first = self.change(timedelta(hours=-10), 10)
     end = now()
     aggregated = self.aggregate([first], extend_until=end)
     self.assert_equals([
         burndown_entry(first.when, first.delta()),
         burndown_entry(end, first.delta())
     ], aggregated)
예제 #40
0
 def _execute(self, sp_controller, date_converter, as_key):
     today = now(tz=utc) 
     day = self.day or today
     actual_burndown = \
         self._get_remaining_times_for_interval(sp_controller.env, day, 
                 day, self.sprint, sp_controller, append_current_time=True)
     self._inject_commitment(actual_burndown, self.commitment)
     return sum(self._transform_to_old_structure(actual_burndown))
예제 #41
0
 def create_change(self, **kwargs):
     change = BurndownDataChange(self.env)
     change.type = 'fnord'
     change.scope = self.sprint.name
     change.when = now()
     for key, value in kwargs.items():
         setattr(change, key, value)
     return change
예제 #42
0
 def _create_sprint_with_team_and_team_member(self, sprint_name, team_name):
     self._tester.login_as(Usernames.admin)
     self._tester.create_new_team(team_name)
     self._tester.add_member_to_team(team_name, 'RestrictOwnerTeamMember')
     self._tester.create_sprint_via_admin(sprint_name,
                                          now(),
                                          duration=9,
                                          team=team_name)
예제 #43
0
    def test_only_one_point_for_today(self):
        # this is the crazy burndown chart regression test
        self.assert_true(self.sprint.is_currently_running)

        bangkok = get_timezone('GMT +7:00')
        times = self.get_times_from_chart(tz=bangkok)
        self.assert_smaller_than(times[-2], times[-1])
        self.assert_time_equals(now(), times[-1])
예제 #44
0
    def testStoreRemainingTimeAsTimestamp(self):
        task = self.teh.create_ticket(Type.TASK)
        task[Key.REMAINING_TIME] = '5'
        task.save_changes(None, None)

        an_hour_before = now() - timedelta(hours=1)
        half_an_hour_before = now() - timedelta(minutes=30)

        remaining = RemainingTime(self.env, task)
        remaining.set_remaining_time(3, day=an_hour_before)

        self.assert_equals(5, remaining.get_remaining_time())
        self.assert_equals(5, remaining.get_remaining_time(now()))
        self.assert_equals(3,
                           remaining.get_remaining_time(half_an_hour_before))
        self.assert_equals(3, remaining.get_remaining_time(an_hour_before))
        self.assert_equals(0, remaining.get_remaining_time(yesterday()))
예제 #45
0
 def test_confirm_commitment_uses_current_remaining_time(self):
     self.sprint.start = now() - timedelta(hours=2)
     self.sprint.save()
     task_properties = {Key.REMAINING_TIME: '7', Key.SPRINT: self.sprint.name}
     self.teh.create_ticket(Type.TASK, props=task_properties)
     
     commitment = TeamController.confirm_commitment_for_sprint(self.env, self.sprint)
     self.assert_equals(7, commitment)
예제 #46
0
 def test_only_one_point_for_today(self):
     # this is the crazy burndown chart regression test
     self.assert_true(self.sprint.is_currently_running)
     
     bangkok = get_timezone('GMT +7:00')
     times = self.get_times_from_chart(tz=bangkok)
     self.assert_smaller_than(times[-2], times[-1])
     self.assert_time_equals(now(), times[-1])
예제 #47
0
        def _execute(self, sp_controller, date_converter, as_key):
            env = sp_controller.env
            end = min(self.sprint.end, now(tz=utc))

            from agilo.scrum.burndown.model import BurndownDataAggregator
            aggregator = BurndownDataAggregator(env, self.remaining_field)
            return aggregator.burndown_data_for_sprint(self.sprint,
                extend_until=end, filter_by_component=self.filter_by_component)
예제 #48
0
 def _create_remaining_times(self,
                             when_to_create_second_remaining_time=None):
     self._create_sprint_with_team()
     self._remaining_time(3 + 6 + 9, self.sprint.start)  # 18
     if when_to_create_second_remaining_time is None:
         when_to_create_second_remaining_time = now() - timedelta(hours=3)
     self._remaining_time(-1 + -2 + -3,
                          when_to_create_second_remaining_time)  # -6
예제 #49
0
 def setUp(self):
     self.super()
     self.teh.disable_sprint_date_normalization()
     self.sprint = self.teh.create_sprint(name='Sprint 1', start=now() - timedelta(days=3), end=now() + timedelta(days=3))
     # already enteres a remaining time!
     self.task = self.teh.create_task(remaining_time=5, sprint=self.sprint.name)
     
     self.assert_true(self.sprint.is_currently_running)
예제 #50
0
 def _execute(self, sp_controller, date_converter, as_key):
     today = now(tz=utc)
     day = self.day or today
     actual_burndown = \
         self._get_remaining_times_for_interval(sp_controller.env, day,
                 day, self.sprint, sp_controller, append_current_time=True)
     self._inject_commitment(actual_burndown, self.commitment)
     return sum(self._transform_to_old_structure(actual_burndown))