Skip to content

Commit 70edc9a

Browse files
Add offline smoke test for tweet-search example (#6)
Signed-off-by: AshSgDe29071999 <AshSgDe29071999@users.noreply.github.com> Co-authored-by: AshSgDe29071999 <AshSgDe29071999@users.noreply.github.com>
1 parent 6f72cbc commit 70edc9a

1 file changed

Lines changed: 84 additions & 0 deletions

File tree

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# SPDX-FileCopyrightText: 2026-present Xquik <support@xquik.com>
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
"""Offline smoke test for the documented tweet-search example."""
6+
7+
from pathlib import Path
8+
from unittest.mock import MagicMock, patch
9+
10+
from haystack import Document, Pipeline
11+
from haystack.utils import Secret
12+
13+
from haystack_integrations.components.websearch.xquik import XquikTweetSearch
14+
15+
EXAMPLE_PATH = Path(__file__).resolve().parents[1] / "examples" / "xquik_tweet_search.py"
16+
17+
FAKE_XQUIK_RESPONSE = {
18+
"tweets": [
19+
{
20+
"id": "555",
21+
"text": "Offline fixture for the Haystack tweet-search example.",
22+
"createdAt": "2026-07-01T12:00:00Z",
23+
"url": "https://x.com/example/status/555",
24+
"lang": "en",
25+
"likeCount": 1,
26+
"retweetCount": 0,
27+
"replyCount": 0,
28+
"quoteCount": 0,
29+
"viewCount": 10,
30+
"bookmarkCount": 0,
31+
"author": {
32+
"id": "9",
33+
"username": "fixture",
34+
"name": "Fixture",
35+
"verified": False,
36+
},
37+
}
38+
],
39+
"has_next_page": False,
40+
"next_cursor": None,
41+
}
42+
43+
44+
def _mock_response(payload: dict[str, object]) -> MagicMock:
45+
response = MagicMock()
46+
response.json.return_value = payload
47+
return response
48+
49+
50+
def test_example_file_still_documents_pipeline_shape() -> None:
51+
source = EXAMPLE_PATH.read_text(encoding="utf-8")
52+
assert "XquikTweetSearch" in source
53+
assert "pipeline.run" in source
54+
assert 'query": "haystack ai"' in source
55+
56+
57+
def test_tweet_search_example_runs_offline_with_fake_xquik_client() -> None:
58+
"""Exercise the README/example pipeline mapping without network access."""
59+
60+
search = XquikTweetSearch(api_key=Secret.from_token("xq_offline"), top_k=10)
61+
pipeline = Pipeline()
62+
pipeline.add_component("x_search", search)
63+
64+
with patch(
65+
"haystack_integrations.components.websearch.xquik.xquik_websearch.request_with_retry",
66+
return_value=_mock_response(FAKE_XQUIK_RESPONSE),
67+
) as mock_request:
68+
result = pipeline.run({"x_search": {"query": "haystack ai"}})
69+
70+
mock_request.assert_called_once()
71+
call_kwargs = mock_request.call_args.kwargs
72+
assert call_kwargs["url"].endswith("/x/tweets/search")
73+
assert call_kwargs["params"]["q"] == "haystack ai"
74+
assert call_kwargs["params"]["limit"] == 10
75+
76+
documents = result["x_search"]["documents"]
77+
assert len(documents) == 1
78+
assert isinstance(documents[0], Document)
79+
assert documents[0].content == "Offline fixture for the Haystack tweet-search example."
80+
assert documents[0].meta["id"] == "555"
81+
assert documents[0].meta["endpoint"] == "x.tweets.search"
82+
assert documents[0].meta["author"]["username"] == "fixture"
83+
assert result["x_search"]["links"] == ["https://x.com/example/status/555"]
84+
assert result["x_search"]["has_more"] is False

0 commit comments

Comments
 (0)