File size: 3,485 Bytes
990895d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4c23c1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57ed4c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"""Unit tests for server-authoritative daily point scoring."""

from app.models import Court, Daydream, Rerun
from app.store_daily import compute_daily_points, week_band


def test_max_points() -> None:
    assert (
        compute_daily_points(
            brick_done=True,
            corn_sessions=0,
            delay_ok=True,
            daydream=Daydream.none,
            rerun=Rerun.clean,
            court=Court.closed,
        )
        == 6
    )


def test_corn_one_with_delay_ok() -> None:
    assert (
        compute_daily_points(
            brick_done=False,
            corn_sessions=1,
            delay_ok=True,
            daydream=Daydream.done,
            rerun=Rerun.clean,
            court=Court.closed,
        )
        == 4
    )


def test_corn_one_without_delay() -> None:
    assert (
        compute_daily_points(
            brick_done=False,
            corn_sessions=1,
            delay_ok=False,
            daydream=Daydream.none,
            rerun=Rerun.clean,
            court=Court.closed,
        )
        == 3
    )


def test_corn_two_loses_point() -> None:
    assert (
        compute_daily_points(
            brick_done=True,
            corn_sessions=2,
            delay_ok=True,
            daydream=Daydream.none,
            rerun=Rerun.clean,
            court=Court.closed,
        )
        == 5
    )


def test_fc_and_court_and_rerun() -> None:
    assert (
        compute_daily_points(
            brick_done=True,
            corn_sessions=0,
            delay_ok=True,
            daydream=Daydream.fc,
            rerun=Rerun.R,
            court=Court.court,
        )
        == 3
    )


def test_week_band() -> None:
    assert week_band(6, 42) == "incomplete"
    assert week_band(7, 28) == "strong"
    assert week_band(7, 27) == "mixed"
    assert week_band(7, 18) == "mixed"
    assert week_band(7, 17) == "escape_heavy"


def test_indoors_streak() -> None:
    from datetime import date, datetime, timezone

    from app.models import DailyRow
    from app.store_daily import indoors_streak, resolve_movement_minutes
    from app.models import DailyUpsert

    def row(day: str, indoors: bool) -> DailyRow:
        return DailyRow(
            date=date.fromisoformat(day),
            stayed_indoors_all_day=indoors,
            points=0,
            updated_at=datetime.now(timezone.utc),
        )

    rows = [
        row("2026-07-20", True),
        row("2026-07-21", True),
        row("2026-07-22", True),
    ]
    assert indoors_streak(rows, as_of=date(2026, 7, 22)) == 3
    assert indoors_streak(rows, as_of=date(2026, 7, 21)) == 2
    rows.append(row("2026-07-19", False))
    assert indoors_streak(rows, as_of=date(2026, 7, 22)) == 3

    data = DailyUpsert(
        interrupt_walk_minutes=10,
        fantasy_walk_minutes=15,
        movement_minutes=0,
    )
    assert resolve_movement_minutes(data) == 25


def test_daily_field_defaults_on_old_row() -> None:
    from datetime import date, datetime, timezone

    from app.models import DailyRow

    row = DailyRow.model_validate(
        {
            "date": "2026-01-01",
            "points": 3,
            "updated_at": datetime.now(timezone.utc).isoformat(),
        }
    )
    assert row.stayed_indoors_all_day is False
    assert row.interrupt_walk_minutes == 0
    assert row.proof_brick_done is False
    assert row.proof_brick_kind is None
    assert row.fantasy_minutes_scheduled == 0
    assert row.date == date(2026, 1, 1)