11"""Tests for data aggregator module."""
22
33from datetime import datetime , timezone
4+ from pathlib import Path
45
56import pytest
67
1011 AggregatedStatsData ,
1112 UsageAggregator ,
1213)
14+ from claude_monitor .types import CompleteAggregatedUsage
15+
16+
17+ def get_daily_result_date (result : CompleteAggregatedUsage ) -> str :
18+ """Get date from daily aggregation result, which should always have date set."""
19+ assert "date" in result , "Daily aggregation result should have date field"
20+ return result ["date" ] # type: ignore[return-value,no-any-return] # Daily aggregation always sets date
21+
22+
23+ def get_monthly_result_month (result : CompleteAggregatedUsage ) -> str :
24+ """Get month from monthly aggregation result, which should always have month set."""
25+ assert "month" in result , "Monthly aggregation result should have month field"
26+ return result ["month" ] # type: ignore[return-value,no-any-return] # Monthly aggregation always sets month
1327
1428
1529class TestAggregatedStats :
@@ -206,7 +220,7 @@ def test_add_entry_with_unknown_model(self) -> None:
206220 cache_creation_tokens = 0 ,
207221 cache_read_tokens = 0 ,
208222 cost_usd = 0.001 ,
209- model = None ,
223+ model = "unknown" ,
210224 message_id = "msg_1" ,
211225 request_id = "req_1" ,
212226 )
@@ -247,7 +261,7 @@ def test_to_dict_daily(self) -> None:
247261
248262 result = period .to_dict ("date" )
249263
250- assert result [ "date" ] == "2024-01-01"
264+ assert get_daily_result_date ( result ) == "2024-01-01"
251265 assert result ["input_tokens" ] == 1000
252266 assert result ["output_tokens" ] == 500
253267 assert result ["cache_creation_tokens" ] == 100
@@ -273,7 +287,7 @@ def test_to_dict_monthly(self) -> None:
273287
274288 result = period .to_dict ("month" )
275289
276- assert result [ "month" ] == "2024-01"
290+ assert get_monthly_result_month ( result ) == "2024-01"
277291 assert result ["input_tokens" ] == 10000
278292 assert result ["total_cost" ] == 0.5
279293
@@ -282,7 +296,7 @@ class TestUsageAggregator:
282296 """Test cases for UsageAggregator class."""
283297
284298 @pytest .fixture
285- def aggregator (self , tmp_path ) -> UsageAggregator :
299+ def aggregator (self , tmp_path : Path ) -> UsageAggregator :
286300 """Create a UsageAggregator instance."""
287301 return UsageAggregator (data_path = str (tmp_path ))
288302
@@ -335,7 +349,7 @@ def test_aggregate_daily_basic(
335349
336350 # Check first day (Jan 1 - 4 entries: 2 at 10AM, 2 at 2PM)
337351 jan1 = result [0 ]
338- assert jan1 [ "date" ] == "2024-01-01"
352+ assert get_daily_result_date ( jan1 ) == "2024-01-01"
339353 assert jan1 ["input_tokens" ] == 400 # 4 entries * 100
340354 assert jan1 ["output_tokens" ] == 200 # 4 entries * 50
341355 assert jan1 ["total_cost" ] == 0.004 # 4 entries * 0.001
@@ -355,8 +369,8 @@ def test_aggregate_daily_with_date_filter(
355369
356370 # Should have Jan 15 and Jan 31 (entries on those days are within the filter)
357371 assert len (result ) == 2
358- assert result [0 ][ "date" ] == "2024-01-15"
359- assert result [1 ][ "date" ] == "2024-01-31"
372+ assert get_daily_result_date ( result [0 ]) == "2024-01-15"
373+ assert get_daily_result_date ( result [1 ]) == "2024-01-31"
360374
361375 def test_aggregate_monthly_basic (
362376 self , aggregator : UsageAggregator , sample_entries : list [UsageEntry ]
@@ -369,7 +383,7 @@ def test_aggregate_monthly_basic(
369383
370384 # Check January
371385 jan = result [0 ]
372- assert jan [ "month" ] == "2024-01"
386+ assert get_monthly_result_month ( jan ) == "2024-01"
373387 assert jan ["input_tokens" ] == 1400 # 14 entries * 100
374388 assert jan ["output_tokens" ] == 700 # 14 entries * 50
375389 assert (
@@ -380,7 +394,7 @@ def test_aggregate_monthly_basic(
380394
381395 # Check February
382396 feb = result [1 ]
383- assert feb [ "month" ] == "2024-02"
397+ assert get_monthly_result_month ( feb ) == "2024-02"
384398 assert feb ["input_tokens" ] == 600 # 3 entries * 200
385399 assert feb ["output_tokens" ] == 300 # 3 entries * 100
386400 assert feb ["total_cost" ] == 0.006 # 3 entries * 0.002
@@ -397,7 +411,7 @@ def test_aggregate_monthly_with_date_filter(
397411
398412 # Should only have February
399413 assert len (result ) == 1
400- assert result [0 ][ "month" ] == "2024-02"
414+ assert get_monthly_result_month ( result [0 ]) == "2024-02"
401415
402416 def test_aggregate_from_blocks_daily (
403417 self , aggregator : UsageAggregator , sample_entries : list [UsageEntry ]
@@ -435,7 +449,7 @@ def test_aggregate_from_blocks_daily(
435449 result = aggregator .aggregate_from_blocks (blocks , "daily" )
436450
437451 assert len (result ) >= 2 # At least 2 days of data
438- assert result [0 ][ "date" ] == "2024-01-01"
452+ assert get_daily_result_date ( result [0 ]) == "2024-01-01"
439453
440454 def test_aggregate_from_blocks_monthly (
441455 self , aggregator : UsageAggregator , sample_entries : list [UsageEntry ]
@@ -454,8 +468,8 @@ def test_aggregate_from_blocks_monthly(
454468 result = aggregator .aggregate_from_blocks ([block ], "monthly" )
455469
456470 assert len (result ) == 2 # Jan and Feb
457- assert result [0 ][ "month" ] == "2024-01"
458- assert result [1 ][ "month" ] == "2024-02"
471+ assert get_monthly_result_month ( result [0 ]) == "2024-01"
472+ assert get_monthly_result_month ( result [1 ]) == "2024-02"
459473
460474 def test_aggregate_from_blocks_invalid_view_type (
461475 self , aggregator : UsageAggregator
@@ -488,25 +502,31 @@ def test_calculate_totals_empty(self, aggregator: UsageAggregator) -> None:
488502
489503 def test_calculate_totals_with_data (self , aggregator : UsageAggregator ) -> None :
490504 """Test calculating totals with aggregated data."""
491- aggregated_data = [
492- {
493- "date" : "2024-01-01" ,
494- "input_tokens" : 1000 ,
495- "output_tokens" : 500 ,
496- "cache_creation_tokens" : 100 ,
497- "cache_read_tokens" : 50 ,
498- "total_cost" : 0.05 ,
499- "entries_count" : 10 ,
500- },
501- {
502- "date" : "2024-01-02" ,
503- "input_tokens" : 2000 ,
504- "output_tokens" : 1000 ,
505- "cache_creation_tokens" : 200 ,
506- "cache_read_tokens" : 100 ,
507- "total_cost" : 0.10 ,
508- "entries_count" : 20 ,
509- },
505+ from claude_monitor .types import CompleteAggregatedUsage
506+
507+ aggregated_data : list [CompleteAggregatedUsage ] = [
508+ CompleteAggregatedUsage (
509+ date = "2024-01-01" ,
510+ input_tokens = 1000 ,
511+ output_tokens = 500 ,
512+ cache_creation_tokens = 100 ,
513+ cache_read_tokens = 50 ,
514+ total_cost = 0.05 ,
515+ entries_count = 10 ,
516+ models_used = [],
517+ model_breakdowns = {},
518+ ),
519+ CompleteAggregatedUsage (
520+ date = "2024-01-02" ,
521+ input_tokens = 2000 ,
522+ output_tokens = 1000 ,
523+ cache_creation_tokens = 200 ,
524+ cache_read_tokens = 100 ,
525+ total_cost = 0.10 ,
526+ entries_count = 20 ,
527+ models_used = [],
528+ model_breakdowns = {},
529+ ),
510530 ]
511531
512532 result = aggregator .calculate_totals (aggregated_data )
@@ -573,9 +593,9 @@ def test_period_sorting(self, aggregator: UsageAggregator) -> None:
573593 # Test daily sorting
574594 daily_result = aggregator .aggregate_daily (entries )
575595 assert len (daily_result ) == 3
576- assert daily_result [0 ][ "date" ] == "2024-01-01"
577- assert daily_result [1 ][ "date" ] == "2024-01-10"
578- assert daily_result [2 ][ "date" ] == "2024-01-15"
596+ assert get_daily_result_date ( daily_result [0 ]) == "2024-01-01"
597+ assert get_daily_result_date ( daily_result [1 ]) == "2024-01-10"
598+ assert get_daily_result_date ( daily_result [2 ]) == "2024-01-15"
579599
580600 # Test monthly sorting
581601 monthly_entries = [
@@ -616,6 +636,6 @@ def test_period_sorting(self, aggregator: UsageAggregator) -> None:
616636
617637 monthly_result = aggregator .aggregate_monthly (monthly_entries )
618638 assert len (monthly_result ) == 3
619- assert monthly_result [0 ][ "month" ] == "2024-01"
620- assert monthly_result [1 ][ "month" ] == "2024-02"
621- assert monthly_result [2 ][ "month" ] == "2024-03"
639+ assert get_monthly_result_month ( monthly_result [0 ]) == "2024-01"
640+ assert get_monthly_result_month ( monthly_result [1 ]) == "2024-02"
641+ assert get_monthly_result_month ( monthly_result [2 ]) == "2024-03"
0 commit comments