| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/file_util.h" |
| 6 #include "base/path_service.h" |
| 7 #include "base/string_util.h" |
| 8 #include "chrome/common/chrome_paths.h" |
| 5 #include "chrome/common/render_messages.h" | 9 #include "chrome/common/render_messages.h" |
| 6 #include "chrome/renderer/extensions/extension_process_bindings.h" | 10 #include "chrome/renderer/extensions/extension_process_bindings.h" |
| 7 #include "chrome/renderer/extensions/renderer_extension_bindings.h" | 11 #include "chrome/renderer/extensions/renderer_extension_bindings.h" |
| 8 #include "chrome/test/render_view_test.h" | 12 #include "chrome/test/render_view_test.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 10 | 14 |
| 11 class ExtensionAPIClientTest : public RenderViewTest { | 15 class ExtensionAPIClientTest : public RenderViewTest { |
| 12 protected: | 16 protected: |
| 13 virtual void SetUp() { | 17 virtual void SetUp() { |
| 14 RenderViewTest::SetUp(); | 18 RenderViewTest::SetUp(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 27 render_thread_.sink().ClearMessages(); | 31 render_thread_.sink().ClearMessages(); |
| 28 return WideToASCII(params.a); | 32 return WideToASCII(params.a); |
| 29 } else { | 33 } else { |
| 30 return ""; | 34 return ""; |
| 31 } | 35 } |
| 32 } | 36 } |
| 33 | 37 |
| 34 void ExpectJsFail(const std::string& js, const std::string& message) { | 38 void ExpectJsFail(const std::string& js, const std::string& message) { |
| 35 ExecuteJavaScript(js.c_str()); | 39 ExecuteJavaScript(js.c_str()); |
| 36 EXPECT_EQ(message, GetConsoleMessage()); | 40 EXPECT_EQ(message, GetConsoleMessage()); |
| 41 render_thread_.sink().ClearMessages(); |
| 42 } |
| 43 |
| 44 void ExpectJsPass(const std::string& js, |
| 45 const std::string& function, |
| 46 const std::string& arg1) { |
| 47 ExecuteJavaScript(js.c_str()); |
| 48 const IPC::Message* request_msg = |
| 49 render_thread_.sink().GetUniqueMessageMatching( |
| 50 ViewHostMsg_ExtensionRequest::ID); |
| 51 ASSERT_EQ("", GetConsoleMessage()) << js; |
| 52 ASSERT_TRUE(request_msg) << js; |
| 53 ViewHostMsg_ExtensionRequest::Param params; |
| 54 ViewHostMsg_ExtensionRequest::Read(request_msg, ¶ms); |
| 55 ASSERT_EQ(function.c_str(), params.a) << js; |
| 56 ASSERT_EQ(arg1.c_str(), params.b) << js; |
| 57 render_thread_.sink().ClearMessages(); |
| 37 } | 58 } |
| 38 }; | 59 }; |
| 39 | 60 |
| 40 // Tests that callback dispatching works correctly and that JSON is properly | 61 // Tests that callback dispatching works correctly and that JSON is properly |
| 41 // deserialized before handing off to the extension code. We use the createTab | 62 // deserialized before handing off to the extension code. We use the createTab |
| 42 // API here, but we could use any of them since they all dispatch callbacks the | 63 // API here, but we could use any of them since they all dispatch callbacks the |
| 43 // same way. | 64 // same way. |
| 44 TEST_F(ExtensionAPIClientTest, CallbackDispatching) { | 65 TEST_F(ExtensionAPIClientTest, CallbackDispatching) { |
| 45 ExecuteJavaScript( | 66 ExecuteJavaScript( |
| 46 "function assert(truth, message) {" | 67 "function assert(truth, message) {" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 } | 99 } |
| 79 | 100 |
| 80 // The remainder of these tests exercise the client side of the various | 101 // The remainder of these tests exercise the client side of the various |
| 81 // extension functions. We test both error and success conditions, but do not | 102 // extension functions. We test both error and success conditions, but do not |
| 82 // test errors exhaustively as json schema code is well tested by itself. | 103 // test errors exhaustively as json schema code is well tested by itself. |
| 83 | 104 |
| 84 TEST_F(ExtensionAPIClientTest, GetTabsForWindow) { | 105 TEST_F(ExtensionAPIClientTest, GetTabsForWindow) { |
| 85 ExpectJsFail("chromium.tabs.getTabsForWindow(42, function(){});", | 106 ExpectJsFail("chromium.tabs.getTabsForWindow(42, function(){});", |
| 86 "Uncaught Error: Too many arguments."); | 107 "Uncaught Error: Too many arguments."); |
| 87 | 108 |
| 88 ExecuteJavaScript("chromium.tabs.getTabsForWindow(function(){})"); | 109 ExpectJsPass("chromium.tabs.getTabsForWindow(function(){})", |
| 89 const IPC::Message* request_msg = | 110 "GetTabsForWindow", "null"); |
| 90 render_thread_.sink().GetUniqueMessageMatching( | |
| 91 ViewHostMsg_ExtensionRequest::ID); | |
| 92 ASSERT_TRUE(request_msg); | |
| 93 ViewHostMsg_ExtensionRequest::Param params; | |
| 94 ViewHostMsg_ExtensionRequest::Read(request_msg, ¶ms); | |
| 95 ASSERT_EQ("GetTabsForWindow", params.a); | |
| 96 ASSERT_EQ("null", params.b); | |
| 97 } | 111 } |
| 98 | 112 |
| 99 TEST_F(ExtensionAPIClientTest, GetTab) { | 113 TEST_F(ExtensionAPIClientTest, GetTab) { |
| 100 ExpectJsFail("chromium.tabs.getTab(null, function(){});", | 114 ExpectJsFail("chromium.tabs.getTab(null, function(){});", |
| 101 "Uncaught Error: Parameter 0 is required."); | 115 "Uncaught Error: Parameter 0 is required."); |
| 102 | 116 |
| 103 ExecuteJavaScript("chromium.tabs.getTab(42)"); | 117 ExpectJsPass("chromium.tabs.getTab(42)", "GetTab", "42"); |
| 104 const IPC::Message* request_msg = | |
| 105 render_thread_.sink().GetUniqueMessageMatching( | |
| 106 ViewHostMsg_ExtensionRequest::ID); | |
| 107 ASSERT_TRUE(request_msg); | |
| 108 ViewHostMsg_ExtensionRequest::Param params; | |
| 109 ViewHostMsg_ExtensionRequest::Read(request_msg, ¶ms); | |
| 110 ASSERT_EQ("GetTab", params.a); | |
| 111 ASSERT_EQ("42", params.b); | |
| 112 } | 118 } |
| 113 | 119 |
| 114 TEST_F(ExtensionAPIClientTest, CreateTab) { | 120 TEST_F(ExtensionAPIClientTest, CreateTab) { |
| 115 ExpectJsFail("chromium.tabs.createTab({windowId: 'foo'}, function(){});", | 121 ExpectJsFail("chromium.tabs.createTab({windowId: 'foo'}, function(){});", |
| 116 "Uncaught Error: Invalid value for argument 0. Property " | 122 "Uncaught Error: Invalid value for argument 0. Property " |
| 117 "'windowId': Expected 'integer' but got 'string'."); | 123 "'windowId': Expected 'integer' but got 'string'."); |
| 118 ExpectJsFail("chromium.tabs.createTab({url: 42}, function(){});", | 124 ExpectJsFail("chromium.tabs.createTab({url: 42}, function(){});", |
| 119 "Uncaught Error: Invalid value for argument 0. Property " | 125 "Uncaught Error: Invalid value for argument 0. Property " |
| 120 "'url': Expected 'string' but got 'integer'."); | 126 "'url': Expected 'string' but got 'integer'."); |
| 121 ExpectJsFail("chromium.tabs.createTab({foo: 42}, function(){});", | 127 ExpectJsFail("chromium.tabs.createTab({foo: 42}, function(){});", |
| 122 "Uncaught Error: Invalid value for argument 0. Property " | 128 "Uncaught Error: Invalid value for argument 0. Property " |
| 123 "'foo': Unexpected property."); | 129 "'foo': Unexpected property."); |
| 124 | 130 |
| 125 ExecuteJavaScript("chromium.tabs.createTab({" | 131 ExpectJsPass("chromium.tabs.createTab({" |
| 126 " url:'http://www.google.com/'," | 132 " url:'http://www.google.com/'," |
| 127 " selected:true," | 133 " selected:true," |
| 128 " windowId:4" | 134 " windowId:4" |
| 129 "})"); | 135 "})", |
| 130 const IPC::Message* request_msg = | 136 "CreateTab", |
| 131 render_thread_.sink().GetUniqueMessageMatching( | 137 "{\"url\":\"http://www.google.com/\"," |
| 132 ViewHostMsg_ExtensionRequest::ID); | 138 "\"selected\":true," |
| 133 ASSERT_TRUE(request_msg); | 139 "\"windowId\":4}"); |
| 134 ViewHostMsg_ExtensionRequest::Param params; | |
| 135 ViewHostMsg_ExtensionRequest::Read(request_msg, ¶ms); | |
| 136 ASSERT_EQ("CreateTab", params.a); | |
| 137 ASSERT_EQ("{\"url\":\"http://www.google.com/\"," | |
| 138 "\"selected\":true," | |
| 139 "\"windowId\":4}", params.b); | |
| 140 } | 140 } |
| 141 | 141 |
| 142 TEST_F(ExtensionAPIClientTest, UpdateTab) { | 142 TEST_F(ExtensionAPIClientTest, UpdateTab) { |
| 143 ExpectJsFail("chromium.tabs.updateTab({id: null});", | 143 ExpectJsFail("chromium.tabs.updateTab({id: null});", |
| 144 "Uncaught Error: Invalid value for argument 0. Property " | 144 "Uncaught Error: Invalid value for argument 0. Property " |
| 145 "'id': Property is required."); | 145 "'id': Property is required."); |
| 146 ExpectJsFail("chromium.tabs.updateTab({id: 42, windowId: 'foo'});", | 146 ExpectJsFail("chromium.tabs.updateTab({id: 42, windowId: 'foo'});", |
| 147 "Uncaught Error: Invalid value for argument 0. Property " | 147 "Uncaught Error: Invalid value for argument 0. Property " |
| 148 "'windowId': Expected 'integer' but got 'string'."); | 148 "'windowId': Expected 'integer' but got 'string'."); |
| 149 ExpectJsFail("chromium.tabs.updateTab({id: 42, url: 42});", | 149 ExpectJsFail("chromium.tabs.updateTab({id: 42, url: 42});", |
| 150 "Uncaught Error: Invalid value for argument 0. Property " | 150 "Uncaught Error: Invalid value for argument 0. Property " |
| 151 "'url': Expected 'string' but got 'integer'."); | 151 "'url': Expected 'string' but got 'integer'."); |
| 152 | 152 |
| 153 ExecuteJavaScript("chromium.tabs.updateTab({" | 153 ExpectJsPass("chromium.tabs.updateTab({" |
| 154 " id:42," | 154 " id:42," |
| 155 " url:'http://www.google.com/'," | 155 " url:'http://www.google.com/'," |
| 156 " selected:true," | 156 " selected:true," |
| 157 " windowId:4" | 157 " windowId:4" |
| 158 "})"); | 158 "})", |
| 159 const IPC::Message* request_msg = | 159 "UpdateTab", |
| 160 render_thread_.sink().GetUniqueMessageMatching( | 160 "{\"id\":42," |
| 161 ViewHostMsg_ExtensionRequest::ID); | 161 "\"url\":\"http://www.google.com/\"," |
| 162 ASSERT_TRUE(request_msg); | 162 "\"selected\":true," |
| 163 ViewHostMsg_ExtensionRequest::Param params; | 163 "\"windowId\":4}"); |
| 164 ViewHostMsg_ExtensionRequest::Read(request_msg, ¶ms); | |
| 165 ASSERT_EQ("UpdateTab", params.a); | |
| 166 ASSERT_EQ("{\"id\":42," | |
| 167 "\"url\":\"http://www.google.com/\"," | |
| 168 "\"selected\":true," | |
| 169 "\"windowId\":4}", params.b); | |
| 170 } | 164 } |
| 171 | 165 |
| 172 TEST_F(ExtensionAPIClientTest, RemoveTab) { | 166 TEST_F(ExtensionAPIClientTest, RemoveTab) { |
| 173 ExpectJsFail("chromium.tabs.removeTab('foobar', function(){});", | 167 ExpectJsFail("chromium.tabs.removeTab('foobar', function(){});", |
| 174 "Uncaught Error: Too many arguments."); | 168 "Uncaught Error: Too many arguments."); |
| 175 | 169 |
| 176 ExecuteJavaScript("chromium.tabs.removeTab(21)"); | 170 ExpectJsPass("chromium.tabs.removeTab(21)", "RemoveTab", "21"); |
| 177 const IPC::Message* request_msg = | |
| 178 render_thread_.sink().GetUniqueMessageMatching( | |
| 179 ViewHostMsg_ExtensionRequest::ID); | |
| 180 ASSERT_TRUE(request_msg); | |
| 181 ViewHostMsg_ExtensionRequest::Param params; | |
| 182 ViewHostMsg_ExtensionRequest::Read(request_msg, ¶ms); | |
| 183 ASSERT_EQ("RemoveTab", params.a); | |
| 184 ASSERT_EQ("21", params.b); | |
| 185 } | 171 } |
| 172 |
| 173 // Bookmark API tests |
| 174 // TODO(erikkay) add more variations here |
| 175 |
| 176 TEST_F(ExtensionAPIClientTest, CreateBookmark) { |
| 177 ExpectJsFail( |
| 178 "chromium.bookmarks.create({parentId:'x', title:0}, function(){})", |
| 179 "Uncaught Error: Invalid value for argument 0. " |
| 180 "Property 'parentId': Expected 'integer' but got 'string', " |
| 181 "Property 'title': Expected 'string' but got 'integer'."); |
| 182 |
| 183 ExpectJsPass( |
| 184 "chromium.bookmarks.create({parentId:0, title:'x'}, function(){})", |
| 185 "CreateBookmark", |
| 186 "{\"parentId\":0,\"title\":\"x\"}"); |
| 187 } |
| 188 |
| 189 TEST_F(ExtensionAPIClientTest, GetBookmarks) { |
| 190 ExpectJsPass("chromium.bookmarks.get([], function(){});", |
| 191 "GetBookmarks", |
| 192 "[]"); |
| 193 ExpectJsPass("chromium.bookmarks.get([0,1,2,3], function(){});", |
| 194 "GetBookmarks", |
| 195 "[0,1,2,3]"); |
| 196 ExpectJsPass("chromium.bookmarks.get(null, function(){});", |
| 197 "GetBookmarks", |
| 198 "null"); |
| 199 ExpectJsFail("chromium.bookmarks.get({}, function(){});", |
| 200 "Uncaught Error: Invalid value for argument 0. " |
| 201 "Expected 'array' but got 'object'."); |
| 202 } |
| 203 |
| 204 TEST_F(ExtensionAPIClientTest, GetBookmarkChildren) { |
| 205 ExpectJsPass("chromium.bookmarks.getChildren(42, function(){});", |
| 206 "GetBookmarkChildren", |
| 207 "42"); |
| 208 } |
| 209 |
| 210 TEST_F(ExtensionAPIClientTest, GetBookmarkTree) { |
| 211 ExpectJsPass("chromium.bookmarks.getTree(function(){});", |
| 212 "GetBookmarkTree", |
| 213 "null"); |
| 214 } |
| 215 |
| 216 TEST_F(ExtensionAPIClientTest, SearchBookmarks) { |
| 217 ExpectJsPass("chromium.bookmarks.search('hello',function(){});", |
| 218 "SearchBookmarks", |
| 219 "\"hello\""); |
| 220 } |
| 221 |
| 222 TEST_F(ExtensionAPIClientTest, RemoveBookmark) { |
| 223 ExpectJsPass("chromium.bookmarks.remove({id:42});", |
| 224 "RemoveBookmark", |
| 225 "{\"id\":42}"); |
| 226 } |
| 227 |
| 228 TEST_F(ExtensionAPIClientTest, MoveBookmark) { |
| 229 ExpectJsPass("chromium.bookmarks.move({id:42,parentId:1,index:0});", |
| 230 "MoveBookmark", |
| 231 "{\"id\":42,\"parentId\":1,\"index\":0}"); |
| 232 } |
| 233 |
| 234 TEST_F(ExtensionAPIClientTest, SetBookmarkTitle) { |
| 235 ExpectJsPass("chromium.bookmarks.setTitle({id:42,title:'x'});", |
| 236 "SetBookmarkTitle", |
| 237 "{\"id\":42,\"title\":\"x\"}"); |
| 238 } |
| 239 |
| OLD | NEW |