From 9409e8bd9126d8fcbf9a9e55251438f8f5ef1251 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Fri, 21 Oct 2022 18:24:27 +0400 Subject: [PATCH] Preventing confusion of tongues in multizim search Multizim search requires that all selected books be in the same language. No new URL query parameter was introduced for specifying the intended search language - `books.filter.lang` can be used for that purpose. The server_search unit-test was updated to use a slightly cheating library xml file where the language of example.zim was tweaked from "en" to "eng" in order to match that of zimfile.zim. Note that this change drops from the tested server two other goofy ZIM files corner_cases.zim and poor.zim that have been/are included in ServerTest. --- src/server/internalServer.cpp | 14 ++++++++++++ static/i18n/en.json | 1 + test/data/lib_for_server_search_test.xml | 4 ++++ test/meson.build | 1 + test/server_search.cpp | 27 +++++++++++++++++++----- 5 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 test/data/lib_for_server_search_test.xml diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index f593b6b2..378f516f 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -211,6 +211,16 @@ void checkBookNumber(const Library::BookIdSet& bookIds, size_t limit) { } } +typedef std::set Languages; + +Languages getLanguages(const Library& lib, const Library::BookIdSet& bookIds) { + Languages langs; + for ( const auto& b : bookIds ) { + langs.insert(lib.getBookById(b).getLanguage()); + } + return langs; +} + struct CustomizedResourceData { std::string mimeType; @@ -306,6 +316,10 @@ SearchInfo InternalServer::getSearchInfo(const RequestContext& request) const { auto bookIds = selectBooks(request); checkBookNumber(bookIds.second, m_multizimSearchLimit); + if ( getLanguages(*mp_library, bookIds.second).size() != 1 ) { + throw Error(nonParameterizedMessage("confusion-of-tongues")); + } + auto pattern = request.get_optional_param("pattern", ""); GeoQuery geoQuery; diff --git a/static/i18n/en.json b/static/i18n/en.json index 89c83c91..bf8441fc 100644 --- a/static/i18n/en.json +++ b/static/i18n/en.json @@ -27,4 +27,5 @@ , "home-button-text": "Go to the main page of '{{BOOK_TITLE}}'" , "random-page-button-text": "Go to a randomly selected page" , "searchbox-tooltip": "Search '{{BOOK_TITLE}}'" + , "confusion-of-tongues": "Two or more books in different languages would participate in search, which may lead to confusing results." } diff --git a/test/data/lib_for_server_search_test.xml b/test/data/lib_for_server_search_test.xml new file mode 100644 index 00000000..994c6a6f --- /dev/null +++ b/test/data/lib_for_server_search_test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/test/meson.build b/test/meson.build index b91f8cd0..90b7ce89 100644 --- a/test/meson.build +++ b/test/meson.build @@ -37,6 +37,7 @@ if gtest_dep.found() and not meson.is_cross_build() 'corner_cases.zim', 'poor.zim', 'library.xml', + 'lib_for_server_search_test.xml', 'customized_resources.txt', 'helloworld.txt', 'welcome.html', diff --git a/test/server_search.cpp b/test/server_search.cpp index 4f301f3e..ca6bc165 100644 --- a/test/server_search.cpp +++ b/test/server_search.cpp @@ -6,6 +6,17 @@ #define SERVER_PORT 8101 #include "server_testing_tools.h" + +class ServerSearchTest : public ServerTest +{ + void SetUp() override { + zfs1_.reset(new ZimFileServer(SERVER_PORT, + ZimFileServer::DEFAULT_OPTIONS, + "./test/lib_for_server_search_test.xml") + ); + } +}; + std::string makeSearchResultsHtml(const std::string& pattern, const std::string& header, const std::string& results, @@ -555,7 +566,7 @@ const std::vector LARGE_SEARCH_RESULTS = { // // In order to be able to share the same expected output data // LARGE_SEARCH_RESULTS between multiple build platforms and test-points -// of the ServerTest.searchResults test-case +// of the ServerSearchTest.searchResults test-case // // 1. Snippets are excluded from the plain-text comparison of actual and // expected HTML strings. This is done with the help of the @@ -916,7 +927,7 @@ struct TestData } }; -TEST_F(ServerTest, searchResults) +TEST_F(ServerSearchTest, searchResults) { const TestData testData[] = { { @@ -1340,14 +1351,12 @@ TEST_F(ServerTest, searchResults) /* pagination */ {} }, - // Only RayCharles is in English. - // [TODO] We should extend our test data to have another zim file in english returning results. { /* query */ "pattern=travel" "&books.filter.lang=eng", /* start */ 0, /* resultsPerPage */ 10, - /* totalResultCount */ 1, + /* totalResultCount */ 2, /* firstResultIndex */ 1, /* results */ { SEARCH_RESULT( @@ -1357,6 +1366,14 @@ TEST_F(ServerTest, searchResults) /*bookTitle*/ "Ray Charles", /*wordCount*/ "204" ), + + SEARCH_RESULT( + /*link*/ "/ROOT/content/example/Wikibooks.html", + /*title*/ "Wikibooks", + /*snippet*/ R"SNIPPET(...Travel guide Wikidata Knowledge database Commons Media repository Meta Coordination MediaWiki MediaWiki software Phabricator MediaWiki bug tracker Wikimedia Labs MediaWiki development The Wikimedia Foundation is a non-profit organization that depends on your voluntarism and donations to operate. If you find Wikibooks or other projects hosted by the Wikimedia Foundation useful, please volunteer or make a donation. Your donations primarily helps to purchase server equipment, launch new projects......)SNIPPET", + /*bookTitle*/ "Wikibooks", + /*wordCount*/ "538" + ) }, /* pagination */ {} },