Commit 7a7d7202 authored by Jiaquan He's avatar Jiaquan He Committed by Commit Bot

Reland "Add tests for ArcPlayStoreAppSearchProvider."

This relands commit cc2fbf55,
which was reverted by f87a709b.

We create threads to load icons while initializing
ArcPlayStoreSearchResult objects,  so we have to wait for
them to finish, otherwise the test will be flaky and fail
the base::MessageLoop::current()->IsIdleForTesting() test
in test_browser_thread_bundle.cc.

Bug=736552

Change-Id: Icd054ea66367f3c28c3333522795e85475f40a1f
Reviewed-on: https://chromium-review.googlesource.com/590027Reviewed-by: default avatarLuis Hector Chavez <lhchavez@chromium.org>
Reviewed-by: default avatarYury Khmel <khmel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491077}
parent 03efa26c
...@@ -23,8 +23,7 @@ class ArcPlayStoreSearchProvider : public SearchProvider { ...@@ -23,8 +23,7 @@ class ArcPlayStoreSearchProvider : public SearchProvider {
AppListControllerDelegate* list_controller); AppListControllerDelegate* list_controller);
~ArcPlayStoreSearchProvider() override; ~ArcPlayStoreSearchProvider() override;
protected: // SearchProvider:
// app_list::SearchProvider overrides:
void Start(bool is_voice_query, const base::string16& query) override; void Start(bool is_voice_query, const base::string16& query) override;
void Stop() override; void Stop() override;
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.h"
#include <memory>
#include <string>
#include <utility>
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/app_list/app_list_test_util.h"
#include "chrome/browser/ui/app_list/arc/arc_app_test.h"
#include "chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h"
#include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h"
#include "chrome/test/base/testing_profile.h"
#include "ui/app_list/search_result.h"
namespace app_list {
class ArcPlayStoreSearchProviderTest : public AppListTestBase {
public:
ArcPlayStoreSearchProviderTest() = default;
~ArcPlayStoreSearchProviderTest() override = default;
// AppListTestBase:
void SetUp() override {
AppListTestBase::SetUp();
arc_test_.SetUp(profile());
controller_ = base::MakeUnique<test::TestAppListControllerDelegate>();
}
void TearDown() override {
controller_.reset();
arc_test_.TearDown();
AppListTestBase::TearDown();
}
protected:
std::unique_ptr<ArcPlayStoreSearchProvider> CreateSearch(int max_results) {
return base::MakeUnique<ArcPlayStoreSearchProvider>(
max_results, profile_.get(), controller_.get());
}
private:
std::unique_ptr<test::TestAppListControllerDelegate> controller_;
ArcAppTest arc_test_;
DISALLOW_COPY_AND_ASSIGN(ArcPlayStoreSearchProviderTest);
};
TEST_F(ArcPlayStoreSearchProviderTest, Basic) {
constexpr size_t kMaxResults = 6;
constexpr char kQuery[] = "Play App";
std::unique_ptr<ArcPlayStoreSearchProvider> provider =
CreateSearch(kMaxResults);
EXPECT_TRUE(provider->results().empty());
ArcPlayStoreSearchResult::DisableSafeDecodingForTesting();
// Check that the result size of a query doesn't exceed the |kMaxResults|.
provider->Start(false, base::UTF8ToUTF16(kQuery));
const app_list::SearchProvider::Results& results = provider->results();
ASSERT_GT(results.size(), 0u);
ASSERT_GE(kMaxResults, results.size());
// Check that information is correctly set in each result.
for (size_t i = 0; i < results.size(); ++i) {
SCOPED_TRACE(base::StringPrintf("Testing result %zu", i));
EXPECT_EQ(base::UTF16ToUTF8(results[i]->title()),
base::StringPrintf("%s %zu", kQuery, i));
EXPECT_EQ(results[i]->display_type(), SearchResult::DISPLAY_TILE);
EXPECT_EQ(base::UTF16ToUTF8(results[i]->formatted_price()),
base::StringPrintf("$%zu.22", i));
EXPECT_EQ(results[i]->rating(), i);
const bool is_instant_app = i % 2 == 0;
EXPECT_EQ(results[i]->result_type(),
is_instant_app ? SearchResult::RESULT_INSTANT_APP
: SearchResult::RESULT_PLAYSTORE_APP);
}
}
} // namespace app_list
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
using content::BrowserThread; using content::BrowserThread;
namespace { namespace {
bool disable_safe_decoding_for_testing = false;
// The id prefix to identify a Play Store search result. // The id prefix to identify a Play Store search result.
constexpr char kPlayAppPrefix[] = "play://"; constexpr char kPlayAppPrefix[] = "play://";
// Badge icon color, #000 at 54% opacity. // Badge icon color, #000 at 54% opacity.
...@@ -136,6 +137,11 @@ class ArcPlayStoreSearchResult::IconDecodeRequest ...@@ -136,6 +137,11 @@ class ArcPlayStoreSearchResult::IconDecodeRequest
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// ArcPlayStoreSearchResult // ArcPlayStoreSearchResult
// static
void ArcPlayStoreSearchResult::DisableSafeDecodingForTesting() {
disable_safe_decoding_for_testing = true;
}
ArcPlayStoreSearchResult::ArcPlayStoreSearchResult( ArcPlayStoreSearchResult::ArcPlayStoreSearchResult(
arc::mojom::AppDiscoveryResultPtr data, arc::mojom::AppDiscoveryResultPtr data,
Profile* profile, Profile* profile,
...@@ -155,9 +161,21 @@ ArcPlayStoreSearchResult::ArcPlayStoreSearchResult( ...@@ -155,9 +161,21 @@ ArcPlayStoreSearchResult::ArcPlayStoreSearchResult(
set_result_type(is_instant_app() ? RESULT_INSTANT_APP : RESULT_PLAYSTORE_APP); set_result_type(is_instant_app() ? RESULT_INSTANT_APP : RESULT_PLAYSTORE_APP);
icon_decode_request_ = base::MakeUnique<IconDecodeRequest>(this); icon_decode_request_ = base::MakeUnique<IconDecodeRequest>(this);
ImageDecoder::StartWithOptions(icon_decode_request_.get(), icon_png_data(), if (disable_safe_decoding_for_testing) {
ImageDecoder::DEFAULT_CODEC, true, SkBitmap bitmap;
gfx::Size()); if (!icon_png_data().empty() &&
gfx::PNGCodec::Decode(
reinterpret_cast<const unsigned char*>(icon_png_data().data()),
icon_png_data().size(), &bitmap)) {
icon_decode_request_->OnImageDecoded(bitmap);
} else {
icon_decode_request_->OnDecodeImageFailed();
}
} else {
ImageDecoder::StartWithOptions(icon_decode_request_.get(), icon_png_data(),
ImageDecoder::DEFAULT_CODEC, true,
gfx::Size());
}
} }
ArcPlayStoreSearchResult::~ArcPlayStoreSearchResult() = default; ArcPlayStoreSearchResult::~ArcPlayStoreSearchResult() = default;
......
...@@ -36,6 +36,13 @@ class ArcPlayStoreSearchResult : public SearchResult, ...@@ -36,6 +36,13 @@ class ArcPlayStoreSearchResult : public SearchResult,
void Open(int event_flags) override; void Open(int event_flags) override;
void ExecuteLaunchCommand(int event_flags) override; void ExecuteLaunchCommand(int event_flags) override;
// Disables async safe decoding requests when unit tests are executed.
// Icons are decoded at a separate process created by ImageDecoder. In unit
// tests these tasks may not finish before the test exits, which causes a
// failure in the base::MessageLoop::current()->IsIdleForTesting() check
// in test_browser_thread_bundle.cc.
static void DisableSafeDecodingForTesting();
private: private:
class IconDecodeRequest; class IconDecodeRequest;
......
...@@ -4972,6 +4972,7 @@ test("unit_tests") { ...@@ -4972,6 +4972,7 @@ test("unit_tests") {
"../browser/ui/app_list/profile_loader_unittest.cc", "../browser/ui/app_list/profile_loader_unittest.cc",
"../browser/ui/app_list/search/answer_card/answer_card_result_unittest.cc", "../browser/ui/app_list/search/answer_card/answer_card_result_unittest.cc",
"../browser/ui/app_list/search/app_search_provider_unittest.cc", "../browser/ui/app_list/search/app_search_provider_unittest.cc",
"../browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc",
"../browser/ui/app_list/search/history_unittest.cc", "../browser/ui/app_list/search/history_unittest.cc",
"../browser/ui/app_list/search/launcher_search/launcher_search_icon_image_loader_unittest.cc", "../browser/ui/app_list/search/launcher_search/launcher_search_icon_image_loader_unittest.cc",
"../browser/ui/app_list/search/omnibox_result_unittest.cc", "../browser/ui/app_list/search/omnibox_result_unittest.cc",
......
...@@ -283,8 +283,28 @@ void FakeAppInstance::GetRecentAndSuggestedAppsFromPlayStore( ...@@ -283,8 +283,28 @@ void FakeAppInstance::GetRecentAndSuggestedAppsFromPlayStore(
const std::string& query, const std::string& query,
int32_t max_results, int32_t max_results,
const GetRecentAndSuggestedAppsFromPlayStoreCallback& callback) { const GetRecentAndSuggestedAppsFromPlayStoreCallback& callback) {
// Fake Play Store app info
std::vector<arc::mojom::AppDiscoveryResultPtr> fake_apps;
for (int i = 0; i < max_results; ++i) {
// Fake icon data
std::string png_data_as_string;
GetFakeIcon(mojom::ScaleFactor::SCALE_FACTOR_100P, &png_data_as_string);
std::vector<uint8_t> fake_icon_png_data(png_data_as_string.begin(),
png_data_as_string.end());
fake_apps.push_back(mojom::AppDiscoveryResult::New(
base::StringPrintf("LauncherIntentUri %d", i), // launch_intent_uri
base::StringPrintf("InstallIntentUri %d", i), // install_intent_uri
base::StringPrintf("%s %d", query.c_str(), i), // label
i % 2 == 0, // is_instant_app
i % 4 == 0, // is_recent
base::StringPrintf("Publisher %d", i), // publisher_name
base::StringPrintf("$%d.22", i), // formatted_price
i, // review_score
fake_icon_png_data)); // icon_png_data
}
callback.Run(arc::mojom::AppDiscoveryRequestState::SUCCESS, callback.Run(arc::mojom::AppDiscoveryRequestState::SUCCESS,
std::vector<arc::mojom::AppDiscoveryResultPtr>()); std::move(fake_apps));
} }
void FakeAppInstance::StartPaiFlow() { void FakeAppInstance::StartPaiFlow() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment