89 lines
2.8 KiB
Python
89 lines
2.8 KiB
Python
# retoor <retoor@molodetz.nl>
|
|
|
|
import json
|
|
|
|
from devplacepy.database import set_setting
|
|
from devplacepy.services.nodes import social as social_module
|
|
from devplacepy.services.nodes.adapters.base import AdapterError
|
|
from devplacepy.services.nodes.fabric import FabricUnavailable
|
|
from devplacepy.services.nodes.social import SocialSearch
|
|
from tests.conftest import run_async
|
|
|
|
HN = json.dumps({"hits": [{"objectID": "1", "title": "HN story", "points": 1}]}).encode()
|
|
SE = json.dumps({"items": [{"title": "SO question", "link": "https://stackoverflow.com/q/1"}]}).encode()
|
|
|
|
|
|
class StubFabric:
|
|
def __init__(self, error=None):
|
|
self.error = error
|
|
self.calls = 0
|
|
|
|
async def fetch(self, url, **kwargs):
|
|
self.calls += 1
|
|
if self.error:
|
|
raise self.error
|
|
raise AssertionError("not expected")
|
|
|
|
|
|
def search(monkeypatch, getter, platforms, fabric=None):
|
|
monkeypatch.setattr(social_module, "direct_get", getter)
|
|
return run_async(
|
|
SocialSearch(fabric or StubFabric()).search(
|
|
"sqlite", caller_kind="user", caller_id="u1", platforms=platforms
|
|
)
|
|
)
|
|
|
|
|
|
def test_hits_are_merged_and_failures_reported(monkeypatch):
|
|
async def getter(url):
|
|
if "algolia" in url:
|
|
return HN
|
|
if "stackexchange" in url:
|
|
return SE
|
|
raise AdapterError("upstream", "HTTP 500")
|
|
|
|
outcome = search(monkeypatch, getter, ["hackernews", "stackexchange", "github"])
|
|
assert {item.platform for item in outcome.hits} == {"hackernews", "stackexchange"}
|
|
assert outcome.unavailable == {"github": "upstream"}
|
|
|
|
|
|
def test_unknown_platform_is_dropped(monkeypatch):
|
|
async def getter(url):
|
|
return HN
|
|
|
|
outcome = search(monkeypatch, getter, ["hackernews", "x", "instagram"])
|
|
assert [item.platform for item in outcome.hits] == ["hackernews"]
|
|
assert outcome.unavailable == {}
|
|
|
|
|
|
def test_reddit_is_off_unless_routing_through_nodes_is_enabled(monkeypatch):
|
|
async def getter(url):
|
|
return HN
|
|
|
|
fabric = StubFabric()
|
|
outcome = search(monkeypatch, getter, ["reddit"], fabric)
|
|
assert outcome.unavailable == {"reddit": "nodes_not_used"}
|
|
assert fabric.calls == 0
|
|
|
|
|
|
def test_reddit_reports_the_fabric_reason(monkeypatch):
|
|
async def getter(url):
|
|
return HN
|
|
|
|
set_setting("nodes_social_via_nodes", "1")
|
|
try:
|
|
outcome = search(monkeypatch, getter, ["reddit"], StubFabric(FabricUnavailable("no_nodes")))
|
|
finally:
|
|
set_setting("nodes_social_via_nodes", "0")
|
|
assert outcome.unavailable == {"reddit": "no_nodes"}
|
|
|
|
|
|
def test_blank_query_and_limit_cap(monkeypatch):
|
|
async def getter(url):
|
|
return HN
|
|
|
|
monkeypatch.setattr(social_module, "direct_get", getter)
|
|
empty = run_async(SocialSearch(StubFabric()).search(" ", caller_kind="user", caller_id="u"))
|
|
assert empty.hits == []
|
|
assert social_module.MAX_LIMIT == 20
|