import sqlite3 import tempfile import unittest from pathlib import Path from app.danmu_queue import bilibili_gift_cny_values from app.stats_store import StatsStore class BilibiliGiftValueTests(unittest.TestCase): def test_gold_coin_conversion_uses_one_thousand_per_cny(self): unit_value, total_value = bilibili_gift_cny_values("gold", 100, 1) self.assertAlmostEqual(unit_value, 0.1) self.assertAlmostEqual(total_value, 0.1) def test_multi_quantity_conversion_preserves_total(self): unit_value, total_value = bilibili_gift_cny_values("gold", 5000, 2) self.assertAlmostEqual(unit_value, 2.5) self.assertAlmostEqual(total_value, 5.0) def test_silver_coin_has_no_cny_value(self): self.assertEqual(bilibili_gift_cny_values("silver", 5000, 1), (0.0, 0.0)) def test_historical_repair_is_idempotent_and_rebuilds_aggregate(self): with tempfile.TemporaryDirectory() as temp_dir: path = Path(temp_dir) / "statistics.sqlite3" connection = sqlite3.connect(path) StatsStore._migrate(connection) fields = { "event_id": "gift-1", "platform": "bilibili", "platform_user_id": "123", "occurred_at_utc": "2026-07-28T00:00:00Z", "business_date": "2026-07-28", "gift_id": "1", "gift_name": "灯牌", "quantity": 1, "unit_value": 10.0, "total_value": 10.0, "currency": "CNY", "payload_json": '{"coin_type":"gold","raw_total_coin":100,"value_rule":"gold_battery_10_to_cny_1_v1"}', } StatsStore._insert(connection, "gift_events", fields) StatsStore._aggregate_gift(connection, fields) legacy_fields = dict(fields) legacy_fields.update({ "event_id": "gift-legacy", "occurred_at_utc": "2026-07-28T00:01:00Z", "payload_json": '{"coin_type":"gold","raw_total_coin":100,"value_migration":"bilibili_coin_to_cny_v1"}', }) StatsStore._insert(connection, "gift_events", legacy_fields) StatsStore._aggregate_gift(connection, legacy_fields) connection.commit() first = StatsStore._repair_gift_value_history(connection) second = StatsStore._repair_gift_value_history(connection) event = connection.execute( "SELECT unit_value, total_value, json_extract(payload_json, '$.value_rule') " "FROM gift_events WHERE event_id='gift-1'" ).fetchone() aggregate = connection.execute( "SELECT quantity, total_value FROM gift_aggregates" ).fetchone() connection.close() self.assertEqual(first, 2) self.assertEqual(second, 0) self.assertAlmostEqual(event[0], 0.1) self.assertAlmostEqual(event[1], 0.1) self.assertEqual(event[2], "bilibili_gold_coin_1000_to_cny_1_v2") self.assertEqual(aggregate[0], 2) self.assertAlmostEqual(aggregate[1], 0.2) if __name__ == "__main__": unittest.main()