OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/extensions/extension_message_handler.h" |
| 6 |
| 7 #include <string> |
| 8 |
| 9 #include "base/scoped_ptr.h" |
| 10 #include "base/string_util.h" |
| 11 #include "base/values.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 |
| 14 namespace { |
| 15 |
| 16 // Helper method for dictionary building. |
| 17 void SetDictionary(const std::wstring name, |
| 18 DictionaryValue* target, |
| 19 DictionaryValue* subtree) { |
| 20 target->Set(name, static_cast<Value*>(subtree)); |
| 21 } |
| 22 |
| 23 void CreateContentTree(const std::wstring& name, |
| 24 const std::string content, |
| 25 DictionaryValue* dict) { |
| 26 DictionaryValue* content_tree = new DictionaryValue; |
| 27 content_tree->SetString(ExtensionMessageHandler::kContentKey, content); |
| 28 SetDictionary(name, dict, content_tree); |
| 29 } |
| 30 |
| 31 void CreatePlaceholdersTree(DictionaryValue* dict) { |
| 32 DictionaryValue* placeholders_tree = new DictionaryValue; |
| 33 CreateContentTree(L"a", "A", placeholders_tree); |
| 34 CreateContentTree(L"b", "B", placeholders_tree); |
| 35 CreateContentTree(L"c", "C", placeholders_tree); |
| 36 SetDictionary(ExtensionMessageHandler::kPlaceholdersKey, |
| 37 dict, |
| 38 placeholders_tree); |
| 39 } |
| 40 |
| 41 void CreateMessageTree(const std::wstring& name, |
| 42 const std::string& message, |
| 43 bool create_placeholder_subtree, |
| 44 DictionaryValue* dict) { |
| 45 DictionaryValue* message_tree = new DictionaryValue; |
| 46 if (create_placeholder_subtree) |
| 47 CreatePlaceholdersTree(message_tree); |
| 48 message_tree->SetString(ExtensionMessageHandler::kMessageKey, message); |
| 49 SetDictionary(name, dict, message_tree); |
| 50 } |
| 51 |
| 52 void CreateGoodDictionary(DictionaryValue* dict) { |
| 53 dict->Clear(); |
| 54 CreateMessageTree(L"n1", "message1 $a$ $b$", true, dict); |
| 55 CreateMessageTree(L"n2", "message2 $c$", true, dict); |
| 56 CreateMessageTree(L"n3", "message3", false, dict); |
| 57 } |
| 58 |
| 59 enum BadDictionary { |
| 60 INVALID_NAME, |
| 61 NAME_NOT_A_TREE, |
| 62 EMPTY_NAME_TREE, |
| 63 MISSING_MESSAGE, |
| 64 PLACEHOLDER_NOT_A_TREE, |
| 65 EMPTY_PLACEHOLDER_TREE, |
| 66 CONTENT_MISSING, |
| 67 MESSAGE_PLACEHOLDER_DOESNT_MATCH, |
| 68 }; |
| 69 |
| 70 void CreateBadDictionary(DictionaryValue* dict, |
| 71 enum BadDictionary what_is_bad) { |
| 72 CreateGoodDictionary(dict); |
| 73 // Now remove/break things. |
| 74 switch (what_is_bad) { |
| 75 case INVALID_NAME: |
| 76 CreateMessageTree(L"n 5", "nevermind", false, dict); |
| 77 break; |
| 78 case NAME_NOT_A_TREE: |
| 79 dict->SetString(L"n4", "whatever"); |
| 80 break; |
| 81 case EMPTY_NAME_TREE: { |
| 82 DictionaryValue* empty_tree = new DictionaryValue; |
| 83 SetDictionary(L"n4", dict, empty_tree); |
| 84 } |
| 85 break; |
| 86 case MISSING_MESSAGE: |
| 87 dict->Remove(L"n1.message", NULL); |
| 88 break; |
| 89 case PLACEHOLDER_NOT_A_TREE: |
| 90 dict->SetString(L"n1.placeholders", "whatever"); |
| 91 break; |
| 92 case EMPTY_PLACEHOLDER_TREE: { |
| 93 DictionaryValue* empty_tree = new DictionaryValue; |
| 94 SetDictionary(L"n1.placeholders", dict, empty_tree); |
| 95 } |
| 96 break; |
| 97 case CONTENT_MISSING: |
| 98 dict->Remove(L"n1.placeholders.a.content", NULL); |
| 99 break; |
| 100 case MESSAGE_PLACEHOLDER_DOESNT_MATCH: |
| 101 DictionaryValue* value; |
| 102 dict->Remove(L"n1.placeholders.a", NULL); |
| 103 dict->GetDictionary(L"n1.placeholders", &value); |
| 104 CreateContentTree(L"x", "X", value); |
| 105 break; |
| 106 } |
| 107 } |
| 108 |
| 109 TEST(ExtensionMessageHandler, InitEmptyDictionaries) { |
| 110 DictionaryValue default_dict; |
| 111 DictionaryValue app_dict; |
| 112 std::string error; |
| 113 ExtensionMessageHandler handler; |
| 114 |
| 115 EXPECT_TRUE(handler.Init(&default_dict, &app_dict, &error)); |
| 116 EXPECT_EQ(0U, handler.GetDictionarySize()); |
| 117 } |
| 118 |
| 119 TEST(ExtensionMessageHandler, InitGoodDefaultDictEmptyAppDict) { |
| 120 DictionaryValue default_dict; |
| 121 DictionaryValue app_dict; |
| 122 std::string error; |
| 123 ExtensionMessageHandler handler; |
| 124 |
| 125 CreateGoodDictionary(&default_dict); |
| 126 EXPECT_TRUE(handler.Init(&default_dict, &app_dict, &error)); |
| 127 EXPECT_EQ(3U, handler.GetDictionarySize()); |
| 128 |
| 129 std::string result; |
| 130 EXPECT_TRUE(handler.GetMessage("n1", &result)); |
| 131 EXPECT_EQ("message1 A B", result); |
| 132 EXPECT_TRUE(handler.GetMessage("n2", &result)); |
| 133 EXPECT_EQ("message2 C", result); |
| 134 EXPECT_TRUE(handler.GetMessage("n3", &result)); |
| 135 EXPECT_EQ("message3", result); |
| 136 } |
| 137 |
| 138 TEST(ExtensionMessageHandler, InitAppDictConsultedFirst) { |
| 139 DictionaryValue default_dict; |
| 140 DictionaryValue app_dict; |
| 141 std::string error; |
| 142 ExtensionMessageHandler handler; |
| 143 |
| 144 CreateGoodDictionary(&default_dict); |
| 145 |
| 146 CreateGoodDictionary(&app_dict); |
| 147 // Flip placeholders in message of n1 tree. |
| 148 app_dict.SetString(L"n1.message", "message1 $b$ $a$"); |
| 149 // Remove one message from app dict. |
| 150 app_dict.Remove(L"n2", NULL); |
| 151 |
| 152 EXPECT_TRUE(handler.Init(&default_dict, &app_dict, &error)); |
| 153 EXPECT_EQ(3U, handler.GetDictionarySize()); |
| 154 |
| 155 std::string result; |
| 156 EXPECT_TRUE(handler.GetMessage("n1", &result)); |
| 157 EXPECT_EQ("message1 B A", result); |
| 158 EXPECT_TRUE(handler.GetMessage("n2", &result)); |
| 159 EXPECT_EQ("message2 C", result); |
| 160 EXPECT_TRUE(handler.GetMessage("n3", &result)); |
| 161 EXPECT_EQ("message3", result); |
| 162 } |
| 163 |
| 164 TEST(ExtensionMessageHandler, InitBadAppDict) { |
| 165 DictionaryValue default_dict; |
| 166 DictionaryValue app_dict; |
| 167 std::string error; |
| 168 ExtensionMessageHandler handler; |
| 169 |
| 170 CreateBadDictionary(&app_dict, INVALID_NAME); |
| 171 EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error)); |
| 172 EXPECT_EQ("Name of a key \"n 5\" is invalid. Only ASCII [a-z], " |
| 173 "[A-Z], [0-9] and \"_\" are allowed.", error); |
| 174 |
| 175 CreateBadDictionary(&app_dict, NAME_NOT_A_TREE); |
| 176 EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error)); |
| 177 EXPECT_EQ("Not a valid tree for key n4.", error); |
| 178 |
| 179 CreateBadDictionary(&app_dict, EMPTY_NAME_TREE); |
| 180 EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error)); |
| 181 EXPECT_EQ("There is no \"message\" element for key n4.", error); |
| 182 |
| 183 CreateBadDictionary(&app_dict, MISSING_MESSAGE); |
| 184 EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error)); |
| 185 EXPECT_EQ("There is no \"message\" element for key n1.", error); |
| 186 |
| 187 CreateBadDictionary(&app_dict, PLACEHOLDER_NOT_A_TREE); |
| 188 EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error)); |
| 189 EXPECT_EQ("Not a valid \"placeholders\" element for key n1.", error); |
| 190 |
| 191 CreateBadDictionary(&app_dict, EMPTY_PLACEHOLDER_TREE); |
| 192 EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error)); |
| 193 EXPECT_EQ("Placeholder \"a\" is missing but used in a message n1.", error); |
| 194 |
| 195 CreateBadDictionary(&app_dict, CONTENT_MISSING); |
| 196 EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error)); |
| 197 EXPECT_EQ("Invalid \"content\" element for key n1.", error); |
| 198 |
| 199 CreateBadDictionary(&app_dict, MESSAGE_PLACEHOLDER_DOESNT_MATCH); |
| 200 EXPECT_FALSE(handler.Init(&default_dict, &app_dict, &error)); |
| 201 EXPECT_EQ("Placeholder \"a\" is missing but used in a message n1.", error); |
| 202 } |
| 203 |
| 204 struct ReplaceVariables { |
| 205 const char* original; |
| 206 const char* result; |
| 207 const char* begin_delimiter; |
| 208 const char* end_delimiter; |
| 209 bool pass; |
| 210 }; |
| 211 |
| 212 TEST(ExtensionMessageHandler, ReplaceMessagesInText) { |
| 213 const char* kMessageBegin = ExtensionMessageHandler::kMessageBegin; |
| 214 const char* kMessageEnd = ExtensionMessageHandler::kMessageEnd; |
| 215 const char* kPlaceholderBegin = ExtensionMessageHandler::kPlaceholderBegin; |
| 216 const char* kPlaceholderEnd = ExtensionMessageHandler::kPlaceholderEnd; |
| 217 |
| 218 static ReplaceVariables test_cases[] = { |
| 219 // Message replacement. |
| 220 { "This is __MSG_simple__ message", "This is simple message", |
| 221 kMessageBegin, kMessageEnd, true }, |
| 222 { "This is __MSG_", "This is __MSG_", |
| 223 kMessageBegin, kMessageEnd, true }, |
| 224 { "This is __MSG__simple__ message", "_simple", |
| 225 kMessageBegin, kMessageEnd, false }, |
| 226 { "__MSG_long__", "A pretty long replacement", |
| 227 kMessageBegin, kMessageEnd, true }, |
| 228 { "A __MSG_simple__MSG_ a", "A simpleMSG_ a", |
| 229 kMessageBegin, kMessageEnd, true }, |
| 230 { "A __MSG_simple__MSG_long__", "A simpleMSG_long__", |
| 231 kMessageBegin, kMessageEnd, true }, |
| 232 { "A __MSG_simple____MSG_long__", "A simpleA pretty long replacement", |
| 233 kMessageBegin, kMessageEnd, true }, |
| 234 { "__MSG_d1g1ts_are_ok__", "I are d1g1t", |
| 235 kMessageBegin, kMessageEnd, true }, |
| 236 // Placeholder replacement. |
| 237 { "This is $simple$ message", "This is simple message", |
| 238 kPlaceholderBegin, kPlaceholderEnd, true }, |
| 239 { "This is $", "This is $", |
| 240 kPlaceholderBegin, kPlaceholderEnd, true }, |
| 241 { "This is $$simple$ message", "This is $simple message", |
| 242 kPlaceholderBegin, kPlaceholderEnd, true }, |
| 243 { "$long_v$", "A pretty long replacement", |
| 244 kPlaceholderBegin, kPlaceholderEnd, true }, |
| 245 { "A $simple$$ a", "A simple$ a", |
| 246 kPlaceholderBegin, kPlaceholderEnd, true }, |
| 247 { "A $simple$long_v$", "A simplelong_v$", |
| 248 kPlaceholderBegin, kPlaceholderEnd, true }, |
| 249 { "A $simple$$long_v$", "A simpleA pretty long replacement", |
| 250 kPlaceholderBegin, kPlaceholderEnd, true }, |
| 251 { "This is $bad name$", "This is $bad name$", |
| 252 kPlaceholderBegin, kPlaceholderEnd, true }, |
| 253 { "This is $missing$", "missing", |
| 254 kPlaceholderBegin, kPlaceholderEnd, false }, |
| 255 }; |
| 256 |
| 257 ExtensionMessageHandler::SSMap messages; |
| 258 messages.insert(std::make_pair("simple", "simple")); |
| 259 messages.insert(std::make_pair("long", "A pretty long replacement")); |
| 260 messages.insert(std::make_pair("long_v", "A pretty long replacement")); |
| 261 messages.insert(std::make_pair("bad name", "Doesn't matter")); |
| 262 messages.insert(std::make_pair("d1g1ts_are_ok", "I are d1g1t")); |
| 263 |
| 264 ExtensionMessageHandler handler; |
| 265 for (size_t i = 0; i < arraysize(test_cases); ++i) { |
| 266 std::string text = test_cases[i].original; |
| 267 EXPECT_EQ(test_cases[i].pass, |
| 268 handler.ReplaceVariablesInString(messages, |
| 269 test_cases[i].begin_delimiter, |
| 270 test_cases[i].end_delimiter, |
| 271 &text)); |
| 272 EXPECT_EQ(test_cases[i].result, text); |
| 273 } |
| 274 } |
| 275 |
| 276 } // namespace |
OLD | NEW |