| // Copyright 2021 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 <memory> |
| #include <string> |
| |
| #include "base/files/file_util.h" |
| #include "base/task/thread_pool.h" |
| #include "base/threading/thread_restrictions.h" |
| #include "chrome/browser/icon_transcoder/svg_icon_transcoder.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "content/public/test/browser_test.h" |
| |
| constexpr char kSvgData[] = |
| "<svg width='20px' height='20px' viewBox='0 0 24 24' fill='rgb(95,99,104)' " |
| "xmlns='http://www.w3.org/2000/svg'><path d='M0 0h24v24H0V0z' " |
| "fill='none'/><path d='M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 " |
| "2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 " |
| "6.41V10h2V3h-7z'/></svg>"; |
| |
| constexpr char kInvalidSvgData[] = "<svg garbled not really useful>bad</svg>"; |
| constexpr char kGarbageData[] = "this is not even svg-like"; |
| constexpr gfx::Size kSize(48, 48); |
| |
| class SvgIconTranscoderTest : public InProcessBrowserTest { |
| public: |
| void SetUpInProcessBrowserTestFixture() override { |
| InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); |
| ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| svg_path_ = temp_dir_.GetPath().Append(FILE_PATH_LITERAL("icon.svg")); |
| png_path_ = temp_dir_.GetPath().Append(FILE_PATH_LITERAL("icon.png")); |
| } |
| |
| void TearDownInProcessBrowserTestFixture() override { |
| svg_icon_transcoder_.reset(); |
| InProcessBrowserTest::TearDownInProcessBrowserTestFixture(); |
| } |
| |
| apps::SvgIconTranscoder* svg_icon_transcoder() { |
| if (!svg_icon_transcoder_) { |
| svg_icon_transcoder_ = |
| std::make_unique<apps::SvgIconTranscoder>(browser()->profile()); |
| } |
| return svg_icon_transcoder_.get(); |
| } |
| |
| void ExpectTranscodeSuccess(base::OnceClosure done_closure, |
| std::string icon_data) { |
| EXPECT_FALSE(icon_data.empty()); |
| compressed_icon_data_ = std::move(icon_data); |
| std::move(done_closure).Run(); |
| } |
| |
| void ExpectTranscodeFailure(base::OnceClosure done_closure, |
| std::string icon_data) { |
| EXPECT_TRUE(icon_data.empty()); |
| compressed_icon_data_ = std::move(icon_data); |
| std::move(done_closure).Run(); |
| } |
| |
| void ExpectSavedIcon(bool saved) { |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| EXPECT_EQ(base::PathExists(png_path()), saved); |
| if (saved) { |
| std::string saved_data; |
| ASSERT_TRUE(base::ReadFileToString(png_path(), &saved_data)); |
| EXPECT_EQ(saved_data, compressed_icon_data_); |
| } |
| } |
| |
| void WriteIconData(const base::FilePath& path, |
| const std::string& icon_data) const { |
| base::RunLoop run_loop; |
| base::ThreadPool::PostTaskAndReply( |
| FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, |
| base::BindOnce( |
| [](const base::FilePath& path, const std::string& icon_data) { |
| EXPECT_TRUE(base::WriteFile(path, icon_data)); |
| }, |
| path, icon_data), |
| run_loop.QuitClosure()); |
| run_loop.Run(); |
| } |
| |
| const base::FilePath png_path() const { return png_path_; } |
| const base::FilePath svg_path() const { return svg_path_; } |
| |
| protected: |
| std::string compressed_icon_data_; |
| std::unique_ptr<apps::SvgIconTranscoder> svg_icon_transcoder_; |
| base::FilePath svg_path_; |
| base::FilePath png_path_; |
| base::ScopedTempDir temp_dir_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(SvgIconTranscoderTest, TranscodeFromDataSuccessNoSave) { |
| base::RunLoop run_loop; |
| svg_icon_transcoder()->Transcode( |
| std::string(kSvgData), base::FilePath(), kSize, |
| base::BindOnce(&SvgIconTranscoderTest::ExpectTranscodeSuccess, |
| base::Unretained(this), run_loop.QuitClosure())); |
| run_loop.Run(); |
| ExpectSavedIcon(false); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SvgIconTranscoderTest, TranscodeFromDataSuccessAndSave) { |
| base::RunLoop run_loop; |
| svg_icon_transcoder()->Transcode( |
| std::string(kSvgData), png_path(), kSize, |
| base::BindOnce(&SvgIconTranscoderTest::ExpectTranscodeSuccess, |
| base::Unretained(this), run_loop.QuitClosure())); |
| run_loop.Run(); |
| ExpectSavedIcon(true); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SvgIconTranscoderTest, TranscodeFromInvalid) { |
| base::RunLoop run_loop; |
| svg_icon_transcoder()->Transcode( |
| std::string(kInvalidSvgData), base::FilePath(), kSize, |
| base::BindOnce(&SvgIconTranscoderTest::ExpectTranscodeFailure, |
| base::Unretained(this), run_loop.QuitClosure())); |
| run_loop.Run(); |
| ExpectSavedIcon(false); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SvgIconTranscoderTest, TranscodeFromGarbage) { |
| base::RunLoop run_loop; |
| svg_icon_transcoder()->Transcode( |
| std::string(kGarbageData), base::FilePath(), kSize, |
| base::BindOnce(&SvgIconTranscoderTest::ExpectTranscodeFailure, |
| base::Unretained(this), run_loop.QuitClosure())); |
| run_loop.Run(); |
| ExpectSavedIcon(false); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SvgIconTranscoderTest, TranscodeFromFileSuccessNoSave) { |
| base::RunLoop run_loop; |
| WriteIconData(svg_path_, kSvgData); |
| |
| svg_icon_transcoder()->Transcode( |
| svg_path(), base::FilePath(), kSize, |
| base::BindOnce(&SvgIconTranscoderTest::ExpectTranscodeSuccess, |
| base::Unretained(this), run_loop.QuitClosure())); |
| run_loop.Run(); |
| ExpectSavedIcon(false); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SvgIconTranscoderTest, TranscodeFromFileSuccessAndSave) { |
| base::RunLoop run_loop; |
| WriteIconData(svg_path_, kSvgData); |
| |
| svg_icon_transcoder()->Transcode( |
| svg_path(), png_path(), kSize, |
| base::BindOnce(&SvgIconTranscoderTest::ExpectTranscodeSuccess, |
| base::Unretained(this), run_loop.QuitClosure())); |
| run_loop.Run(); |
| ExpectSavedIcon(true); |
| } |