2024-05-09 15:40:36 +02:00
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
2023-09-20 11:55:18 +02:00
import os
2023-09-06 17:31:42 +02:00
from unittest . mock import Mock , patch
2024-02-05 13:17:01 +01:00
from haystack . utils . auth import Secret
2023-09-06 17:31:42 +02:00
import pytest
from requests import Timeout , RequestException , HTTPError
2023-11-24 14:48:43 +01:00
from haystack import Document
from haystack . components . websearch . serper_dev import SerperDevWebSearch , SerperDevError
2023-09-06 17:31:42 +02:00
EXAMPLE_SERPERDEV_RESPONSE = {
" searchParameters " : {
" q " : " Who is the boyfriend of Olivia Wilde? " ,
" gl " : " us " ,
" hl " : " en " ,
" autocorrect " : True ,
" type " : " search " ,
} ,
" organic " : [
{
" title " : " Olivia Wilde embraces Jason Sudeikis amid custody battle, Harry Styles split - Page Six " ,
" link " : " https://pagesix.com/2023/01/29/olivia-wilde-hugs-it-out-with-jason-sudeikis-after-harry-styles-split/ " ,
" snippet " : " Looks like Olivia Wilde and Jason Sudeikis are starting 2023 on good terms. Amid their highly publicized custody battle – and the actress ' ... " ,
" date " : " Jan 29, 2023 " ,
" position " : 1 ,
} ,
{
" title " : " Olivia Wilde Is ' Quietly Dating ' Again Following Harry Styles Split: ' He Makes Her Happy ' " ,
" link " : " https://www.yahoo.com/now/olivia-wilde-quietly-dating-again-183844364.html " ,
" snippet " : " Olivia Wilde is “quietly dating again” following her November 2022 split from Harry Styles, a source exclusively tells Life & Style. " ,
" date " : " Feb 10, 2023 " ,
" position " : 2 ,
} ,
{
" title " : " Olivia Wilde and Harry Styles ' Relationship Timeline: The Way They Were - Us Weekly " ,
" link " : " https://www.usmagazine.com/celebrity-news/pictures/olivia-wilde-and-harry-styles-relationship-timeline/ " ,
" snippet " : " Olivia Wilde started dating Harry Styles after ending her years-long engagement to Jason Sudeikis — see their relationship timeline. " ,
" date " : " Mar 10, 2023 " ,
" imageUrl " : " https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSgTcalNFvptTbYBiDXX55s8yCGfn6F1qbed9DAN16LvynTr9GayK5SPmY&s " ,
" position " : 3 ,
} ,
{
" title " : " Olivia Wilde Is ' Ready to Date Again ' After Harry Styles Split - Us Weekly " ,
" link " : " https://www.usmagazine.com/celebrity-news/news/olivia-wilde-is-ready-to-date-again-after-harry-styles-split/ " ,
" snippet " : " Ready for love! Olivia Wilde is officially back on the dating scene following her split from her ex-boyfriend, Harry Styles. " ,
" date " : " Mar 1, 2023 " ,
" imageUrl " : " https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRCRAeRy5sVE631ZctzbzuOF70xkIOHaTvh2K7dYvdiVBwALiKrIjpscok&s " ,
" position " : 4 ,
} ,
{
" title " : " Harry Styles and Olivia Wilde ' s Definitive Relationship Timeline - Harper ' s Bazaar " ,
" link " : " https://www.harpersbazaar.com/celebrity/latest/a35172115/harry-styles-olivia-wilde-relationship-timeline/ " ,
" snippet " : " November 2020: News breaks about Olivia splitting from fiancé Jason Sudeikis. ... In mid-November, news breaks of Olivia Wilde ' s split from Jason ... " ,
" date " : " Feb 23, 2023 " ,
" imageUrl " : " https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRRqw3fvZOIGHEepxCc7yFAWYsS_v_1H6X-4nxyFJxdfRuFQw_BrI6JVzI&s " ,
" position " : 5 ,
} ,
{
" title " : " Harry Styles and Olivia Wilde ' s Relationship Timeline - People " ,
" link " : " https://people.com/music/harry-styles-olivia-wilde-relationship-timeline/ " ,
" snippet " : " Harry Styles and Olivia Wilde first met on the set of Don ' t Worry Darling and stepped out as a couple in January 2021. Relive all their biggest relationship ... " ,
" position " : 6 ,
} ,
{
" title " : " Jason Sudeikis and Olivia Wilde ' s Relationship Timeline - People " ,
" link " : " https://people.com/movies/jason-sudeikis-olivia-wilde-relationship-timeline/ " ,
" snippet " : " Jason Sudeikis and Olivia Wilde ended their engagement of seven years in 2020. Here ' s a complete timeline of their relationship. " ,
" date " : " Mar 24, 2023 " ,
" imageUrl " : " https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSleZoXusQyJJe2WMgIuck_cVaJ8AE0_hU2QxsXzYvKANi55UQlv82yAVI&s " ,
" position " : 7 ,
} ,
{
" title " : " Olivia Wilde ' s anger at ex-boyfriend Harry Styles: She resents him and thinks he was using her | Marca " ,
" link " : " https://www.marca.com/en/lifestyle/celebrities/2023/02/23/63f779a4e2704e8d988b4624.html " ,
" snippet " : " The two started dating after Wilde split up with actor Jason Sudeikisin 2020. However, their relationship came to an end last November. " ,
" date " : " Feb 23, 2023 " ,
" imageUrl " : " https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQBgJF2mSnIWCvPrqUqM4WTI9xPNWPyLvHuune85swpB1yE_G8cy_7KRh0&s " ,
" position " : 8 ,
} ,
{
" title " : " Olivia Wilde ' s dating history: Who has the actress dated? | The US Sun " ,
" link " : " https://www.the-sun.com/entertainment/5221040/olivia-wildes-dating-history/ " ,
" snippet " : " AMERICAN actress Olivia Wilde started dating Harry Styles in January 2021 after breaking off her engagement the year prior. " ,
" date " : " Nov 19, 2022 " ,
" imageUrl " : " https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTpm8BToVFHJoH6yRggg0fLocLT9mt6lwsnRxFFDNdDGhDydzQiSKZ9__g&s " ,
" position " : 9 ,
} ,
] ,
" relatedSearches " : [
{ " query " : " Harry Styles girlfriends in order " } ,
{ " query " : " Harry Styles and Olivia Wilde engaged " } ,
{ " query " : " Harry Styles and Olivia Wilde wedding " } ,
{ " query " : " Who is Harry Styles married to " } ,
{ " query " : " Jason Sudeikis Olivia Wilde relationship " } ,
{ " query " : " Olivia Wilde and Jason Sudeikis kids " } ,
{ " query " : " Olivia Wilde children " } ,
{ " query " : " Harry Styles and Olivia Wilde age difference " } ,
{ " query " : " Jason Sudeikis Olivia Wilde, Harry Styles " } ,
] ,
}
@pytest.fixture
def mock_serper_dev_search_result ( ) :
2023-11-24 14:48:43 +01:00
with patch ( " haystack.components.websearch.serper_dev.requests " ) as mock_run :
2023-09-06 17:31:42 +02:00
mock_run . post . return_value = Mock ( status_code = 200 , json = lambda : EXAMPLE_SERPERDEV_RESPONSE )
yield mock_run
class TestSerperDevSearchAPI :
2023-10-23 15:56:23 +05:30
def test_init_fail_wo_api_key ( self , monkeypatch ) :
monkeypatch . delenv ( " SERPERDEV_API_KEY " , raising = False )
2024-02-05 13:17:01 +01:00
with pytest . raises ( ValueError , match = " None of the .* environment variables are set " ) :
2023-10-23 15:56:23 +05:30
SerperDevWebSearch ( )
2024-02-05 13:17:01 +01:00
def test_to_dict ( self , monkeypatch ) :
monkeypatch . setenv ( " SERPERDEV_API_KEY " , " test-api-key " )
component = SerperDevWebSearch ( top_k = 10 , allowed_domains = [ " test.com " ] , search_params = { " param " : " test " } )
2023-09-06 17:31:42 +02:00
data = component . to_dict ( )
assert data == {
2023-11-24 14:48:43 +01:00
" type " : " haystack.components.websearch.serper_dev.SerperDevWebSearch " ,
2024-02-05 13:17:01 +01:00
" init_parameters " : {
" api_key " : { " env_vars " : [ " SERPERDEV_API_KEY " ] , " strict " : True , " type " : " env_var " } ,
" top_k " : 10 ,
" allowed_domains " : [ " test.com " ] ,
" search_params " : { " param " : " test " } ,
} ,
2023-09-06 17:31:42 +02:00
}
@pytest.mark.parametrize ( " top_k " , [ 1 , 5 , 7 ] )
def test_web_search_top_k ( self , mock_serper_dev_search_result , top_k : int ) :
2024-02-05 13:17:01 +01:00
ws = SerperDevWebSearch ( api_key = Secret . from_token ( " test-api-key " ) , top_k = top_k )
2023-09-25 10:03:01 +02:00
results = ws . run ( query = " Who is the boyfriend of Olivia Wilde? " )
documents = results [ " documents " ]
links = results [ " links " ]
assert len ( documents ) == len ( links ) == top_k
assert all ( isinstance ( doc , Document ) for doc in documents )
assert all ( isinstance ( link , str ) for link in links )
assert all ( link . startswith ( " http " ) for link in links )
2023-09-06 17:31:42 +02:00
@patch ( " requests.post " )
def test_timeout_error ( self , mock_post ) :
mock_post . side_effect = Timeout
2024-02-05 13:17:01 +01:00
ws = SerperDevWebSearch ( api_key = Secret . from_token ( " test-api-key " ) )
2023-09-06 17:31:42 +02:00
with pytest . raises ( TimeoutError ) :
ws . run ( query = " Who is the boyfriend of Olivia Wilde? " )
@patch ( " requests.post " )
def test_request_exception ( self , mock_post ) :
mock_post . side_effect = RequestException
2024-02-05 13:17:01 +01:00
ws = SerperDevWebSearch ( api_key = Secret . from_token ( " test-api-key " ) )
2023-09-06 17:31:42 +02:00
with pytest . raises ( SerperDevError ) :
ws . run ( query = " Who is the boyfriend of Olivia Wilde? " )
@patch ( " requests.post " )
def test_bad_response_code ( self , mock_post ) :
mock_response = mock_post . return_value
mock_response . status_code = 404
mock_response . raise_for_status . side_effect = HTTPError
2024-02-05 13:17:01 +01:00
ws = SerperDevWebSearch ( api_key = Secret . from_token ( " test-api-key " ) )
2023-09-06 17:31:42 +02:00
with pytest . raises ( SerperDevError ) :
ws . run ( query = " Who is the boyfriend of Olivia Wilde? " )
2023-09-20 11:55:18 +02:00
@pytest.mark.skipif (
not os . environ . get ( " SERPERDEV_API_KEY " , None ) ,
reason = " Export an env var called SERPERDEV_API_KEY containing the SerperDev API key to run this test. " ,
)
@pytest.mark.integration
2023-09-25 10:03:01 +02:00
def test_web_search ( self ) :
2024-02-05 13:17:01 +01:00
ws = SerperDevWebSearch ( top_k = 10 )
2023-09-25 10:03:01 +02:00
results = ws . run ( query = " Who is the boyfriend of Olivia Wilde? " )
documents = results [ " documents " ]
2024-02-28 16:43:08 +01:00
links = results [ " links " ]
2023-09-25 10:03:01 +02:00
assert len ( documents ) == len ( links ) == 10
2023-09-20 11:55:18 +02:00
assert all ( isinstance ( doc , Document ) for doc in results )
2023-09-25 10:03:01 +02:00
assert all ( isinstance ( link , str ) for link in links )
assert all ( link . startswith ( " http " ) for link in links )