mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-14 21:15:06 +00:00
feat(search): add ANONYMOUS_SEARCH to skip the login for a service
A service that sets the flag gets no cookie load, no authenticate() call and no cookie save on a search, on the CLI and in the REST search handler. /api/services reports it as anonymous_search.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
"""The search command skips the login for a service that sets ANONYMOUS_SEARCH."""
|
||||
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from unshackle.commands import search as search_command
|
||||
from unshackle.core.search_result import SearchResult
|
||||
|
||||
|
||||
class _SearchService:
|
||||
ANONYMOUS_SEARCH = False
|
||||
|
||||
def __init__(self):
|
||||
self.calls = []
|
||||
self.session = SimpleNamespace(cookies=object())
|
||||
|
||||
def authenticate(self, cookies, credential):
|
||||
self.calls.append("authenticate")
|
||||
|
||||
def search(self):
|
||||
yield SearchResult(id_="abc", title="A Title")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def login_calls(monkeypatch, tmp_path):
|
||||
calls = []
|
||||
|
||||
def record(name, value):
|
||||
def call(*args):
|
||||
calls.append(name)
|
||||
return value
|
||||
|
||||
return call
|
||||
|
||||
dl = search_command.dl
|
||||
monkeypatch.setattr(dl, "get_cookie_jar", record("get_cookie_jar", None))
|
||||
monkeypatch.setattr(dl, "get_credentials", record("get_credentials", None))
|
||||
monkeypatch.setattr(dl, "get_cookie_path", record("get_cookie_path", tmp_path / "cookies.txt"))
|
||||
monkeypatch.setattr(dl, "save_cookies", record("save_cookies", None))
|
||||
return calls
|
||||
|
||||
|
||||
def test_search_authenticates_and_saves_cookies_by_default(login_calls):
|
||||
service = _SearchService()
|
||||
search_command.result(service)
|
||||
|
||||
assert service.calls == ["authenticate"]
|
||||
assert login_calls == ["get_cookie_jar", "get_credentials", "get_cookie_path", "save_cookies"]
|
||||
|
||||
|
||||
def test_anonymous_search_touches_no_login_material_and_no_cookie_file(login_calls):
|
||||
service = _SearchService()
|
||||
service.ANONYMOUS_SEARCH = True
|
||||
search_command.result(service)
|
||||
|
||||
assert service.calls == []
|
||||
assert login_calls == []
|
||||
@@ -144,6 +144,27 @@ async def test_server_account_uses_its_own_cache_and_returns_none(seen, tmp_path
|
||||
assert not (tmp_path / "_requests").exists()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_anonymous_search_skips_the_login_and_keeps_the_account_cache(seen, tmp_path, monkeypatch):
|
||||
def search(self):
|
||||
seen["search_cache_dir"] = self.cache.get("tokens").path.parent
|
||||
return iter(())
|
||||
|
||||
def no_login_material(*args):
|
||||
raise AssertionError("an anonymous search must not read login material")
|
||||
|
||||
handlers.Services.load("EXAMPLE").ANONYMOUS_SEARCH = True
|
||||
monkeypatch.setattr(_CacheService, "search", search)
|
||||
monkeypatch.setattr(handlers, "resolve_server_account", lambda *args: "acct")
|
||||
monkeypatch.setattr(handlers, "server_login_material", no_login_material)
|
||||
response = await handlers.search_handler({"service": "EXAMPLE", "query": "q", **CREDENTIALS})
|
||||
|
||||
assert json.loads(response.body)["results"] == []
|
||||
assert "seeded" not in seen
|
||||
assert seen["parent_params"]["cookies_supplied"] is False
|
||||
assert seen["search_cache_dir"] == tmp_path / "_accounts" / "EXAMPLE" / "acct"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_full_mode_keeps_the_server_cache(seen, tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(stats, "mode", "full")
|
||||
|
||||
Reference in New Issue
Block a user