-
Notifications
You must be signed in to change notification settings - Fork 0
Fix month-estimate test that fails in the first days of any month #50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,6 +57,33 @@ async def _q(): | |
| return asyncio.run(_q()) | ||
|
|
||
|
|
||
| def _month_start_boundary(): | ||
| """The 4am-local start of the current billing month, as UTC. | ||
|
|
||
| month_estimate covers a whole calendar month (billing_service._period_window), | ||
| so nights anchored here are always inside the window. Counting backwards from | ||
| tonight is not: on the 1st or 2nd of a month the previous play-night falls | ||
| into the previous month and silently drops out of the estimate. | ||
| """ | ||
| async def _q(): | ||
| conn = await asyncpg.connect(os.environ["DATABASE_URL"]) | ||
| try: | ||
| return await conn.fetchval( | ||
| """ | ||
| SELECT ( | ||
| (date_trunc('month', (NOW() AT TIME ZONE $1) - INTERVAL '4 hours') | ||
| + INTERVAL '4 hours') | ||
| AT TIME ZONE $1 | ||
| ) AT TIME ZONE 'UTC' | ||
| """, | ||
| "Australia/Melbourne", | ||
| ) | ||
| finally: | ||
| await conn.close() | ||
|
|
||
| return asyncio.run(_q()) | ||
|
|
||
|
|
||
| def _insert_session(table_id, venue_id, started_at=None, ended_at=None, | ||
| billable_blocks=None, total_rounds=0, | ||
| active_span_seconds=None, active_play_seconds=0): | ||
|
|
@@ -529,12 +556,20 @@ def test_billing_bola(client, api_key_header, fresh_table): | |
| def test_billing_month_estimate_has_nights(client, api_key_header, fresh_table): | ||
| """Finalized sessions on 2 distinct play-nights produce >= 2 night entries.""" | ||
| table_id = fresh_table["table_id"] | ||
| boundary = _tonight_boundary() | ||
|
|
||
| s1 = _insert_session(table_id, VENUE_A_ID, started_at=_utcnow(), | ||
| ended_at=_utcnow(), billable_blocks=2, total_rounds=3) | ||
| s2 = _insert_session(table_id, VENUE_A_ID, started_at=boundary - timedelta(hours=25), | ||
| ended_at=boundary - timedelta(hours=24), billable_blocks=2, total_rounds=3) | ||
| # Anchor both nights to the start of the current billing month: 16:00 local | ||
| # on its 1st and 2nd, which are two distinct play-nights inside the window | ||
| # whatever today's date is. The 12/36 hour offsets sit far enough from the | ||
| # 4am boundary that a DST shift cannot move either play-date. | ||
| month_start = _month_start_boundary() | ||
|
|
||
| s1 = _insert_session(table_id, VENUE_A_ID, | ||
| started_at=month_start + timedelta(hours=12), | ||
| ended_at=month_start + timedelta(hours=13), | ||
|
Comment on lines
+566
to
+567
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 12 \
'_period_window|month_estimate|started_at|ended_at|CURRENT_TIMESTAMP|NOW\(\)' \
api --glob '*.py' || trueRepository: MrTig-afk/MingleHub Length of output: 50376 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- changed test section ---'
sed -n '500,590p' api/tests/test_dashboard_settings_billing.py
printf '%s\n' '--- billing symbols and callers ---'
rg -n -C 8 'month_estimate|_period_window|billing' api/routers api/services api/tests/test_dashboard_settings_billing.py --glob '*.py' | head -n 500Repository: MrTig-afk/MingleHub Length of output: 48015 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- billing implementation files ---'
rg --files api | rg 'billing|dashboard'
printf '%s\n' '--- exact billing window and session query definitions ---'
rg -n -C 20 'def _period_window|async def _period_window|month_estimate|ended_at IS NOT NULL|started_at <|started_at >|game_sessions' api/services api/routers --glob '*.py' | head -n 600Repository: MrTig-afk/MingleHub Length of output: 43027 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- api/services/billing_service.py ---'
sed -n '1,320p' api/services/billing_service.py
printf '%s\n' '--- billing route in api/routers/dashboard_router.py ---'
rg -n -C 35 'billing_service|/billing|month_estimate' api/routers/dashboard_router.pyRepository: MrTig-afk/MingleHub Length of output: 26245 🏁 Script executed: #!/bin/bash
set -euo pipefail
sed -n '775,860p' api/routers/dashboard_router.pyRepository: MrTig-afk/MingleHub Length of output: 3911 Use past-dated fixtures for finalized sessions. The billing query includes every session with 🤖 Prompt for AI Agents |
||
| billable_blocks=2, total_rounds=3) | ||
| s2 = _insert_session(table_id, VENUE_A_ID, | ||
| started_at=month_start + timedelta(hours=36), | ||
| ended_at=month_start + timedelta(hours=37), | ||
| billable_blocks=2, total_rounds=3) | ||
| try: | ||
| token = dev_login(client, api_key_header, OWNER_A_CLERK_ID) | ||
| resp = client.get("/api/dashboard/billing", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: MrTig-afk/MingleHub
Length of output: 1374
🏁 Script executed:
Repository: MrTig-afk/MingleHub
Length of output: 4801
Add
datetimereturn annotations to both helpers.ANN202is enabled and not ignored. Annotate_month_start_boundary()and its nested async_q()with-> datetime.🧰 Tools
🪛 Ruff (0.16.3)
[warning] 60-60: Missing return type annotation for private function
_month_start_boundary(ANN202)
🤖 Prompt for AI Agents
Source: Linters/SAST tools