OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file contains download browser tests that are known to be runnable | 5 // This file contains download browser tests that are known to be runnable |
6 // in a pure content context. Over time tests should be migrated here. | 6 // in a pure content context. Over time tests should be migrated here. |
7 | 7 |
8 #include <queue> | |
9 | |
8 #include "base/command_line.h" | 10 #include "base/command_line.h" |
9 #include "base/file_util.h" | 11 #include "base/file_util.h" |
10 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
11 #include "base/files/scoped_temp_dir.h" | 13 #include "base/files/scoped_temp_dir.h" |
12 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
13 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
14 #include "base/threading/platform_thread.h" | 16 #include "base/threading/platform_thread.h" |
15 #include "base/time/time.h" | 17 #include "base/time/time.h" |
16 #include "content/browser/byte_stream.h" | 18 #include "content/browser/byte_stream.h" |
17 #include "content/browser/download/download_file_factory.h" | 19 #include "content/browser/download/download_file_factory.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
29 #include "content/public/test/content_browser_test_utils.h" | 31 #include "content/public/test/content_browser_test_utils.h" |
30 #include "content/public/test/download_test_observer.h" | 32 #include "content/public/test/download_test_observer.h" |
31 #include "content/public/test/test_file_error_injector.h" | 33 #include "content/public/test/test_file_error_injector.h" |
32 #include "content/public/test/test_utils.h" | 34 #include "content/public/test/test_utils.h" |
33 #include "content/shell/browser/shell.h" | 35 #include "content/shell/browser/shell.h" |
34 #include "content/shell/browser/shell_browser_context.h" | 36 #include "content/shell/browser/shell_browser_context.h" |
35 #include "content/shell/browser/shell_download_manager_delegate.h" | 37 #include "content/shell/browser/shell_download_manager_delegate.h" |
36 #include "content/shell/browser/shell_network_delegate.h" | 38 #include "content/shell/browser/shell_network_delegate.h" |
37 #include "content/test/net/url_request_mock_http_job.h" | 39 #include "content/test/net/url_request_mock_http_job.h" |
38 #include "content/test/net/url_request_slow_download_job.h" | 40 #include "content/test/net/url_request_slow_download_job.h" |
41 #include "net/test/embedded_test_server/embedded_test_server.h" | |
42 #include "net/test/embedded_test_server/http_request.h" | |
43 #include "net/test/embedded_test_server/http_response.h" | |
39 #include "net/test/spawned_test_server/spawned_test_server.h" | 44 #include "net/test/spawned_test_server/spawned_test_server.h" |
40 #include "testing/gmock/include/gmock/gmock.h" | 45 #include "testing/gmock/include/gmock/gmock.h" |
41 #include "testing/gtest/include/gtest/gtest.h" | 46 #include "testing/gtest/include/gtest/gtest.h" |
42 #include "url/gurl.h" | 47 #include "url/gurl.h" |
43 | 48 |
44 using ::testing::_; | 49 using ::testing::_; |
45 using ::testing::AllOf; | 50 using ::testing::AllOf; |
46 using ::testing::Field; | 51 using ::testing::Field; |
47 using ::testing::InSequence; | 52 using ::testing::InSequence; |
48 using ::testing::Property; | 53 using ::testing::Property; |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 // Filter for saving the size of the download when the first IN_PROGRESS | 501 // Filter for saving the size of the download when the first IN_PROGRESS |
497 // is hit. | 502 // is hit. |
498 bool InitialSizeFilter(int* download_size, DownloadItem* download) { | 503 bool InitialSizeFilter(int* download_size, DownloadItem* download) { |
499 if (download->GetState() != DownloadItem::IN_PROGRESS) | 504 if (download->GetState() != DownloadItem::IN_PROGRESS) |
500 return false; | 505 return false; |
501 | 506 |
502 *download_size = download->GetReceivedBytes(); | 507 *download_size = download->GetReceivedBytes(); |
503 return true; | 508 return true; |
504 } | 509 } |
505 | 510 |
511 // RAII test server. Once instantiated, it initializes an embedded test server. | |
512 // Expectations can be set via the OnURL method. | |
513 // | |
514 // Call HasFatalFailure() after constructing a TestServer instance to check if | |
515 // the initialization was successful. | |
516 // | |
517 // Example: | |
518 // | |
519 // TEST_F(Foo, Bar) { | |
520 // TestServer test_server; | |
521 // if (HasFatalFailure()) | |
522 // return; | |
523 // | |
524 // test_server.OnURL("/foo").RedirectTo("/bar"); | |
525 // test_server.OnURL("/bar").SendBody("baz"); | |
526 // ... | |
527 // test_server.ServeFilesFromDirectory(test_file_path); | |
528 // ... | |
529 // // Do something that fetches "/foo". | |
530 // } | |
531 // | |
532 // Note that the order of the OnURL() calls are significant. The server expects | |
533 // the requests to arrive in the same order as the OnURL() calls. | |
534 // TODO(asanka): Consider migrating more tests to use the embedded test server. | |
Randy Smith (Not in Mondays)
2014/04/23 19:12:27
I'd encourage this; this type of infrastructure lo
asanka
2014/04/23 22:59:27
I actually removed this TestServer since in the en
| |
535 class TestServer { | |
536 public: | |
537 // An expectation for a request. Created by TestServer::OnURL(). | |
538 class ExpectedRequest { | |
539 public: | |
540 // Respond with a status code of 302 and a Location header set to | |
541 // |redirect_url|. | |
542 ExpectedRequest& RedirectTo(const GURL& redirect_url); | |
543 | |
544 // Set the body of the response to |string|. Overwrites the current body if | |
545 // one had been previously set. | |
546 ExpectedRequest& SendBody(const std::string& string); | |
Randy Smith (Not in Mondays)
2014/04/23 19:12:27
Should you say what happens if you use both Redire
asanka
2014/04/23 22:59:27
Removed.
| |
547 | |
548 // Set the Content-Type to |mime_type|. | |
549 ExpectedRequest& WithContentType(const char* mime_type); | |
550 | |
551 private: | |
552 friend class TestServer; | |
553 | |
554 // Construct a ExpectedRequest that will expect an HTTP GET for | |
555 // |relative_url|. | |
556 ExpectedRequest(const std::string& relative_url); | |
557 | |
558 // Returns true if this expectation matches |url|. | |
559 bool MatchesUrl(const std::string& url) const; | |
560 | |
561 // Returns the HttpResponse for this expectation. Once this is called, the | |
562 // ExpectedRequest object is no longer valid. | |
563 scoped_ptr<net::test_server::HttpResponse> GetResponse(); | |
564 | |
565 std::string relative_url_; | |
566 scoped_ptr<net::test_server::BasicHttpResponse> response_; | |
567 DISALLOW_COPY_AND_ASSIGN(ExpectedRequest); | |
568 }; | |
569 | |
570 TestServer(); | |
571 ~TestServer(); | |
572 | |
573 // Create a new expectation for receiving an HTTP GET for |relative_url|. By | |
574 // default the response is an HTTP 200 with an empty body. The response can be | |
575 // modified via the returned |ExpectedRequest| reference. Note that the | |
576 // reference becomes invalidated once a request has been received by the | |
577 // server. | |
578 ExpectedRequest& OnURL(const std::string& relative_url); | |
Randy Smith (Not in Mondays)
2014/04/23 19:12:27
Huh. I twitch somewhat hard at returning a non-co
asanka
2014/04/23 22:59:27
Hehe. It's a builder pattern. See for example htt
| |
579 | |
580 // Get the absolue URL for |relative_url|. | |
581 GURL GetURL(const std::string& relative_url); | |
582 | |
583 // Serve files contained within |directory|. See | |
584 // EmbeddedTestServer::ServeFilesFromDirectory(). | |
585 void ServeFilesFromDirectory(const base::FilePath& directory); | |
Randy Smith (Not in Mondays)
2014/04/23 19:12:27
Probably worthwhile calling out that any ExpectedR
asanka
2014/04/23 22:59:27
Removed.
| |
586 | |
587 private: | |
588 scoped_ptr<net::test_server::HttpResponse> HandleRequest( | |
589 const net::test_server::HttpRequest& request); | |
590 void InitializeAndWaitUntilReady(); | |
591 void ShutdownAndWaitUntilComplete(); | |
592 | |
593 net::test_server::EmbeddedTestServer embedded_test_server_; | |
594 std::queue<ExpectedRequest*> expected_requests_; | |
595 DISALLOW_COPY_AND_ASSIGN(TestServer); | |
596 }; | |
597 | |
598 TestServer::ExpectedRequest::ExpectedRequest(const std::string& relative_url) | |
599 : relative_url_(relative_url), | |
600 response_(new net::test_server::BasicHttpResponse) { | |
601 } | |
602 | |
603 TestServer::ExpectedRequest& TestServer::ExpectedRequest::RedirectTo( | |
604 const GURL& redirect_url) { | |
605 response_->set_code(net::HTTP_FOUND); | |
606 response_->AddCustomHeader("Location", redirect_url.spec()); | |
607 return *this; | |
608 } | |
609 | |
610 TestServer::ExpectedRequest& TestServer::ExpectedRequest::SendBody( | |
611 const std::string& string) { | |
612 response_->set_content(string); | |
613 return *this; | |
614 } | |
615 | |
616 TestServer::ExpectedRequest& TestServer::ExpectedRequest::WithContentType( | |
617 const char* mime_type) { | |
618 response_->set_content_type(mime_type); | |
619 return *this; | |
620 } | |
621 | |
622 bool TestServer::ExpectedRequest::MatchesUrl(const std::string& url) const { | |
623 return relative_url_ == url; | |
624 } | |
625 | |
626 scoped_ptr<net::test_server::HttpResponse> | |
627 TestServer::ExpectedRequest::GetResponse() { | |
628 return response_.PassAs<net::test_server::HttpResponse>(); | |
629 } | |
630 | |
631 TestServer::TestServer() { | |
632 InitializeAndWaitUntilReady(); | |
633 } | |
634 | |
635 TestServer::~TestServer() { | |
636 EXPECT_TRUE(expected_requests_.empty()); | |
637 while (!expected_requests_.empty()) { | |
638 delete expected_requests_.front(); | |
639 expected_requests_.pop(); | |
640 } | |
641 ShutdownAndWaitUntilComplete(); | |
642 } | |
643 | |
644 void TestServer::InitializeAndWaitUntilReady() { | |
645 ASSERT_TRUE(embedded_test_server_.InitializeAndWaitUntilReady()); | |
646 embedded_test_server_.RegisterRequestHandler( | |
647 base::Bind(&TestServer::HandleRequest, base::Unretained(this))); | |
648 } | |
649 | |
650 void TestServer::ShutdownAndWaitUntilComplete() { | |
651 ASSERT_TRUE(embedded_test_server_.ShutdownAndWaitUntilComplete()); | |
652 } | |
653 | |
654 TestServer::ExpectedRequest& TestServer::OnURL( | |
655 const std::string& relative_url) { | |
656 ExpectedRequest* request = new ExpectedRequest(relative_url); | |
657 expected_requests_.push(request); | |
658 return *request; | |
659 } | |
660 | |
661 void TestServer::ServeFilesFromDirectory(const base::FilePath& directory) { | |
662 embedded_test_server_.ServeFilesFromDirectory(directory); | |
663 } | |
664 | |
665 GURL TestServer::GetURL(const std::string& relative_url) { | |
666 return embedded_test_server_.GetURL(relative_url); | |
667 } | |
668 | |
669 scoped_ptr<net::test_server::HttpResponse> TestServer::HandleRequest( | |
670 const net::test_server::HttpRequest& request) { | |
671 scoped_ptr<net::test_server::HttpResponse> response; | |
672 if (!expected_requests_.empty() && | |
673 expected_requests_.front()->MatchesUrl(request.relative_url)) { | |
674 scoped_ptr<ExpectedRequest> expected_request(expected_requests_.front()); | |
675 response = expected_request->GetResponse(); | |
676 expected_requests_.pop(); | |
677 } | |
678 return response.Pass(); | |
679 } | |
680 | |
506 } // namespace | 681 } // namespace |
507 | 682 |
508 class DownloadContentTest : public ContentBrowserTest { | 683 class DownloadContentTest : public ContentBrowserTest { |
509 protected: | 684 protected: |
510 // An initial send from a website of at least this size will not be | 685 // An initial send from a website of at least this size will not be |
511 // help up by buffering in the underlying downloads ByteStream data | 686 // help up by buffering in the underlying downloads ByteStream data |
512 // transfer. This is important because on resumption tests we wait | 687 // transfer. This is important because on resumption tests we wait |
513 // until we've gotten the data we expect before allowing the test server | 688 // until we've gotten the data we expect before allowing the test server |
514 // to send its reset, to get around hard close semantics on the Windows | 689 // to send its reset, to get around hard close semantics on the Windows |
515 // socket layer implementation. | 690 // socket layer implementation. |
(...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1644 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); | 1819 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); |
1645 ASSERT_EQ(1u, downloads.size()); | 1820 ASSERT_EQ(1u, downloads.size()); |
1646 ASSERT_EQ(DownloadItem::COMPLETE, downloads[0]->GetState()); | 1821 ASSERT_EQ(DownloadItem::COMPLETE, downloads[0]->GetState()); |
1647 | 1822 |
1648 // Check that the cookies were correctly set. | 1823 // Check that the cookies were correctly set. |
1649 EXPECT_EQ("A=B", | 1824 EXPECT_EQ("A=B", |
1650 content::GetCookies(shell()->web_contents()->GetBrowserContext(), | 1825 content::GetCookies(shell()->web_contents()->GetBrowserContext(), |
1651 GURL(download))); | 1826 GURL(download))); |
1652 } | 1827 } |
1653 | 1828 |
1829 // A filename suggestion specified via a @download attribute should be effective | |
1830 // if the final download URL is in the same origin as the initial download URL. | |
1831 // Test that this holds even if there are cross origin redirects in the middle | |
1832 // of the redirect chain. | |
1833 IN_PROC_BROWSER_TEST_F(DownloadContentTest, | |
1834 DownloadAttributeSameOriginRedirect) { | |
1835 TestServer origin_one; | |
1836 TestServer origin_two; | |
1837 if (HasFatalFailure()) | |
1838 return; | |
1839 | |
1840 // The download-attribute.html page contains an anchor element whose href is | |
1841 // set to the value of the query parameter (specified as |target| in the URL | |
1842 // below). The suggested filename for the anchor is 'suggested-filename'. When | |
1843 // the page is loaded, a script simulates a click on the anchor, triggering a | |
1844 // download of the target URL. | |
1845 // | |
1846 // We construct two test servers; origin_one and origin_two. Once started, the | |
1847 // server URLs will differ by the port number. Therefore they will be in | |
1848 // different origins. | |
1849 GURL download_url = origin_one.GetURL("/ping"); | |
1850 GURL referrer_url = origin_one.GetURL( | |
1851 std::string("/download-attribute.html?target=") + download_url.spec()); | |
1852 origin_one.ServeFilesFromDirectory(GetTestFilePath("download", "")); | |
1853 | |
1854 // <origin_one>/download-attribute.html initiates a download of | |
1855 // <origin_one>/ping, which redirects to <origin_two>/pong, and then finally | |
1856 // to <origin_one>/download. | |
1857 origin_one.OnURL("/ping").RedirectTo(origin_two.GetURL("/pong")); | |
1858 origin_two.OnURL("/pong").RedirectTo(origin_one.GetURL("/download")); | |
1859 origin_one.OnURL("/download").SendBody("Hello").WithContentType( | |
1860 "application/octet-stream"); | |
1861 | |
1862 DownloadAndWait(shell(), referrer_url, DownloadItem::COMPLETE); | |
Randy Smith (Not in Mondays)
2014/04/23 19:12:27
nit: Chuckle. This relies on "DownloadAndWait()"
asanka
2014/04/23 22:59:27
I renamed the function to NavigateToURLAndWaitForD
| |
1863 | |
1864 std::vector<DownloadItem*> downloads; | |
1865 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); | |
1866 ASSERT_EQ(1u, downloads.size()); | |
1867 | |
1868 EXPECT_EQ(FILE_PATH_LITERAL("suggested-filename"), | |
1869 downloads[0]->GetTargetFilePath().BaseName().value()); | |
1870 } | |
1871 | |
1872 // A filename suggestion specified via a @download attribute should not be | |
1873 // effective if the final download URL is in another origin from the original | |
1874 // download URL. | |
Randy Smith (Not in Mondays)
2014/04/23 19:12:27
nit: I'd interchange the order of these two tests;
asanka
2014/04/23 22:59:27
Done.
| |
1875 IN_PROC_BROWSER_TEST_F(DownloadContentTest, | |
1876 DownloadAttributeCrossOriginRedirect) { | |
1877 TestServer origin_one; | |
1878 TestServer origin_two; | |
1879 if (HasFatalFailure()) | |
1880 return; | |
1881 | |
1882 // The download-attribute.html page contains an anchor element whose href is | |
1883 // set to the value of the query parameter (specified as |target| in the URL | |
1884 // below). The suggested filename for the anchor is 'suggested-filename'. When | |
1885 // the page is loaded, a script simulates a click on the anchor, triggering a | |
1886 // download of the target URL. | |
1887 // | |
1888 // We construct two test servers; origin_one and origin_two. Once started, the | |
1889 // server URLs will differ by the port number. Therefore they will be in | |
1890 // different origins. | |
1891 GURL download_url = origin_one.GetURL("/ping"); | |
1892 GURL referrer_url = origin_one.GetURL( | |
1893 std::string("/download-attribute.html?target=") + download_url.spec()); | |
1894 | |
1895 // <origin_one>/download-attribute.html initiates a download of | |
1896 // <origin_one>/ping, which redirects to <origin_two>/download. | |
1897 origin_one.ServeFilesFromDirectory(GetTestFilePath("download", "")); | |
1898 origin_one.OnURL("/ping").RedirectTo(origin_two.GetURL("/download")); | |
1899 origin_two.OnURL("/download").SendBody("Hello").WithContentType( | |
1900 "application/octet-stream"); | |
1901 | |
1902 DownloadAndWait(shell(), referrer_url, DownloadItem::COMPLETE); | |
1903 | |
1904 std::vector<DownloadItem*> downloads; | |
1905 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); | |
1906 ASSERT_EQ(1u, downloads.size()); | |
1907 | |
1908 EXPECT_EQ(FILE_PATH_LITERAL("download"), | |
1909 downloads[0]->GetTargetFilePath().BaseName().value()); | |
1910 } | |
1911 | |
1654 } // namespace content | 1912 } // namespace content |
OLD | NEW |