def test_size_is_invalid(self, mock_url_for): """The order parameter on the request is invalid.""" request_data = MultiDict({ 'searchtype': 'title', 'query': 'foo title', 'size': 51, # Invalid 'order': '' # Valid }) with self.assertRaises(BadRequest): simple.search(request_data)
def test_size_is_invalid(self, mock_url_for): """The order parameter on the request is invalid.""" request_data = MultiDict({ "searchtype": "title", "query": "foo title", "size": 51, # Invalid "order": "", # Valid }) with self.assertRaises(BadRequest): simple.search(request_data)
def test_index_raises_query_error(self, mock_index): """Index service raises a QueryError.""" # We need to explicit assign the exception to the mock, otherwise the # exception raised in the side-effect will just be a mock object (not # inheriting from BaseException). mock_index.QueryError = QueryError mock_index.IndexConnectionError = IndexConnectionError def _raiseQueryError(*args, **kwargs): raise QueryError('What now') mock_index.search.side_effect = _raiseQueryError request_data = MultiDict({ 'searchtype': 'title', 'query': 'foo title' }) with self.assertRaises(InternalServerError): try: response_data, code, headers = simple.search(request_data) except QueryError as e: self.fail("QueryError should be handled (caught %s)" % e) self.assertEqual(mock_index.search.call_count, 1, "A search should be attempted")
def test_no_form_data(self, mock_index): """No form data has been submitted.""" request_data = MultiDict() response_data, code, headers = simple.search(request_data) self.assertEqual(code, HTTPStatus.OK, "Response should be OK.") self.assertIn("form", response_data, "Response should include form.") self.assertEqual(mock_index.search.call_count, 0, "No search should be attempted")
def test_invalid_data(self, mock_index): """Form data are invalid.""" request_data = MultiDict({"searchtype": "title"}) response_data, code, headers = simple.search(request_data) self.assertEqual(code, HTTPStatus.OK, "Response should be OK.") self.assertIn("form", response_data, "Response should include form.") self.assertEqual(mock_index.search.call_count, 0, "No search should be attempted")
def test_arxiv_id(self, mock_index): """Query parameter contains an arXiv ID.""" request_data = MultiDict({'query': '1702.00123'}) response_data, code, headers = simple.search(request_data) self.assertEqual(code, status.HTTP_301_MOVED_PERMANENTLY, "Response should be a 301 redirect.") self.assertIn('Location', headers, "Location header should be set") self.assertEqual(mock_index.search.call_count, 0, "No search should be attempted")
def test_single_field_term(self, mock_index): """Form data are present.""" mock_index.search.return_value = DocumentSet(metadata={}, results=[]) request_data = MultiDict({'searchtype': 'title', 'query': 'foo title'}) response_data, code, headers = simple.search(request_data) self.assertEqual(mock_index.search.call_count, 1, "A search should be attempted") call_args, call_kwargs = mock_index.search.call_args self.assertIsInstance(call_args[0], SimpleQuery, "An SimpleQuery is passed to the search index") self.assertEqual(code, status.HTTP_200_OK, "Response should be OK.")
def search() -> Union[str, Response]: """First pass at a search results page.""" response, code, headers = simple.search(request.args) logger.debug(f"controller returned code: {code}") if code == status.HTTP_200_OK: return render_template("search/search.html", pagetitle="Search", **response) elif (code == status.HTTP_301_MOVED_PERMANENTLY or code == status.HTTP_303_SEE_OTHER): return redirect(headers['Location'], code=code) raise InternalServerError('Unexpected error')
def search(archives: Optional[List[str]] = None) -> Union[str, Response]: """Simple search interface.""" response, code, headers = simple.search(request.args, archives) logger.debug(f"controller returned code: {code}") if code == status.HTTP_200_OK: return render_template("search/search.html", pagetitle="Search", archives=archives, **response) elif (code == status.HTTP_301_MOVED_PERMANENTLY or code == status.HTTP_303_SEE_OTHER): return redirect(headers['Location'], code=code) raise InternalServerError('Unexpected error')
def test_single_field_term(self, mock_index): """Form data are present.""" mock_index.search.return_value = {"metadata": {}, "results": []} request_data = MultiDict({"searchtype": "title", "query": "foo title"}) response_data, code, headers = simple.search(request_data) self.assertEqual(mock_index.search.call_count, 1, "A search should be attempted") call_args, call_kwargs = mock_index.search.call_args self.assertIsInstance( call_args[0], SimpleQuery, "An SimpleQuery is passed to the search index", ) self.assertEqual(code, HTTPStatus.OK, "Response should be OK.")
def test_title_search_contains_classic_syntax(self, mock_index): """User has entered a `surname_f` query in a title search.""" request_data = MultiDict({ 'searchtype': 'title', 'query': 'franklin_r', 'size': 50, 'order': '' }) mock_index.search.return_value = DocumentSet(metadata={}, results=[]) data, code, headers = simple.search(request_data) self.assertEqual(data['query'].value, "franklin_r", "The query should not be rewritten.") self.assertFalse(data['has_classic_format'], "Flag should not be set, as no rewrite has occurred.")
def test_index_raises_query_error(self, mock_index): """Index service raises a QueryError.""" def _raiseQueryError(*args, **kwargs): raise QueryError("What now") mock_index.search.side_effect = _raiseQueryError request_data = MultiDict({"searchtype": "title", "query": "foo title"}) with self.assertRaises(InternalServerError): try: response_data, code, headers = simple.search(request_data) except QueryError as ex: self.fail("QueryError should be handled (caught %s)" % ex) self.assertEqual(mock_index.search.call_count, 1, "A search should be attempted")
def test_index_raises_connection_exception(self, mock_index): """Index service raises a IndexConnectionError.""" def _raiseIndexConnectionError(*args, **kwargs): raise IndexConnectionError('What now') mock_index.search.side_effect = _raiseIndexConnectionError request_data = MultiDict({'searchtype': 'title', 'query': 'foo title'}) with self.assertRaises(InternalServerError): response_data, code, headers = simple.search(request_data) self.assertEqual(mock_index.search.call_count, 1, "A search should be attempted") call_args, call_kwargs = mock_index.search.call_args self.assertIsInstance(call_args[0], SimpleQuery, "An SimpleQuery is passed to the search index")
def search(archives: Optional[List[str]] = None) -> _Response: """Simple search interface.""" data, code, hdrs = simple.search(request.args, archives) logger.debug(f"controller returned code: {code}") if code == HTTPStatus.OK: content = render_template("search/search.html", pagetitle="Search", archives=archives, **data) response: Response = make_response(content) for key, value in hdrs.items(): response.headers[key] = value return response elif code == HTTPStatus.MOVED_PERMANENTLY or code == HTTPStatus.SEE_OTHER: return redirect(hdrs["Location"], code=code) raise InternalServerError("Unexpected error")
def test_author_search_contains_classic_syntax(self, mock_index): """User has entered a `surname_f` query in an author search.""" request_data = MultiDict({ 'searchtype': 'author', 'query': 'franklin_r', 'size': 50, 'order': '' }) mock_index.search.return_value = DocumentSet(metadata={}, results=[]) data, code, headers = simple.search(request_data) self.assertEqual(data['query'].value, "franklin, r", "The query should be rewritten.") self.assertTrue(data['has_classic_format'], "A flag denoting the syntax interception should be set" " in the response context, so that a message may be" " rendered in the template.")
def test_all_fields_search_multiple_classic_syntax(self, mock_index): """User has entered a classic query with multiple authors.""" request_data = MultiDict({ 'searchtype': 'all', 'query': 'j franklin_r hawking_s', 'size': 50, 'order': '' }) mock_index.search.return_value = DocumentSet(metadata={}, results=[]) data, code, headers = simple.search(request_data) self.assertEqual(data['query'].value, "j franklin, r; hawking, s", "The query should be rewritten.") self.assertTrue(data['has_classic_format'], "A flag denoting the syntax interception should be set" " in the response context, so that a message may be" " rendered in the template.")
def test_index_raises_connection_exception(self, mock_index): """Index service raises a IndexConnectionError.""" def _raiseIndexConnectionError(*args, **kwargs): raise IndexConnectionError("What now") mock_index.search.side_effect = _raiseIndexConnectionError request_data = MultiDict({"searchtype": "title", "query": "foo title"}) with self.assertRaises(InternalServerError): _, _, _ = simple.search(request_data) self.assertEqual(mock_index.search.call_count, 1, "A search should be attempted") call_args, call_kwargs = mock_index.search.call_args self.assertIsInstance( call_args[0], SimpleQuery, "An SimpleQuery is passed to the search index", )
def test_title_search_contains_classic_syntax(self, mock_index): """User has entered a `surname_f` query in a title search.""" request_data = MultiDict({ "searchtype": "title", "query": "franklin_r", "size": 50, "order": "", }) mock_index.search.return_value = {"metadata": {}, "results": []} data, code, headers = simple.search(request_data) self.assertEqual( data["query"].value, "franklin_r", "The query should not be rewritten.", ) self.assertFalse( data["has_classic_format"], "Flag should not be set, as no rewrite has occurred.", )
def test_index_raises_connection_exception(self, mock_index): """Index service raises a IndexConnectionError.""" # We need to explicit assign the exception to the mock, otherwise the # exception raised in the side-effect will just be a mock object (not # inheriting from BaseException). mock_index.IndexConnectionError = IndexConnectionError def _raiseIndexConnectionError(*args, **kwargs): raise IndexConnectionError('What now') mock_index.search.side_effect = _raiseIndexConnectionError request_data = MultiDict({'searchtype': 'title', 'query': 'foo title'}) with self.assertRaises(InternalServerError): response_data, code, headers = simple.search(request_data) self.assertEqual(mock_index.search.call_count, 1, "A search should be attempted") call_args, call_kwargs = mock_index.search.call_args self.assertIsInstance(call_args[0], SimpleQuery, "An SimpleQuery is passed to the search index")
def test_all_fields_search_multiple_classic_syntax(self, mock_index): """User has entered a classic query with multiple authors.""" request_data = MultiDict({ "searchtype": "all", "query": "j franklin_r hawking_s", "size": 50, "order": "", }) mock_index.search.return_value = {"metadata": {}, "results": []} data, code, headers = simple.search(request_data) self.assertEqual( data["query"].value, "j franklin, r; hawking, s", "The query should be rewritten.", ) self.assertTrue( data["has_classic_format"], "A flag denoting the syntax interception should be set" " in the response context, so that a message may be" " rendered in the template.", )
def test_author_search_contains_classic_syntax(self, mock_index): """User has entered a `surname_f` query in an author search.""" request_data = MultiDict({ "searchtype": "author", "query": "franklin_r", "size": 50, "order": "", }) mock_index.search.return_value = {"metadata": {}, "results": []} data, code, headers = simple.search(request_data) self.assertEqual( data["query"].value, "franklin, r", "The query should be rewritten.", ) self.assertTrue( data["has_classic_format"], "A flag denoting the syntax interception should be set" " in the response context, so that a message may be" " rendered in the template.", )