summaryrefslogtreecommitdiffstats
path: root/chrome_frame/chrome_frame_npapi_unittest.cc
diff options
context:
space:
mode:
authorslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
committerslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
commitf781782dd67077478e117c61dca4ea5eefce3544 (patch)
tree4801f724123cfdcbb69c4e7fe40a565b331723ae /chrome_frame/chrome_frame_npapi_unittest.cc
parent63cf4759efa2373e33436fb5df6849f930081226 (diff)
downloadchromium_src-f781782dd67077478e117c61dca4ea5eefce3544.zip
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.gz
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.bz2
Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming in a separate CL.
BUG=None TEST=None Review URL: http://codereview.chromium.org/218019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/chrome_frame_npapi_unittest.cc')
-rw-r--r--chrome_frame/chrome_frame_npapi_unittest.cc551
1 files changed, 551 insertions, 0 deletions
diff --git a/chrome_frame/chrome_frame_npapi_unittest.cc b/chrome_frame/chrome_frame_npapi_unittest.cc
new file mode 100644
index 0000000..d2c9b4e
--- /dev/null
+++ b/chrome_frame/chrome_frame_npapi_unittest.cc
@@ -0,0 +1,551 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "chrome_frame/chrome_frame_automation.h"
+#include "chrome_frame/chrome_frame_npapi.h"
+#include "chrome_frame/ff_privilege_check.h"
+
+
+TEST(ChromeFrameNPAPI, DoesNotCrashOnConstruction) {
+ ChromeFrameNPAPI* api = new ChromeFrameNPAPI();
+ delete api;
+}
+
+
+// All mocks in the anonymous namespace.
+namespace {
+
+using ::testing::_;
+using ::testing::Eq;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::StrEq;
+
+// Make mocking privilege test easy.
+class MockPrivilegeTest {
+ public:
+ MockPrivilegeTest() {
+ CHECK(current_ == NULL);
+ current_ = this;
+ }
+ ~MockPrivilegeTest() {
+ CHECK(current_ == this);
+ current_ = NULL;
+ }
+
+ MOCK_METHOD1(IsFireFoxPrivilegedInvocation, bool(NPP));
+
+ static MockPrivilegeTest* current() { return current_; }
+
+ private:
+ static MockPrivilegeTest* current_;
+};
+
+MockPrivilegeTest* MockPrivilegeTest::current_ = NULL;
+
+const char* kMimeType = "application/chromeframe";
+// The default profile name is by default derived from the currently
+// running executable's name.
+const wchar_t* kDefaultProfileName = L"chrome_frame_unittests";
+
+
+class MockNPAPI: public ChromeFrameNPAPI {
+ public:
+ MockNPAPI() : mock_automation_client_(NULL) {}
+
+ MOCK_METHOD0(CreatePrefService, NpProxyService*());
+
+ MOCK_METHOD0(GetLocation, std::string());
+ MOCK_METHOD0(GetBrowserIncognitoMode, bool());
+
+ MOCK_METHOD1(JavascriptToNPObject, virtual NPObject*(const std::string&));
+
+ // Make public for test purposes
+ void OnAutomationServerReady() {
+ ChromeFrameNPAPI::OnAutomationServerReady();
+ }
+
+ // Neuter this (or it dchecks during testing).
+ void SetReadyState(READYSTATE new_state) {}
+
+ ChromeFrameAutomationClient* CreateAutomationClient() {
+ return mock_automation_client_;
+ }
+
+ ChromeFrameAutomationClient* mock_automation_client_;
+};
+
+class MockAutomationClient: public ChromeFrameAutomationClient {
+ public:
+ MOCK_METHOD6(Initialize, bool(ChromeFrameDelegate*, int, bool,
+ const std::wstring&, const std::wstring&,
+ bool));
+ MOCK_METHOD1(SetEnableExtensionAutomation, void(bool)); // NOLINT
+};
+
+class MockProxyService: public NpProxyService {
+ public:
+ MOCK_METHOD2(Initialize, bool(NPP instance, ChromeFrameAutomationClient*));
+};
+
+
+// Test fixture to allow testing the privileged NPAPI APIs
+class TestNPAPIPrivilegedApi: public ::testing::Test {
+ public:
+ virtual void SetUp() {
+ memset(&instance, 0, sizeof(instance));
+
+ // Gets owned & destroyed by mock_api (in the
+ // ChromeFramePlugin<T>::Uninitialize() function).
+ mock_automation = new MockAutomationClient;
+
+ mock_api.mock_automation_client_ = mock_automation;
+ mock_proxy = new MockProxyService;
+ mock_proxy->AddRef();
+ mock_proxy_holder.Attach(mock_proxy);
+ }
+
+ virtual void TearDown() {
+ }
+
+ void SetupPrivilegeTest(bool is_incognito,
+ bool expect_privilege_check,
+ bool is_privileged,
+ const std::wstring& profile_name,
+ const std::wstring& extra_args) {
+ EXPECT_CALL(mock_api, GetLocation())
+ .WillOnce(Return(std::string("http://www.google.com")));
+ EXPECT_CALL(mock_api, CreatePrefService())
+ .WillOnce(Return(mock_proxy));
+ EXPECT_CALL(mock_api, GetBrowserIncognitoMode())
+ .WillOnce(Return(is_incognito));
+
+ EXPECT_CALL(*mock_proxy, Initialize(_, _)).WillRepeatedly(Return(false));
+
+ EXPECT_CALL(*mock_automation,
+ Initialize(_, _, true, StrEq(profile_name), StrEq(extra_args), false))
+ .WillOnce(Return(true));
+
+ if (expect_privilege_check) {
+ EXPECT_CALL(mock_priv, IsFireFoxPrivilegedInvocation(_))
+ .WillOnce(Return(is_privileged));
+ } else {
+ EXPECT_CALL(mock_priv, IsFireFoxPrivilegedInvocation(_))
+ .Times(0); // Fail if privilege check invoked.
+ }
+ }
+
+ public:
+ MockNPAPI mock_api;
+ MockAutomationClient* mock_automation;
+ MockProxyService* mock_proxy;
+ ScopedNsPtr<nsISupports> mock_proxy_holder;
+ MockPrivilegeTest mock_priv;
+ NPP_t instance;
+};
+
+} // namespace
+
+// Stub for unittesting.
+bool IsFireFoxPrivilegedInvocation(NPP npp) {
+ MockPrivilegeTest* mock = MockPrivilegeTest::current();
+ if (!mock)
+ return false;
+
+ return mock->IsFireFoxPrivilegedInvocation(npp);
+}
+
+TEST_F(TestNPAPIPrivilegedApi, NoPrivilegeCheckWhenNoArguments) {
+ SetupPrivilegeTest(false, // Not incognito
+ false, // Fail if privilege check is invoked.
+ false,
+ kDefaultProfileName,
+ L""); // No extra args to initialize.
+
+ // No arguments, no privilege requested.
+ EXPECT_TRUE(mock_api.Initialize(const_cast<NPMIMEType>(kMimeType),
+ &instance,
+ NP_EMBED,
+ 0, 0, 0));
+}
+
+TEST_F(TestNPAPIPrivilegedApi, NoPrivilegeCheckWhenZeroArgument) {
+ SetupPrivilegeTest(false, // Not incognito
+ false, // Fail if privilege check is invoked.
+ false,
+ kDefaultProfileName,
+ L""); // No extra args to initialize.
+
+ // Privileged mode explicitly zero.
+ char* argn = "is_privileged";
+ char* argv = "0";
+ EXPECT_TRUE(mock_api.Initialize(const_cast<NPMIMEType>(kMimeType),
+ &instance,
+ NP_EMBED,
+ 1, &argn, &argv));
+}
+
+TEST_F(TestNPAPIPrivilegedApi, NotPrivilegedDoesNotAllowArgsOrProfile) {
+ SetupPrivilegeTest(false, // Not incognito.
+ true, // Fail unless privilege check is invoked.
+ false, // Not privileged.
+ kDefaultProfileName,
+ L""); // No extra arguments allowed.
+
+ char* argn[] = {
+ "privileged_mode",
+ "chrome_extra_arguments",
+ "chrome_profile_name",
+ };
+ char *argv[] = {
+ "1",
+ "foo",
+ "bar",
+ };
+ EXPECT_TRUE(mock_api.Initialize(const_cast<NPMIMEType>(kMimeType),
+ &instance,
+ NP_EMBED,
+ arraysize(argn), argn, argv));
+}
+
+TEST_F(TestNPAPIPrivilegedApi, PrivilegedAllowsArgsAndProfile) {
+ SetupPrivilegeTest(false, // Not incognito.
+ true, // Fail unless privilege check is invoked.
+ true, // Privileged mode.
+ L"custom_profile_name", // Custom profile expected.
+ L"-bar=far"); // Extra arguments expected
+
+ // With privileged mode we expect automation to be enabled.
+ EXPECT_CALL(*mock_automation, SetEnableExtensionAutomation(true))
+ .Times(1);
+
+ char* argn[] = {
+ "privileged_mode",
+ "chrome_extra_arguments",
+ "chrome_profile_name",
+ };
+ char *argv[] = {
+ "1",
+ "-bar=far",
+ "custom_profile_name",
+ };
+ EXPECT_TRUE(mock_api.Initialize(const_cast<NPMIMEType>(kMimeType),
+ &instance,
+ NP_EMBED,
+ arraysize(argn), argn, argv));
+
+ // Since we're mocking out ChromeFrameAutomationClient::Initialize, we need
+ // to tickle this explicitly.
+ mock_api.OnAutomationServerReady();
+}
+
+
+namespace {
+
+static const NPIdentifier kOnPrivateMessageId =
+ reinterpret_cast<NPIdentifier>(0x100);
+static const NPIdentifier kPostPrivateMessageId =
+ reinterpret_cast<NPIdentifier>(0x100);
+
+
+class MockNetscapeFuncs {
+ public:
+ MockNetscapeFuncs() {
+ CHECK(NULL == current_);
+ current_ = this;
+ }
+
+ ~MockNetscapeFuncs() {
+ CHECK(this == current_);
+ current_ = NULL;
+ }
+
+ MOCK_METHOD3(GetValue, NPError(NPP, NPNVariable, void *));
+ MOCK_METHOD3(GetStringIdentifiers, void(const NPUTF8 **,
+ int32_t,
+ NPIdentifier *)); // NOLINT
+ MOCK_METHOD1(RetainObject, NPObject*(NPObject*)); // NOLINT
+ MOCK_METHOD1(ReleaseObject, void(NPObject*)); // NOLINT
+
+
+ void GetPrivilegedStringIdentifiers(const NPUTF8 **names,
+ int32_t name_count,
+ NPIdentifier *identifiers) {
+ for (int32_t i = 0; i < name_count; ++i) {
+ if (0 == strcmp(names[i], "onprivatemessage")) {
+ identifiers[i] = kOnPrivateMessageId;
+ } else if (0 == strcmp(names[i], "postPrivateMessage")) {
+ identifiers[i] = kPostPrivateMessageId;
+ } else {
+ identifiers[i] = 0;
+ }
+ }
+ }
+
+ static const NPNetscapeFuncs* netscape_funcs() {
+ return &netscape_funcs_;
+ }
+
+ private:
+ static NPError MockGetValue(NPP instance,
+ NPNVariable variable,
+ void *ret_value) {
+ DCHECK(current_);
+ return current_->GetValue(instance, variable, ret_value);
+ }
+
+ static void MockGetStringIdentifiers(const NPUTF8 **names,
+ int32_t name_count,
+ NPIdentifier *identifiers) {
+ DCHECK(current_);
+ return current_->GetStringIdentifiers(names, name_count, identifiers);
+ }
+
+ static NPObject* MockRetainObject(NPObject* obj) {
+ DCHECK(current_);
+ return current_->RetainObject(obj);
+ }
+
+ static void MockReleaseObject(NPObject* obj) {
+ DCHECK(current_);
+ current_->ReleaseObject(obj);
+ }
+
+ static MockNetscapeFuncs* current_;
+ static NPNetscapeFuncs netscape_funcs_;
+};
+
+MockNetscapeFuncs* MockNetscapeFuncs::current_ = NULL;
+NPNetscapeFuncs MockNetscapeFuncs::netscape_funcs_ = {
+ 0, // size
+ 0, // version
+ NULL, // geturl
+ NULL, // posturl
+ NULL, // requestread
+ NULL, // newstream
+ NULL, // write
+ NULL, // destroystream
+ NULL, // status
+ NULL, // uagent
+ NULL, // memalloc
+ NULL, // memfree
+ NULL, // memflush
+ NULL, // reloadplugins
+ NULL, // getJavaEnv
+ NULL, // getJavaPeer
+ NULL, // geturlnotify
+ NULL, // posturlnotify
+ MockGetValue, // getvalue
+ NULL, // setvalue
+ NULL, // invalidaterect
+ NULL, // invalidateregion
+ NULL, // forceredraw
+ NULL, // getstringidentifier
+ MockGetStringIdentifiers, // getstringidentifiers
+ NULL, // getintidentifier
+ NULL, // identifierisstring
+ NULL, // utf8fromidentifier
+ NULL, // intfromidentifier
+ NULL, // createobject
+ MockRetainObject, // retainobject
+ MockReleaseObject, // releaseobject
+ NULL, // invoke
+ NULL, // invokeDefault
+ NULL, // evaluate
+ NULL, // getproperty
+ NULL, // setproperty
+ NULL, // removeproperty
+ NULL, // hasproperty
+ NULL, // hasmethod
+ NULL, // releasevariantvalue
+ NULL, // setexception
+ NULL, // pushpopupsenabledstate
+ NULL, // poppopupsenabledstate
+ NULL, // enumerate
+ NULL, // pluginthreadasynccall
+ NULL, // construct
+};
+
+NPObject* const kMockNPObject = reinterpret_cast<NPObject*>(0xCafeBabe);
+
+class TestNPAPIPrivilegedProperty: public TestNPAPIPrivilegedApi {
+ public:
+ virtual void SetUp() {
+ TestNPAPIPrivilegedApi::SetUp();
+ npapi::InitializeBrowserFunctions(
+ const_cast<NPNetscapeFuncs*>(mock_funcs.netscape_funcs()));
+
+ // Expect calls to release and retain objects.
+ EXPECT_CALL(mock_funcs, RetainObject(kMockNPObject))
+ .WillRepeatedly(Return(kMockNPObject));
+ EXPECT_CALL(mock_funcs, ReleaseObject(kMockNPObject))
+ .WillRepeatedly(Return());
+
+ // And we should expect SetEnableExtensionAutomation to be called
+ // for privileged tests.
+ EXPECT_CALL(*mock_automation, SetEnableExtensionAutomation(true))
+ .WillRepeatedly(Return());
+
+ // Initializes identifiers.
+ EXPECT_CALL(mock_funcs, GetStringIdentifiers(_, _, _))
+ .WillRepeatedly(
+ Invoke(&mock_funcs,
+ &MockNetscapeFuncs::GetPrivilegedStringIdentifiers));
+ MockNPAPI::InitializeIdentifiers();
+ }
+
+ virtual void TearDown() {
+ npapi::UninitializeBrowserFunctions();
+ TestNPAPIPrivilegedApi::TearDown();
+ }
+
+ public:
+ MockNetscapeFuncs mock_funcs;
+};
+
+
+} // namespace
+
+TEST_F(TestNPAPIPrivilegedProperty,
+ NonPrivilegedOnPrivateMessageInitializationFails) {
+ // Attempt setting onprivatemessage when not privileged.
+ SetupPrivilegeTest(false, // not incognito.
+ true, // expect privilege check.
+ false, // not privileged.
+ kDefaultProfileName,
+ L"");
+
+ char* on_private_message_str = "onprivatemessage()";
+ EXPECT_CALL(mock_api, JavascriptToNPObject(StrEq(on_private_message_str)))
+ .Times(0); // this should not be called.
+
+ char* argn[] = {
+ "privileged_mode",
+ "onprivatemessage",
+ };
+ char* argv[] = {
+ "1",
+ on_private_message_str,
+ };
+ EXPECT_TRUE(mock_api.Initialize(const_cast<NPMIMEType>(kMimeType),
+ &instance,
+ NP_EMBED,
+ arraysize(argn), argn, argv));
+ // Shouldn't be able to retrieve it.
+ NPVariant var;
+ VOID_TO_NPVARIANT(var);
+ EXPECT_FALSE(mock_api.GetProperty(kOnPrivateMessageId, &var));
+ EXPECT_TRUE(NPVARIANT_IS_VOID(var));
+
+ mock_api.Uninitialize();
+}
+
+TEST_F(TestNPAPIPrivilegedProperty,
+ PrivilegedOnPrivateMessageInitializationSucceeds) {
+ // Set onprivatemessage argument when privileged.
+ SetupPrivilegeTest(false, // not incognito.
+ true, // expect privilege check.
+ true, // privileged.
+ kDefaultProfileName,
+ L"");
+
+ char* on_private_message_str = "onprivatemessage()";
+ NPObject* on_private_object = kMockNPObject;
+ EXPECT_CALL(mock_api, JavascriptToNPObject(StrEq(on_private_message_str)))
+ .WillOnce(Return(on_private_object));
+
+ char* argn[] = {
+ "privileged_mode",
+ "onprivatemessage",
+ };
+ char* argv[] = {
+ "1",
+ on_private_message_str,
+ };
+ EXPECT_TRUE(mock_api.Initialize(const_cast<NPMIMEType>(kMimeType),
+ &instance,
+ NP_EMBED,
+ arraysize(argn), argn, argv));
+ // The property should have been set, verify that
+ // we can retrieve it and test it for correct value.
+ NPVariant var;
+ VOID_TO_NPVARIANT(var);
+ EXPECT_TRUE(mock_api.GetProperty(kOnPrivateMessageId, &var));
+ EXPECT_TRUE(NPVARIANT_IS_OBJECT(var));
+ EXPECT_EQ(kMockNPObject, NPVARIANT_TO_OBJECT(var));
+
+ mock_api.Uninitialize();
+}
+
+TEST_F(TestNPAPIPrivilegedProperty,
+ NonPrivilegedOnPrivateMessageAssignmentFails) {
+ // Assigning to onprivatemessage when not privileged should fail.
+ SetupPrivilegeTest(false, // not incognito.
+ true, // expect privilege check.
+ false, // not privileged.
+ kDefaultProfileName,
+ L"");
+
+ char* argn = "privileged_mode";
+ char* argv = "1";
+ EXPECT_TRUE(mock_api.Initialize(const_cast<NPMIMEType>(kMimeType),
+ &instance,
+ NP_EMBED,
+ 1, &argn, &argv));
+
+ NPVariant var = {};
+ OBJECT_TO_NPVARIANT(kMockNPObject, var);
+ // Setting should fail.
+ EXPECT_FALSE(mock_api.SetProperty(kOnPrivateMessageId, &var));
+
+ // And so should getting.
+ NULL_TO_NPVARIANT(var);
+ EXPECT_FALSE(mock_api.GetProperty(kOnPrivateMessageId, &var));
+
+ mock_api.Uninitialize();
+}
+
+TEST_F(TestNPAPIPrivilegedProperty,
+ PrivilegedOnPrivateMessageAssignmentSucceeds) {
+ // Assigning to onprivatemessage when privileged should succeed.
+ SetupPrivilegeTest(false, // not incognito.
+ true, // expect privilege check.
+ true, // privileged.
+ kDefaultProfileName,
+ L"");
+
+ char* argn = "privileged_mode";
+ char* argv = "1";
+ EXPECT_TRUE(mock_api.Initialize(const_cast<NPMIMEType>(kMimeType),
+ &instance,
+ NP_EMBED,
+ 1, &argn, &argv));
+
+ NPVariant var = {};
+ VOID_TO_NPVARIANT(var);
+ // Getting the property when NULL fails under current implementation.
+ // I shouldn't have thought this is correct behavior, e.g. I should
+ // have thought retrieving the NULL should succeed, but this is consistent
+ // with how other properties behave.
+ // TODO(robertshield): investigate and/or fix.
+ EXPECT_FALSE(mock_api.GetProperty(kOnPrivateMessageId, &var));
+ // EXPECT_TRUE(NPVARIANT_IS_OBJECT(var));
+ // EXPECT_EQ(NULL, NPVARIANT_TO_OBJECT(var));
+
+ // Setting the property should succeed.
+ OBJECT_TO_NPVARIANT(kMockNPObject, var);
+ EXPECT_TRUE(mock_api.SetProperty(kOnPrivateMessageId, &var));
+
+ // And fething it should return the value we just set.
+ VOID_TO_NPVARIANT(var);
+ EXPECT_TRUE(mock_api.GetProperty(kOnPrivateMessageId, &var));
+ EXPECT_TRUE(NPVARIANT_IS_OBJECT(var));
+ EXPECT_EQ(kMockNPObject, NPVARIANT_TO_OBJECT(var));
+
+ mock_api.Uninitialize();
+}
+
+// TODO(siggi): test invoking postPrivateMessage.