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) 5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_codec.h" 6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_file_value_serializer.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/json/json_string_value_serializer.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl1Title[] = "url1"; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl1Url[] = "http://www.url1.com"; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl2Title[] = "url2"; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl2Url[] = "http://www.url2.com"; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl3Title[] = "url3"; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl3Url[] = "http://www.url3.com"; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl4Title[] = "url4"; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrl4Url[] = "http://www.url4.com"; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFolder1Title[] = "folder1"; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFolder2Title[] = "folder2"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper to get a mutable bookmark node. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarkNode* AsMutable(const BookmarkNode* node) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return const_cast<BookmarkNode*>(node); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Helper to verify the two given bookmark nodes. 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AssertNodesEqual(const BookmarkNode* expected, 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const BookmarkNode* actual) { 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_TRUE(expected); 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_TRUE(actual); 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(expected->id(), actual->id()); 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(expected->GetTitle(), actual->GetTitle()); 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(expected->type(), actual->type()); 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(expected->date_added() == actual->date_added()); 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (expected->is_url()) { 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(expected->url(), actual->url()); 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(expected->date_folder_modified() == 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) actual->date_folder_modified()); 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_EQ(expected->child_count(), actual->child_count()); 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (int i = 0; i < expected->child_count(); ++i) 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AssertNodesEqual(expected->GetChild(i), actual->GetChild(i)); 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Verifies that the two given bookmark models are the same. 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AssertModelsEqual(BookmarkModel* expected, BookmarkModel* actual) { 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE(AssertNodesEqual(expected->bookmark_bar_node(), 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) actual->bookmark_bar_node())); 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE( 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AssertNodesEqual(expected->other_node(), actual->other_node())); 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE( 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AssertNodesEqual(expected->mobile_node(), actual->mobile_node())); 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkCodecTest : public testing::Test { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helpers to create bookmark models with different data. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel* CreateTestModel1() { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model(new BookmarkModel(NULL)); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bookmark_bar = model->bookmark_bar_node(); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url)); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model.release(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel* CreateTestModel2() { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model(new BookmarkModel(NULL)); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bookmark_bar = model->bookmark_bar_node(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url)); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->AddURL(bookmark_bar, 1, ASCIIToUTF16(kUrl2Title), GURL(kUrl2Url)); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model.release(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel* CreateTestModel3() { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model(new BookmarkModel(NULL)); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bookmark_bar = model->bookmark_bar_node(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url)); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* folder1 = model->AddFolder(bookmark_bar, 1, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASCIIToUTF16(kFolder1Title)); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->AddURL(folder1, 0, ASCIIToUTF16(kUrl2Title), GURL(kUrl2Url)); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model.release(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetBookmarksBarChildValue(Value* value, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue** result_value) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(Value::TYPE_DICTIONARY, value->GetType()); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* d_value = static_cast<DictionaryValue*>(value); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value* roots; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(d_value->Get(BookmarkCodec::kRootsKey, &roots)); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(Value::TYPE_DICTIONARY, roots->GetType()); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* roots_d_value = static_cast<DictionaryValue*>(roots); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value* bb_value; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(roots_d_value->Get(BookmarkCodec::kRootFolderNameKey, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &bb_value)); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(Value::TYPE_DICTIONARY, bb_value->GetType()); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* bb_d_value = static_cast<DictionaryValue*>(bb_value); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value* bb_children_value; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(bb_d_value->Get(BookmarkCodec::kChildrenKey, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &bb_children_value)); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(Value::TYPE_LIST, bb_children_value->GetType()); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* bb_children_l_value = static_cast<ListValue*>(bb_children_value); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value* child_value; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(bb_children_l_value->Get(index, &child_value)); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(Value::TYPE_DICTIONARY, child_value->GetType()); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result_value = static_cast<DictionaryValue*>(child_value); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value* EncodeHelper(BookmarkModel* model, std::string* checksum) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec encoder; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Computed and stored checksums should be empty. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("", encoder.computed_checksum()); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("", encoder.stored_checksum()); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value(encoder.Encode(model)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& computed_checksum = encoder.computed_checksum(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& stored_checksum = encoder.stored_checksum(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Computed and stored checksums should not be empty and should be equal. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(computed_checksum.empty()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(stored_checksum.empty()); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(computed_checksum, stored_checksum); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *checksum = computed_checksum; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value.release(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Decode(BookmarkCodec* codec, BookmarkModel* model, const Value& value) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 max_id; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = codec->Decode(AsMutable(model->bookmark_bar_node()), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsMutable(model->other_node()), 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsMutable(model->mobile_node()), 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_id, value); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->set_next_node_id(max_id); 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AsMutable(model->root_node())-> 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SetMetaInfoMap(codec->model_meta_info_map()); 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AsMutable(model->root_node())-> 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) set_sync_transaction_version(codec->model_sync_transaction_version()); 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel* DecodeHelper(const Value& value, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& expected_stored_checksum, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* computed_checksum, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool expected_changes) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec decoder; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Computed and stored checksums should be empty. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("", decoder.computed_checksum()); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("", decoder.stored_checksum()); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model(new BookmarkModel(NULL)); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Decode(&decoder, model.get(), value)); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *computed_checksum = decoder.computed_checksum(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& stored_checksum = decoder.stored_checksum(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Computed and stored checksums should not be empty. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(computed_checksum->empty()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(stored_checksum.empty()); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stored checksum should be as expected. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(expected_stored_checksum, stored_checksum); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The two checksums should be equal if expected_changes is true; otherwise 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // they should be different. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (expected_changes) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(*computed_checksum, stored_checksum); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(*computed_checksum, stored_checksum); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model.release(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CheckIDs(const BookmarkNode* node, std::set<int64>* assigned_ids) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(node); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 node_id = node->id(); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(assigned_ids->find(node_id) == assigned_ids->end()); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assigned_ids->insert(node_id); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < node->child_count(); ++i) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckIDs(node->GetChild(i), assigned_ids); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ExpectIDsUnique(BookmarkModel* model) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<int64> assigned_ids; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckIDs(model->bookmark_bar_node(), &assigned_ids); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckIDs(model->other_node(), &assigned_ids); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckIDs(model->mobile_node(), &assigned_ids); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, ChecksumEncodeDecodeTest) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel1()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string enc_checksum; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value(EncodeHelper(model_to_encode.get(), &enc_checksum)); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value.get() != NULL); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dec_checksum; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> decoded_model(DecodeHelper( 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value.get(), enc_checksum, &dec_checksum, false)); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, ChecksumEncodeIdenticalModelsTest) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Encode two identical models and make sure the check-sums are same as long 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as the data is the same. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model1(CreateTestModel1()); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string enc_checksum1; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value1(EncodeHelper(model1.get(), &enc_checksum1)); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value1.get() != NULL); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model2(CreateTestModel1()); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string enc_checksum2; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value2(EncodeHelper(model2.get(), &enc_checksum2)); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value2.get() != NULL); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(enc_checksum1, enc_checksum2); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, ChecksumManualEditTest) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel1()); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string enc_checksum; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value(EncodeHelper(model_to_encode.get(), &enc_checksum)); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value.get() != NULL); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change something in the encoded value before decoding it. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* child1_value; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBookmarksBarChildValue(value.get(), 0, &child1_value); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string title; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(child1_value->GetString(BookmarkCodec::kNameKey, &title)); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child1_value->SetString(BookmarkCodec::kNameKey, title + "1"); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dec_checksum; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> decoded_model1(DecodeHelper( 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value.get(), enc_checksum, &dec_checksum, true)); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Undo the change and make sure the checksum is same as original. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child1_value->SetString(BookmarkCodec::kNameKey, title); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> decoded_model2(DecodeHelper( 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value.get(), enc_checksum, &dec_checksum, false)); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, ChecksumManualEditIDsTest) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel3()); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The test depends on existence of multiple children under bookmark bar, so 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // make sure that's the case. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bb_child_count = model_to_encode->bookmark_bar_node()->child_count(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(bb_child_count, 1); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string enc_checksum; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value(EncodeHelper(model_to_encode.get(), &enc_checksum)); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value.get() != NULL); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change IDs for all children of bookmark bar to be 1. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* child_value; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < bb_child_count; ++i) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBookmarksBarChildValue(value.get(), i, &child_value); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string id; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(child_value->GetString(BookmarkCodec::kIdKey, &id)); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_value->SetString(BookmarkCodec::kIdKey, "1"); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string dec_checksum; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> decoded_model(DecodeHelper( 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value.get(), enc_checksum, &dec_checksum, true)); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExpectIDsUnique(decoded_model.get()); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // add a few extra nodes to bookmark model and make sure IDs are still uniuqe. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bb_node = decoded_model->bookmark_bar_node(); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_model->AddURL(bb_node, 0, ASCIIToUTF16("new url1"), 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL("http://newurl1.com")); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_model->AddURL(bb_node, 0, ASCIIToUTF16("new url2"), 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL("http://newurl2.com")); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExpectIDsUnique(decoded_model.get()); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, PersistIDsTest) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel3()); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec encoder; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> model_value(encoder.Encode(model_to_encode.get())); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel decoded_model(NULL); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec decoder; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(Decode(&decoder, &decoded_model, *model_value.get())); 307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE( 308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AssertModelsEqual(model_to_encode.get(), &decoded_model)); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a couple of more items to the decoded bookmark model and make sure 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ID persistence is working properly. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bookmark_bar = decoded_model.bookmark_bar_node(); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_model.AddURL( 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar, bookmark_bar->child_count(), ASCIIToUTF16(kUrl3Title), 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL(kUrl3Url)); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* folder2_node = decoded_model.AddFolder( 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_bar, bookmark_bar->child_count(), ASCIIToUTF16(kFolder2Title)); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_model.AddURL(folder2_node, 0, ASCIIToUTF16(kUrl4Title), 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL(kUrl4Url)); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec encoder2; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> model_value2(encoder2.Encode(&decoded_model)); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel decoded_model2(NULL); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec decoder2; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(Decode(&decoder2, &decoded_model2, *model_value2.get())); 327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE(AssertModelsEqual(&decoded_model, &decoded_model2)); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, CanDecodeModelWithoutMobileBookmarks) { 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath test_data_directory; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory)); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath test_file = test_data_directory.AppendASCII( 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bookmarks/model_without_sync.json"); 3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_TRUE(base::PathExists(test_file)); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JSONFileValueSerializer serializer(test_file); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> root(serializer.Deserialize(NULL, NULL)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel decoded_model(NULL); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkCodec decoder; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(Decode(&decoder, &decoded_model, *root.get())); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExpectIDsUnique(&decoded_model); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bbn = decoded_model.bookmark_bar_node(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, bbn->child_count()); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* child = bbn->GetChild(0); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(BookmarkNode::FOLDER, child->type()); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("Folder A"), child->GetTitle()); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, child->child_count()); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = child->GetChild(0); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(BookmarkNode::URL, child->type()); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("Bookmark Manager"), child->GetTitle()); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* other = decoded_model.other_node(); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, other->child_count()); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = other->GetChild(0); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(BookmarkNode::FOLDER, child->type()); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("Folder B"), child->GetTitle()); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, child->child_count()); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = child->GetChild(0); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(BookmarkNode::URL, child->type()); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("Get started with Google Chrome"), child->GetTitle()); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(decoded_model.mobile_node() != NULL); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkCodecTest, EncodeAndDecodeMetaInfo) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add meta info and encode. 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkModel> model(CreateTestModel1()); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->SetNodeMetaInfo(model->root_node(), "model_info", "value1"); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->SetNodeMetaInfo(model->bookmark_bar_node()->GetChild(0), 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "node_info", "value2"); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string checksum; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> value(EncodeHelper(model.get(), &checksum)); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(value.get() != NULL); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Decode and check for meta info. 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model.reset(DecodeHelper(*value, checksum, &checksum, false)); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string meta_value; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(model->root_node()->GetMetaInfo("model_info", &meta_value)); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("value1", meta_value); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(model->root_node()->GetMetaInfo("other_key", &meta_value)); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* bbn = model->bookmark_bar_node(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, bbn->child_count()); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* child = bbn->GetChild(0); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(child->GetMetaInfo("node_info", &meta_value)); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("value2", meta_value); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(child->GetMetaInfo("other_key", &meta_value)); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(BookmarkCodecTest, EncodeAndDecodeSyncTransactionVersion) { 397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Add sync transaction version and encode. 398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<BookmarkModel> model(CreateTestModel2()); 399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) model->SetNodeSyncTransactionVersion(model->root_node(), 1); 400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const BookmarkNode* bbn = model->bookmark_bar_node(); 401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) model->SetNodeSyncTransactionVersion(bbn->GetChild(1), 42); 402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string checksum; 404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<Value> value(EncodeHelper(model.get(), &checksum)); 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(value.get() != NULL); 406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Decode and verify. 408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) model.reset(DecodeHelper(*value, checksum, &checksum, false)); 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(1, model->root_node()->sync_transaction_version()); 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bbn = model->bookmark_bar_node(); 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(42, bbn->GetChild(1)->sync_transaction_version()); 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(BookmarkNode::kInvalidSyncTransactionVersion, 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bbn->GetChild(0)->sync_transaction_version()); 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Verifies that we can still decode the old codec format after changing the 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// way meta info is stored. 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(BookmarkCodecTest, CanDecodeMetaInfoAsString) { 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::FilePath test_data_directory; 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory)); 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::FilePath test_file = test_data_directory.AppendASCII( 422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "bookmarks/meta_info_as_string.json"); 423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(base::PathExists(test_file)); 424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) JSONFileValueSerializer serializer(test_file); 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<Value> root(serializer.Deserialize(NULL, NULL)); 427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BookmarkModel model(NULL); 429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BookmarkCodec decoder; 430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ASSERT_TRUE(Decode(&decoder, &model, *root.get())); 431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(1, model.root_node()->sync_transaction_version()); 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const BookmarkNode* bbn = model.bookmark_bar_node(); 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(BookmarkNode::kInvalidSyncTransactionVersion, 435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bbn->GetChild(0)->sync_transaction_version()); 436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(42, bbn->GetChild(1)->sync_transaction_version()); 437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kSyncTransactionVersionKey[] = "sync.transaction_version"; 439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kNormalKey[] = "key"; 440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kNestedKey[] = "nested.key"; 441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string meta_value; 442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_FALSE(model.root_node()->GetMetaInfo(kSyncTransactionVersionKey, 443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &meta_value)); 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_FALSE(bbn->GetChild(1)->GetMetaInfo(kSyncTransactionVersionKey, 445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &meta_value)); 446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(bbn->GetChild(0)->GetMetaInfo(kNormalKey, &meta_value)); 447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ("value", meta_value); 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(bbn->GetChild(1)->GetMetaInfo(kNormalKey, &meta_value)); 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ("value2", meta_value); 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(bbn->GetChild(0)->GetMetaInfo(kNestedKey, &meta_value)); 451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ("value3", meta_value); 452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 453