| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/json/json_value_serializer.h" | 10 #include "base/json/json_value_serializer.h" |
| 11 #import "base/memory/scoped_nsobject.h" | 11 #import "base/memory/scoped_nsobject.h" |
| 12 #include "base/path_service.h" | 12 #include "base/path_service.h" |
| 13 #include "base/sys_string_conversions.h" | 13 #include "base/sys_string_conversions.h" |
| 14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 15 #include "base/values.h" | 15 #include "base/values.h" |
| 16 #import "chrome/browser/extensions/extension_install_ui.h" | 16 #import "chrome/browser/extensions/extension_install_ui.h" |
| 17 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" | 17 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" |
| 18 #import "chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.
h" | 18 #import "chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.
h" |
| 19 #include "chrome/common/chrome_paths.h" | 19 #include "chrome/common/chrome_paths.h" |
| 20 #include "chrome/common/extensions/extension.h" | 20 #include "chrome/common/extensions/extension.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 22 #import "testing/gtest_mac.h" | 22 #import "testing/gtest_mac.h" |
| 23 #include "testing/platform_test.h" | 23 #include "testing/platform_test.h" |
| 24 #include "third_party/skia/include/core/SkBitmap.h" | 24 #include "third_party/skia/include/core/SkBitmap.h" |
| 25 #include "ui/gfx/image/image.h" |
| 25 #include "webkit/glue/image_decoder.h" | 26 #include "webkit/glue/image_decoder.h" |
| 26 | 27 |
| 27 | 28 |
| 28 // Base class for our tests. | 29 // Base class for our tests. |
| 29 class ExtensionInstallDialogControllerTest : public CocoaProfileTest { | 30 class ExtensionInstallDialogControllerTest : public CocoaProfileTest { |
| 30 public: | 31 public: |
| 31 ExtensionInstallDialogControllerTest() { | 32 ExtensionInstallDialogControllerTest() { |
| 32 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); | 33 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); |
| 33 test_data_dir_ = test_data_dir_.AppendASCII("extensions") | 34 test_data_dir_ = test_data_dir_.AppendASCII("extensions") |
| 34 .AppendASCII("install_prompt"); | 35 .AppendASCII("install_prompt"); |
| 35 | 36 |
| 36 LoadIcon(); | 37 LoadIcon(); |
| 37 LoadExtension(); | 38 LoadExtension(); |
| 38 } | 39 } |
| 39 | 40 |
| 40 protected: | 41 protected: |
| 41 void LoadIcon() { | 42 void LoadIcon() { |
| 42 std::string file_contents; | 43 std::string file_contents; |
| 43 file_util::ReadFileToString(test_data_dir_.AppendASCII("icon.png"), | 44 file_util::ReadFileToString(test_data_dir_.AppendASCII("icon.png"), |
| 44 &file_contents); | 45 &file_contents); |
| 45 | 46 |
| 46 webkit_glue::ImageDecoder decoder; | 47 webkit_glue::ImageDecoder decoder; |
| 47 icon_ = decoder.Decode( | 48 SkBitmap bitmap = decoder.Decode( |
| 48 reinterpret_cast<const unsigned char*>(file_contents.c_str()), | 49 reinterpret_cast<const unsigned char*>(file_contents.c_str()), |
| 49 file_contents.length()); | 50 file_contents.length()); |
| 51 icon_ = gfx::Image(new SkBitmap(bitmap)); |
| 50 } | 52 } |
| 51 | 53 |
| 52 void LoadExtension() { | 54 void LoadExtension() { |
| 53 FilePath path = test_data_dir_.AppendASCII("extension.json"); | 55 FilePath path = test_data_dir_.AppendASCII("extension.json"); |
| 54 | 56 |
| 55 std::string error; | 57 std::string error; |
| 56 JSONFileValueSerializer serializer(path); | 58 JSONFileValueSerializer serializer(path); |
| 57 scoped_ptr<DictionaryValue> value(static_cast<DictionaryValue*>( | 59 scoped_ptr<DictionaryValue> value(static_cast<DictionaryValue*>( |
| 58 serializer.Deserialize(NULL, &error))); | 60 serializer.Deserialize(NULL, &error))); |
| 59 if (!value.get()) { | 61 if (!value.get()) { |
| 60 LOG(ERROR) << error; | 62 LOG(ERROR) << error; |
| 61 return; | 63 return; |
| 62 } | 64 } |
| 63 | 65 |
| 64 extension_ = Extension::Create(path.DirName(), Extension::INVALID, *value, | 66 extension_ = Extension::Create(path.DirName(), Extension::INVALID, *value, |
| 65 Extension::STRICT_ERROR_CHECKS, &error); | 67 Extension::STRICT_ERROR_CHECKS, &error); |
| 66 if (!extension_.get()) { | 68 if (!extension_.get()) { |
| 67 LOG(ERROR) << error; | 69 LOG(ERROR) << error; |
| 68 return; | 70 return; |
| 69 } | 71 } |
| 70 } | 72 } |
| 71 | 73 |
| 72 FilePath test_data_dir_; | 74 FilePath test_data_dir_; |
| 73 SkBitmap icon_; | 75 gfx::Image icon_; |
| 74 scoped_refptr<Extension> extension_; | 76 scoped_refptr<Extension> extension_; |
| 75 }; | 77 }; |
| 76 | 78 |
| 77 | 79 |
| 78 // Mock out the ExtensionInstallUI::Delegate interface so we can ensure the | 80 // Mock out the ExtensionInstallUI::Delegate interface so we can ensure the |
| 79 // dialog is interacting with it correctly. | 81 // dialog is interacting with it correctly. |
| 80 class MockExtensionInstallUIDelegate : public ExtensionInstallUI::Delegate { | 82 class MockExtensionInstallUIDelegate : public ExtensionInstallUI::Delegate { |
| 81 public: | 83 public: |
| 82 MockExtensionInstallUIDelegate() | 84 MockExtensionInstallUIDelegate() |
| 83 : proceed_count_(0), | 85 : proceed_count_(0), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 102 | 104 |
| 103 // Test that we can load the two kinds of prompts correctly, that the outlets | 105 // Test that we can load the two kinds of prompts correctly, that the outlets |
| 104 // are hooked up, and that the dialog calls cancel when cancel is pressed. | 106 // are hooked up, and that the dialog calls cancel when cancel is pressed. |
| 105 TEST_F(ExtensionInstallDialogControllerTest, BasicsNormalCancel) { | 107 TEST_F(ExtensionInstallDialogControllerTest, BasicsNormalCancel) { |
| 106 MockExtensionInstallUIDelegate delegate; | 108 MockExtensionInstallUIDelegate delegate; |
| 107 | 109 |
| 108 ExtensionInstallUI::Prompt prompt(ExtensionInstallUI::INSTALL_PROMPT); | 110 ExtensionInstallUI::Prompt prompt(ExtensionInstallUI::INSTALL_PROMPT); |
| 109 std::vector<string16> permissions; | 111 std::vector<string16> permissions; |
| 110 permissions.push_back(UTF8ToUTF16("warning 1")); | 112 permissions.push_back(UTF8ToUTF16("warning 1")); |
| 111 prompt.SetPermissions(permissions); | 113 prompt.SetPermissions(permissions); |
| 114 prompt.set_extension(extension_.get()); |
| 115 prompt.set_icon(icon_); |
| 112 | 116 |
| 113 scoped_nsobject<ExtensionInstallDialogController> | 117 scoped_nsobject<ExtensionInstallDialogController> |
| 114 controller([[ExtensionInstallDialogController alloc] | 118 controller([[ExtensionInstallDialogController alloc] |
| 115 initWithParentWindow:test_window() | 119 initWithParentWindow:test_window() |
| 116 profile:profile() | 120 profile:profile() |
| 117 extension:extension_.get() | |
| 118 delegate:&delegate | 121 delegate:&delegate |
| 119 icon:&icon_ | |
| 120 prompt:prompt]); | 122 prompt:prompt]); |
| 121 | 123 |
| 122 [controller window]; // force nib load | 124 [controller window]; // force nib load |
| 123 | 125 |
| 124 // Test the right nib loaded. | 126 // Test the right nib loaded. |
| 125 EXPECT_NSEQ(@"ExtensionInstallPrompt", [controller windowNibName]); | 127 EXPECT_NSEQ(@"ExtensionInstallPrompt", [controller windowNibName]); |
| 126 | 128 |
| 127 // Check all the controls. | 129 // Check all the controls. |
| 128 // Make sure everything is non-nil, and that the fields that are | 130 // Make sure everything is non-nil, and that the fields that are |
| 129 // auto-translated don't start with a caret (that would indicate that they | 131 // auto-translated don't start with a caret (that would indicate that they |
| (...skipping 27 matching lines...) Expand all Loading... |
| 157 } | 159 } |
| 158 | 160 |
| 159 | 161 |
| 160 TEST_F(ExtensionInstallDialogControllerTest, BasicsNormalOK) { | 162 TEST_F(ExtensionInstallDialogControllerTest, BasicsNormalOK) { |
| 161 MockExtensionInstallUIDelegate delegate; | 163 MockExtensionInstallUIDelegate delegate; |
| 162 | 164 |
| 163 ExtensionInstallUI::Prompt prompt(ExtensionInstallUI::INSTALL_PROMPT); | 165 ExtensionInstallUI::Prompt prompt(ExtensionInstallUI::INSTALL_PROMPT); |
| 164 std::vector<string16> permissions; | 166 std::vector<string16> permissions; |
| 165 permissions.push_back(UTF8ToUTF16("warning 1")); | 167 permissions.push_back(UTF8ToUTF16("warning 1")); |
| 166 prompt.SetPermissions(permissions); | 168 prompt.SetPermissions(permissions); |
| 169 prompt.set_extension(extension_.get()); |
| 170 prompt.set_icon(icon_); |
| 167 | 171 |
| 168 scoped_nsobject<ExtensionInstallDialogController> | 172 scoped_nsobject<ExtensionInstallDialogController> |
| 169 controller([[ExtensionInstallDialogController alloc] | 173 controller([[ExtensionInstallDialogController alloc] |
| 170 initWithParentWindow:test_window() | 174 initWithParentWindow:test_window() |
| 171 profile:profile() | 175 profile:profile() |
| 172 extension:extension_.get() | |
| 173 delegate:&delegate | 176 delegate:&delegate |
| 174 icon:&icon_ | |
| 175 prompt:prompt]); | 177 prompt:prompt]); |
| 176 | 178 |
| 177 [controller window]; // force nib load | 179 [controller window]; // force nib load |
| 178 [controller ok:nil]; | 180 [controller ok:nil]; |
| 179 | 181 |
| 180 EXPECT_EQ(0, delegate.abort_count()); | 182 EXPECT_EQ(0, delegate.abort_count()); |
| 181 EXPECT_EQ(1, delegate.proceed_count()); | 183 EXPECT_EQ(1, delegate.proceed_count()); |
| 182 } | 184 } |
| 183 | 185 |
| 184 // Test that controls get repositioned when there are two warnings vs one | 186 // Test that controls get repositioned when there are two warnings vs one |
| 185 // warning. | 187 // warning. |
| 186 TEST_F(ExtensionInstallDialogControllerTest, MultipleWarnings) { | 188 TEST_F(ExtensionInstallDialogControllerTest, MultipleWarnings) { |
| 187 MockExtensionInstallUIDelegate delegate1; | 189 MockExtensionInstallUIDelegate delegate1; |
| 188 MockExtensionInstallUIDelegate delegate2; | 190 MockExtensionInstallUIDelegate delegate2; |
| 189 | 191 |
| 190 ExtensionInstallUI::Prompt one_warning_prompt( | 192 ExtensionInstallUI::Prompt one_warning_prompt( |
| 191 ExtensionInstallUI::INSTALL_PROMPT); | 193 ExtensionInstallUI::INSTALL_PROMPT); |
| 192 std::vector<string16> permissions; | 194 std::vector<string16> permissions; |
| 193 permissions.push_back(UTF8ToUTF16("warning 1")); | 195 permissions.push_back(UTF8ToUTF16("warning 1")); |
| 194 one_warning_prompt.SetPermissions(permissions); | 196 one_warning_prompt.SetPermissions(permissions); |
| 197 one_warning_prompt.set_extension(extension_.get()); |
| 198 one_warning_prompt.set_icon(icon_); |
| 195 | 199 |
| 196 ExtensionInstallUI::Prompt two_warnings_prompt( | 200 ExtensionInstallUI::Prompt two_warnings_prompt( |
| 197 ExtensionInstallUI::INSTALL_PROMPT); | 201 ExtensionInstallUI::INSTALL_PROMPT); |
| 198 permissions.push_back(UTF8ToUTF16("warning 2")); | 202 permissions.push_back(UTF8ToUTF16("warning 2")); |
| 199 two_warnings_prompt.SetPermissions(permissions); | 203 two_warnings_prompt.SetPermissions(permissions); |
| 204 two_warnings_prompt.set_extension(extension_.get()); |
| 205 two_warnings_prompt.set_icon(icon_); |
| 200 | 206 |
| 201 scoped_nsobject<ExtensionInstallDialogController> | 207 scoped_nsobject<ExtensionInstallDialogController> |
| 202 controller1([[ExtensionInstallDialogController alloc] | 208 controller1([[ExtensionInstallDialogController alloc] |
| 203 initWithParentWindow:test_window() | 209 initWithParentWindow:test_window() |
| 204 profile:profile() | 210 profile:profile() |
| 205 extension:extension_.get() | |
| 206 delegate:&delegate1 | 211 delegate:&delegate1 |
| 207 icon:&icon_ | |
| 208 prompt:one_warning_prompt]); | 212 prompt:one_warning_prompt]); |
| 209 | 213 |
| 210 [controller1 window]; // force nib load | 214 [controller1 window]; // force nib load |
| 211 | 215 |
| 212 scoped_nsobject<ExtensionInstallDialogController> | 216 scoped_nsobject<ExtensionInstallDialogController> |
| 213 controller2([[ExtensionInstallDialogController alloc] | 217 controller2([[ExtensionInstallDialogController alloc] |
| 214 initWithParentWindow:test_window() | 218 initWithParentWindow:test_window() |
| 215 profile:profile() | 219 profile:profile() |
| 216 extension:extension_.get() | |
| 217 delegate:&delegate2 | 220 delegate:&delegate2 |
| 218 icon:&icon_ | |
| 219 prompt:two_warnings_prompt]); | 221 prompt:two_warnings_prompt]); |
| 220 | 222 |
| 221 [controller2 window]; // force nib load | 223 [controller2 window]; // force nib load |
| 222 | 224 |
| 223 // Test control positioning. We don't test exact positioning because we don't | 225 // Test control positioning. We don't test exact positioning because we don't |
| 224 // want this to depend on string details and localization. But we do know the | 226 // want this to depend on string details and localization. But we do know the |
| 225 // relative effect that adding a second warning should have on the layout. | 227 // relative effect that adding a second warning should have on the layout. |
| 226 ASSERT_LT([[controller1 window] frame].size.height, | 228 ASSERT_LT([[controller1 window] frame].size.height, |
| 227 [[controller2 window] frame].size.height); | 229 [[controller2 window] frame].size.height); |
| 228 | 230 |
| 229 ASSERT_LT([[controller1 warningsField] frame].size.height, | 231 ASSERT_LT([[controller1 warningsField] frame].size.height, |
| 230 [[controller2 warningsField] frame].size.height); | 232 [[controller2 warningsField] frame].size.height); |
| 231 | 233 |
| 232 ASSERT_LT([[controller1 subtitleField] frame].origin.y, | 234 ASSERT_LT([[controller1 subtitleField] frame].origin.y, |
| 233 [[controller2 subtitleField] frame].origin.y); | 235 [[controller2 subtitleField] frame].origin.y); |
| 234 | 236 |
| 235 ASSERT_LT([[controller1 titleField] frame].origin.y, | 237 ASSERT_LT([[controller1 titleField] frame].origin.y, |
| 236 [[controller2 titleField] frame].origin.y); | 238 [[controller2 titleField] frame].origin.y); |
| 237 } | 239 } |
| 238 | 240 |
| 239 // Test that we can load the skinny prompt correctly, and that the outlets are | 241 // Test that we can load the skinny prompt correctly, and that the outlets are |
| 240 // are hooked up. | 242 // are hooked up. |
| 241 TEST_F(ExtensionInstallDialogControllerTest, BasicsSkinny) { | 243 TEST_F(ExtensionInstallDialogControllerTest, BasicsSkinny) { |
| 242 MockExtensionInstallUIDelegate delegate; | 244 MockExtensionInstallUIDelegate delegate; |
| 243 | 245 |
| 244 // No warnings should trigger skinny prompt. | 246 // No warnings should trigger skinny prompt. |
| 245 ExtensionInstallUI::Prompt no_warnings_prompt( | 247 ExtensionInstallUI::Prompt no_warnings_prompt( |
| 246 ExtensionInstallUI::INSTALL_PROMPT); | 248 ExtensionInstallUI::INSTALL_PROMPT); |
| 249 no_warnings_prompt.set_extension(extension_.get()); |
| 250 no_warnings_prompt.set_icon(icon_); |
| 247 | 251 |
| 248 scoped_nsobject<ExtensionInstallDialogController> | 252 scoped_nsobject<ExtensionInstallDialogController> |
| 249 controller([[ExtensionInstallDialogController alloc] | 253 controller([[ExtensionInstallDialogController alloc] |
| 250 initWithParentWindow:test_window() | 254 initWithParentWindow:test_window() |
| 251 profile:profile() | 255 profile:profile() |
| 252 extension:extension_.get() | |
| 253 delegate:&delegate | 256 delegate:&delegate |
| 254 icon:&icon_ | |
| 255 prompt:no_warnings_prompt]); | 257 prompt:no_warnings_prompt]); |
| 256 | 258 |
| 257 [controller window]; // force nib load | 259 [controller window]; // force nib load |
| 258 | 260 |
| 259 // Test the right nib loaded. | 261 // Test the right nib loaded. |
| 260 EXPECT_NSEQ(@"ExtensionInstallPromptNoWarnings", [controller windowNibName]); | 262 EXPECT_NSEQ(@"ExtensionInstallPromptNoWarnings", [controller windowNibName]); |
| 261 | 263 |
| 262 // Check all the controls. | 264 // Check all the controls. |
| 263 // In the skinny prompt, only the icon, title and buttons are non-nill. | 265 // In the skinny prompt, only the icon, title and buttons are non-nill. |
| 264 // Everything else is nil. | 266 // Everything else is nil. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 283 | 285 |
| 284 // Test that we can load the inline prompt correctly, and that the outlets are | 286 // Test that we can load the inline prompt correctly, and that the outlets are |
| 285 // are hooked up. | 287 // are hooked up. |
| 286 TEST_F(ExtensionInstallDialogControllerTest, BasicsInline) { | 288 TEST_F(ExtensionInstallDialogControllerTest, BasicsInline) { |
| 287 MockExtensionInstallUIDelegate delegate; | 289 MockExtensionInstallUIDelegate delegate; |
| 288 | 290 |
| 289 // No warnings should trigger skinny prompt. | 291 // No warnings should trigger skinny prompt. |
| 290 ExtensionInstallUI::Prompt inline_prompt( | 292 ExtensionInstallUI::Prompt inline_prompt( |
| 291 ExtensionInstallUI::INLINE_INSTALL_PROMPT); | 293 ExtensionInstallUI::INLINE_INSTALL_PROMPT); |
| 292 inline_prompt.SetInlineInstallWebstoreData("1,000", 3.5, 200); | 294 inline_prompt.SetInlineInstallWebstoreData("1,000", 3.5, 200); |
| 295 inline_prompt.set_extension(extension_.get()); |
| 296 inline_prompt.set_icon(icon_); |
| 293 | 297 |
| 294 scoped_nsobject<ExtensionInstallDialogController> | 298 scoped_nsobject<ExtensionInstallDialogController> |
| 295 controller([[ExtensionInstallDialogController alloc] | 299 controller([[ExtensionInstallDialogController alloc] |
| 296 initWithParentWindow:test_window() | 300 initWithParentWindow:test_window() |
| 297 profile:profile() | 301 profile:profile() |
| 298 extension:extension_.get() | |
| 299 delegate:&delegate | 302 delegate:&delegate |
| 300 icon:&icon_ | |
| 301 prompt:inline_prompt]); | 303 prompt:inline_prompt]); |
| 302 | 304 |
| 303 [controller window]; // force nib load | 305 [controller window]; // force nib load |
| 304 | 306 |
| 305 // Test the right nib loaded. | 307 // Test the right nib loaded. |
| 306 EXPECT_NSEQ(@"ExtensionInstallPromptInline", [controller windowNibName]); | 308 EXPECT_NSEQ(@"ExtensionInstallPromptInline", [controller windowNibName]); |
| 307 | 309 |
| 308 // Check all the controls. | 310 // Check all the controls. |
| 309 EXPECT_TRUE([controller iconView] != nil); | 311 EXPECT_TRUE([controller iconView] != nil); |
| 310 EXPECT_TRUE([[controller iconView] image] != nil); | 312 EXPECT_TRUE([[controller iconView] image] != nil); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 331 | 333 |
| 332 // Though we have no permissions warnings, these should still be hooked up, | 334 // Though we have no permissions warnings, these should still be hooked up, |
| 333 // just invisible. | 335 // just invisible. |
| 334 EXPECT_TRUE([controller subtitleField] != nil); | 336 EXPECT_TRUE([controller subtitleField] != nil); |
| 335 EXPECT_TRUE([[controller subtitleField] isHidden]); | 337 EXPECT_TRUE([[controller subtitleField] isHidden]); |
| 336 EXPECT_TRUE([controller warningsField] != nil); | 338 EXPECT_TRUE([controller warningsField] != nil); |
| 337 EXPECT_TRUE([[controller warningsField] isHidden]); | 339 EXPECT_TRUE([[controller warningsField] isHidden]); |
| 338 EXPECT_TRUE([controller warningsSeparator] != nil); | 340 EXPECT_TRUE([controller warningsSeparator] != nil); |
| 339 EXPECT_TRUE([[controller warningsSeparator] isHidden]); | 341 EXPECT_TRUE([[controller warningsSeparator] isHidden]); |
| 340 } | 342 } |
| OLD | NEW |