1// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/sync/engine/syncer_proto_util.h"
6
7#include <string>
8
9#include "base/basictypes.h"
10#include "chrome/browser/sync/engine/syncproto.h"
11#include "chrome/browser/sync/syncable/blob.h"
12#include "chrome/browser/sync/syncable/directory_manager.h"
13#include "chrome/browser/sync/syncable/syncable.h"
14#include "chrome/test/sync/engine/mock_connection_manager.h"
15#include "chrome/test/sync/engine/test_directory_setter_upper.h"
16
17#include "testing/gtest/include/gtest/gtest.h"
18
19using syncable::Blob;
20using syncable::ScopedDirLookup;
21using syncable::SyncName;
22
23namespace browser_sync {
24
25TEST(SyncerProtoUtil, TestBlobToProtocolBufferBytesUtilityFunctions) {
26  unsigned char test_data1[] = {1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 4, 2, 9};
27  unsigned char test_data2[] = {1, 99, 3, 4, 5, 6, 7, 8, 0, 1, 4, 2, 9};
28  unsigned char test_data3[] = {99, 2, 3, 4, 5, 6, 7, 8};
29
30  syncable::Blob test_blob1, test_blob2, test_blob3;
31  for (size_t i = 0; i < arraysize(test_data1); ++i)
32    test_blob1.push_back(test_data1[i]);
33  for (size_t i = 0; i < arraysize(test_data2); ++i)
34    test_blob2.push_back(test_data2[i]);
35  for (size_t i = 0; i < arraysize(test_data3); ++i)
36    test_blob3.push_back(test_data3[i]);
37
38  std::string test_message1(reinterpret_cast<char*>(test_data1),
39      arraysize(test_data1));
40  std::string test_message2(reinterpret_cast<char*>(test_data2),
41      arraysize(test_data2));
42  std::string test_message3(reinterpret_cast<char*>(test_data3),
43      arraysize(test_data3));
44
45  EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1,
46                                                    test_blob1));
47  EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1,
48                                                     test_blob2));
49  EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1,
50                                                     test_blob3));
51  EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message2,
52                                                     test_blob1));
53  EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message2,
54                                                    test_blob2));
55  EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message2,
56                                                     test_blob3));
57  EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message3,
58                                                     test_blob1));
59  EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message3,
60                                                     test_blob2));
61  EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message3,
62                                                    test_blob3));
63
64  Blob blob1_copy;
65  EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1,
66                                                     blob1_copy));
67  SyncerProtoUtil::CopyProtoBytesIntoBlob(test_message1, &blob1_copy);
68  EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1,
69                                                    blob1_copy));
70
71  std::string message2_copy;
72  EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(message2_copy,
73                                                     test_blob2));
74  SyncerProtoUtil::CopyBlobIntoProtoBytes(test_blob2, &message2_copy);
75  EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(message2_copy,
76                                                    test_blob2));
77}
78
79// Tests NameFromSyncEntity and NameFromCommitEntryResponse when only the name
80// field is provided.
81TEST(SyncerProtoUtil, NameExtractionOneName) {
82  SyncEntity one_name_entity;
83  CommitResponse_EntryResponse one_name_response;
84
85  const std::string one_name_string("Eggheadednesses");
86  one_name_entity.set_name(one_name_string);
87  one_name_response.set_name(one_name_string);
88
89  const std::string name_a =
90      SyncerProtoUtil::NameFromSyncEntity(one_name_entity);
91  EXPECT_EQ(one_name_string, name_a);
92}
93
94TEST(SyncerProtoUtil, NameExtractionOneUniqueName) {
95  SyncEntity one_name_entity;
96  CommitResponse_EntryResponse one_name_response;
97
98  const std::string one_name_string("Eggheadednesses");
99
100  one_name_entity.set_non_unique_name(one_name_string);
101  one_name_response.set_non_unique_name(one_name_string);
102
103  const std::string name_a =
104      SyncerProtoUtil::NameFromSyncEntity(one_name_entity);
105  EXPECT_EQ(one_name_string, name_a);
106}
107
108// Tests NameFromSyncEntity and NameFromCommitEntryResponse when both the name
109// field and the non_unique_name fields are provided.
110// Should prioritize non_unique_name.
111TEST(SyncerProtoUtil, NameExtractionTwoNames) {
112  SyncEntity two_name_entity;
113  CommitResponse_EntryResponse two_name_response;
114
115  const std::string neuro("Neuroanatomists");
116  const std::string oxyphen("Oxyphenbutazone");
117
118  two_name_entity.set_name(oxyphen);
119  two_name_entity.set_non_unique_name(neuro);
120
121  two_name_response.set_name(oxyphen);
122  two_name_response.set_non_unique_name(neuro);
123
124  const std::string name_a =
125      SyncerProtoUtil::NameFromSyncEntity(two_name_entity);
126  EXPECT_EQ(neuro, name_a);
127}
128
129class SyncerProtoUtilTest : public testing::Test {
130 public:
131  virtual void SetUp() {
132    setter_upper_.SetUp();
133  }
134
135  virtual void TearDown() {
136    setter_upper_.TearDown();
137  }
138
139 protected:
140  browser_sync::TestDirectorySetterUpper setter_upper_;
141};
142
143TEST_F(SyncerProtoUtilTest, VerifyResponseBirthday) {
144  ScopedDirLookup lookup(setter_upper_.manager(), setter_upper_.name());
145  ASSERT_TRUE(lookup.good());
146
147  // Both sides empty
148  EXPECT_TRUE(lookup->store_birthday().empty());
149  ClientToServerResponse response;
150  EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(lookup, &response));
151
152  // Remote set, local empty
153  response.set_store_birthday("flan");
154  EXPECT_TRUE(SyncerProtoUtil::VerifyResponseBirthday(lookup, &response));
155  EXPECT_EQ(lookup->store_birthday(), "flan");
156
157  // Remote empty, local set.
158  response.clear_store_birthday();
159  EXPECT_TRUE(SyncerProtoUtil::VerifyResponseBirthday(lookup, &response));
160  EXPECT_EQ(lookup->store_birthday(), "flan");
161
162  // Doesn't match
163  response.set_store_birthday("meat");
164  EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(lookup, &response));
165
166  response.set_error_code(ClientToServerResponse::CLEAR_PENDING);
167  EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(lookup, &response));
168}
169
170TEST_F(SyncerProtoUtilTest, AddRequestBirthday) {
171  ScopedDirLookup lookup(setter_upper_.manager(), setter_upper_.name());
172  ASSERT_TRUE(lookup.good());
173
174  EXPECT_TRUE(lookup->store_birthday().empty());
175  ClientToServerMessage msg;
176  SyncerProtoUtil::AddRequestBirthday(lookup, &msg);
177  EXPECT_FALSE(msg.has_store_birthday());
178
179  lookup->set_store_birthday("meat");
180  SyncerProtoUtil::AddRequestBirthday(lookup, &msg);
181  EXPECT_EQ(msg.store_birthday(), "meat");
182}
183
184class DummyConnectionManager : public browser_sync::ServerConnectionManager {
185 public:
186  DummyConnectionManager()
187      : ServerConnectionManager("unused", 0, false, "version"),
188        send_error_(false),
189        access_denied_(false) {}
190
191  virtual ~DummyConnectionManager() {}
192  virtual bool PostBufferWithCachedAuth(const PostBufferParams* params,
193                                        ScopedServerStatusWatcher* watcher) {
194    if (send_error_) {
195      return false;
196    }
197
198    ClientToServerResponse response;
199    if (access_denied_) {
200      response.set_error_code(ClientToServerResponse::ACCESS_DENIED);
201    }
202    response.SerializeToString(params->buffer_out);
203
204    return true;
205  }
206
207  void set_send_error(bool send) {
208    send_error_ = send;
209  }
210
211  void set_access_denied(bool denied) {
212    access_denied_ = denied;
213  }
214
215 private:
216  bool send_error_;
217  bool access_denied_;
218};
219
220TEST_F(SyncerProtoUtilTest, PostAndProcessHeaders) {
221  DummyConnectionManager dcm;
222  ClientToServerMessage msg;
223  msg.set_share("required");
224  msg.set_message_contents(ClientToServerMessage::GET_UPDATES);
225  ClientToServerResponse response;
226
227  dcm.set_send_error(true);
228  EXPECT_FALSE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, NULL,
229      msg, &response));
230
231  dcm.set_send_error(false);
232  EXPECT_TRUE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, NULL,
233      msg, &response));
234
235  dcm.set_access_denied(true);
236  EXPECT_FALSE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, NULL,
237      msg, &response));
238}
239
240}  // namespace browser_sync
241