drivefs_search_unittest.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/components/drivefs/drivefs_search.h"
  5. #include <utility>
  6. #include "ash/components/drivefs/mojom/drivefs.mojom-test-utils.h"
  7. #include "ash/components/drivefs/mojom/drivefs.mojom.h"
  8. #include "base/run_loop.h"
  9. #include "base/test/bind.h"
  10. #include "base/test/simple_test_clock.h"
  11. #include "base/test/task_environment.h"
  12. #include "mojo/public/cpp/bindings/pending_receiver.h"
  13. #include "mojo/public/cpp/bindings/receiver.h"
  14. #include "services/network/test/test_network_connection_tracker.h"
  15. #include "testing/gmock/include/gmock/gmock.h"
  16. #include "testing/gtest/include/gtest/gtest.h"
  17. namespace drivefs {
  18. namespace {
  19. using testing::_;
  20. class MockDriveFs : public mojom::DriveFsInterceptorForTesting,
  21. public mojom::SearchQuery {
  22. public:
  23. MockDriveFs() = default;
  24. MockDriveFs(const MockDriveFs&) = delete;
  25. MockDriveFs& operator=(const MockDriveFs&) = delete;
  26. DriveFs* GetForwardingInterface() override {
  27. NOTREACHED();
  28. return nullptr;
  29. }
  30. MOCK_CONST_METHOD1(OnStartSearchQuery, void(const mojom::QueryParameters&));
  31. void StartSearchQuery(mojo::PendingReceiver<mojom::SearchQuery> receiver,
  32. mojom::QueryParametersPtr query_params) override {
  33. search_receiver_.reset();
  34. OnStartSearchQuery(*query_params);
  35. search_receiver_.Bind(std::move(receiver));
  36. }
  37. MOCK_METHOD1(OnGetNextPage,
  38. drive::FileError(
  39. absl::optional<std::vector<mojom::QueryItemPtr>>* items));
  40. void GetNextPage(GetNextPageCallback callback) override {
  41. absl::optional<std::vector<mojom::QueryItemPtr>> items;
  42. auto error = OnGetNextPage(&items);
  43. std::move(callback).Run(error, std::move(items));
  44. }
  45. private:
  46. mojo::Receiver<mojom::SearchQuery> search_receiver_{this};
  47. };
  48. class DriveFsSearchTest : public testing::Test {
  49. public:
  50. DriveFsSearchTest()
  51. : network_connection_tracker_(
  52. network::TestNetworkConnectionTracker::CreateInstance()) {
  53. clock_.SetNow(base::Time::Now());
  54. }
  55. protected:
  56. base::test::TaskEnvironment task_environment_;
  57. std::unique_ptr<network::TestNetworkConnectionTracker>
  58. network_connection_tracker_;
  59. MockDriveFs mock_drivefs_;
  60. base::SimpleTestClock clock_;
  61. };
  62. } // namespace
  63. ACTION_P(PopulateSearch, count) {
  64. if (count < 0)
  65. return;
  66. std::vector<mojom::QueryItemPtr> items;
  67. for (int i = 0; i < count; ++i) {
  68. items.emplace_back(mojom::QueryItem::New());
  69. items.back()->metadata = mojom::FileMetadata::New();
  70. items.back()->metadata->capabilities = mojom::Capabilities::New();
  71. }
  72. *arg0 = std::move(items);
  73. }
  74. MATCHER_P5(MatchQuery, source, text, title, shared, offline, "") {
  75. if (arg.query_source != source)
  76. return false;
  77. if (text != nullptr) {
  78. if (!arg.text_content || *arg.text_content != std::string(text))
  79. return false;
  80. } else {
  81. if (arg.text_content)
  82. return false;
  83. }
  84. if (title != nullptr) {
  85. if (!arg.title || *arg.title != std::string(title))
  86. return false;
  87. } else {
  88. if (arg.title)
  89. return false;
  90. }
  91. return arg.shared_with_me == shared && arg.available_offline == offline;
  92. }
  93. TEST_F(DriveFsSearchTest, Search) {
  94. DriveFsSearch search(&mock_drivefs_, network_connection_tracker_.get(),
  95. &clock_);
  96. EXPECT_CALL(mock_drivefs_, OnStartSearchQuery(_));
  97. EXPECT_CALL(mock_drivefs_, OnGetNextPage(_))
  98. .WillOnce(testing::DoAll(
  99. PopulateSearch(3), testing::Return(drive::FileError::FILE_ERROR_OK)));
  100. mojom::QueryParametersPtr params = mojom::QueryParameters::New();
  101. params->query_source = mojom::QueryParameters::QuerySource::kLocalOnly;
  102. bool called = false;
  103. mojom::QueryParameters::QuerySource source = search.PerformSearch(
  104. std::move(params),
  105. base::BindLambdaForTesting(
  106. [&called](drive::FileError err,
  107. absl::optional<std::vector<mojom::QueryItemPtr>> items) {
  108. called = true;
  109. EXPECT_EQ(drive::FileError::FILE_ERROR_OK, err);
  110. EXPECT_EQ(3u, items->size());
  111. }));
  112. EXPECT_EQ(mojom::QueryParameters::QuerySource::kLocalOnly, source);
  113. base::RunLoop().RunUntilIdle();
  114. EXPECT_TRUE(called);
  115. }
  116. TEST_F(DriveFsSearchTest, Search_Fail) {
  117. DriveFsSearch search(&mock_drivefs_, network_connection_tracker_.get(),
  118. &clock_);
  119. EXPECT_CALL(mock_drivefs_, OnStartSearchQuery(_));
  120. EXPECT_CALL(mock_drivefs_, OnGetNextPage(_))
  121. .WillOnce(testing::Return(drive::FileError::FILE_ERROR_ACCESS_DENIED));
  122. mojom::QueryParametersPtr params = mojom::QueryParameters::New();
  123. params->query_source = mojom::QueryParameters::QuerySource::kCloudOnly;
  124. bool called = false;
  125. mojom::QueryParameters::QuerySource source = search.PerformSearch(
  126. std::move(params),
  127. base::BindLambdaForTesting(
  128. [&called](drive::FileError err,
  129. absl::optional<std::vector<mojom::QueryItemPtr>> items) {
  130. called = true;
  131. EXPECT_EQ(drive::FileError::FILE_ERROR_ACCESS_DENIED, err);
  132. }));
  133. EXPECT_EQ(mojom::QueryParameters::QuerySource::kCloudOnly, source);
  134. base::RunLoop().RunUntilIdle();
  135. EXPECT_TRUE(called);
  136. }
  137. TEST_F(DriveFsSearchTest, Search_OnlineToOffline) {
  138. DriveFsSearch search(&mock_drivefs_, network_connection_tracker_.get(),
  139. &clock_);
  140. network_connection_tracker_->SetConnectionType(
  141. network::mojom::ConnectionType::CONNECTION_NONE);
  142. EXPECT_CALL(mock_drivefs_, OnStartSearchQuery(_));
  143. EXPECT_CALL(mock_drivefs_, OnGetNextPage(_))
  144. .WillOnce(testing::DoAll(
  145. PopulateSearch(3), testing::Return(drive::FileError::FILE_ERROR_OK)));
  146. mojom::QueryParametersPtr params = mojom::QueryParameters::New();
  147. params->query_source = mojom::QueryParameters::QuerySource::kCloudOnly;
  148. bool called = false;
  149. mojom::QueryParameters::QuerySource source = search.PerformSearch(
  150. std::move(params),
  151. base::BindLambdaForTesting(
  152. [&called](drive::FileError err,
  153. absl::optional<std::vector<mojom::QueryItemPtr>> items) {
  154. called = true;
  155. EXPECT_EQ(drive::FileError::FILE_ERROR_OK, err);
  156. EXPECT_EQ(3u, items->size());
  157. }));
  158. EXPECT_EQ(mojom::QueryParameters::QuerySource::kLocalOnly, source);
  159. base::RunLoop().RunUntilIdle();
  160. EXPECT_TRUE(called);
  161. }
  162. TEST_F(DriveFsSearchTest, Search_OnlineToOfflineFallback) {
  163. DriveFsSearch search(&mock_drivefs_, network_connection_tracker_.get(),
  164. &clock_);
  165. EXPECT_CALL(mock_drivefs_,
  166. OnStartSearchQuery(
  167. MatchQuery(mojom::QueryParameters::QuerySource::kCloudOnly,
  168. "foobar", nullptr, false, false)));
  169. EXPECT_CALL(mock_drivefs_,
  170. OnStartSearchQuery(
  171. MatchQuery(mojom::QueryParameters::QuerySource::kLocalOnly,
  172. nullptr, "foobar", false, false)));
  173. EXPECT_CALL(mock_drivefs_, OnGetNextPage(_))
  174. .WillOnce(testing::Return(drive::FileError::FILE_ERROR_NO_CONNECTION))
  175. .WillOnce(testing::DoAll(
  176. PopulateSearch(3), testing::Return(drive::FileError::FILE_ERROR_OK)));
  177. mojom::QueryParametersPtr params = mojom::QueryParameters::New();
  178. params->query_source = mojom::QueryParameters::QuerySource::kCloudOnly;
  179. params->text_content = "foobar";
  180. bool called = false;
  181. mojom::QueryParameters::QuerySource source = search.PerformSearch(
  182. std::move(params),
  183. base::BindLambdaForTesting(
  184. [&called](drive::FileError err,
  185. absl::optional<std::vector<mojom::QueryItemPtr>> items) {
  186. called = true;
  187. EXPECT_EQ(drive::FileError::FILE_ERROR_OK, err);
  188. EXPECT_EQ(3u, items->size());
  189. }));
  190. EXPECT_EQ(mojom::QueryParameters::QuerySource::kCloudOnly, source);
  191. base::RunLoop().RunUntilIdle();
  192. EXPECT_TRUE(called);
  193. }
  194. TEST_F(DriveFsSearchTest, Search_SharedWithMeCaching) {
  195. DriveFsSearch search(&mock_drivefs_, network_connection_tracker_.get(),
  196. &clock_);
  197. EXPECT_CALL(mock_drivefs_,
  198. OnStartSearchQuery(
  199. MatchQuery(mojom::QueryParameters::QuerySource::kCloudOnly,
  200. nullptr, nullptr, true, false)))
  201. .Times(2);
  202. EXPECT_CALL(mock_drivefs_,
  203. OnStartSearchQuery(
  204. MatchQuery(mojom::QueryParameters::QuerySource::kLocalOnly,
  205. nullptr, nullptr, true, false)))
  206. .Times(1);
  207. EXPECT_CALL(mock_drivefs_, OnGetNextPage(_))
  208. .WillOnce(testing::DoAll(
  209. PopulateSearch(3), testing::Return(drive::FileError::FILE_ERROR_OK)))
  210. .WillOnce(testing::DoAll(
  211. PopulateSearch(3), testing::Return(drive::FileError::FILE_ERROR_OK)))
  212. .WillOnce(testing::DoAll(
  213. PopulateSearch(3), testing::Return(drive::FileError::FILE_ERROR_OK)));
  214. mojom::QueryParametersPtr params = mojom::QueryParameters::New();
  215. params->query_source = mojom::QueryParameters::QuerySource::kCloudOnly;
  216. params->shared_with_me = true;
  217. bool called = false;
  218. mojom::QueryParameters::QuerySource source = search.PerformSearch(
  219. std::move(params),
  220. base::BindLambdaForTesting(
  221. [&called](drive::FileError err,
  222. absl::optional<std::vector<mojom::QueryItemPtr>> items) {
  223. called = true;
  224. EXPECT_EQ(drive::FileError::FILE_ERROR_OK, err);
  225. EXPECT_EQ(3u, items->size());
  226. }));
  227. EXPECT_EQ(mojom::QueryParameters::QuerySource::kCloudOnly, source);
  228. base::RunLoop().RunUntilIdle();
  229. EXPECT_TRUE(called);
  230. params = mojom::QueryParameters::New();
  231. params->query_source = mojom::QueryParameters::QuerySource::kCloudOnly;
  232. params->shared_with_me = true;
  233. called = false;
  234. source = search.PerformSearch(
  235. std::move(params),
  236. base::BindLambdaForTesting(
  237. [&called](drive::FileError err,
  238. absl::optional<std::vector<mojom::QueryItemPtr>> items) {
  239. called = true;
  240. EXPECT_EQ(drive::FileError::FILE_ERROR_OK, err);
  241. EXPECT_EQ(3u, items->size());
  242. }));
  243. EXPECT_EQ(mojom::QueryParameters::QuerySource::kLocalOnly, source);
  244. base::RunLoop().RunUntilIdle();
  245. EXPECT_TRUE(called);
  246. // Time has passed...
  247. clock_.Advance(base::Hours(1));
  248. params = mojom::QueryParameters::New();
  249. params->query_source = mojom::QueryParameters::QuerySource::kCloudOnly;
  250. params->shared_with_me = true;
  251. called = false;
  252. source = search.PerformSearch(
  253. std::move(params),
  254. base::BindLambdaForTesting(
  255. [&called](drive::FileError err,
  256. absl::optional<std::vector<mojom::QueryItemPtr>> items) {
  257. called = true;
  258. EXPECT_EQ(drive::FileError::FILE_ERROR_OK, err);
  259. EXPECT_EQ(3u, items->size());
  260. }));
  261. EXPECT_EQ(mojom::QueryParameters::QuerySource::kCloudOnly, source);
  262. base::RunLoop().RunUntilIdle();
  263. EXPECT_TRUE(called);
  264. }
  265. TEST_F(DriveFsSearchTest, Search_NoErrorCaching) {
  266. DriveFsSearch search(&mock_drivefs_, network_connection_tracker_.get(),
  267. &clock_);
  268. EXPECT_CALL(mock_drivefs_,
  269. OnStartSearchQuery(
  270. MatchQuery(mojom::QueryParameters::QuerySource::kCloudOnly,
  271. nullptr, nullptr, true, false)))
  272. .Times(2);
  273. EXPECT_CALL(mock_drivefs_,
  274. OnStartSearchQuery(
  275. MatchQuery(mojom::QueryParameters::QuerySource::kLocalOnly,
  276. nullptr, nullptr, true, false)))
  277. .Times(0);
  278. EXPECT_CALL(mock_drivefs_, OnGetNextPage(_))
  279. .WillOnce(
  280. testing::DoAll(PopulateSearch(0),
  281. testing::Return(drive::FileError::FILE_ERROR_FAILED)))
  282. .WillOnce(testing::DoAll(
  283. PopulateSearch(3), testing::Return(drive::FileError::FILE_ERROR_OK)));
  284. mojom::QueryParametersPtr params = mojom::QueryParameters::New();
  285. params->query_source = mojom::QueryParameters::QuerySource::kCloudOnly;
  286. params->shared_with_me = true;
  287. bool called = false;
  288. mojom::QueryParameters::QuerySource source = search.PerformSearch(
  289. std::move(params),
  290. base::BindLambdaForTesting(
  291. [&called](drive::FileError err,
  292. absl::optional<std::vector<mojom::QueryItemPtr>>) {
  293. called = true;
  294. EXPECT_EQ(drive::FileError::FILE_ERROR_FAILED, err);
  295. }));
  296. EXPECT_EQ(mojom::QueryParameters::QuerySource::kCloudOnly, source);
  297. base::RunLoop().RunUntilIdle();
  298. EXPECT_TRUE(called);
  299. params = mojom::QueryParameters::New();
  300. params->query_source = mojom::QueryParameters::QuerySource::kCloudOnly;
  301. params->shared_with_me = true;
  302. // As previous call failed this one will go to the cloud again.
  303. called = false;
  304. source = search.PerformSearch(
  305. std::move(params),
  306. base::BindLambdaForTesting(
  307. [&called](drive::FileError err,
  308. absl::optional<std::vector<mojom::QueryItemPtr>> items) {
  309. called = true;
  310. EXPECT_EQ(drive::FileError::FILE_ERROR_OK, err);
  311. EXPECT_EQ(3u, items->size());
  312. }));
  313. EXPECT_EQ(mojom::QueryParameters::QuerySource::kCloudOnly, source);
  314. base::RunLoop().RunUntilIdle();
  315. EXPECT_TRUE(called);
  316. }
  317. } // namespace drivefs