launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #18138
[Merge] lp:~wgrant/launchpad/question-search-api into lp:launchpad
William Grant has proposed merging lp:~wgrant/launchpad/question-search-api into lp:launchpad.
Commit message:
Export QuestionSet.searchQuestions on the webservice.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~wgrant/launchpad/question-search-api/+merge/253009
Export QuestionSet.searchQuestions on the webservice. Question targets' methods were already exported.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/question-search-api into lp:launchpad.
=== modified file 'lib/lp/answers/interfaces/questioncollection.py'
--- lib/lp/answers/interfaces/questioncollection.py 2013-01-07 02:40:55 +0000
+++ lib/lp/answers/interfaces/questioncollection.py 2015-03-15 23:49:41 +0000
@@ -46,8 +46,23 @@
"""An object that can be used to search through a collection of questions.
"""
+ @operation_parameters(
+ search_text=TextLine(
+ title=_('Search text'), required=False),
+ status=List(
+ title=_('Status'), required=False,
+ value_type=Choice(vocabulary=QuestionStatus)),
+ language=List(
+ title=_('Language'), required=False,
+ value_type=ReferenceChoice(vocabulary='Language')),
+ sort=Choice(
+ title=_('Sort'), required=False,
+ vocabulary=QuestionSort))
+ @operation_returns_collection_of(Interface) # IQuestion.
+ @export_read_operation()
+ @operation_for_version('devel')
def searchQuestions(search_text=None,
- status=QUESTION_STATUS_DEFAULT_SEARCH,
+ status=list(QUESTION_STATUS_DEFAULT_SEARCH),
language=None, sort=None):
"""Return the questions from the collection matching search criteria.
=== modified file 'lib/lp/answers/interfaces/webservice.py'
--- lib/lp/answers/interfaces/webservice.py 2012-01-01 02:58:52 +0000
+++ lib/lp/answers/interfaces/webservice.py 2015-03-15 23:49:41 +0000
@@ -19,6 +19,7 @@
from lp.answers.interfaces.question import IQuestion
from lp.answers.interfaces.questioncollection import (
+ IQuestionCollection,
IQuestionSet,
ISearchableByQuestionOwner,
)
@@ -39,6 +40,8 @@
patch_collection_return_type(
IQuestionTarget, 'findSimilarQuestions', IQuestion)
patch_collection_return_type(
+ IQuestionCollection, 'searchQuestions', IQuestion)
+patch_collection_return_type(
ISearchableByQuestionOwner, 'searchQuestions', IQuestion)
patch_reference_property(IQuestionMessage, 'question', IQuestion)
patch_reference_property(IQuestionSubscription, 'question', IQuestion)
=== modified file 'lib/lp/answers/tests/test_question_webservice.py'
--- lib/lp/answers/tests/test_question_webservice.py 2012-10-30 16:59:58 +0000
+++ lib/lp/answers/tests/test_question_webservice.py 2015-03-15 23:49:41 +0000
@@ -8,6 +8,7 @@
from BeautifulSoup import BeautifulSoup
from lazr.restfulclient.errors import HTTPError
from simplejson import dumps
+from testtools.matchers import Equals
import transaction
from zope.security.proxy import removeSecurityProxy
@@ -21,10 +22,12 @@
QuestionTargetError,
)
from lp.testing import (
+ admin_logged_in,
celebrity_logged_in,
launchpadlib_for,
logout,
person_logged_in,
+ record_two_runs,
TestCase,
TestCaseWithFactory,
ws_object,
@@ -34,7 +37,11 @@
DatabaseFunctionalLayer,
FunctionalLayer,
)
-from lp.testing.pages import LaunchpadWebServiceCaller
+from lp.testing.matchers import HasQueryCount
+from lp.testing.pages import (
+ LaunchpadWebServiceCaller,
+ webservice_for_person,
+ )
from lp.testing.views import create_webservice_error_view
@@ -243,3 +250,37 @@
# Check the results.
self.assertFalse(db_question.isSubscribed(db_person))
+
+
+class TestQuestionSetWebService(TestCaseWithFactory):
+
+ layer = DatabaseFunctionalLayer
+
+ def test_searchQuestions(self):
+ created = [self.factory.makeQuestion(title="foo") for i in range(10)]
+ webservice = webservice_for_person(self.factory.makePerson())
+ collection = webservice.named_get(
+ '/questions', 'searchQuestions', search_text='foo',
+ sort='oldest first', api_version='devel').jsonBody()
+ # The first few matching questions are returned.
+ self.assertEqual(
+ [q.id for q in created[:5]],
+ [int(q['self_link'].rsplit('/', 1)[-1])
+ for q in collection['entries']])
+
+ def test_searchQuestions_query_count(self):
+ webservice = webservice_for_person(self.factory.makePerson())
+
+ def create_question():
+ with admin_logged_in():
+ self.factory.makeQuestion(title="foobar")
+
+ def search_questions():
+ webservice.named_get(
+ '/questions', 'searchQuestions', search_text='foobar',
+ api_version='devel').jsonBody()
+
+ search_questions()
+ recorder1, recorder2 = record_two_runs(
+ search_questions, create_question, 2)
+ self.assertThat(recorder2, HasQueryCount(Equals(recorder1.count)))
Follow ups