15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_file_value_serializer.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_codec.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_test_utils.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl1Title[] = "url1"; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl1Url[] = "http://www.url1.com"; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl2Title[] = "url2"; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl2Url[] = "http://www.url2.com"; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl3Title[] = "url3"; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl3Url[] = "http://www.url3.com"; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl4Title[] = "url4"; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl4Url[] = "http://www.url4.com"; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFolder1Title[] = "folder1"; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFolder2Title[] = "folder2"; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper to get a mutable bookmark node. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarkNode* AsMutable(const BookmarkNode* node) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return const_cast<BookmarkNode*>(node); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkCodecTest : public testing::Test { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helpers to create bookmark models with different data. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel* CreateTestModel1() { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model(new BookmarkModel(NULL)); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bookmark_bar = model->bookmark_bar_node(); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url)); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model.release(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel* CreateTestModel2() { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model(new BookmarkModel(NULL)); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bookmark_bar = model->bookmark_bar_node(); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url)); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->AddURL(bookmark_bar, 1, ASCIIToUTF16(kUrl2Title), GURL(kUrl2Url)); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model.release(); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel* CreateTestModel3() { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model(new BookmarkModel(NULL)); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bookmark_bar = model->bookmark_bar_node(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url)); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* folder1 = model->AddFolder(bookmark_bar, 1, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASCIIToUTF16(kFolder1Title)); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->AddURL(folder1, 0, ASCIIToUTF16(kUrl2Title), GURL(kUrl2Url)); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model.release(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetBookmarksBarChildValue(Value* value, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue** result_value) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(Value::TYPE_DICTIONARY, value->GetType()); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* d_value = static_cast<DictionaryValue*>(value); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value* roots; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(d_value->Get(BookmarkCodec::kRootsKey, &roots)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(Value::TYPE_DICTIONARY, roots->GetType()); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* roots_d_value = static_cast<DictionaryValue*>(roots); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value* bb_value; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(roots_d_value->Get(BookmarkCodec::kRootFolderNameKey, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &bb_value)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(Value::TYPE_DICTIONARY, bb_value->GetType()); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* bb_d_value = static_cast<DictionaryValue*>(bb_value); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value* bb_children_value; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(bb_d_value->Get(BookmarkCodec::kChildrenKey, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &bb_children_value)); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(Value::TYPE_LIST, bb_children_value->GetType()); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* bb_children_l_value = static_cast<ListValue*>(bb_children_value); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value* child_value; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(bb_children_l_value->Get(index, &child_value)); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(Value::TYPE_DICTIONARY, child_value->GetType()); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result_value = static_cast<DictionaryValue*>(child_value); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value* EncodeHelper(BookmarkModel* model, std::string* checksum) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec encoder; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Computed and stored checksums should be empty. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("", encoder.computed_checksum()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("", encoder.stored_checksum()); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value(encoder.Encode(model)); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& computed_checksum = encoder.computed_checksum(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& stored_checksum = encoder.stored_checksum(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Computed and stored checksums should not be empty and should be equal. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(computed_checksum.empty()); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(stored_checksum.empty()); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(computed_checksum, stored_checksum); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *checksum = computed_checksum; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value.release(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Decode(BookmarkCodec* codec, BookmarkModel* model, const Value& value) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 max_id; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = codec->Decode(AsMutable(model->bookmark_bar_node()), 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsMutable(model->other_node()), 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsMutable(model->mobile_node()), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_id, value); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->set_next_node_id(max_id); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsMutable(model->root_node())->set_meta_info_str(codec->model_meta_info()); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel* DecodeHelper(const Value& value, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& expected_stored_checksum, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* computed_checksum, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool expected_changes) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec decoder; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Computed and stored checksums should be empty. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("", decoder.computed_checksum()); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("", decoder.stored_checksum()); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model(new BookmarkModel(NULL)); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Decode(&decoder, model.get(), value)); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *computed_checksum = decoder.computed_checksum(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& stored_checksum = decoder.stored_checksum(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Computed and stored checksums should not be empty. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(computed_checksum->empty()); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(stored_checksum.empty()); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stored checksum should be as expected. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(expected_stored_checksum, stored_checksum); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The two checksums should be equal if expected_changes is true; otherwise 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // they should be different. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (expected_changes) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(*computed_checksum, stored_checksum); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(*computed_checksum, stored_checksum); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model.release(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CheckIDs(const BookmarkNode* node, std::set<int64>* assigned_ids) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(node); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 node_id = node->id(); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(assigned_ids->find(node_id) == assigned_ids->end()); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assigned_ids->insert(node_id); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < node->child_count(); ++i) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckIDs(node->GetChild(i), assigned_ids); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ExpectIDsUnique(BookmarkModel* model) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<int64> assigned_ids; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckIDs(model->bookmark_bar_node(), &assigned_ids); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckIDs(model->other_node(), &assigned_ids); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckIDs(model->mobile_node(), &assigned_ids); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, ChecksumEncodeDecodeTest) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel1()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string enc_checksum; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value(EncodeHelper(model_to_encode.get(), &enc_checksum)); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value.get() != NULL); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dec_checksum; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> decoded_model(DecodeHelper( 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value.get(), enc_checksum, &dec_checksum, false)); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, ChecksumEncodeIdenticalModelsTest) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Encode two identical models and make sure the check-sums are same as long 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as the data is the same. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model1(CreateTestModel1()); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string enc_checksum1; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value1(EncodeHelper(model1.get(), &enc_checksum1)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value1.get() != NULL); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model2(CreateTestModel1()); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string enc_checksum2; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value2(EncodeHelper(model2.get(), &enc_checksum2)); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value2.get() != NULL); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(enc_checksum1, enc_checksum2); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, ChecksumManualEditTest) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel1()); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string enc_checksum; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value(EncodeHelper(model_to_encode.get(), &enc_checksum)); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value.get() != NULL); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change something in the encoded value before decoding it. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* child1_value; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBookmarksBarChildValue(value.get(), 0, &child1_value); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string title; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(child1_value->GetString(BookmarkCodec::kNameKey, &title)); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child1_value->SetString(BookmarkCodec::kNameKey, title + "1"); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dec_checksum; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> decoded_model1(DecodeHelper( 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value.get(), enc_checksum, &dec_checksum, true)); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Undo the change and make sure the checksum is same as original. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child1_value->SetString(BookmarkCodec::kNameKey, title); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> decoded_model2(DecodeHelper( 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value.get(), enc_checksum, &dec_checksum, false)); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, ChecksumManualEditIDsTest) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel3()); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The test depends on existence of multiple children under bookmark bar, so 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // make sure that's the case. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bb_child_count = model_to_encode->bookmark_bar_node()->child_count(); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(bb_child_count, 1); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string enc_checksum; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value(EncodeHelper(model_to_encode.get(), &enc_checksum)); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value.get() != NULL); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change IDs for all children of bookmark bar to be 1. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* child_value; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < bb_child_count; ++i) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBookmarksBarChildValue(value.get(), i, &child_value); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string id; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(child_value->GetString(BookmarkCodec::kIdKey, &id)); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_value->SetString(BookmarkCodec::kIdKey, "1"); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dec_checksum; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> decoded_model(DecodeHelper( 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value.get(), enc_checksum, &dec_checksum, true)); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExpectIDsUnique(decoded_model.get()); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // add a few extra nodes to bookmark model and make sure IDs are still uniuqe. 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bb_node = decoded_model->bookmark_bar_node(); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_model->AddURL(bb_node, 0, ASCIIToUTF16("new url1"), 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL("http://newurl1.com")); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_model->AddURL(bb_node, 0, ASCIIToUTF16("new url2"), 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL("http://newurl2.com")); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExpectIDsUnique(decoded_model.get()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, PersistIDsTest) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel3()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec encoder; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> model_value(encoder.Encode(model_to_encode.get())); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel decoded_model(NULL); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec decoder; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(Decode(&decoder, &decoded_model, *model_value.get())); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModelTestUtils::AssertModelsEqual(model_to_encode.get(), 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &decoded_model, 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a couple of more items to the decoded bookmark model and make sure 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ID persistence is working properly. 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bookmark_bar = decoded_model.bookmark_bar_node(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_model.AddURL( 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar, bookmark_bar->child_count(), ASCIIToUTF16(kUrl3Title), 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL(kUrl3Url)); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* folder2_node = decoded_model.AddFolder( 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar, bookmark_bar->child_count(), ASCIIToUTF16(kFolder2Title)); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_model.AddURL(folder2_node, 0, ASCIIToUTF16(kUrl4Title), 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL(kUrl4Url)); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec encoder2; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> model_value2(encoder2.Encode(&decoded_model)); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel decoded_model2(NULL); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec decoder2; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(Decode(&decoder2, &decoded_model2, *model_value2.get())); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModelTestUtils::AssertModelsEqual(&decoded_model, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &decoded_model2, 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, CanDecodeModelWithoutMobileBookmarks) { 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath test_data_directory; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory)); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath test_file = test_data_directory.AppendASCII( 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bookmarks/model_without_sync.json"); 3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_TRUE(base::PathExists(test_file)); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JSONFileValueSerializer serializer(test_file); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> root(serializer.Deserialize(NULL, NULL)); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel decoded_model(NULL); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec decoder; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(Decode(&decoder, &decoded_model, *root.get())); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExpectIDsUnique(&decoded_model); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bbn = decoded_model.bookmark_bar_node(); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, bbn->child_count()); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* child = bbn->GetChild(0); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(BookmarkNode::FOLDER, child->type()); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("Folder A"), child->GetTitle()); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, child->child_count()); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = child->GetChild(0); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(BookmarkNode::URL, child->type()); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("Bookmark Manager"), child->GetTitle()); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* other = decoded_model.other_node(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, other->child_count()); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = other->GetChild(0); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(BookmarkNode::FOLDER, child->type()); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("Folder B"), child->GetTitle()); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, child->child_count()); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = child->GetChild(0); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(BookmarkNode::URL, child->type()); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("Get started with Google Chrome"), child->GetTitle()); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(decoded_model.mobile_node() != NULL); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, EncodeAndDecodeMetaInfo) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add meta info and encode. 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model(CreateTestModel1()); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->SetNodeMetaInfo(model->root_node(), "model_info", "value1"); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->SetNodeMetaInfo(model->bookmark_bar_node()->GetChild(0), 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "node_info", "value2"); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string checksum; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value(EncodeHelper(model.get(), &checksum)); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(value.get() != NULL); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Decode and check for meta info. 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model.reset(DecodeHelper(*value, checksum, &checksum, false)); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string meta_value; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(model->root_node()->GetMetaInfo("model_info", &meta_value)); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("value1", meta_value); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(model->root_node()->GetMetaInfo("other_key", &meta_value)); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bbn = model->bookmark_bar_node(); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, bbn->child_count()); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* child = bbn->GetChild(0); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(child->GetMetaInfo("node_info", &meta_value)); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("value2", meta_value); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(child->GetMetaInfo("other_key", &meta_value)); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 363