From 61209ea0d7433aa77902b51ad4b437ca495ac190 Mon Sep 17 00:00:00 2001 From: Maneesh P M Date: Sun, 25 Jul 2021 12:24:44 +0530 Subject: [PATCH] Allow kiwix-serve to get suggestions of custom range This will allow handle_suggest API to accept two arguments `start` and `suggestionLength` that will allow handle_suggest to retrieve suggestions in the given range rather than the default 0-10 range. --- src/server/internalServer.cpp | 23 +++++++++---- test/server.cpp | 64 +++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index 6cf8b01e3..345da10eb 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -345,13 +345,13 @@ std::unique_ptr InternalServer::build_homepage(const RequestContext& r // TODO: retrieve searcher from caching mechanism SuggestionsList_t getSuggestions(const zim::Archive* const archive, - const std::string& queryString, int suggestionCount) + const std::string& queryString, int start, int suggestionCount) { SuggestionsList_t suggestions; auto searcher = zim::SuggestionSearcher(*archive); if (archive->hasTitleIndex()) { auto search = searcher.suggest(queryString); - auto srs = search.getResults(0, suggestionCount); + auto srs = search.getResults(start, suggestionCount); for (auto it : srs) { SuggestionItem suggestion(it.getTitle(), kiwix::normalize(it.getTitle()), @@ -439,8 +439,6 @@ std::unique_ptr InternalServer::handle_suggest(const RequestContext& r std::string content; std::string mimeType; - unsigned int maxSuggestionCount = 10; - unsigned int suggestionCount = 0; std::string bookName; std::string bookId; @@ -455,6 +453,20 @@ std::unique_ptr InternalServer::handle_suggest(const RequestContext& r return Response::build_404(*this, request, bookName, ""); } + auto start = 0; + try { + start = request.get_argument("start"); + } catch (const std::exception&) {} + + unsigned int count = 10; + try { + count = request.get_argument("count"); + } catch (const std::exception&) {} + + if (count == 0) { + count = 10; + } + if (archive == nullptr) { return Response::build_404(*this, request, bookName, ""); } @@ -468,7 +480,7 @@ std::unique_ptr InternalServer::handle_suggest(const RequestContext& r bool first = true; /* Get the suggestions */ - SuggestionsList_t suggestions = getSuggestions(archive.get(), queryString, maxSuggestionCount); + SuggestionsList_t suggestions = getSuggestions(archive.get(), queryString, start, count); for(auto& suggestion:suggestions) { MustacheData result; result.set("label", suggestion.getTitle()); @@ -483,7 +495,6 @@ std::unique_ptr InternalServer::handle_suggest(const RequestContext& r result.set("first", first); first = false; results.push_back(result); - suggestionCount++; } diff --git a/test/server.cpp b/test/server.cpp index f67e57fd3..f039df253 100644 --- a/test/server.cpp +++ b/test/server.cpp @@ -1176,3 +1176,67 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_search_terms) "\n" ); } + +TEST_F(LibraryServerTest, suggestions_in_range) +{ + /** + * Attempt to get 50 suggestions in steps of 5 + * The suggestions are returned in the json format + * [{sugg1}, {sugg2}, ... , {suggN}, {suggest ft search}] + * Assuming the number of suggestions = (occurance of "{" - 1) + */ + { + int suggCount = 0; + for (int i = 0; i < 10; i++) { + std::string url = "/suggest?content=zimfile&term=ray&start=" + std::to_string(i*5) + "&count=5"; + const auto r = zfs1_->GET(url.c_str()); + std::string body = r->body; + int currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 5); + suggCount += currCount; + } + ASSERT_EQ(suggCount, 50); + } + + // Attempt to get 10 suggestions in steps of 5 even though there are only 8 + { + std::string url = "/suggest?content=zimfile&term=song+for+you&start=0&count=5"; + const auto r1 = zfs1_->GET(url.c_str()); + std::string body = r1->body; + int currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 5); + + url = "/suggest?content=zimfile&term=song+for+you&start=5&count=5"; + const auto r2 = zfs1_->GET(url.c_str()); + body = r2->body; + currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 3); + } + + // Attempt to get 10 suggestions even though there is only 1 + { + std::string url = "/suggest?content=zimfile&term=strong&start=0&count=5"; + const auto r = zfs1_->GET(url.c_str()); + std::string body = r->body; + int currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 1); + } + + // No Suggestion + { + std::string url = "/suggest?content=zimfile&term=oops&start=0&count=5"; + const auto r = zfs1_->GET(url.c_str()); + std::string body = r->body; + int currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 0); + } + + // Out of bound value + { + std::string url = "/suggest?content=zimfile&term=ray&start=-2&count=-1"; + const auto r = zfs1_->GET(url.c_str()); + std::string body = r->body; + int currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 0); + } +} \ No newline at end of file