blob: a77134bab78db5b3bd3429d5a1a8f03bf5b9c9dd [file] [log] [blame]
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Unit tests for the SyncApi. Note that a lot of the underlying
// functionality is provided by the Syncable layer, which has its own
// unit tests. We'll test SyncApi specific things in this harness.
#include "base/scoped_ptr.h"
#include "base/scoped_temp_dir.h"
#include "chrome/browser/sync/engine/syncapi.h"
#include "chrome/browser/sync/protocol/password_specifics.pb.h"
#include "chrome/browser/sync/syncable/directory_manager.h"
#include "chrome/browser/sync/syncable/syncable.h"
#include "chrome/test/sync/engine/test_directory_setter_upper.h"
#include "testing/gtest/include/gtest/gtest.h"
using browser_sync::KeyParams;
namespace sync_api {
class SyncApiTest : public testing::Test {
public:
virtual void SetUp() {
setter_upper_.SetUp();
share_.dir_manager.reset(setter_upper_.manager());
share_.authenticated_name = setter_upper_.name();
}
virtual void TearDown() {
// |share_.dir_manager| does not actually own its value.
ignore_result(share_.dir_manager.release());
setter_upper_.TearDown();
}
protected:
UserShare share_;
browser_sync::TestDirectorySetterUpper setter_upper_;
};
TEST_F(SyncApiTest, SanityCheckTest) {
{
ReadTransaction trans(&share_);
EXPECT_TRUE(trans.GetWrappedTrans() != NULL);
}
{
WriteTransaction trans(&share_);
EXPECT_TRUE(trans.GetWrappedTrans() != NULL);
}
{
// No entries but root should exist
ReadTransaction trans(&share_);
ReadNode node(&trans);
// Metahandle 1 can be root, sanity check 2
EXPECT_FALSE(node.InitByIdLookup(2));
}
}
TEST_F(SyncApiTest, BasicTagWrite) {
{
WriteTransaction trans(&share_);
ReadNode root_node(&trans);
root_node.InitByRootLookup();
EXPECT_EQ(root_node.GetFirstChildId(), 0);
WriteNode wnode(&trans);
EXPECT_TRUE(wnode.InitUniqueByCreation(syncable::BOOKMARKS,
root_node, "testtag"));
wnode.SetIsFolder(false);
}
{
ReadTransaction trans(&share_);
ReadNode node(&trans);
EXPECT_TRUE(node.InitByClientTagLookup(syncable::BOOKMARKS,
"testtag"));
ReadNode root_node(&trans);
root_node.InitByRootLookup();
EXPECT_NE(node.GetId(), 0);
EXPECT_EQ(node.GetId(), root_node.GetFirstChildId());
}
}
TEST_F(SyncApiTest, GenerateSyncableHash) {
EXPECT_EQ("OyaXV5mEzrPS4wbogmtKvRfekAI=",
BaseNode::GenerateSyncableHash(syncable::BOOKMARKS, "tag1"));
EXPECT_EQ("iNFQtRFQb+IZcn1kKUJEZDDkLs4=",
BaseNode::GenerateSyncableHash(syncable::PREFERENCES, "tag1"));
EXPECT_EQ("gO1cPZQXaM73sHOvSA+tKCKFs58=",
BaseNode::GenerateSyncableHash(syncable::AUTOFILL, "tag1"));
EXPECT_EQ("A0eYIHXM1/jVwKDDp12Up20IkKY=",
BaseNode::GenerateSyncableHash(syncable::BOOKMARKS, "tag2"));
EXPECT_EQ("XYxkF7bhS4eItStFgiOIAU23swI=",
BaseNode::GenerateSyncableHash(syncable::PREFERENCES, "tag2"));
EXPECT_EQ("GFiWzo5NGhjLlN+OyCfhy28DJTQ=",
BaseNode::GenerateSyncableHash(syncable::AUTOFILL, "tag2"));
}
TEST_F(SyncApiTest, ModelTypesSiloed) {
{
WriteTransaction trans(&share_);
ReadNode root_node(&trans);
root_node.InitByRootLookup();
EXPECT_EQ(root_node.GetFirstChildId(), 0);
WriteNode bookmarknode(&trans);
EXPECT_TRUE(bookmarknode.InitUniqueByCreation(syncable::BOOKMARKS,
root_node, "collideme"));
bookmarknode.SetIsFolder(false);
WriteNode prefnode(&trans);
EXPECT_TRUE(prefnode.InitUniqueByCreation(syncable::PREFERENCES,
root_node, "collideme"));
prefnode.SetIsFolder(false);
WriteNode autofillnode(&trans);
EXPECT_TRUE(autofillnode.InitUniqueByCreation(syncable::AUTOFILL,
root_node, "collideme"));
autofillnode.SetIsFolder(false);
}
{
ReadTransaction trans(&share_);
ReadNode bookmarknode(&trans);
EXPECT_TRUE(bookmarknode.InitByClientTagLookup(syncable::BOOKMARKS,
"collideme"));
ReadNode prefnode(&trans);
EXPECT_TRUE(prefnode.InitByClientTagLookup(syncable::PREFERENCES,
"collideme"));
ReadNode autofillnode(&trans);
EXPECT_TRUE(autofillnode.InitByClientTagLookup(syncable::AUTOFILL,
"collideme"));
EXPECT_NE(bookmarknode.GetId(), prefnode.GetId());
EXPECT_NE(autofillnode.GetId(), prefnode.GetId());
EXPECT_NE(bookmarknode.GetId(), autofillnode.GetId());
}
}
TEST_F(SyncApiTest, ReadMissingTagsFails) {
{
ReadTransaction trans(&share_);
ReadNode node(&trans);
EXPECT_FALSE(node.InitByClientTagLookup(syncable::BOOKMARKS,
"testtag"));
}
{
WriteTransaction trans(&share_);
WriteNode node(&trans);
EXPECT_FALSE(node.InitByClientTagLookup(syncable::BOOKMARKS,
"testtag"));
}
}
// TODO(chron): Hook this all up to the server and write full integration tests
// for update->undelete behavior.
TEST_F(SyncApiTest, TestDeleteBehavior) {
int64 node_id;
int64 folder_id;
std::wstring test_title(L"test1");
{
WriteTransaction trans(&share_);
ReadNode root_node(&trans);
root_node.InitByRootLookup();
// we'll use this spare folder later
WriteNode folder_node(&trans);
EXPECT_TRUE(folder_node.InitByCreation(syncable::BOOKMARKS,
root_node, NULL));
folder_id = folder_node.GetId();
WriteNode wnode(&trans);
EXPECT_TRUE(wnode.InitUniqueByCreation(syncable::BOOKMARKS,
root_node, "testtag"));
wnode.SetIsFolder(false);
wnode.SetTitle(test_title);
node_id = wnode.GetId();
}
// Ensure we can delete something with a tag.
{
WriteTransaction trans(&share_);
WriteNode wnode(&trans);
EXPECT_TRUE(wnode.InitByClientTagLookup(syncable::BOOKMARKS,
"testtag"));
EXPECT_FALSE(wnode.GetIsFolder());
EXPECT_EQ(wnode.GetTitle(), test_title);
wnode.Remove();
}
// Lookup of a node which was deleted should return failure,
// but have found some data about the node.
{
ReadTransaction trans(&share_);
ReadNode node(&trans);
EXPECT_FALSE(node.InitByClientTagLookup(syncable::BOOKMARKS,
"testtag"));
// Note that for proper function of this API this doesn't need to be
// filled, we're checking just to make sure the DB worked in this test.
EXPECT_EQ(node.GetTitle(), test_title);
}
{
WriteTransaction trans(&share_);
ReadNode folder_node(&trans);
EXPECT_TRUE(folder_node.InitByIdLookup(folder_id));
WriteNode wnode(&trans);
// This will undelete the tag.
EXPECT_TRUE(wnode.InitUniqueByCreation(syncable::BOOKMARKS,
folder_node, "testtag"));
EXPECT_EQ(wnode.GetIsFolder(), false);
EXPECT_EQ(wnode.GetParentId(), folder_node.GetId());
EXPECT_EQ(wnode.GetId(), node_id);
EXPECT_NE(wnode.GetTitle(), test_title); // Title should be cleared
wnode.SetTitle(test_title);
}
// Now look up should work.
{
ReadTransaction trans(&share_);
ReadNode node(&trans);
EXPECT_TRUE(node.InitByClientTagLookup(syncable::BOOKMARKS,
"testtag"));
EXPECT_EQ(node.GetTitle(), test_title);
EXPECT_EQ(node.GetModelType(), syncable::BOOKMARKS);
}
}
TEST_F(SyncApiTest, WriteAndReadPassword) {
KeyParams params = {"localhost", "username", "passphrase"};
share_.dir_manager->cryptographer()->AddKey(params);
{
WriteTransaction trans(&share_);
ReadNode root_node(&trans);
root_node.InitByRootLookup();
WriteNode password_node(&trans);
EXPECT_TRUE(password_node.InitUniqueByCreation(syncable::PASSWORDS,
root_node, "foo"));
sync_pb::PasswordSpecificsData data;
data.set_password_value("secret");
password_node.SetPasswordSpecifics(data);
}
{
ReadTransaction trans(&share_);
ReadNode root_node(&trans);
root_node.InitByRootLookup();
ReadNode password_node(&trans);
EXPECT_TRUE(password_node.InitByClientTagLookup(syncable::PASSWORDS,
"foo"));
const sync_pb::PasswordSpecificsData& data =
password_node.GetPasswordSpecifics();
EXPECT_EQ("secret", data.password_value());
}
}
} // namespace browser_sync