Index: content/browser/background_fetch/background_fetch_job_controller_unittest.cc |
diff --git a/content/browser/background_fetch/background_fetch_job_controller_unittest.cc b/content/browser/background_fetch/background_fetch_job_controller_unittest.cc |
index 18513b2b8f8477d47b396a9070cdbf202b870163..94848a36d8e3d560cb5412601f2c25842ed6d0d1 100644 |
--- a/content/browser/background_fetch/background_fetch_job_controller_unittest.cc |
+++ b/content/browser/background_fetch/background_fetch_job_controller_unittest.cc |
@@ -4,15 +4,20 @@ |
#include "content/browser/background_fetch/background_fetch_job_controller.h" |
+#include <string> |
+#include <vector> |
+ |
#include "base/bind_helpers.h" |
#include "base/callback_helpers.h" |
+#include "base/guid.h" |
#include "base/memory/ptr_util.h" |
#include "base/run_loop.h" |
+#include "base/strings/string_number_conversions.h" |
#include "content/browser/background_fetch/background_fetch_data_manager.h" |
#include "content/browser/background_fetch/background_fetch_job_info.h" |
#include "content/browser/background_fetch/background_fetch_request_info.h" |
#include "content/public/browser/browser_thread.h" |
-#include "content/public/test/mock_download_item.h" |
+#include "content/public/test/fake_download_item.h" |
#include "content/public/test/mock_download_manager.h" |
#include "content/public/test/test_browser_context.h" |
#include "content/public/test/test_browser_thread_bundle.h" |
@@ -30,36 +35,42 @@ const char kTag[] = "testTag"; |
namespace content { |
-// Use the basic MockDownloadItem, but override it to provide a valid GUID. |
-class MockDownloadItemWithValues : public MockDownloadItem { |
- public: |
- const std::string& GetGuid() const override { return guid_; } |
- void SetGuid(const std::string& guid) { guid_ = guid; } |
- |
- private: |
- std::string guid_; |
-}; |
- |
// Use the basic MockDownloadManager, but override it so that it implements the |
// functionality that the JobController requires. |
class MockDownloadManagerWithCallback : public MockDownloadManager { |
public: |
void DownloadUrl(std::unique_ptr<DownloadUrlParameters> params) override { |
+ base::RunLoop run_loop; |
DownloadUrlMock(params.get()); |
+ std::string guid = base::GenerateGUID(); |
+ std::unique_ptr<FakeDownloadItem> item = |
+ base::MakeUnique<FakeDownloadItem>(); |
+ item->SetState(DownloadItem::DownloadState::IN_PROGRESS); |
+ item->SetGuid(guid); |
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
- base::Bind(params->callback(), &download_item_, |
+ base::Bind(params->callback(), item.get(), |
DOWNLOAD_INTERRUPT_REASON_NONE)); |
+ download_items_.push_back(std::move(item)); |
+ run_loop.RunUntilIdle(); |
} |
+ // This is called during shutdown for each DownloadItem so can be an |
+ // O(n^2) where n is controlled by the users of the API. If n is expected to |
+ // be larger or the method is called in more places, consider alternatives. |
DownloadItem* GetDownloadByGuid(const std::string& guid) override { |
- DCHECK_EQ(download_item_.GetGuid(), guid); |
- return &download_item_; |
+ for (const auto& item : download_items_) { |
+ if (item->GetGuid() == guid) |
+ return item.get(); |
+ } |
+ return nullptr; |
} |
- MockDownloadItemWithValues* download_item() { return &download_item_; } |
+ const std::vector<std::unique_ptr<FakeDownloadItem>>& download_items() const { |
+ return download_items_; |
+ } |
private: |
- MockDownloadItemWithValues download_item_; |
+ std::vector<std::unique_ptr<FakeDownloadItem>> download_items_; |
}; |
class BackgroundFetchJobControllerTest : public ::testing::Test { |
@@ -115,21 +126,18 @@ class BackgroundFetchJobControllerTest : public ::testing::Test { |
MockDownloadManagerWithCallback* download_manager_; |
}; |
-TEST_F(BackgroundFetchJobControllerTest, StartDownload) { |
+TEST_F(BackgroundFetchJobControllerTest, SingleRequestJob) { |
BackgroundFetchJobInfo job_info(kTag, url::Origin(GURL(kOrigin)), |
kServiceWorkerRegistrationId); |
BackgroundFetchRequestInfo request_info(GURL(kTestUrl), kJobGuid); |
std::vector<BackgroundFetchRequestInfo> request_infos{request_info}; |
- // Create a MockDownloadItem that the test can manipulate. |
- MockDownloadItemWithValues* item = download_manager()->download_item(); |
- item->SetGuid("foo"); |
- |
// Get a JobData to give to the JobController. The JobController then gets |
// the BackgroundFetchRequestInfos from the JobData. |
- std::unique_ptr<BackgroundFetchJobData> job_data = |
+ std::unique_ptr<BackgroundFetchJobData> owned_job_data = |
base::MakeUnique<BackgroundFetchJobData>(request_infos); |
- InitializeJobController(std::move(job_data)); |
+ BackgroundFetchJobData* job_data = owned_job_data.get(); |
+ InitializeJobController(std::move(owned_job_data)); |
EXPECT_CALL(*(download_manager()), |
DownloadUrlMock(::testing::Pointee(::testing::Property( |
@@ -137,6 +145,72 @@ TEST_F(BackgroundFetchJobControllerTest, StartDownload) { |
.Times(1); |
StartProcessing(); |
+ |
+ // Get one of the pending downloads from the download manager. |
+ auto& download_items = download_manager()->download_items(); |
+ ASSERT_EQ(1U, download_items.size()); |
+ FakeDownloadItem* item = download_items[0].get(); |
+ |
+ // Update the observer with no actual change. |
+ ItemObserver()->OnDownloadUpdated(item); |
+ EXPECT_FALSE(job_data->IsComplete()); |
+ |
+ // Update the item to be completed then update the observer. The JobController |
+ // should update the JobData that the request is complete. |
+ item->SetState(DownloadItem::DownloadState::COMPLETE); |
+ ItemObserver()->OnDownloadUpdated(item); |
+ EXPECT_TRUE(job_data->IsComplete()); |
+} |
+ |
+TEST_F(BackgroundFetchJobControllerTest, MultipleRequestJob) { |
+ BackgroundFetchJobInfo job_info(kTag, url::Origin(GURL(kOrigin)), |
+ kServiceWorkerRegistrationId); |
+ std::vector<BackgroundFetchRequestInfo> request_infos; |
+ for (int i = 0; i < 10; i++) { |
+ request_infos.emplace_back(GURL(kTestUrl), base::IntToString(i)); |
+ } |
+ |
+ // Get a JobData to give to the JobController. The JobController then gets |
+ // the BackgroundFetchRequestInfos from the JobData. |
+ std::unique_ptr<BackgroundFetchJobData> owned_job_data = |
+ base::MakeUnique<BackgroundFetchJobData>(request_infos); |
+ BackgroundFetchJobData* job_data = owned_job_data.get(); |
+ InitializeJobController(std::move(owned_job_data)); |
+ |
+ EXPECT_CALL(*(download_manager()), |
+ DownloadUrlMock(::testing::Pointee(::testing::Property( |
+ &DownloadUrlParameters::url, GURL(kTestUrl))))) |
+ .Times(10); |
+ |
+ StartProcessing(); |
+ |
+ // Get one of the pending downloads from the download manager. |
+ auto& download_items = download_manager()->download_items(); |
+ ASSERT_EQ(1U, download_items.size()); |
+ FakeDownloadItem* item = download_items[0].get(); |
+ |
+ // Update the observer with no actual change. |
+ ItemObserver()->OnDownloadUpdated(item); |
+ EXPECT_FALSE(job_data->IsComplete()); |
+ ASSERT_EQ(1U, download_items.size()); |
+ |
+ for (size_t i = 0; i < 9; i++) { |
+ // Update the next item to be completed then update the observer. |
+ ASSERT_EQ(i + 1, download_items.size()); |
+ item = download_items[i].get(); |
+ item->SetState(DownloadItem::DownloadState::COMPLETE); |
+ ItemObserver()->OnDownloadUpdated(item); |
+ EXPECT_FALSE(job_data->IsComplete()); |
+ } |
+ EXPECT_FALSE(job_data->HasRequestsRemaining()); |
+ |
+ // Finally, update the last request to be complete. The JobController should |
+ // see that there are no more requests and mark the job as done. |
+ ASSERT_EQ(10U, download_items.size()); |
+ item = download_items[9].get(); |
+ item->SetState(DownloadItem::DownloadState::COMPLETE); |
+ ItemObserver()->OnDownloadUpdated(item); |
+ EXPECT_TRUE(job_data->IsComplete()); |
} |
} // namespace content |