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
|
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
import pytest
from pydantic import ValidationError
from generalresearch.models.thl.user_streak import (
UserStreak,
StreakPeriod,
StreakFulfillment,
StreakState,
)
def test_user_streak_empty_fail():
us = UserStreak(
period=StreakPeriod.DAY,
fulfillment=StreakFulfillment.COMPLETE,
country_iso="us",
user_id=1,
last_fulfilled_period_start=None,
current_streak=0,
longest_streak=0,
state=StreakState.BROKEN,
)
assert us.time_remaining_in_period is None
with pytest.raises(
ValidationError, match="StreakState.BROKEN but current_streak not 0"
):
UserStreak(
period=StreakPeriod.DAY,
fulfillment=StreakFulfillment.COMPLETE,
country_iso="us",
user_id=1,
last_fulfilled_period_start=None,
current_streak=1,
longest_streak=0,
state=StreakState.BROKEN,
)
with pytest.raises(
ValidationError, match="Current streak can't be longer than longest streak"
):
UserStreak(
period=StreakPeriod.DAY,
fulfillment=StreakFulfillment.COMPLETE,
country_iso="us",
user_id=1,
last_fulfilled_period_start=None,
current_streak=1,
longest_streak=0,
state=StreakState.ACTIVE,
)
def test_user_streak_remaining():
us = UserStreak(
period=StreakPeriod.DAY,
fulfillment=StreakFulfillment.COMPLETE,
country_iso="us",
user_id=1,
last_fulfilled_period_start=None,
current_streak=1,
longest_streak=1,
state=StreakState.AT_RISK,
)
now = datetime.now(tz=ZoneInfo("America/New_York"))
end_of_today = now.replace(hour=0, minute=0, second=0, microsecond=0) + timedelta(
days=1
)
print(f"{now.isoformat()=}, {end_of_today.isoformat()=}")
expected = (end_of_today - now).total_seconds()
assert us.time_remaining_in_period.total_seconds() == pytest.approx(expected, abs=1)
def test_user_streak_remaining_month():
us = UserStreak(
period=StreakPeriod.MONTH,
fulfillment=StreakFulfillment.COMPLETE,
country_iso="us",
user_id=1,
last_fulfilled_period_start=None,
current_streak=1,
longest_streak=1,
state=StreakState.AT_RISK,
)
now = datetime.now(tz=ZoneInfo("America/New_York"))
end_of_month = (
now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
+ timedelta(days=32)
).replace(day=1)
print(f"{now.isoformat()=}, {end_of_month.isoformat()=}")
expected = (end_of_month - now).total_seconds()
assert us.time_remaining_in_period.total_seconds() == pytest.approx(expected, abs=1)
print(us.time_remaining_in_period)
|