mirror of
https://github.com/This-weiyuqing/mi-fitness-health.git
synced 2026-10-18 03:03:49 +08:00
59 lines
3.1 KiB
Python
59 lines
3.1 KiB
Python
"""在本机 Linux 候选镜像内核查数据边界;无真实账号或网络。"""
|
|
import asyncio
|
|
import json
|
|
import tempfile
|
|
from datetime import datetime, timedelta, timezone
|
|
from pathlib import Path
|
|
from mi_fitness_mcp import api
|
|
from mi_fitness_mcp.models import DailyActivity, StressSample, Workout
|
|
from mi_fitness_mcp.storage import Database
|
|
from mi_fitness_mcp.services.sync_service import SyncService
|
|
|
|
CN = timezone(timedelta(hours=8))
|
|
with tempfile.TemporaryDirectory(prefix='audit3-edges-') as temporary:
|
|
db = Database(Path(temporary) / 'synthetic.sqlite')
|
|
item = DailyActivity(id='day-A', provider='mi_fitness', source_type='cloud_session', user_id='A',
|
|
date='2026-10-16', steps=1111, active_kcal=100, distance_m=1000)
|
|
db.insert_daily_activity(item)
|
|
with db._get_connection() as conn:
|
|
conn.execute('CREATE TABLE api_keys (key TEXT,label TEXT,user_id TEXT,pass_token TEXT,region TEXT,created_at TEXT,revoked INTEGER DEFAULT 0)')
|
|
conn.commit()
|
|
try:
|
|
db.insert_daily_activity(item.model_copy(update={'user_id':'B','steps':2222}))
|
|
except ValueError:
|
|
pass
|
|
else:
|
|
raise AssertionError('Account collision not blocked')
|
|
try:
|
|
api._create_key_record(db, 'B', 'synthetic', 'cn', 'other')
|
|
except api.HTTPException as exc:
|
|
assert exc.status_code == 409
|
|
else:
|
|
raise AssertionError('Second owner authorization accepted')
|
|
assert db.query_daily_activity('A','2026-10-16','2026-10-16')[0]['steps'] == 1111
|
|
db.update_sync_state('heart_rate', datetime(2026,10,16,9,tzinfo=CN), user_id='A')
|
|
assert db.get_sync_state('heart_rate', user_id='B') is None
|
|
class Adapter:
|
|
user_id='A'
|
|
region='cn'
|
|
calls=[]
|
|
def is_connected(self): return True
|
|
async def iter_heart_rate(self,start,end):
|
|
self.calls.append((start,end))
|
|
if False: yield None
|
|
adapter=Adapter()
|
|
result=asyncio.run(SyncService(adapter,db).sync_data_type('heart_rate',end_date='2026-10-16'))
|
|
assert result['status']=='ok' and adapter.calls==[('2026-10-16','2026-10-16')]
|
|
for index,hour in enumerate((1,9)):
|
|
db.insert_stress_sample(StressSample(id=f'stress-{index}',provider='mi_fitness',source_type='cloud_session',user_id='A',
|
|
timestamp=datetime(2026,10,16,hour,tzinfo=CN),stress_score=30,level='medium'))
|
|
coverage=next(row for row in db.get_data_coverage('A') if row['data_type']=='stress')
|
|
assert coverage['days_with_data']==1 and coverage['first_date']=='2026-10-16'
|
|
exercise=Workout(id='exercise',workout_id='exercise',provider='mi_fitness',source_type='cloud_session',user_id='A',
|
|
activity_type='running',start_at=datetime(2026,10,16,9,tzinfo=CN),end_at=datetime(2026,10,16,9,30,tzinfo=CN),duration_minutes=30)
|
|
db.insert_workout(exercise)
|
|
db.insert_workout(exercise.model_copy(update={'total_steps':4000,'avg_pace_sec_per_km':300}))
|
|
row=db.query_workouts('A','2026-10-16','2026-10-16')[0]
|
|
assert row['total_steps']==4000 and row['avg_pace_sec_per_km']==300
|
|
print(json.dumps({'account_isolation':'ok','cursor_isolation':'ok','same_day_incremental':'ok','coverage_dates':'ok','workout_updates':'ok'}))
|