Edgewall Software
Modify

Opened 45 hours ago

Closed 12 hours ago

#13871 closed defect (fixed)

Daysback in timeline page has off-by-one issue

Reported by: Jun Omae Owned by: Jun Omae
Priority: normal Milestone: 1.6.1
Component: timeline Version: 1.2
Severity: normal Keywords:
Cc: Branch:
Release Notes:

Restored allowing 0 to daysback field of timeline.

API Changes:
Internal Changes:

Description

When submitting form in timeline page with 1 in daysback field, the user expects searching events between yesterday of the from date and the from date (just one day). However, it actually searches events between 2 days ago of the from date and the from date.

Also, entering 0 in the daysback field, the timeline page treat as 1. As the result, it is unable to search events for just one day. Before Trac 1.2, entering 0 in the daysback field is able to search events for just one day.

  • trac/timeline/web_ui.py

    diff --git a/trac/timeline/web_ui.py b/trac/timeline/web_ui.py
    index 719618fd2..c186add27 100644
    a b class TimelineModule(Component):  
    174174
    175175        stop = fromdate
    176176        start = to_datetime(stop.replace(tzinfo=None) -
    177                             timedelta(days=daysback + 1), req.tz)
     177                            timedelta(days=daysback), req.tz)
    178178
    179179        # create author include and exclude sets
    180180        include = set()
  • trac/timeline/tests/web_ui.py

    diff --git a/trac/timeline/tests/web_ui.py b/trac/timeline/tests/web_ui.py
    index 0877c6225..b917b0e30 100644
    a b class TimelineEventProviderTestCase(unittest.TestCase):  
    225225                yield ('test', 'Test')
    226226
    227227            def get_timeline_events(self, req, start, stop, filters):
    228                 return iter(self._events or ())
     228                for event in self._events:
     229                    if start <= event[1] <= stop:
     230                        yield event
    229231
    230232            def render_timeline_event(self, context, field, event):
    231233                return event[3].render(context, field, event)
    class TimelineEventProviderTestCase(unittest.TestCase):  
    270272            ('test&2', datetime(2018, 3, 19, 23, 56, 12, 987654, utc),
    271273             'Joe <joe@example.org>', Mock(render=render)),
    272274        ]
    273         req = MockRequest(self.env, path_info='/timeline',
    274                           args={'format': 'rss'})
     275        req = MockRequest(self.env, path_info='/timeline', tz=utc,
     276                          args={'format': 'rss', 'daysback': '90',
     277                                'from': '2018-04-30T00:00:00Z'})
    275278        rv = self._process_request(req)
    276279        self.assertEqual('timeline.rss', rv[0])
    277280        self.assertEqual({'content_type': 'application/rss+xml'}, rv[2])
    class TimelineEventProviderTestCase(unittest.TestCase):  
    307310        self.assertEqual('<?xml version="1.0"?>', output[:21])
    308311        minidom.parseString(output)  # verify valid xml
    309312
     313    def test_daysback(self):
     314        provider = self.timeline_event_providers['normal'](self.env)
     315        provider._events = [
     316            ('test', datetime(2025, 2, 19, 12, tzinfo=utc),
     317             'trac', None),
     318            ('test', datetime(2025, 2, 18, 12, tzinfo=utc),
     319             'trac', None),
     320        ]
     321        req = MockRequest(self.env, path_info='/timeline', tz=utc,
     322                          args={'from': '2025-02-19T00:00:00Z',
     323                                'daysback': '1'})
     324        rv = self._process_request(req)
     325        data = rv[1]
     326        events = data['events']
     327        self.assertEqual(1, len(events))
     328        self.assertEqual(datetime(2025, 2, 19, 12, tzinfo=utc),
     329                         events[0]['datetime'])
     330
    310331    def _process_request(self, req):
    311332        mod = TimelineModule(self.env)
    312         req = MockRequest(self.env, path_info='/timeline',
    313                           args={'format': 'rss'})
    314333        self.assertTrue(mod.match_request(req))
    315334        return mod.process_request(req)
    316335

Attachments (0)

Change History (2)

comment:1 by Jun Omae, 32 hours ago

Proposed changes in [5cd8a7449/jomae.git] (jomae.git@t13871).

The issue is introduced in [14702]. Reconsidering the issue, I think we should simply restore allowing 0 to daysback field in timeline.

comment:2 by Jun Omae, 12 hours ago

Release Notes: modified (diff)
Resolution: fixed
Status: assignedclosed

Committed in [17887] and merged in [17888].

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Jun Omae.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Jun Omae to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.