Reconcile verified account IDs and make language repairs observable
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from backend.app import db
|
||||
from backend.app.services import jellyfin_sync
|
||||
from backend.app.services.jellyfin_identity import link_user, user_for_identity
|
||||
from backend.app.routers import admin
|
||||
from backend.tests.test_backend_quality import TempDatabaseMixin
|
||||
|
||||
|
||||
class IdentitySyncTests(TempDatabaseMixin, unittest.IsolatedAsyncioTestCase):
|
||||
async def test_sync_reuses_id_when_names_differ_and_preserves_settings(self):
|
||||
db.create_user('old@example.test', 'Password-123456!', auth_provider='jellyseerr', jellyseerr_user_id=42,
|
||||
auto_search_enabled=False, email='kept@example.test')
|
||||
original = db.get_user_by_username('old@example.test')
|
||||
runtime = SimpleNamespace(jellyfin_base_url='http://jf', jellyfin_api_key='test')
|
||||
jf = SimpleNamespace(configured=lambda: True, get_users=AsyncMock(return_value=[{'Id': 'a' * 32, 'Name': 'NewName'}]))
|
||||
with patch.object(jellyfin_sync, 'get_runtime_settings', return_value=runtime), \
|
||||
patch.object(jellyfin_sync, 'JellyfinClient', return_value=jf), \
|
||||
patch.object(jellyfin_sync, 'get_cached_jellyseerr_users', return_value=[{'id': 42, 'jellyfinUserId': 'a' * 32, 'email': 'upstream@example.test'}]), \
|
||||
patch.object(jellyfin_sync, 'save_jellyfin_users_cache'):
|
||||
self.assertEqual(await jellyfin_sync.sync_jellyfin_users(), 0)
|
||||
self.assertEqual(await jellyfin_sync.sync_jellyfin_users(), 0)
|
||||
kept = user_for_identity('a' * 32, 'http://jf')
|
||||
self.assertEqual(kept['id'], original['id'])
|
||||
self.assertFalse(kept['auto_search_enabled'])
|
||||
self.assertEqual(kept['email'], 'kept@example.test')
|
||||
self.assertIsNone(db.get_user_by_username('NewName'))
|
||||
self.assertEqual(kept['auth_provider'], 'jellyfin')
|
||||
|
||||
async def test_resync_no_longer_deletes_accounts(self):
|
||||
db.create_user('Keep', 'Password-123456!')
|
||||
runtime = SimpleNamespace(jellyseerr_base_url='http://seer', jellyseerr_api_key='test')
|
||||
with patch.object(admin, 'get_runtime_settings', return_value=runtime), \
|
||||
patch.object(admin, '_fetch_all_jellyseerr_users', new=AsyncMock(return_value=[{'id': 42}])), \
|
||||
patch.object(jellyfin_sync, 'sync_jellyfin_users', new=AsyncMock(return_value=0)), \
|
||||
patch.object(admin, 'delete_non_admin_users') as delete:
|
||||
result = await admin.jellyseerr_users_resync()
|
||||
self.assertEqual(result['cleared'], 0)
|
||||
delete.assert_not_called()
|
||||
self.assertIsNotNone(db.get_user_by_username('Keep'))
|
||||
|
||||
def test_jellyfin_lookup_is_scoped_to_server(self):
|
||||
db.create_user('Viewer', 'Password-123456!', auth_provider='jellyfin')
|
||||
link_user('Viewer', 'a' * 32, 'http://jf')
|
||||
self.assertIsNotNone(user_for_identity('a' * 32, 'http://jf'))
|
||||
self.assertIsNone(user_for_identity('a' * 32, 'http://other-server'))
|
||||
Reference in New Issue
Block a user