Index: chrome/browser/google_apis/fake_drive_service.cc |
diff --git a/chrome/browser/google_apis/fake_drive_service.cc b/chrome/browser/google_apis/fake_drive_service.cc |
index c4f7064249d36965023995f746319e9071019213..28925512a544976d3bea563ab2194c963a74b424 100644 |
--- a/chrome/browser/google_apis/fake_drive_service.cc |
+++ b/chrome/browser/google_apis/fake_drive_service.cc |
@@ -6,6 +6,7 @@ |
#include "base/logging.h" |
#include "base/message_loop.h" |
+#include "base/stringprintf.h" |
#include "chrome/browser/google_apis/gdata_wapi_parser.h" |
#include "chrome/browser/google_apis/test_util.h" |
#include "content/public/browser/browser_thread.h" |
@@ -14,7 +15,8 @@ using content::BrowserThread; |
namespace google_apis { |
-FakeDriveService::FakeDriveService() { |
+FakeDriveService::FakeDriveService() |
+ : resource_id_count_(0) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
} |
@@ -48,6 +50,13 @@ bool FakeDriveService::LoadAccountMetadataForWapi( |
return account_metadata_value_; |
} |
+bool FakeDriveService::LoadApplicationInfoForDriveApi( |
+ const std::string& relative_path) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ app_info_value_ = test_util::LoadJSONFile(relative_path); |
+ return app_info_value_; |
+} |
+ |
void FakeDriveService::Initialize(Profile* profile) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
} |
@@ -113,27 +122,14 @@ void FakeDriveService::GetResourceEntry( |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(!callback.is_null()); |
- base::DictionaryValue* resource_list_dict = NULL; |
- base::ListValue* entries = NULL; |
- // Go through entries and return the one that matches |resource_id|. |
- if (resource_list_value_->GetAsDictionary(&resource_list_dict) && |
- resource_list_dict->GetList("entry", &entries)) { |
- for (size_t i = 0; i < entries->GetSize(); ++i) { |
- base::DictionaryValue* entry = NULL; |
- base::DictionaryValue* resource_id_dict = NULL; |
- std::string current_resource_id; |
- if (entries->GetDictionary(i, &entry) && |
- entry->GetDictionary("gd$resourceId", &resource_id_dict) && |
- resource_id_dict->GetString("$t", ¤t_resource_id) && |
- resource_id == current_resource_id) { |
- scoped_ptr<ResourceEntry> resource_entry = |
- ResourceEntry::CreateFrom(*entry); |
- MessageLoop::current()->PostTask( |
- FROM_HERE, |
- base::Bind(callback, HTTP_SUCCESS, base::Passed(&resource_entry))); |
- return; |
- } |
- } |
+ base::DictionaryValue* entry = FindEntryByResourceId(resource_id); |
+ if (entry) { |
+ scoped_ptr<ResourceEntry> resource_entry = |
+ ResourceEntry::CreateFrom(*entry); |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(callback, HTTP_SUCCESS, base::Passed(&resource_entry))); |
+ return; |
} |
scoped_ptr<ResourceEntry> null; |
@@ -160,6 +156,15 @@ void FakeDriveService::GetApplicationInfo( |
const GetDataCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(!callback.is_null()); |
+ |
+ scoped_ptr<base::Value> copied_app_info_value( |
+ app_info_value_->DeepCopy()); |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(callback, |
+ HTTP_SUCCESS, |
+ base::Passed(&copied_app_info_value))); |
+ |
} |
void FakeDriveService::DeleteResource( |
@@ -227,6 +232,61 @@ void FakeDriveService::CopyHostedDocument( |
const GetResourceEntryCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(!callback.is_null()); |
+ |
+ base::DictionaryValue* resource_list_dict = NULL; |
+ base::ListValue* entries = NULL; |
+ // Go through entries and copy the one that matches |resource_id|. |
+ if (resource_list_value_->GetAsDictionary(&resource_list_dict) && |
+ resource_list_dict->GetList("entry", &entries)) { |
+ for (size_t i = 0; i < entries->GetSize(); ++i) { |
+ base::DictionaryValue* entry = NULL; |
+ base::DictionaryValue* resource_id_dict = NULL; |
+ base::ListValue* categories = NULL; |
+ std::string current_resource_id; |
+ if (entries->GetDictionary(i, &entry) && |
+ entry->GetDictionary("gd$resourceId", &resource_id_dict) && |
+ resource_id_dict->GetString("$t", ¤t_resource_id) && |
+ resource_id == current_resource_id && |
+ entry->GetList("category", &categories)) { |
+ // Check that the resource is a hosted document. We consider it a |
+ // hosted document if the kind is neither "folder" nor "file". |
+ for (size_t k = 0; k < categories->GetSize(); ++k) { |
+ base::DictionaryValue* category = NULL; |
+ std::string scheme, term; |
+ if (categories->GetDictionary(k, &category) && |
+ category->GetString("scheme", &scheme) && |
+ category->GetString("term", &term) && |
+ scheme == "http://schemas.google.com/g/2005#kind" && |
+ term != "http://schemas.google.com/docs/2007#file" && |
+ term != "http://schemas.google.com/docs/2007#folder") { |
+ // Make a copy and set the new resource ID and the new title. |
+ scoped_ptr<DictionaryValue> copied_entry(entry->DeepCopy()); |
+ copied_entry->SetString("gd$resourceId.$t", |
+ resource_id + "_copied"); |
+ copied_entry->SetString("title.$t", |
+ FilePath(new_name).AsUTF8Unsafe()); |
+ // Parse the new entry. |
+ scoped_ptr<ResourceEntry> resource_entry = |
+ ResourceEntry::CreateFrom(*copied_entry); |
+ // Add it to the resource list. |
+ entries->Append(copied_entry.release()); |
+ |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(callback, |
+ HTTP_SUCCESS, |
+ base::Passed(&resource_entry))); |
+ return; |
+ } |
+ } |
+ } |
+ } |
+ } |
+ |
+ scoped_ptr<ResourceEntry> null; |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); |
} |
void FakeDriveService::RenameResource( |
@@ -235,6 +295,18 @@ void FakeDriveService::RenameResource( |
const EntryActionCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(!callback.is_null()); |
+ |
+ base::DictionaryValue* entry = FindEntryByEditUrl(edit_url); |
+ if (entry) { |
+ entry->SetString("title.$t", |
+ FilePath(new_name).AsUTF8Unsafe()); |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); |
+ return; |
+ } |
+ |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); |
} |
void FakeDriveService::AddResourceToDirectory( |
@@ -243,6 +315,39 @@ void FakeDriveService::AddResourceToDirectory( |
const EntryActionCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(!callback.is_null()); |
+ |
+ base::DictionaryValue* entry = FindEntryByEditUrl(edit_url); |
+ if (entry) { |
+ base::ListValue* links = NULL; |
+ if (entry->GetList("link", &links)) { |
+ bool parent_link_found = false; |
+ for (size_t i = 0; i < links->GetSize(); ++i) { |
+ base::DictionaryValue* link = NULL; |
+ std::string rel; |
+ if (links->GetDictionary(i, &link) && |
+ link->GetString("rel", &rel) && |
+ rel == "http://schemas.google.com/docs/2007#parent") { |
+ link->SetString("href", parent_content_url.spec()); |
+ parent_link_found = true; |
+ } |
+ } |
+ // The parent link does not exist if a resource is in the root |
+ // directory. |
+ if (!parent_link_found) { |
+ base::DictionaryValue* link = new base::DictionaryValue; |
+ link->SetString("rel", "http://schemas.google.com/docs/2007#parent"); |
+ link->SetString("href", parent_content_url.spec()); |
+ links->Append(link); |
+ } |
+ |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); |
+ return; |
+ } |
+ } |
+ |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); |
} |
void FakeDriveService::RemoveResourceFromDirectory( |
@@ -251,6 +356,31 @@ void FakeDriveService::RemoveResourceFromDirectory( |
const EntryActionCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(!callback.is_null()); |
+ |
+ base::DictionaryValue* entry = FindEntryByResourceId(resource_id); |
+ if (entry) { |
+ base::ListValue* links = NULL; |
+ if (entry->GetList("link", &links)) { |
+ for (size_t i = 0; i < links->GetSize(); ++i) { |
+ base::DictionaryValue* link = NULL; |
+ std::string rel; |
+ std::string href; |
+ if (links->GetDictionary(i, &link) && |
+ link->GetString("rel", &rel) && |
+ link->GetString("href", &href) && |
+ rel == "http://schemas.google.com/docs/2007#parent" && |
+ GURL(href) == parent_content_url) { |
+ links->Remove(i, NULL); |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, base::Bind(callback, HTTP_SUCCESS)); |
+ return; |
+ } |
+ } |
+ } |
+ } |
+ |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, base::Bind(callback, HTTP_NOT_FOUND)); |
} |
void FakeDriveService::AddNewDirectory( |
@@ -259,6 +389,77 @@ void FakeDriveService::AddNewDirectory( |
const GetResourceEntryCallback& callback) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(!callback.is_null()); |
+ |
+ // If the parent content URL is not empty, the parent should exist. |
+ if (!parent_content_url.is_empty()) { |
+ base::DictionaryValue* parent_entry = |
+ FindEntryByContentUrl(parent_content_url); |
+ if (!parent_entry) { |
+ scoped_ptr<ResourceEntry> null; |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); |
+ return; |
+ } |
+ } |
+ |
+ const std::string new_resource_id = GetNewResourceId(); |
+ |
+ scoped_ptr<base::DictionaryValue> new_entry(new base::DictionaryValue); |
+ // Set the resource ID and the title |
+ new_entry->SetString("gd$resourceId.$t", new_resource_id); |
+ new_entry->SetString("title.$t", FilePath(directory_name).AsUTF8Unsafe()); |
+ |
+ // Add "category" which sets the resource type to folder. |
+ base::ListValue* categories = new base::ListValue; |
+ base::DictionaryValue* category = new base::DictionaryValue; |
+ category->SetString("label", "folder"); |
+ category->SetString("scheme", "http://schemas.google.com/g/2005#kind"); |
+ category->SetString("term", "http://schemas.google.com/docs/2007#folder"); |
+ categories->Append(category); |
+ new_entry->Set("category", categories); |
+ |
+ // Add "content" which sets the content URL. |
+ base::DictionaryValue* content = new base::DictionaryValue; |
+ content->SetString("src", "https://xxx/content/" + new_resource_id); |
+ new_entry->Set("content", content); |
+ |
+ // Add "link" which sets the parent URL and the edit URL. |
+ base::ListValue* links = new base::ListValue; |
+ if (!parent_content_url.is_empty()) { |
+ base::DictionaryValue* parent_link = new base::DictionaryValue; |
+ parent_link->SetString("href", parent_content_url.spec()); |
+ parent_link->SetString("rel", |
+ "http://schemas.google.com/docs/2007#parent"); |
+ links->Append(parent_link); |
+ } |
+ base::DictionaryValue* edit_link = new base::DictionaryValue; |
+ edit_link->SetString("href", "https://xxx/edit/" + new_resource_id); |
+ edit_link->SetString("rel", "edit"); |
+ links->Append(edit_link); |
+ new_entry->Set("link", links); |
+ |
+ // Add the new entry to the resource list. |
+ base::DictionaryValue* resource_list_dict = NULL; |
+ base::ListValue* entries = NULL; |
+ if (resource_list_value_->GetAsDictionary(&resource_list_dict) && |
+ resource_list_dict->GetList("entry", &entries)) { |
+ // Parse the entry before releasing it. |
+ scoped_ptr<ResourceEntry> parsed_entry( |
+ ResourceEntry::CreateFrom(*new_entry)); |
+ |
+ entries->Append(new_entry.release()); |
+ |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(callback, HTTP_SUCCESS, base::Passed(&parsed_entry))); |
+ return; |
+ } |
+ |
+ scoped_ptr<ResourceEntry> null; |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind(callback, HTTP_NOT_FOUND, base::Passed(&null))); |
} |
void FakeDriveService::InitiateUpload( |
@@ -281,4 +482,92 @@ void FakeDriveService::AuthorizeApp(const GURL& edit_url, |
DCHECK(!callback.is_null()); |
} |
+base::DictionaryValue* FakeDriveService::FindEntryByResourceId( |
+ const std::string& resource_id) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ base::DictionaryValue* resource_list_dict = NULL; |
+ base::ListValue* entries = NULL; |
+ // Go through entries and return the one that matches |resource_id|. |
+ if (resource_list_value_->GetAsDictionary(&resource_list_dict) && |
+ resource_list_dict->GetList("entry", &entries)) { |
+ for (size_t i = 0; i < entries->GetSize(); ++i) { |
+ base::DictionaryValue* entry = NULL; |
+ base::DictionaryValue* resource_id_dict = NULL; |
+ std::string current_resource_id; |
+ if (entries->GetDictionary(i, &entry) && |
+ entry->GetDictionary("gd$resourceId", &resource_id_dict) && |
+ resource_id_dict->GetString("$t", ¤t_resource_id) && |
+ resource_id == current_resource_id) { |
+ return entry; |
+ } |
+ } |
+ } |
+ |
+ return NULL; |
+} |
+ |
+base::DictionaryValue* FakeDriveService::FindEntryByEditUrl( |
+ const GURL& edit_url) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ base::DictionaryValue* resource_list_dict = NULL; |
+ base::ListValue* entries = NULL; |
+ // Go through entries and return the one that matches |edit_url|. |
+ if (resource_list_value_->GetAsDictionary(&resource_list_dict) && |
+ resource_list_dict->GetList("entry", &entries)) { |
+ for (size_t i = 0; i < entries->GetSize(); ++i) { |
+ base::DictionaryValue* entry = NULL; |
+ base::ListValue* links = NULL; |
+ if (entries->GetDictionary(i, &entry) && |
+ entry->GetList("link", &links)) { |
+ for (size_t j = 0; j < links->GetSize(); ++j) { |
+ base::DictionaryValue* link = NULL; |
+ std::string rel; |
+ std::string href; |
+ if (links->GetDictionary(j, &link) && |
+ link->GetString("rel", &rel) && |
+ link->GetString("href", &href) && |
+ rel == "edit" && |
+ GURL(href) == edit_url) { |
+ return entry; |
+ } |
+ } |
+ } |
+ } |
+ } |
+ |
+ return NULL; |
+} |
+ |
+base::DictionaryValue* FakeDriveService::FindEntryByContentUrl( |
+ const GURL& content_url) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ base::DictionaryValue* resource_list_dict = NULL; |
+ base::ListValue* entries = NULL; |
+ // Go through entries and return the one that matches |content_url|. |
+ if (resource_list_value_->GetAsDictionary(&resource_list_dict) && |
+ resource_list_dict->GetList("entry", &entries)) { |
+ for (size_t i = 0; i < entries->GetSize(); ++i) { |
+ base::DictionaryValue* entry = NULL; |
+ base::DictionaryValue* content = NULL; |
+ std::string current_content_url; |
+ if (entries->GetDictionary(i, &entry) && |
+ entry->GetDictionary("content", &content) && |
+ content->GetString("src", ¤t_content_url) && |
+ content_url == GURL(current_content_url)) { |
+ return entry; |
+ } |
+ } |
+ } |
+ |
+ return NULL; |
+} |
+ |
+std::string FakeDriveService::GetNewResourceId() { |
+ ++resource_id_count_; |
+ return base::StringPrintf("resource_id_%d", resource_id_count_); |
+} |
+ |
} // namespace google_apis |