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:
parent
6c704cac97
commit
fde9a439df
25 changed files with 420 additions and 174 deletions
|
|
@ -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")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue