// Copyright 2020 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 "ash/ambient/ambient_photo_cache.h" #include #include #include "ash/ambient/ambient_access_token_controller.h" #include "ash/ambient/ambient_constants.h" #include "ash/ambient/test/ambient_ash_test_helper.h" #include "ash/ambient/test/test_ambient_client.h" #include "ash/constants/ash_features.h" #include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h" #include "base/bind.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/path_service.h" #include "base/run_loop.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" namespace ash { namespace { base::FilePath GetTestPath() { base::FilePath path; EXPECT_TRUE(base::PathService::Get(base::DIR_TEMP, &path)); path = path.Append(FILE_PATH_LITERAL(kAmbientModeDirectoryName)); return path; } } // namespace class AmbientPhotoCacheTest : public testing::Test { public: AmbientPhotoCacheTest() = default; void SetUp() override { ambient_ash_test_helper_ = std::make_unique(); access_token_controller_ = std::make_unique(); auto test_path = GetTestPath(); base::DeletePathRecursively(test_path); photo_cache_ = AmbientPhotoCache::Create( test_path, ambient_ash_test_helper_->ambient_client(), *access_token_controller_); } void TearDown() override { base::DeletePathRecursively(GetTestPath()); } AmbientPhotoCache* photo_cache() { return photo_cache_.get(); } network::TestURLLoaderFactory& test_url_loader_factory() { return ambient_ash_test_helper_->ambient_client().test_url_loader_factory(); } bool IsAccessTokenRequestPending() { return ambient_ash_test_helper_->ambient_client() .IsAccessTokenRequestPending(); } void IssueAccessToken() { ambient_ash_test_helper_->ambient_client().IssueAccessToken( /*is_empty=*/false); } void RunUntilIdle() { task_environment_.RunUntilIdle(); } private: base::test::TaskEnvironment task_environment_; std::unique_ptr ambient_ash_test_helper_; std::unique_ptr access_token_controller_; std::unique_ptr photo_cache_; }; TEST_F(AmbientPhotoCacheTest, ReadsBackWrittenFiles) { int cache_index = 0; std::string image("image"); std::string details("details"); std::string related_image("related image"); std::string related_details("related details"); bool is_portrait = true; { ambient::PhotoCacheEntry cache; cache.mutable_primary_photo()->set_image(image); cache.mutable_primary_photo()->set_details(details); cache.mutable_primary_photo()->set_is_portrait(is_portrait); cache.mutable_related_photo()->set_image(related_image); cache.mutable_related_photo()->set_details(related_details); cache.mutable_related_photo()->set_is_portrait(is_portrait); base::RunLoop loop; photo_cache()->WritePhotoCache(cache_index, cache, loop.QuitClosure()); loop.Run(); } { base::RunLoop loop; // Read the files back using photo cache. ambient::PhotoCacheEntry cache_read; photo_cache()->ReadPhotoCache( cache_index, base::BindLambdaForTesting( [&cache_read, &loop](ambient::PhotoCacheEntry cache_entry_in) { cache_read = std::move(cache_entry_in); loop.Quit(); })); loop.Run(); EXPECT_EQ(cache_read.primary_photo().image(), "image"); EXPECT_EQ(cache_read.primary_photo().details(), "details"); EXPECT_TRUE(cache_read.primary_photo().is_portrait()); EXPECT_EQ(cache_read.related_photo().image(), "related image"); EXPECT_EQ(cache_read.related_photo().details(), "related details"); EXPECT_TRUE(cache_read.related_photo().is_portrait()); } } TEST_F(AmbientPhotoCacheTest, SetsDataToEmptyStringWhenFilesMissing) { base::FilePath test_path = GetTestPath(); EXPECT_FALSE(base::DirectoryExists(test_path)); { base::RunLoop loop; ambient::PhotoCacheEntry cache_read; photo_cache()->ReadPhotoCache( /*cache_index=*/1, base::BindLambdaForTesting( [&cache_read, &loop](ambient::PhotoCacheEntry cache_entry_in) { cache_read = std::move(cache_entry_in); loop.Quit(); })); loop.Run(); EXPECT_TRUE(cache_read.primary_photo().image().empty()); EXPECT_TRUE(cache_read.primary_photo().details().empty()); EXPECT_FALSE(cache_read.primary_photo().is_portrait()); EXPECT_TRUE(cache_read.related_photo().image().empty()); EXPECT_TRUE(cache_read.related_photo().details().empty()); EXPECT_FALSE(cache_read.related_photo().is_portrait()); } } TEST_F(AmbientPhotoCacheTest, AttachTokenToDownloadRequest) { std::string fake_url = "https://faketesturl/"; photo_cache()->DownloadPhoto(fake_url, base::BindOnce([](std::string&&) {})); RunUntilIdle(); EXPECT_TRUE(IsAccessTokenRequestPending()); IssueAccessToken(); EXPECT_FALSE(IsAccessTokenRequestPending()); auto* pending_requests = test_url_loader_factory().pending_requests(); EXPECT_EQ(pending_requests->size(), std::size_t{1}); EXPECT_EQ(pending_requests->at(0).request.url, fake_url); std::string header; pending_requests->at(0).request.headers.GetHeader("Authorization", &header); EXPECT_EQ(header, std::string("Bearer ") + TestAmbientClient::kTestAccessToken); } TEST_F(AmbientPhotoCacheTest, AttachTokenToDownloadToFileRequest) { std::string fake_url = "https://faketesturl/"; photo_cache()->DownloadPhotoToFile(fake_url, /*cache_index=*/1, base::BindOnce([](bool) {})); RunUntilIdle(); EXPECT_TRUE(IsAccessTokenRequestPending()); IssueAccessToken(); EXPECT_FALSE(IsAccessTokenRequestPending()); auto* pending_requests = test_url_loader_factory().pending_requests(); EXPECT_EQ(pending_requests->size(), std::size_t{1}); EXPECT_EQ(pending_requests->at(0).request.url, fake_url); std::string header; pending_requests->at(0).request.headers.GetHeader("Authorization", &header); EXPECT_EQ(header, std::string("Bearer ") + TestAmbientClient::kTestAccessToken); } } // namespace ash