Repository navigation
feat(integrations): let Google Custom Search use another API address #557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Specstreamai
wants to merge
2
commits into
existence-master:main
Choose a base branch
from
Specstreamai:feat/google-cse-address
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+142
−7
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| **Google Custom Search can use another API address.** An optional field when you connect it sends searches to a | ||
| service that answers in the same format; left empty, searches go to Google as before. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| """Which address Google Custom Search calls: Google by default, the connected base_url when one is set.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import httpx | ||
| import pytest | ||
| import respx | ||
|
|
||
| from sentient.integrations.base import IntegrationError | ||
| from sentient.integrations.plugins.alternatives import GoogleCSEPlugin | ||
| from sentient.integrations.plugins.search import GOOGLE_CSE_URL, google_cse_search | ||
|
|
||
| OTHER = "http://search.example.test/customsearch/v1" | ||
| ITEMS = {"items": [{"title": "T", "link": "https://example.com/a", "snippet": "S"}]} | ||
|
|
||
|
|
||
| def test_default_address_is_google(): | ||
| assert GOOGLE_CSE_URL == "https://www.googleapis.com/customsearch/v1" | ||
|
|
||
|
|
||
| @respx.mock | ||
| async def test_search_calls_google_without_base_url(): | ||
| route = respx.get(GOOGLE_CSE_URL).mock(return_value=httpx.Response(200, json=ITEMS)) | ||
| rows = await google_cse_search("k", "cx1", "sentient", 3) | ||
| assert route.called | ||
| assert route.calls.last.request.url.params["cx"] == "cx1" | ||
| assert rows == [{"title": "T", "url": "https://example.com/a", "snippet": "S"}] | ||
|
|
||
|
|
||
| @respx.mock | ||
| async def test_search_calls_base_url_with_the_same_params(): | ||
| google = respx.get(GOOGLE_CSE_URL) | ||
| route = respx.get(OTHER).mock(return_value=httpx.Response(200, json=ITEMS)) | ||
| rows = await google_cse_search("k", "cx1", "sentient", 3, OTHER) | ||
| params = route.calls.last.request.url.params | ||
| assert (params["key"], params["cx"], params["q"], params["num"]) == ("k", "cx1", "sentient", "3") | ||
| assert not google.called | ||
| assert rows[0]["url"] == "https://example.com/a" | ||
|
|
||
|
|
||
| @respx.mock | ||
| async def test_connect_without_base_url_checks_google_and_stores_no_address(): | ||
| route = respx.get(GOOGLE_CSE_URL).mock(return_value=httpx.Response(200, json=ITEMS)) | ||
| creds, _ = await GoogleCSEPlugin().validate({"api_key": "k", "cx": "cx1", "base_url": " "}, None) | ||
| assert route.called | ||
| assert creds == {"api_key": "k", "cx": "cx1"} | ||
|
|
||
|
|
||
| @respx.mock | ||
| async def test_connect_with_base_url_checks_it_and_stores_it(): | ||
| google = respx.get(GOOGLE_CSE_URL) | ||
| route = respx.get(OTHER).mock(return_value=httpx.Response(200, json=ITEMS)) | ||
| creds, _ = await GoogleCSEPlugin().validate({"api_key": "k", "cx": "cx1", "base_url": OTHER}, None) | ||
| assert route.called and not google.called | ||
| assert creds == {"api_key": "k", "cx": "cx1", "base_url": OTHER} | ||
|
|
||
|
|
||
| @respx.mock | ||
| async def test_search_keeps_the_query_already_in_base_url(): | ||
| route = respx.get(OTHER).mock(return_value=httpx.Response(200, json=ITEMS)) | ||
| await google_cse_search("k", "cx1", "sentient", 3, OTHER + "?tenant=abc") | ||
| params = route.calls.last.request.url.params | ||
| assert (params["tenant"], params["cx"], params["q"]) == ("abc", "cx1", "sentient") | ||
|
|
||
|
|
||
| @respx.mock | ||
| async def test_connect_keeps_the_query_already_in_base_url(): | ||
| route = respx.get(OTHER).mock(return_value=httpx.Response(200, json=ITEMS)) | ||
| creds, _ = await GoogleCSEPlugin().validate({"api_key": "k", "cx": "cx1", "base_url": OTHER + "?tenant=abc"}, None) | ||
| params = route.calls.last.request.url.params | ||
| assert (params["tenant"], params["cx"]) == ("abc", "cx1") | ||
| assert creds["base_url"] == OTHER + "?tenant=abc" | ||
|
|
||
|
|
||
| @respx.mock | ||
| async def test_connect_rejects_a_malformed_address(): | ||
| with pytest.raises(IntegrationError): | ||
| await GoogleCSEPlugin().validate({"api_key": "k", "cx": "cx1", "base_url": "https://example.test:notaport"}, None) | ||
|
|
||
|
|
||
| @respx.mock | ||
| async def test_connect_reports_an_unreachable_address_as_an_integration_error(): | ||
| respx.get(OTHER).mock(side_effect=httpx.ConnectError("refused")) | ||
| with pytest.raises(IntegrationError): | ||
| await GoogleCSEPlugin().validate({"api_key": "k", "cx": "cx1", "base_url": OTHER}, None) | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("answer", [ | ||
| httpx.Response(200, text="<html>Sign in</html>", headers={"Content-Type": "text/html"}), | ||
| httpx.Response(200, json=[1, 2]), | ||
| ]) | ||
| @respx.mock | ||
| async def test_connect_rejects_an_address_that_does_not_answer_with_a_json_object(answer): | ||
| respx.get(OTHER).mock(return_value=answer) | ||
| with pytest.raises(IntegrationError): | ||
| await GoogleCSEPlugin().validate({"api_key": "k", "cx": "cx1", "base_url": OTHER}, None) | ||
|
|
||
|
|
||
| async def test_connect_rejects_a_non_http_address(): | ||
| with pytest.raises(IntegrationError): | ||
| await GoogleCSEPlugin().validate({"api_key": "k", "cx": "cx1", "base_url": "file:///etc/passwd"}, None) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.