// 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/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" 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); } } } // namespace browser_sync