| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/webshare/chromeos/sharesheet_client.h" |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/files/file_util.h" |
| #include "base/run_loop.h" |
| #include "base/task/task_traits.h" |
| #include "base/task/thread_pool.h" |
| #include "base/test/bind.h" |
| #include "base/threading/scoped_blocking_call.h" |
| #include "chrome/browser/ash/file_manager/path_util.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "content/public/test/browser_test.h" |
| #include "content/public/test/browser_test_utils.h" |
| #include "net/base/filename_util.h" |
| #include "net/test/embedded_test_server/embedded_test_server.h" |
| #include "third_party/blink/public/mojom/webshare/webshare.mojom.h" |
| #include "url/gurl.h" |
| |
| namespace webshare { |
| |
| class SharesheetClientBrowserTest : public InProcessBrowserTest { |
| public: |
| static void CheckSize(const base::FilePath& file_path, |
| int64_t expected_size) { |
| base::RunLoop run_loop; |
| base::ThreadPool::PostTaskAndReplyWithResult( |
| FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING}, |
| base::BindLambdaForTesting([&file_path]() -> std::optional<int64_t> { |
| base::ScopedBlockingCall scoped_blocking_call( |
| FROM_HERE, base::BlockingType::WILL_BLOCK); |
| return base::GetFileSize(file_path); |
| }), |
| base::BindLambdaForTesting( |
| [&run_loop, &expected_size](std::optional<int64_t> file_size) { |
| ASSERT_TRUE(file_size.has_value()); |
| EXPECT_EQ(expected_size, file_size); |
| run_loop.Quit(); |
| })); |
| run_loop.Run(); |
| } |
| |
| GURL GetAppUrl() const { |
| return embedded_test_server()->GetURL("/webshare/index.html"); |
| } |
| |
| void ConfirmShareText( |
| const std::string& script, |
| const char* expected_text, |
| const char* expected_title, |
| const std::vector<std::string>& expected_content_types) { |
| SharesheetClient::SetSharesheetCallbackForTesting( |
| base::BindLambdaForTesting( |
| [&expected_text, &expected_title, &expected_content_types]( |
| content::WebContents* in_contents, |
| const std::vector<base::FilePath>& file_paths, |
| const std::vector<std::string>& content_types, |
| const std::vector<uint64_t>& file_sizes, |
| const std::string& text, const std::string& title, |
| SharesheetClient::DeliveredCallback delivered_callback) { |
| EXPECT_EQ(text, expected_text); |
| EXPECT_EQ(title, expected_title); |
| EXPECT_EQ(file_paths.size(), content_types.size()); |
| EXPECT_EQ(content_types, expected_content_types); |
| std::move(delivered_callback) |
| .Run(sharesheet::SharesheetResult::kSuccess); |
| })); |
| |
| content::WebContents* const contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| EXPECT_EQ("share succeeded", content::EvalJs(contents, script)); |
| } |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(SharesheetClientBrowserTest, ShareMultipleFiles) { |
| const std::string script = "share_multiple_files()"; |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetAppUrl())); |
| content::WebContents* const contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| std::vector<base::FilePath> file_paths; |
| |
| SharesheetClient::SetSharesheetCallbackForTesting(base::BindLambdaForTesting( |
| [contents, &file_paths]( |
| content::WebContents* in_contents, |
| const std::vector<base::FilePath>& in_file_paths, |
| const std::vector<std::string>& content_types, |
| const std::vector<uint64_t>& file_sizes, const std::string& text, |
| const std::string& title, |
| SharesheetClient::DeliveredCallback delivered_callback) { |
| EXPECT_EQ(contents, in_contents); |
| |
| file_paths = std::move(in_file_paths); |
| |
| EXPECT_EQ(content_types.size(), 3U); |
| EXPECT_EQ(content_types[0], "audio/mpeg"); |
| EXPECT_EQ(content_types[1], "video/mp4"); |
| EXPECT_EQ(content_types[2], "image/gif"); |
| |
| std::move(delivered_callback) |
| .Run(sharesheet::SharesheetResult::kSuccess); |
| })); |
| |
| EXPECT_EQ("share succeeded", content::EvalJs(contents, script)); |
| EXPECT_EQ(file_paths.size(), 3U); |
| |
| const base::FilePath share_cache = |
| file_manager::util::GetShareCacheFilePath(browser()->profile()); |
| EXPECT_EQ(file_paths[0], |
| share_cache.AppendASCII(".WebShare/share1/sam.ple.mp3")); |
| EXPECT_EQ(file_paths[1], |
| share_cache.AppendASCII(".WebShare/share2/sample.mp4")); |
| EXPECT_EQ(file_paths[2], |
| share_cache.AppendASCII(".WebShare/share3/sam_ple.gif")); |
| |
| CheckSize(file_paths[0], /*expected_size=*/345); |
| CheckSize(file_paths[1], /*expected_size=*/67890); |
| CheckSize(file_paths[2], /*expected_size=*/1); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SharesheetClientBrowserTest, RepeatedShare) { |
| const int kRepeats = 3; |
| const std::string script = "share_single_file()"; |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetAppUrl())); |
| content::WebContents* const contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| |
| for (int count = 0; count < kRepeats; ++count) { |
| std::vector<base::FilePath> file_paths; |
| |
| SharesheetClient::SetSharesheetCallbackForTesting( |
| base::BindLambdaForTesting( |
| [contents, &file_paths]( |
| content::WebContents* in_contents, |
| const std::vector<base::FilePath>& in_file_paths, |
| const std::vector<std::string>& content_types, |
| const std::vector<uint64_t>& file_sizes, |
| const std::string& text, const std::string& title, |
| SharesheetClient::DeliveredCallback delivered_callback) { |
| EXPECT_EQ(contents, in_contents); |
| |
| file_paths = std::move(in_file_paths); |
| |
| EXPECT_EQ(content_types.size(), 1U); |
| EXPECT_EQ(content_types[0], "image/webp"); |
| |
| std::move(delivered_callback) |
| .Run(sharesheet::SharesheetResult::kSuccess); |
| })); |
| |
| EXPECT_EQ("share succeeded", content::EvalJs(contents, script)); |
| EXPECT_EQ(file_paths.size(), 1U); |
| CheckSize(file_paths[0], /*expected_size=*/12); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SharesheetClientBrowserTest, CancelledShare) { |
| const std::string script = "share_single_file()"; |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| content::WebContents* const contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetAppUrl())); |
| SharesheetClient::SetSharesheetCallbackForTesting(base::BindLambdaForTesting( |
| [](content::WebContents* in_contents, |
| const std::vector<base::FilePath>& file_paths, |
| const std::vector<std::string>& content_types, |
| const std::vector<uint64_t>& file_sizes, const std::string& text, |
| const std::string& title, |
| SharesheetClient::DeliveredCallback delivered_callback) { |
| std::move(delivered_callback) |
| .Run(sharesheet::SharesheetResult::kCancel); |
| })); |
| |
| EXPECT_EQ("share failed: AbortError: Share canceled", |
| content::EvalJs(contents, script)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SharesheetClientBrowserTest, Text) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetAppUrl())); |
| ConfirmShareText("share_title()", |
| /*expected_text=*/"", |
| /*expected_title=*/"Subject", /*expected_content_types=*/{}); |
| ConfirmShareText("share_title_url()", |
| /*expected_text=*/"https://example.com/", |
| /*expected_title=*/"Subject", /*expected_content_types=*/{}); |
| ConfirmShareText("share_text()", |
| /*expected_text=*/"Message", |
| /*expected_title=*/"", /*expected_content_types=*/{}); |
| ConfirmShareText("share_text_url()", |
| /*expected_text=*/"Message https://example.com/", |
| /*expected_title=*/"", /*expected_content_types=*/{}); |
| ConfirmShareText("share_url()", |
| /*expected_text=*/"https://example.com/", |
| /*expected_title=*/"", /*expected_content_types=*/{}); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SharesheetClientBrowserTest, TextWithFile) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GetAppUrl())); |
| const std::vector<std::string> expected_content_types{"image/webp"}; |
| ConfirmShareText("share_file_title()", |
| /*expected_text=*/"", |
| /*expected_title=*/"Subject", expected_content_types); |
| ConfirmShareText("share_file_title_url()", |
| /*expected_text=*/"https://example.com/", |
| /*expected_title=*/"Subject", expected_content_types); |
| ConfirmShareText("share_file_text()", |
| /*expected_text=*/"Message", |
| /*expected_title=*/"", expected_content_types); |
| ConfirmShareText("share_file_text_url()", |
| /*expected_text=*/"Message https://example.com/", |
| /*expected_title=*/"", expected_content_types); |
| ConfirmShareText("share_file_url()", |
| /*expected_text=*/"https://example.com/", |
| /*expected_title=*/"", expected_content_types); |
| } |
| |
| } // namespace webshare |