Fix review findings and remove Uncategorized from sidebar

Backend: cache Google access tokens (drop dead access_token_expires_at,
migration 0007), handle MeTube cleared/canceled events by URL, return
email from /auth/status only when authenticated, move Google base URLs
into settings, run container as non-root.

Frontend: include local feed filters in the query key, remove dead
Saved page and unused assets, drop stale CategoryNav props and classes,
send Content-Type only with a body, remove Uncategorized from sidebar.
This commit is contained in:
vrubelroman 2026-09-17 17:22:22 +00:00
parent 6c704cac97
commit fde9a439df
25 changed files with 420 additions and 174 deletions

View file

@ -235,6 +235,101 @@ async def test_handle_metube_event_canceled_marks_failed(db_session):
assert job.status == "failed"
@pytest.mark.asyncio
async def test_handle_metube_event_canceled_matches_by_url(db_session):
"""MeTube keys canceled/cleared events by the download's URL, not its id."""
video = _seed_video(db_session)
job = DownloadJob(video_id=video.id, status="downloading", metube_job_id="vid1.vid1")
db_session.add(job)
db_session.commit()
await download_jobs.handle_metube_event(db_session, "canceled", json.dumps(video.youtube_url))
db_session.refresh(job)
assert job.status == "failed"
assert job.error_message == "Отменено в MeTube"
@pytest.mark.asyncio
async def test_handle_metube_event_cleared_matches_job_by_url(db_session):
video = _seed_video(db_session)
job = DownloadJob(video_id=video.id, status="downloading", metube_job_id="vid1.vid1")
other_video = _seed_video(db_session, youtube_video_id="vid2", youtube_channel_id="chanB")
other_job = DownloadJob(video_id=other_video.id, status="queued")
db_session.add(job)
db_session.add(other_job)
db_session.commit()
await download_jobs.handle_metube_event(db_session, "cleared", json.dumps(video.youtube_url))
db_session.refresh(job)
db_session.refresh(other_job)
assert job.status == "failed"
assert job.error_message == "Очищено в MeTube"
assert other_job.status == "queued"
@pytest.mark.asyncio
async def test_handle_metube_event_cleared_matching_terminal_job_is_noop(db_session):
"""Cleared payload resolving to a finished job must not touch terminal
statuses, nor spill over onto unrelated active jobs."""
video = _seed_video(db_session)
completed = DownloadJob(video_id=video.id, status="completed", media_url="http://x/f.mp4")
other_video = _seed_video(db_session, youtube_video_id="vid2", youtube_channel_id="chanB")
active = DownloadJob(video_id=other_video.id, status="downloading")
db_session.add_all([completed, active])
db_session.commit()
await download_jobs.handle_metube_event(db_session, "cleared", json.dumps(video.youtube_url))
db_session.refresh(completed)
db_session.refresh(active)
assert completed.status == "completed"
assert active.status == "downloading"
@pytest.mark.asyncio
async def test_handle_metube_event_cleared_unmatched_payload_is_noop(db_session):
"""'cleared' only ever refers to the one done-entry being removed (trash
or CLEAR_COMPLETED_AFTER). A payload that doesn't match any of our jobs is
a foreign MeTube download we never tracked -- the jobs MeTube is still
running must stay untouched."""
video1 = _seed_video(db_session)
job1 = DownloadJob(video_id=video1.id, status="downloading")
video2 = _seed_video(db_session, youtube_video_id="vid2", youtube_channel_id="chanB")
job2 = DownloadJob(video_id=video2.id, status="postprocessing")
video3 = _seed_video(db_session, youtube_video_id="vid3", youtube_channel_id="chanC")
completed = DownloadJob(video_id=video3.id, status="completed", media_url="http://x/f.mp4")
unknown = DownloadJob(video_id=video3.id, status="unknown")
db_session.add_all([job1, job2, completed, unknown])
db_session.commit()
await download_jobs.handle_metube_event(db_session, "cleared", json.dumps("https://example.com/other"))
db_session.refresh(job1)
db_session.refresh(job2)
db_session.refresh(completed)
db_session.refresh(unknown)
assert job1.status == "downloading"
assert job2.status == "postprocessing"
assert completed.status == "completed"
assert unknown.status == "unknown"
@pytest.mark.asyncio
async def test_handle_metube_event_cleared_without_payload_is_noop(db_session):
video = _seed_video(db_session)
job = DownloadJob(video_id=video.id, status="queued")
db_session.add(job)
db_session.commit()
await download_jobs.handle_metube_event(db_session, "cleared", None)
db_session.refresh(job)
assert job.status == "queued"
assert job.error_message is None
def test_reconcile_marks_unknown_when_history_unavailable(monkeypatch, db_session):
video = _seed_video(db_session)
job = DownloadJob(video_id=video.id, status="downloading")