Skip to content

Commit 6b4638d

Browse files
committed
test: Add comprehensive tests for timestamp parsing functionality
- Add TestParseSnowflakeTimestamp class with 10 test cases - Test parsing timestamps with different timezone offsets - Test handling of invalid formats and edge cases - Test null/empty inputs and non-string inputs - Update TestFormatSnowflakeRow to test timestamp column parsing - Test case-insensitive timestamp column detection - All 45 database tests passing Ensures robust testing coverage for the timestamp parsing fix that resolves discrepancy between MCP server dates and JIRA UI dates.
1 parent 480e7e9 commit 6b4638d

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

tests/test_database.py

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
make_snowflake_request,
1313
execute_snowflake_query,
1414
format_snowflake_row,
15+
parse_snowflake_timestamp,
1516
get_issue_labels,
1617
get_issue_comments,
1718
get_issue_links
@@ -256,6 +257,98 @@ async def test_query_exception(self, mock_track, mock_request):
256257
mock_track.assert_called_once()
257258

258259

260+
class TestParseSnowflakeTimestamp:
261+
"""Test cases for parse_snowflake_timestamp function"""
262+
263+
def test_parse_timestamp_with_offset(self):
264+
"""Test parsing timestamp with timezone offset"""
265+
# Test with actual KONFLUX-9430 timestamp
266+
timestamp_str = "1753767533.658000000 1440"
267+
result = parse_snowflake_timestamp(timestamp_str)
268+
269+
# Should convert to ISO format with timezone offset applied
270+
assert result == "2025-07-30T05:38:53.658000+00:00"
271+
272+
def test_parse_timestamp_different_offsets(self):
273+
"""Test parsing timestamps with different timezone offsets"""
274+
test_cases = [
275+
("1753767533.658000000 1440", "2025-07-30T05:38:53.658000+00:00"), # +24 hours
276+
("1753767533.658000000 0", "2025-07-29T05:38:53.658000+00:00"), # no offset
277+
("1753767533.658000000 -300", "2025-07-29T00:38:53.658000+00:00"), # -5 hours
278+
]
279+
280+
for input_timestamp, expected_output in test_cases:
281+
result = parse_snowflake_timestamp(input_timestamp)
282+
assert result == expected_output
283+
284+
def test_parse_timestamp_without_offset(self):
285+
"""Test parsing timestamp without timezone offset"""
286+
timestamp_str = "1753767533.658000000"
287+
result = parse_snowflake_timestamp(timestamp_str)
288+
289+
# Should convert to UTC ISO format
290+
assert result == "2025-07-29T05:38:53.658000+00:00"
291+
292+
def test_parse_timestamp_integer_seconds(self):
293+
"""Test parsing timestamp with integer seconds"""
294+
timestamp_str = "1753767533 1440"
295+
result = parse_snowflake_timestamp(timestamp_str)
296+
297+
# Should handle integer timestamps
298+
assert result == "2025-07-30T05:38:53+00:00"
299+
300+
def test_parse_timestamp_none_input(self):
301+
"""Test parsing None input"""
302+
result = parse_snowflake_timestamp(None)
303+
assert result is None
304+
305+
def test_parse_timestamp_empty_string(self):
306+
"""Test parsing empty string"""
307+
result = parse_snowflake_timestamp("")
308+
assert result == ""
309+
310+
def test_parse_timestamp_non_string_input(self):
311+
"""Test parsing non-string input"""
312+
result = parse_snowflake_timestamp(123)
313+
assert result == 123
314+
315+
def test_parse_timestamp_invalid_format(self):
316+
"""Test parsing invalid timestamp format"""
317+
invalid_timestamps = [
318+
"invalid_timestamp",
319+
"1753767533.658000000 invalid_offset",
320+
"not_a_number 1440",
321+
]
322+
323+
for invalid_ts in invalid_timestamps:
324+
result = parse_snowflake_timestamp(invalid_ts)
325+
# Should return original string if parsing fails
326+
assert result == invalid_ts
327+
328+
def test_parse_timestamp_with_extra_data(self):
329+
"""Test parsing timestamp with extra data - should still parse the valid parts"""
330+
timestamp_str = "1753767533.658000000 1440 extra_data"
331+
result = parse_snowflake_timestamp(timestamp_str)
332+
333+
# Function should parse the first two parts and ignore extra data
334+
assert result == "2025-07-30T05:38:53.658000+00:00"
335+
336+
def test_parse_timestamp_edge_cases(self):
337+
"""Test parsing edge case timestamps"""
338+
test_cases = [
339+
# Very large offset
340+
("1753767533.658000000 43200", "2025-08-28T05:38:53.658000+00:00"), # +30 days
341+
# Negative large offset
342+
("1753767533.658000000 -43200", "2025-06-29T05:38:53.658000+00:00"), # -30 days
343+
# Zero timestamp
344+
("0.0 0", "1970-01-01T00:00:00+00:00"),
345+
]
346+
347+
for input_timestamp, expected_output in test_cases:
348+
result = parse_snowflake_timestamp(input_timestamp)
349+
assert result == expected_output
350+
351+
259352
class TestFormatSnowflakeRow:
260353
"""Test cases for format_snowflake_row function"""
261354

