12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/test_util.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/file_util.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_file_value_serializer.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_reader.h"
109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/rand_util.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/run_loop.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/drive_api_parser.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/gdata_wapi_parser.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/google_apis/gdata_wapi_requests.h"
21b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/embedded_test_server/http_request.h"
22b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/embedded_test_server/http_response.h"
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace google_apis {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test_util {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool RemovePrefix(const std::string& input,
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  const std::string& prefix,
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  std::string* output) {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!StartsWithASCII(input, prefix, true /* case sensitive */))
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *output = input.substr(prefix.size());
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetTestFilePath(const std::string& relative_path) {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!PathService::Get(base::DIR_SOURCE_ROOT, &path))
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath();
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  path = path.AppendASCII("chrome")
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             .AppendASCII("test")
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             .AppendASCII("data")
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             .Append(base::FilePath::FromUTF8Unsafe(relative_path));
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return path;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL GetBaseUrlForTesting(int port) {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GURL(base::StringPrintf("http://127.0.0.1:%d/", port));
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid RunAndQuit(base::RunLoop* run_loop, const base::Closure& closure) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  closure.Run();
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  run_loop->Quit();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool WriteStringToFile(const base::FilePath& file_path,
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       const std::string& content) {
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int result = file_util::WriteFile(file_path, content.data(), content.size());
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return content.size() == static_cast<size_t>(result);
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool CreateFileOfSpecifiedSize(const base::FilePath& temp_dir,
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               size_t size,
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               base::FilePath* path,
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               std::string* data) {
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!file_util::CreateTemporaryFileInDir(temp_dir, path))
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (size == 0) {
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Note: RandBytesAsString doesn't support generating an empty string.
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    data->clear();
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *data = base::RandBytesAsString(size);
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return WriteStringToFile(*path, *data);
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<base::Value> LoadJSONFile(const std::string& relative_path) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path = GetTestFilePath(relative_path);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string error;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  JSONFileValueSerializer serializer(path);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::Value> value(serializer.Deserialize(NULL, &error));
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG_IF(WARNING, !value.get()) << "Failed to parse " << path.value()
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                << ": " << error;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return value.Pass();
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns a HttpResponse created from the given file path.
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)scoped_ptr<net::test_server::BasicHttpResponse> CreateHttpResponseFromFile(
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& file_path) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string content;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!file_util::ReadFileToString(file_path, &content))
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return scoped_ptr<net::test_server::BasicHttpResponse>();
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string content_type = "text/plain";
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (EndsWith(file_path.AsUTF8Unsafe(), ".json", true /* case sensitive */))
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content_type = "application/json";
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<net::test_server::BasicHttpResponse> http_response(
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new net::test_server::BasicHttpResponse);
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  http_response->set_code(net::HTTP_OK);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  http_response->set_content(content);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  http_response->set_content_type(content_type);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return http_response.Pass();
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_ptr<net::test_server::HttpResponse> HandleDownloadFileRequest(
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& base_url,
113b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    net::test_server::HttpRequest* out_request,
114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const net::test_server::HttpRequest& request) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *out_request = request;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL absolute_url = base_url.Resolve(request.relative_url);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string remaining_path;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!RemovePrefix(absolute_url.path(), "/files/", &remaining_path))
120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return scoped_ptr<net::test_server::HttpResponse>();
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return CreateHttpResponseFromFile(
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetTestFilePath(remaining_path)).PassAs<net::test_server::HttpResponse>();
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VerifyJsonData(const base::FilePath& expected_json_file_path,
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const base::Value* json_data) {
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!json_data) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "json_data is NULL";
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string expected_content;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!file_util::ReadFileToString(
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          expected_json_file_path, &expected_content)) {
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Failed to read file: " << expected_json_file_path.value();
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::Value> expected_json_data(
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::JSONReader::Read(expected_content));
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!base::Value::Equals(expected_json_data.get(), json_data)) {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "The value of json_data is different from the file's content.";
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ParseContentRangeHeader(const std::string& value,
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             int64* start_position,
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             int64* end_position,
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             int64* length) {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(start_position);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(end_position);
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(length);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string remaining;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!RemovePrefix(value, "bytes ", &remaining))
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> parts;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SplitString(remaining, '/', &parts);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (parts.size() != 2U)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string range = parts[0];
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!base::StringToInt64(parts[1], length))
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parts.clear();
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SplitString(range, '-', &parts);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (parts.size() != 2U)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (base::StringToInt64(parts[0], start_position) &&
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::StringToInt64(parts[1], end_position));
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AppendProgressCallbackResult(std::vector<ProgressInfo>* progress_values,
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  int64 progress,
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  int64 total) {
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  progress_values->push_back(ProgressInfo(progress, total));
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TestGetContentCallback::TestGetContentCallback()
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : callback_(base::Bind(&TestGetContentCallback::OnGetContent,
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           base::Unretained(this))) {
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TestGetContentCallback::~TestGetContentCallback() {
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string TestGetContentCallback::GetConcatenatedData() const {
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string result;
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < data_.size(); ++i) {
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    result += *data_[i];
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return result;
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TestGetContentCallback::OnGetContent(google_apis::GDataErrorCode error,
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          scoped_ptr<std::string> data) {
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data_.push_back(data.release());
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace test_util
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace google_apis
209