146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file.
446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "sync/internal_api/public/attachments/attachment_service_impl.h"
646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/bind.h"
846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/weak_ptr.h"
946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/message_loop/message_loop.h"
1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/run_loop.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/timer/mock_timer.h"
1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "sync/internal_api/public/attachments/fake_attachment_downloader.h"
1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "sync/internal_api/public/attachments/fake_attachment_uploader.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gmock/include/gmock/gmock-matchers.h"
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace syncer {
1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class MockAttachmentStore : public AttachmentStore,
2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                            public base::SupportsWeakPtr<MockAttachmentStore> {
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockAttachmentStore() {}
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void Read(const AttachmentIdList& ids,
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                    const ReadCallback& callback) OVERRIDE {
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    read_ids.push_back(ids);
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    read_callbacks.push_back(callback);
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void Write(const AttachmentList& attachments,
3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     const WriteCallback& callback) OVERRIDE {
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    write_attachments.push_back(attachments);
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    write_callbacks.push_back(callback);
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void Drop(const AttachmentIdList& ids,
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                    const DropCallback& callback) OVERRIDE {
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    NOTREACHED();
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Respond to Read request. Attachments found in local_attachments should be
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // returned, everything else should be reported unavailable.
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void RespondToRead(const AttachmentIdSet& local_attachments) {
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_refptr<base::RefCountedString> data = new base::RefCountedString();
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ReadCallback callback = read_callbacks.back();
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    AttachmentIdList ids = read_ids.back();
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    read_callbacks.pop_back();
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    read_ids.pop_back();
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<AttachmentMap> attachments(new AttachmentMap());
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<AttachmentIdList> unavailable_attachments(
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        new AttachmentIdList());
5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    for (AttachmentIdList::const_iterator iter = ids.begin(); iter != ids.end();
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)         ++iter) {
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      if (local_attachments.find(*iter) != local_attachments.end()) {
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        Attachment attachment = Attachment::CreateWithId(*iter, data);
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        attachments->insert(std::make_pair(*iter, attachment));
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      } else {
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        unavailable_attachments->push_back(*iter);
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    Result result =
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        unavailable_attachments->empty() ? SUCCESS : UNSPECIFIED_ERROR;
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        FROM_HERE,
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(callback,
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   result,
6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(&attachments),
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(&unavailable_attachments)));
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Respond to Write request with |result|.
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void RespondToWrite(const Result& result) {
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    WriteCallback callback = write_callbacks.back();
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AttachmentList attachments = write_attachments.back();
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    write_callbacks.pop_back();
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    write_attachments.pop_back();
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::MessageLoop::current()->PostTask(FROM_HERE,
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                           base::Bind(callback, result));
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::vector<AttachmentIdList> read_ids;
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::vector<ReadCallback> read_callbacks;
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::vector<AttachmentList> write_attachments;
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::vector<WriteCallback> write_callbacks;
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~MockAttachmentStore() {}
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockAttachmentStore);
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class MockAttachmentDownloader
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    : public AttachmentDownloader,
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      public base::SupportsWeakPtr<MockAttachmentDownloader> {
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockAttachmentDownloader() {}
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void DownloadAttachment(const AttachmentId& id,
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  const DownloadCallback& callback) OVERRIDE {
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_TRUE(download_requests.find(id) == download_requests.end());
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    download_requests.insert(std::make_pair(id, callback));
10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Multiple requests to download will be active at the same time.
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // RespondToDownload should respond to only one of them.
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void RespondToDownload(const AttachmentId& id, const DownloadResult& result) {
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_TRUE(download_requests.find(id) != download_requests.end());
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<Attachment> attachment;
11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (result == DOWNLOAD_SUCCESS) {
11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      scoped_refptr<base::RefCountedString> data = new base::RefCountedString();
11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      attachment.reset(new Attachment(Attachment::CreateWithId(id, data)));
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        FROM_HERE,
11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(download_requests[id], result, base::Passed(&attachment)));
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    download_requests.erase(id);
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::map<AttachmentId, DownloadCallback> download_requests;
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockAttachmentDownloader);
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass MockAttachmentUploader
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : public AttachmentUploader,
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      public base::SupportsWeakPtr<MockAttachmentUploader> {
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockAttachmentUploader() {}
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // AttachmentUploader implementation.
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void UploadAttachment(const Attachment& attachment,
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                const UploadCallback& callback) OVERRIDE {
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const AttachmentId id = attachment.GetId();
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ASSERT_TRUE(upload_requests.find(id) == upload_requests.end());
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    upload_requests.insert(std::make_pair(id, callback));
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void RespondToUpload(const AttachmentId& id, const UploadResult& result) {
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ASSERT_TRUE(upload_requests.find(id) != upload_requests.end());
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::MessageLoop::current()->PostTask(
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        FROM_HERE, base::Bind(upload_requests[id], result, id));
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    upload_requests.erase(id);
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::map<AttachmentId, UploadCallback> upload_requests;
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(MockAttachmentUploader);
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass AttachmentServiceImplTest : public testing::Test,
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  public AttachmentService::Delegate {
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) protected:
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AttachmentServiceImplTest() {}
15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    network_change_notifier_.reset(net::NetworkChangeNotifier::CreateMock());
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    InitializeAttachmentService(make_scoped_ptr(new MockAttachmentUploader()),
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                make_scoped_ptr(new MockAttachmentDownloader()),
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                this);
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    attachment_service_.reset();
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_FALSE(attachment_store_);
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ASSERT_FALSE(attachment_uploader_);
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_FALSE(attachment_downloader_);
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // AttachmentService::Delegate implementation.
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnAttachmentUploaded(
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const AttachmentId& attachment_id) OVERRIDE {
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    on_attachment_uploaded_list_.push_back(attachment_id);
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void InitializeAttachmentService(
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      scoped_ptr<MockAttachmentUploader> uploader,
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      scoped_ptr<MockAttachmentDownloader> downloader,
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AttachmentService::Delegate* delegate) {
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<MockAttachmentStore> attachment_store(
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new MockAttachmentStore());
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    attachment_store_ = attachment_store->AsWeakPtr();
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (uploader.get()) {
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      attachment_uploader_ = uploader->AsWeakPtr();
188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (downloader.get()) {
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      attachment_downloader_ = downloader->AsWeakPtr();
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    attachment_service_.reset(
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new AttachmentServiceImpl(attachment_store,
194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  uploader.PassAs<AttachmentUploader>(),
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  downloader.PassAs<AttachmentDownloader>(),
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  delegate,
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  base::TimeDelta::FromMinutes(1),
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  base::TimeDelta::FromMinutes(8)));
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<base::MockTimer> timer_to_pass(
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new base::MockTimer(false, false));
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    mock_timer_ = timer_to_pass.get();
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    attachment_service_->SetTimerForTest(timer_to_pass.PassAs<base::Timer>());
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AttachmentService* attachment_service() { return attachment_service_.get(); }
20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::MockTimer* mock_timer() { return mock_timer_; }
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AttachmentService::GetOrDownloadCallback download_callback() {
21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return base::Bind(&AttachmentServiceImplTest::DownloadDone,
21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      base::Unretained(this));
21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void DownloadDone(const AttachmentService::GetOrDownloadResult& result,
21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                    scoped_ptr<AttachmentMap> attachments) {
21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    download_results_.push_back(result);
21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    last_download_attachments_ = attachments.Pass();
21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void RunLoop() {
22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::RunLoop run_loop;
22346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    run_loop.RunUntilIdle();
22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
22546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void RunLoopAndFireTimer() {
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RunLoop();
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (mock_timer()->IsRunning()) {
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      mock_timer()->Fire();
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RunLoop();
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const std::vector<AttachmentService::GetOrDownloadResult>&
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  download_results() const {
23646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return download_results_;
23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const AttachmentMap& last_download_attachments() const {
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return *last_download_attachments_.get();
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  net::NetworkChangeNotifier* network_change_notifier() {
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return network_change_notifier_.get();
24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockAttachmentStore* store() { return attachment_store_.get(); }
24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockAttachmentDownloader* downloader() {
25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return attachment_downloader_.get();
25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockAttachmentUploader* uploader() {
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return attachment_uploader_.get();
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const std::vector<AttachmentId>& on_attachment_uploaded_list() const {
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return on_attachment_uploaded_list_;
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::MessageLoop message_loop_;
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::WeakPtr<MockAttachmentStore> attachment_store_;
26546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::WeakPtr<MockAttachmentDownloader> attachment_downloader_;
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::WeakPtr<MockAttachmentUploader> attachment_uploader_;
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<AttachmentServiceImpl> attachment_service_;
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::MockTimer* mock_timer_;  // not owned
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::vector<AttachmentService::GetOrDownloadResult> download_results_;
27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<AttachmentMap> last_download_attachments_;
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::vector<AttachmentId> on_attachment_uploaded_list_;
27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(AttachmentServiceImplTest, GetStore) {
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(store(), attachment_service()->GetStore());
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(AttachmentServiceImplTest, GetOrDownload_EmptyAttachmentList) {
28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AttachmentIdList attachment_ids;
28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  attachment_service()->GetOrDownloadAttachments(attachment_ids,
28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 download_callback());
28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  store()->RespondToRead(AttachmentIdSet());
28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RunLoop();
28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(1U, download_results().size());
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(0U, last_download_attachments().size());
28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(AttachmentServiceImplTest, GetOrDownload_Local) {
29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AttachmentIdList attachment_ids;
29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  attachment_ids.push_back(AttachmentId::Create());
29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  attachment_service()->GetOrDownloadAttachments(attachment_ids,
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 download_callback());
29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AttachmentIdSet local_attachments;
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  local_attachments.insert(attachment_ids[0]);
29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  store()->RespondToRead(local_attachments);
29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RunLoop();
30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(1U, download_results().size());
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(1U, last_download_attachments().size());
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(last_download_attachments().find(attachment_ids[0]) !=
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              last_download_attachments().end());
30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(AttachmentServiceImplTest, GetOrDownload_LocalRemoteUnavailable) {
30746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Create attachment list with 3 ids.
30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AttachmentIdList attachment_ids;
30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  attachment_ids.push_back(AttachmentId::Create());
31046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  attachment_ids.push_back(AttachmentId::Create());
31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  attachment_ids.push_back(AttachmentId::Create());
31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Call attachment service.
31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  attachment_service()->GetOrDownloadAttachments(attachment_ids,
31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 download_callback());
31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Ensure AttachmentStore is called.
31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(store()->read_ids.empty());
31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
31846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // make AttachmentStore return only attachment 0.
31946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AttachmentIdSet local_attachments;
32046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  local_attachments.insert(attachment_ids[0]);
32146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  store()->RespondToRead(local_attachments);
32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RunLoop();
32346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Ensure Downloader called with right attachment ids
32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(2U, downloader()->download_requests.size());
32546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Make downloader return attachment 1.
32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  downloader()->RespondToDownload(attachment_ids[1],
32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  AttachmentDownloader::DOWNLOAD_SUCCESS);
32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RunLoop();
33046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Ensure consumer callback is not called.
33146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(download_results().empty());
33246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Make downloader fail attachment 2.
33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  downloader()->RespondToDownload(
33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      attachment_ids[2], AttachmentDownloader::DOWNLOAD_UNSPECIFIED_ERROR);
33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RunLoop();
33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Ensure callback is called
33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(download_results().empty());
33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // There should be only two attachments returned, 0 and 1.
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(2U, last_download_attachments().size());
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(last_download_attachments().find(attachment_ids[0]) !=
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              last_download_attachments().end());
343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(last_download_attachments().find(attachment_ids[1]) !=
344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              last_download_attachments().end());
345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(last_download_attachments().find(attachment_ids[2]) ==
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              last_download_attachments().end());
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
349116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(AttachmentServiceImplTest, GetOrDownload_NoDownloader) {
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // No downloader.
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  InitializeAttachmentService(
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      make_scoped_ptr<MockAttachmentUploader>(new MockAttachmentUploader()),
353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      make_scoped_ptr<MockAttachmentDownloader>(NULL),
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this);
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AttachmentIdList attachment_ids;
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  attachment_ids.push_back(AttachmentId::Create());
358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  attachment_service()->GetOrDownloadAttachments(attachment_ids,
359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                 download_callback());
360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(store()->read_ids.empty());
361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AttachmentIdSet local_attachments;
363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  store()->RespondToRead(local_attachments);
364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunLoop();
365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_EQ(1U, download_results().size());
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(AttachmentService::GET_UNSPECIFIED_ERROR, download_results()[0]);
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(last_download_attachments().empty());
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(AttachmentServiceImplTest, UploadAttachments_Success) {
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AttachmentIdSet attachment_ids;
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const unsigned num_attachments = 3;
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (unsigned i = 0; i < num_attachments; ++i) {
3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    attachment_ids.insert(AttachmentId::Create());
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_service()->UploadAttachments(attachment_ids);
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (unsigned i = 0; i < num_attachments; ++i) {
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RunLoopAndFireTimer();
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // See that the service has issued a read for at least one of the
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // attachments.
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_GE(store()->read_ids.size(), 1U);
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    store()->RespondToRead(attachment_ids);
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RunLoop();
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_GE(uploader()->upload_requests.size(), 1U);
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                AttachmentUploader::UPLOAD_SUCCESS);
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunLoop();
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(0U, store()->read_ids.size());
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(0U, uploader()->upload_requests.size());
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // See that all the attachments were uploaded.
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(attachment_ids.size(), on_attachment_uploaded_list().size());
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AttachmentIdSet::const_iterator iter = attachment_ids.begin();
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const AttachmentIdSet::const_iterator end = attachment_ids.end();
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (iter = attachment_ids.begin(); iter != end; ++iter) {
3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_THAT(on_attachment_uploaded_list(), testing::Contains(*iter));
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(AttachmentServiceImplTest, UploadAttachments_Success_NoDelegate) {
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  InitializeAttachmentService(make_scoped_ptr(new MockAttachmentUploader()),
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              make_scoped_ptr(new MockAttachmentDownloader()),
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              NULL);  // No delegate.
4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AttachmentIdSet attachment_ids;
4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_ids.insert(AttachmentId::Create());
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_service()->UploadAttachments(attachment_ids);
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunLoopAndFireTimer();
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1U, store()->read_ids.size());
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(0U, uploader()->upload_requests.size());
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  store()->RespondToRead(attachment_ids);
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunLoop();
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(0U, store()->read_ids.size());
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1U, uploader()->upload_requests.size());
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uploader()->RespondToUpload(*attachment_ids.begin(),
418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              AttachmentUploader::UPLOAD_SUCCESS);
419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunLoop();
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(on_attachment_uploaded_list().empty());
421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(AttachmentServiceImplTest, UploadAttachments_SomeMissingFromStore) {
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AttachmentIdSet attachment_ids;
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_ids.insert(AttachmentId::Create());
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_ids.insert(AttachmentId::Create());
4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_service()->UploadAttachments(attachment_ids);
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunLoopAndFireTimer();
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_GE(store()->read_ids.size(), 1U);
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(0U, uploader()->upload_requests.size());
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  store()->RespondToRead(attachment_ids);
433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunLoop();
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1U, uploader()->upload_requests.size());
435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              AttachmentUploader::UPLOAD_SUCCESS);
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunLoopAndFireTimer();
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1U, on_attachment_uploaded_list().size());
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_GE(store()->read_ids.size(), 1U);
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Not found!
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  store()->RespondToRead(AttachmentIdSet());
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunLoop();
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // No upload requests since the read failed.
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(0U, uploader()->upload_requests.size());
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(AttachmentServiceImplTest, UploadAttachments_AllMissingFromStore) {
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AttachmentIdSet attachment_ids;
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const unsigned num_attachments = 2;
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (unsigned i = 0; i < num_attachments; ++i) {
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    attachment_ids.insert(AttachmentId::Create());
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_service()->UploadAttachments(attachment_ids);
455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (unsigned i = 0; i < num_attachments; ++i) {
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RunLoopAndFireTimer();
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_GE(store()->read_ids.size(), 1U);
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // None found!
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    store()->RespondToRead(AttachmentIdSet());
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunLoop();
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Nothing uploaded.
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0U, uploader()->upload_requests.size());
4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // See that the delegate was never called.
4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(0U, on_attachment_uploaded_list().size());
468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(AttachmentServiceImplTest, UploadAttachments_NoUploader) {
471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  InitializeAttachmentService(make_scoped_ptr<MockAttachmentUploader>(NULL),
472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              make_scoped_ptr(new MockAttachmentDownloader()),
473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              this);
474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AttachmentIdSet attachment_ids;
4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_ids.insert(AttachmentId::Create());
4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_service()->UploadAttachments(attachment_ids);
4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunLoop();
4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0U, store()->read_ids.size());
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(0U, on_attachment_uploaded_list().size());
4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Upload three attachments.  For one of them, server responds with error.
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(AttachmentServiceImplTest, UploadAttachments_OneUploadFails) {
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AttachmentIdSet attachment_ids;
4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const unsigned num_attachments = 3;
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (unsigned i = 0; i < num_attachments; ++i) {
4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    attachment_ids.insert(AttachmentId::Create());
4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_service()->UploadAttachments(attachment_ids);
4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (unsigned i = 0; i < 3; ++i) {
4931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RunLoopAndFireTimer();
4941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_GE(store()->read_ids.size(), 1U);
4951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    store()->RespondToRead(attachment_ids);
4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RunLoop();
4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(1U, uploader()->upload_requests.size());
4981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    AttachmentUploader::UploadResult result =
4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        AttachmentUploader::UPLOAD_SUCCESS;
5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Fail the 2nd one.
5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (i == 2U) {
5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      result = AttachmentUploader::UPLOAD_UNSPECIFIED_ERROR;
5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      result = AttachmentUploader::UPLOAD_SUCCESS;
5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                result);
5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RunLoop();
5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(2U, on_attachment_uploaded_list().size());
5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
5121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Attempt an upload, respond with transient error to trigger backoff, issue
5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// network disconnect/connect events and see that backoff is cleared.
5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(AttachmentServiceImplTest,
5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       UploadAttachments_ResetBackoffAfterNetworkChange) {
5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AttachmentIdSet attachment_ids;
5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_ids.insert(AttachmentId::Create());
5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attachment_service()->UploadAttachments(attachment_ids);
5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunLoopAndFireTimer();
5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1U, store()->read_ids.size());
5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  store()->RespondToRead(attachment_ids);
5241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunLoop();
5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(1U, uploader()->upload_requests.size());
5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              AttachmentUploader::UPLOAD_TRANSIENT_ERROR);
529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunLoop();
5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // See that we are in backoff.
5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(mock_timer()->IsRunning());
5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_GT(mock_timer()->GetCurrentDelay(), base::TimeDelta());
5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Issue a network disconnect event.
5361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  network_change_notifier()->NotifyObserversOfNetworkChangeForTests(
5371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      net::NetworkChangeNotifier::CONNECTION_NONE);
5381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunLoop();
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Still in backoff.
5411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(mock_timer()->IsRunning());
5421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_GT(mock_timer()->GetCurrentDelay(), base::TimeDelta());
5431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Issue a network connect event.
5451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
5461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      net::NetworkChangeNotifier::CONNECTION_WIFI);
5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunLoop();
5481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // No longer in backoff.
5501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(mock_timer()->IsRunning());
5511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(base::TimeDelta(), mock_timer()->GetCurrentDelay());
55246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
55346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
55446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace syncer
555