update
This commit is contained in:
@@ -6,6 +6,7 @@ import pytest
|
||||
|
||||
from api.utils import official_gold as gold
|
||||
from api.core.Gzip import gzip_zip
|
||||
from api.utils.gold_time import refresh_slot
|
||||
|
||||
|
||||
class FakeResponse:
|
||||
@@ -67,14 +68,37 @@ def test_fetch_official_gold_uses_async_http_with_isolated_forms(monkeypatch):
|
||||
assert [item['region'] for item in result] == [f'跨{region}' for region in gold.REGIONS]
|
||||
assert [item['code'] for item in result] == ['k1', 'k2', 'k3a', 'k3b', 'k4', 'k5', 'k6', 'k7']
|
||||
assert all(isinstance(item['updataTime'], str) and item['updataTime'].isdigit() for item in result)
|
||||
assert abs(int(result[0]['updataTime']) - time.time()) < 2
|
||||
assert int(result[0]['updataTime']) == refresh_slot()
|
||||
assert result[0]['goldDealRank'] == [100.5, 101, 102, 103, 104]
|
||||
assert result[0]['goldTopDealRank'] == [200.25, 201, 202, 203, 204]
|
||||
assert result[0]['max'] == round(10000 / 100.5, 4)
|
||||
assert result[0]['min'] == round(10000 / 204, 4)
|
||||
assert result[0]['max'] == round(10000 / 100.5, 2)
|
||||
assert result[0]['min'] == round(10000 / 204, 2)
|
||||
assert sessions[0].kwargs['timeout'].total == 10
|
||||
|
||||
|
||||
def test_official_batch_timestamp_comes_from_start_not_fetch_completion(monkeypatch):
|
||||
started_at = 1793766300 # 与真实结束时间不同的固定开始时间。
|
||||
monkeypatch.setattr(gold.aiohttp, 'ClientSession', lambda **kwargs: FakeSession([], **kwargs))
|
||||
rows = asyncio.run(gold.fetch_gold(started_at=started_at))
|
||||
assert {row['updataTime'] for row in rows} == {str(refresh_slot(started_at))}
|
||||
|
||||
|
||||
def test_preloaded_next_slot_cache_is_servable_before_the_half_hour(monkeypatch):
|
||||
from datetime import datetime, timedelta, timezone
|
||||
china = timezone(timedelta(hours=8))
|
||||
now = datetime(2026, 11, 4, 1, 25, tzinfo=china).timestamp()
|
||||
monkeypatch.setattr(gold.time, 'time', lambda: now)
|
||||
rows = cached_rows()
|
||||
redis = FakeRedis()
|
||||
redis.values[gold.CACHE_KEY] = gzip_zip(json.dumps(rows))
|
||||
assert gold.is_fresh(asyncio.run(gold.read_cache(redis)))
|
||||
target = int(rows[0]['updataTime'])
|
||||
assert target > now
|
||||
assert target - now == 300
|
||||
monkeypatch.setattr(gold.time, 'time', lambda: now + 1800)
|
||||
assert not gold.is_fresh(rows)
|
||||
|
||||
|
||||
def test_official_route_uses_new_cache_contract_and_numeric_rank_arrays(monkeypatch, client):
|
||||
calls = []
|
||||
|
||||
@@ -82,7 +106,7 @@ def test_official_route_uses_new_cache_contract_and_numeric_rank_arrays(monkeypa
|
||||
calls.append(redis)
|
||||
return [{'updataTime': '1793711716', 'region': '跨3B', 'code': 'k3b',
|
||||
'goldDealRank': [100.5, 101], 'goldTopDealRank': [200.25, 201],
|
||||
'max': round(10000 / 100.5, 4), 'min': round(10000 / 201, 4)}]
|
||||
'max': round(10000 / 100.5, 2), 'min': round(10000 / 201, 2)}]
|
||||
|
||||
monkeypatch.setattr(gold, 'get_data', cached)
|
||||
body = client.get('/api/open/gold/official/').json()
|
||||
@@ -95,8 +119,8 @@ def test_official_route_uses_new_cache_contract_and_numeric_rank_arrays(monkeypa
|
||||
assert row['code'] == 'k3b'
|
||||
assert row['goldDealRank'] == [100.5, 101]
|
||||
assert row['goldTopDealRank'] == [200.25, 201]
|
||||
assert row['max'] == round(10000 / 100.5, 4)
|
||||
assert row['min'] == round(10000 / 201, 4)
|
||||
assert row['max'] == round(10000 / 100.5, 2)
|
||||
assert row['min'] == round(10000 / 201, 2)
|
||||
for rank in (row['goldDealRank'], row['goldTopDealRank']):
|
||||
assert len(rank) <= 5
|
||||
assert all(isinstance(value, (int, float)) for value in rank)
|
||||
@@ -140,7 +164,7 @@ class FakeRedis:
|
||||
|
||||
|
||||
def cached_rows(age=0):
|
||||
return [{'updataTime': str(int(time.time() - age)), 'region': f'跨{region}',
|
||||
return [{'updataTime': str(refresh_slot(time.time() - age)), 'region': f'跨{region}',
|
||||
'code': f'k{region.lower()}', 'goldDealRank': [100.5], 'goldTopDealRank': [200.25]}
|
||||
for region in gold.REGIONS]
|
||||
|
||||
@@ -169,8 +193,8 @@ def test_old_official_cache_gets_max_and_min_without_refetch():
|
||||
redis.values[gold.CACHE_KEY] = gzip_zip(json.dumps(cached_rows()))
|
||||
rows = asyncio.run(gold.read_cache(redis))
|
||||
assert len(rows) == 8
|
||||
assert rows[0]['max'] == round(10000 / 100.5, 4)
|
||||
assert rows[0]['min'] == round(10000 / 200.25, 4)
|
||||
assert rows[0]['max'] == round(10000 / 100.5, 2)
|
||||
assert rows[0]['min'] == round(10000 / 200.25, 2)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('payload', [
|
||||
@@ -206,7 +230,7 @@ def test_refresh_updates_cache_without_http_request_and_skips_when_fresh(monkeyp
|
||||
redis = FakeRedis()
|
||||
calls = []
|
||||
|
||||
async def fetch():
|
||||
async def fetch(*, started_at=None):
|
||||
calls.append(1)
|
||||
return cached_rows()
|
||||
|
||||
@@ -225,7 +249,7 @@ def test_failed_refresh_preserves_cache_and_notifies_once_per_fetch(monkeypatch)
|
||||
redis.values[gold.CACHE_KEY] = old
|
||||
alerts = []
|
||||
|
||||
async def fetch():
|
||||
async def fetch(*, started_at=None):
|
||||
raise gold.TokenExpired()
|
||||
|
||||
async def notify(redis):
|
||||
@@ -247,7 +271,7 @@ def test_network_failure_preserves_cache_without_token_alert(monkeypatch):
|
||||
old = gzip_zip(json.dumps(cached_rows(age=1900)))
|
||||
redis.values[gold.CACHE_KEY] = old
|
||||
|
||||
async def fetch():
|
||||
async def fetch(*, started_at=None):
|
||||
raise TimeoutError('upstream unavailable')
|
||||
|
||||
async def notify(redis):
|
||||
|
||||
Reference in New Issue
Block a user