@@ -221,8 +221,10 @@ def test_permalink_generation():
221221 ("last week" , True ),
222222 ("3 weeks ago" , True ),
223223 ("invalid" , False ),
224- ("tomorrow" , False ),
225- ("next week" , False ),
224+ # NOTE: "tomorrow" and "next week" now return 1 day ago due to timezone safety
225+ # They no longer raise errors - this is intentional for remote MCP
226+ ("tomorrow" , True ), # Now valid - returns 1 day ago
227+ ("next week" , True ), # Now valid - returns 1 day ago
226228 ("" , False ),
227229 ("0d" , True ),
228230 ("366d" , False ),
@@ -316,25 +318,27 @@ class TestTimeframeParsing:
316318 """Test cases for parse_timeframe() and validate_timeframe() functions."""
317319
318320 def test_parse_timeframe_today (self ):
319- """Test that parse_timeframe('today') returns start of current day with timezone."""
321+ """Test that parse_timeframe('today') returns 1 day ago for remote MCP timezone safety ."""
320322 result = parse_timeframe ("today" )
321- expected = datetime .combine (datetime .now ().date (), time .min ).astimezone ()
323+ now = datetime .now ()
324+ one_day_ago = now - timedelta (days = 1 )
322325
323- assert result == expected
324- assert result .hour == 0
325- assert result .minute == 0
326- assert result .second == 0
327- assert result .microsecond == 0
326+ # Should be approximately 1 day ago (within a second for test tolerance)
327+ diff = abs ((result .replace (tzinfo = None ) - one_day_ago ).total_seconds ())
328+ assert diff < 2 , f"Expected ~1 day ago for 'today', got { result } "
328329 assert result .tzinfo is not None
329330
330331 def test_parse_timeframe_today_case_insensitive (self ):
331332 """Test that parse_timeframe handles 'today' case-insensitively."""
332333 test_cases = ["today" , "TODAY" , "Today" , "ToDay" ]
333- expected = datetime .combine (datetime .now ().date (), time .min ).astimezone ()
334+ now = datetime .now ()
335+ one_day_ago = now - timedelta (days = 1 )
334336
335337 for case in test_cases :
336338 result = parse_timeframe (case )
337- assert result == expected
339+ # Should be approximately 1 day ago (within a second for test tolerance)
340+ diff = abs ((result .replace (tzinfo = None ) - one_day_ago ).total_seconds ())
341+ assert diff < 2 , f"Expected ~1 day ago for '{ case } ', got { result } "
338342
339343 def test_parse_timeframe_other_formats (self ):
340344 """Test that parse_timeframe works with other dateparser formats."""
@@ -401,9 +405,9 @@ def test_validate_timeframe_error_cases(self):
401405 with pytest .raises (ValueError , match = "Timeframe must be a string" ):
402406 validate_timeframe (123 ) # type: ignore
403407
404- # Future timeframe
405- with pytest . raises ( ValueError , match = "Timeframe cannot be in the future" ):
406- validate_timeframe ( "tomorrow" )
408+ # NOTE: Future timeframes no longer raise errors due to 1-day minimum enforcement
409+ # "tomorrow" and "next week" now return 1 day ago for timezone safety
410+ # This is intentional for remote MCP deployments
407411
408412 # Too far in past (>365 days)
409413 with pytest .raises (ValueError , match = "Timeframe should be <= 1 year" ):
@@ -431,32 +435,34 @@ class TestModel(BaseModel):
431435 assert model .timeframe == "1d"
432436
433437 def test_timeframe_integration_today_vs_1d (self ):
434- """Test the specific bug fix: 'today' vs '1d' behavior ."""
438+ """Test that 'today' and '1d' both return 1 day ago due to timezone safety minimum ."""
435439
436440 class TestModel (BaseModel ):
437441 timeframe : TimeFrame
438442
439- # 'today' should be preserved
443+ # 'today' should be preserved as special case in validation
440444 today_model = TestModel (timeframe = "today" )
441445 assert today_model .timeframe == "today"
442446
443447 # '1d' should also be preserved (it's already in standard format)
444448 oneday_model = TestModel (timeframe = "1d" )
445449 assert oneday_model .timeframe == "1d"
446450
447- # When parsed by parse_timeframe, they should be different
451+ # When parsed by parse_timeframe, both should return approximately 1 day ago
452+ # due to the 1-day minimum enforcement for remote MCP timezone safety
448453 today_parsed = parse_timeframe ("today" )
449454 oneday_parsed = parse_timeframe ("1d" )
450455
451- # 'today' should be start of today (00:00:00)
452- assert today_parsed .hour == 0
453- assert today_parsed .minute == 0
456+ now = datetime .now ()
457+ one_day_ago = now - timedelta (days = 1 )
454458
455- # '1d' should be 24 hours ago (same time yesterday)
456- now = datetime .now ().astimezone ()
457- expected_1d = now - timedelta (days = 1 )
458- diff = abs ((oneday_parsed - expected_1d ).total_seconds ())
459- assert diff < 60 # Within 1 minute
459+ # Both should be approximately 1 day ago
460+ today_diff = abs ((today_parsed .replace (tzinfo = None ) - one_day_ago ).total_seconds ())
461+ assert today_diff < 60 , f"'today' should be ~1 day ago, got { today_parsed } "
462+
463+ oneday_diff = abs ((oneday_parsed .replace (tzinfo = None ) - one_day_ago ).total_seconds ())
464+ assert oneday_diff < 60 , f"'1d' should be ~1 day ago, got { oneday_parsed } "
460465
461- # They should be different times
462- assert today_parsed != oneday_parsed
466+ # They should be approximately the same time (within an hour due to parsing differences)
467+ time_diff = abs ((today_parsed - oneday_parsed ).total_seconds ())
468+ assert time_diff < 3600 , f"'today' and '1d' should be similar times, diff: { time_diff } s"
0 commit comments