Serve recent stages from SQLite with configurable background refresh
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock, patch
|
||||
from unittest.mock import AsyncMock, AsyncMock, patch
|
||||
from contextlib import ExitStack
|
||||
from backend.app.routers import requests
|
||||
|
||||
@@ -14,11 +14,11 @@ class RecentStageTests(unittest.IsolatedAsyncioTestCase):
|
||||
requested_by_id=10) for i, status in [(1,5),(2,5),(3,4),(4,6),(5,5),(6,2),(7,1),(8,3)]]
|
||||
async def available(client, title, *args): return title in {'1','3','4','5'}
|
||||
with ExitStack() as stack:
|
||||
for name, value in [('get_runtime_settings', runtime), ('_recent_cache_stale', False),
|
||||
for name, value in [('get_runtime_settings', runtime), ('get_request_stage_cache', {1:{'ready':True},3:{'ready':True},4:{'ready':True},5:{'ready':True}}), ('_recent_cache_stale', False),
|
||||
('active_repair_request_ids', {'5'}), ('get_request_cache_payload', None)]:
|
||||
stack.enter_context(patch.object(requests, name, return_value=value))
|
||||
stack.enter_context(patch.dict(requests._recent_cache, {'items':rows}))
|
||||
stack.enter_context(patch.object(requests, '_request_is_available_in_jellyfin', new=available))
|
||||
stack.enter_context(patch.object(requests, '_request_is_available_in_jellyfin', new=AsyncMock(side_effect=AssertionError('Recent requests must not call Jellyfin'))))
|
||||
user={'role':'user','username':'viewer','jellyseerr_user_id':10}
|
||||
expected={'working':[2,5], 'ready':[1,3], 'partial':[4], 'approved':[6],
|
||||
'pending':[7], 'declined':[8], 'in_progress':[2,4,5,6]}
|
||||
@@ -31,3 +31,35 @@ class RecentStageTests(unittest.IsolatedAsyncioTestCase):
|
||||
self.assertEqual(result['results'][0]['status'],4)
|
||||
result=await requests.recent_requests(take=20,skip=0,days=0,stage='all',user={**user,'jellyseerr_user_id':99})
|
||||
self.assertEqual(result['results'],[])
|
||||
|
||||
async def test_background_refresh_skips_fresh_rows_and_preserves_failures(self):
|
||||
import time
|
||||
rows=[{'request_id':i,'status':5,'title':str(i),'updated_at':'v1'} for i in [1,2,3]]
|
||||
runtime=SimpleNamespace(jellyfin_base_url='http://jellyfin',jellyfin_api_key='test',requests_stage_refresh_minutes=15)
|
||||
with ExitStack() as stack:
|
||||
stack.enter_context(patch.object(requests,'get_runtime_settings',return_value=runtime))
|
||||
stack.enter_context(patch.object(requests,'get_cached_requests_since',return_value=rows))
|
||||
stack.enter_context(patch.object(requests,'get_request_stage_cache',return_value={1:{'source_updated':'v1','checked_at':time.time()}}))
|
||||
stack.enter_context(patch.object(requests,'get_request_cache_payload',return_value={}))
|
||||
check=stack.enter_context(patch.object(requests,'_request_is_available_in_jellyfin',new=AsyncMock(side_effect=[True,RuntimeError('offline')])) )
|
||||
save=stack.enter_context(patch.object(requests,'save_request_stage_cache'))
|
||||
await requests.refresh_local_request_stages()
|
||||
self.assertEqual(check.await_count,2)
|
||||
written=save.call_args.args[0]
|
||||
self.assertEqual(len(written),1)
|
||||
self.assertEqual(written[0][:3],(2,'v1',1))
|
||||
|
||||
|
||||
from backend.tests.test_backend_quality import TempDatabaseMixin
|
||||
from backend.app import db
|
||||
|
||||
class StagePersistenceTests(TempDatabaseMixin, unittest.TestCase):
|
||||
def test_saved_stages_survive_initialization_and_actions_mark_due(self):
|
||||
with db._connect() as conn:
|
||||
conn.execute("INSERT INTO requests_cache (request_id, payload_json) VALUES (42, '{}')")
|
||||
db.save_request_stage_cache([(42,'v1',1,12345)])
|
||||
db.init_db()
|
||||
self.assertTrue(db.get_request_stage_cache()[42]['ready'])
|
||||
db.save_action('42','search_releases','Search','ok')
|
||||
self.assertEqual(db.get_request_stage_cache()[42]['checked_at'],0)
|
||||
self.assertTrue(db.get_request_stage_cache()[42]['ready'])
|
||||
|
||||
Reference in New Issue
Block a user