@@ -287,6 +380,61 @@ def test_format_empty_data(self):
287380

288381
assert result == {}
289382

383+
def test_format_with_timestamp_columns(self):
384+
"""Test formatting with timestamp columns that should be parsed"""
385+
row_data = ["123", "1753767533.658000000 1440", "1753824211.261000000 1440", "regular_value"]
386+
columns = ["ID", "CREATED", "RESOLUTIONDATE", "SUMMARY"]
387+
388+
result = format_snowflake_row(row_data, columns)
389+
390+
expected = {
391+
"ID": "123",
392+
"CREATED": "2025-07-30T05:38:53.658000+00:00",
393+
"RESOLUTIONDATE": "2025-07-30T21:23:31.261000+00:00",
394+
"SUMMARY": "regular_value"
395+
}
396+
assert result == expected
397+
398+
def test_format_with_non_timestamp_columns(self):
399+
"""Test formatting with non-timestamp columns that should not be parsed"""
400+
row_data = ["123", "1753767533.658000000 1440", "some_description"]
401+
columns = ["ID", "SOME_NUMBER", "DESCRIPTION"] # SOME_NUMBER is not a recognized timestamp column
402+
403+
result = format_snowflake_row(row_data, columns)
404+
405+
expected = {
406+
"ID": "123",
407+
"SOME_NUMBER": "1753767533.658000000 1440", # Should not be parsed
408+
"DESCRIPTION": "some_description"
409+
}
410+
assert result == expected
411+
412+
def test_format_with_null_timestamp_values(self):
413+
"""Test formatting with null timestamp values"""
414+
row_data = ["123", None, "", "value"]
415+
columns = ["ID", "CREATED", "UPDATED", "SUMMARY"]
416+
417+
result = format_snowflake_row(row_data, columns)
418+
419+
expected = {
420+
"ID": "123",
421+
"CREATED": None, # None should remain None
422+
"UPDATED": "", # Empty string should remain empty
423+
"SUMMARY": "value"
424+
}
425+
assert result == expected
426+
427+
def test_format_case_insensitive_timestamp_columns(self):
428+
"""Test that timestamp column detection is case insensitive"""
429+
row_data = ["123", "1753767533.658000000 1440", "1753824211.261000000 1440"]
430+
columns = ["id", "created", "Updated"] # Mixed case
431+
432+
result = format_snowflake_row(row_data, columns)
433+
434+
# Should still parse timestamps regardless of case
435+
assert "2025-07-30T05:38:53.658000+00:00" in result["created"]
436+
assert "2025-07-30T21:23:31.261000+00:00" in result["Updated"]
437+
290438

291439
class TestGetIssueLabels:
292440
"""Test cases for get_issue_labels function"""

0 commit comments

Comments
 (0)