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 |