launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #22392
Re: [Merge] lp:~maxiberta/launchpad/sitesearch-cleanup-2 into lp:launchpad
All comments addressed. Was unsure about deleting those doctests or keeping them for documentation purposes. Also, there's an extra disabled doctest, which I think I could tackle in this same branch. What do you think?
Diff comments:
> === modified file 'lib/lp/services/sitesearch/tests/test_bing.py'
> --- lib/lp/services/sitesearch/tests/test_bing.py 2018-04-12 19:42:23 +0000
> +++ lib/lp/services/sitesearch/tests/test_bing.py 2018-04-13 19:56:29 +0000
> @@ -7,31 +7,177 @@
>
> __metaclass__ = type
>
> +import json
> +from os import path
Done (both bing and google).
> +
> from fixtures import MockPatch
> from requests.exceptions import (
> ConnectionError,
> HTTPError,
> )
> -from testtools.matchers import MatchesStructure
> +from testtools.matchers import (
> + HasLength,
> + MatchesStructure,
> +)
Fixed.
>
> +from lp.services.config import config
> from lp.services.sitesearch import BingSearchService
> from lp.services.sitesearch.interfaces import SiteSearchResponseError
> from lp.services.timeout import TimeoutError
> from lp.testing import TestCase
> -from lp.testing.layers import (
> - BingLaunchpadFunctionalLayer,
> - LaunchpadFunctionalLayer,
> - )
> +from lp.testing.layers import BingLaunchpadFunctionalLayer
>
>
> class TestBingSearchService(TestCase):
> """Test BingSearchService."""
>
> - layer = LaunchpadFunctionalLayer
> -
> def setUp(self):
> super(TestBingSearchService, self).setUp()
> self.search_service = BingSearchService()
> + self.base_path = path.normpath(
> + path.join(path.dirname(__file__), 'data'))
> +
> + def test_configuration(self):
> + self.assertEqual(config.bing.site, self.search_service.site)
> + self.assertEqual(
> + config.bing.subscription_key, self.search_service.subscription_key)
> + self.assertEqual(
> + config.bing.custom_config_id, self.search_service.custom_config_id)
> +
> + def test_create_search_url(self):
> + self.assertEndsWith(
> + self.search_service.create_search_url(terms='svg +bugs'),
> + '&offset=0&q=svg+%2Bbugs')
> +
> + def test_create_search_url_escapes_unicode_chars(self):
> + self.assertEndsWith(
> + self.search_service.create_search_url('Carlo Perell\xf3 Mar\xedn'),
Done.
> + '&offset=0&q=Carlo+Perell%C3%B3+Mar%C3%ADn')
> +
> + def test_create_search_url_with_offset(self):
> + self.assertEndsWith(
> + self.search_service.create_search_url(terms='svg +bugs', start=20),
> + '&offset=20&q=svg+%2Bbugs')
> +
> + def test_create_search_url_empty_terms(self):
> + e = self.assertRaises(
> + ValueError, self.search_service.create_search_url, '')
> + self.assertEqual("Missing value for parameter 'q'.", str(e))
Updated.
> +
> + def test_create_search_url_null_terms(self):
> + e = self.assertRaises(
> + ValueError, self.search_service.create_search_url, None)
> + self.assertEqual("Missing value for parameter 'q'.", str(e))
> +
> + def test_create_search_url_requires_start(self):
> + e = self.assertRaises(
> + ValueError, self.search_service.create_search_url, 'bugs', 'true')
> + self.assertEqual("Value for parameter 'offset' is not an int.", str(e))
> +
> + def test_parse_search_response_invalid_total(self):
> + """The PageMatches's total attribute comes from the
> + `webPages.totalEstimatedMatches` JSON element.
> + When it cannot be found and the value cast to an int,
> + an error is raised. If Bing were to redefine the meaning of the
> + element to use a '~' to indicate an approximate total, an error would
> + be raised.
> + """
> + file_name = path.join(
> + self.base_path, 'bingsearchservice-incompatible-matches.json')
> + with open(file_name, 'r') as response_file:
> + response = response_file.read()
> + assert (
> + json.loads(response)['webPages']['totalEstimatedMatches'] == '~25')
Oh, in other projects (SCA comes to my mind), `assert` in tests is used for invariants. Replaced by `self.assertEqual`.
> +
> + e = self.assertRaises(
> + SiteSearchResponseError,
> + self.search_service._parse_search_response, response)
> + self.assertEqual(
> + "Could not get the total from the Bing JSON response.", str(e))
> +
> + def test_parse_search_response_negative_total(self):
> + """If the total is ever less than zero (see bug 683115),
> + this is expected: we simply return a total of 0.
> + """
> + file_name = path.join(
> + self.base_path, 'bingsearchservice-negative-total.json')
> + with open(file_name, 'r') as response_file:
> + response = response_file.read()
> + assert json.loads(response)['webPages']['totalEstimatedMatches'] == -25
> +
> + matches = self.search_service._parse_search_response(response)
> + self.assertEqual(0, matches.total)
> +
> + def test_parse_search_response_missing_title(self):
> + """A PageMatch requires a title, url, and a summary. If those elements
> + cannot be found, a PageMatch cannot be made. A missing title ('name')
> + indicates a bad page on Launchpad, so it is ignored. In this example,
> + the first match is missing a title, so only the second page is present
> + in the PageMatches.
> + """
> + file_name = path.join(
> + self.base_path, 'bingsearchservice-missing-title.json')
> + with open(file_name, 'r') as response_file:
> + response = response_file.read()
> + assert len(json.loads(response)['webPages']['value']) == 2
> +
> + matches = self.search_service._parse_search_response(response)
> + self.assertThat(matches, HasLength(1))
> + self.assertEqual('GCleaner in Launchpad', matches[0].title)
> + self.assertEqual('http://launchpad.dev/gcleaner', matches[0].url)
Good idea, thanks.
> +
> + def test_parse_search_response_missing_summary(self):
> + """When a match is missing a summary ('snippet'), the match is skipped
> + because there is no information about why it matched. This appears to
> + relate to pages that are in the index, but should be removed. In this
> + example taken from real data, the links are to the same page on
> + different vhosts. The edge vhost has no summary, so it is skipped.
> + """
> + file_name = path.join(
> + self.base_path, 'bingsearchservice-missing-summary.json')
> + with open(file_name, 'r') as response_file:
> + response = response_file.read()
> + assert len(json.loads(response)['webPages']['value']) == 2
> +
> + matches = self.search_service._parse_search_response(response)
> + self.assertThat(matches, HasLength(1))
> + self.assertEqual('BugExpiry - Launchpad Help', matches[0].title)
> + self.assertEqual(
> + 'https://help.launchpad.net/BugExpiry', matches[0].url)
> +
> + def test_parse_search_response_missing_url(self):
> + """When the URL ('url') cannot be found the match is skipped. There are
> + no examples of this. We do not want this hypothetical situation to give
> + users a bad experience.
> + """
> + file_name = path.join(
> + self.base_path, 'bingsearchservice-missing-url.json')
> + with open(file_name, 'r') as response_file:
> + response = response_file.read()
> + assert len(json.loads(response)['webPages']['value']) == 2
> +
> + matches = self.search_service._parse_search_response(response)
> + self.assertThat(matches, HasLength(1))
> + self.assertEqual('LongoMatch in Launchpad', matches[0].title)
> + self.assertEqual('http://launchpad.dev/longomatch', matches[0].url)
> +
> + def test_parse_search_response_with_no_meaningful_results(self):
> + """If no matches are found in the response, and there are 20 or fewer
> + results, an Empty PageMatches is returned. This happens when the
> + results are missing titles and summaries. This is not considered to be
> + a problem because the small number implies that Bing did a poor job
> + of indexing pages or indexed the wrong Launchpad server. In this
> + example, there is only one match, but the results is missing a title so
> + there is not enough information to make a PageMatch.
> + """
> + file_name = path.join(
> + self.base_path, 'bingsearchservice-no-meaningful-results.json')
> + with open(file_name, 'r') as response_file:
> + response = response_file.read()
> + assert len(json.loads(response)['webPages']['value']) == 1
> +
> + matches = self.search_service._parse_search_response(response)
> + self.assertThat(matches, HasLength(0))
>
> def test_search_converts_HTTPError(self):
> # The method converts HTTPError to SiteSearchResponseError.
--
https://code.launchpad.net/~maxiberta/launchpad/sitesearch-cleanup-2/+merge/343236
Your team Launchpad code reviewers is subscribed to branch lp:launchpad.
References