root/chrome/browser/chromeos/extensions/accessibility_features_apitest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. GetPrefs
  2. GetTestExtensionPath
  3. ShouldModifyingFeatureSucceed
  4. GetPrefForFeature
  5. InitPrefServiceForTest
  6. VerifyPrefServiceState
  7. GenerateTestArg
  8. IN_PROC_BROWSER_TEST_P
  9. IN_PROC_BROWSER_TEST_P
  10. IN_PROC_BROWSER_TEST_F

// Copyright 2014 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 <string>
#include <vector>

#include "base/json/json_writer.h"
#include "base/prefs/pref_service.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/pref_names.h"

// API tests for chrome.accessibilityFeatures API.
// Note that the API is implemented using preference API infrastructure.
// See preference_api.cc for the list of accessibility features exposed by the
// API and the related preferences.

namespace extensions {

namespace {

// Keys for data in the test config argument that will be set for the test app
// to use.
// The test that the app should run.
const char kTestNameKey[] = "testName";
// Key for list of features enabled when the test is initialized.
const char kEnabledFeaturesKey[] = "enabled";
// Key for list fo features disabled when the test is initialized.
const char kDisabledFeaturesKey[] = "disabled";

// A test extension path. The extension has only |accessibilityFeatures.read|
// permission.
const char kTestExtensionPathReadPermission[] =
    "accessibility_features/read_permission/";
// A test extension path. The extension has only |accessibilityFeatures.modify|
// permission.
const char kTestExtensionPathMofifyPermission[] =
    "accessibility_features/modify_permission/";

// Accessibility features API test.
// Tests are parameterized by whether the test extension is write-only (the
// parameter value is true) or read-only (the parameter value is false).
class AccessibilityFeaturesApiTest : public ExtensionApiTest,
                                     public testing::WithParamInterface<bool> {
 public:
  AccessibilityFeaturesApiTest() {}
  virtual ~AccessibilityFeaturesApiTest() {}

 protected:
  // Returns pref service to be used to initialize and later verify
  // accessibility preference values.
  PrefService* GetPrefs() { return browser()->profile()->GetPrefs(); }

  // Returns the path of the extension that should be used in a parameterized
  // test.
  std::string GetTestExtensionPath() const {
    if (GetParam())
      return kTestExtensionPathMofifyPermission;
    return kTestExtensionPathReadPermission;
  }

  // Whether a parameterized test should have been able to modify accessibility
  // preferences (i.e. whether the test extension had modify permission).
  bool ShouldModifyingFeatureSucceed() const { return GetParam(); }

  // Returns preference path for accessibility features as defined by the API.
  const char* const GetPrefForFeature(const std::string& feature) {
    if (feature == "spokenFeedback")
      return prefs::kSpokenFeedbackEnabled;
    if (feature == "largeCursor")
      return prefs::kLargeCursorEnabled;
    if (feature == "stickyKeys")
      return prefs::kStickyKeysEnabled;
    if (feature == "highContrast")
      return prefs::kHighContrastEnabled;
    if (feature == "screenMagnifier")
      return prefs::kScreenMagnifierEnabled;
    if (feature == "autoclick")
      return prefs::kAutoclickEnabled;
    if (feature == "virtualKeyboard")
      return prefs::kVirtualKeyboardEnabled;
    return NULL;
  }

  // Initializes preferences before running the test extension.
  // |prefs| Pref service which should be initializzed.
  // |enabled_features| List of boolean preference whose value should be set to
  //     true.
  // |disabled_features| List of boolean preferences whose value should be set
  //     to false.
  bool InitPrefServiceForTest(
      PrefService* prefs,
      const std::vector<std::string>& enabled_features,
      const std::vector<std::string>& disabled_features) {
    for (size_t i = 0; i < enabled_features.size(); ++i) {
      const char* const pref_name = GetPrefForFeature(enabled_features[i]);
      EXPECT_TRUE(pref_name) << "Invalid feature " << enabled_features[i];
      if (!pref_name)
        return false;
      prefs->SetBoolean(pref_name, true);
    }

    for (size_t i = 0; i < disabled_features.size(); ++i) {
      const char* const pref_name = GetPrefForFeature(disabled_features[i]);
      EXPECT_TRUE(pref_name) << "Invalid feature " << disabled_features[i];
      if (!pref_name)
        return false;
      prefs->SetBoolean(pref_name, false);
    }
    return true;
  }

  // Verifies that preferences have the expected value.
  // |prefs| The pref service to be verified.
  // |enabled_features| The list of boolean preferences whose value should be
  //     true.
  // |disabled_features| The list of boolean preferences whose value should be
  //     false.
  void VerifyPrefServiceState(
      PrefService* prefs,
      const std::vector<std::string>& enabled_features,
      const std::vector<std::string>& disabled_features) {
    for (size_t i = 0; i < enabled_features.size(); ++i) {
      const char* const pref_name = GetPrefForFeature(enabled_features[i]);
      ASSERT_TRUE(pref_name) << "Invalid feature " << enabled_features[i];
      ASSERT_TRUE(prefs->GetBoolean(pref_name));
    }

    for (size_t i = 0; i < disabled_features.size(); ++i) {
      const char* const pref_name = GetPrefForFeature(disabled_features[i]);
      ASSERT_TRUE(pref_name) << "Invalid feature " << disabled_features[i];
      ASSERT_FALSE(prefs->GetBoolean(pref_name));
    }
  }

  // Given the test name and list of enabled and disabled features, generates
  // and sets the JSON string that should be given to the test extension as
  // test configuration.
  // The result is saved to |result|. The return value is whether the test
  // argument was successfully generated.
  bool GenerateTestArg(const std::string& test_name,
                       const std::vector<std::string>& enabled_features,
                       const std::vector<std::string>& disabled_features,
                       std::string* result) {
    base::DictionaryValue test_arg;
    test_arg.SetString(kTestNameKey, test_name);

    scoped_ptr<base::ListValue> enabled_list(new base::ListValue);
    for (size_t i = 0; i < enabled_features.size(); ++i)
      enabled_list->AppendString(enabled_features[i]);
    test_arg.Set(kEnabledFeaturesKey, enabled_list.release());

    scoped_ptr<base::ListValue> disabled_list(new base::ListValue);
    for (size_t i = 0; i < disabled_features.size(); ++i)
      disabled_list->AppendString(disabled_features[i]);
    test_arg.Set(kDisabledFeaturesKey, disabled_list.release());

    return base::JSONWriter::Write(&test_arg, result);
  }
};

INSTANTIATE_TEST_CASE_P(AccessibilityFeatureaApiTestInstantiatePermission,
                        AccessibilityFeaturesApiTest,
                        testing::Bool());

// Tests that an extension with read permission can read accessibility features
// state, while an extension that doesn't have the permission cannot.
IN_PROC_BROWSER_TEST_P(AccessibilityFeaturesApiTest, Get) {
  std::vector<std::string> enabled_features;
  enabled_features.push_back("largeCursor");
  enabled_features.push_back("stickyKeys");
  enabled_features.push_back("highContrast");

  std::vector<std::string> disabled_features;
  disabled_features.push_back("spokenFeedback");
  disabled_features.push_back("screenMagnifier");
  disabled_features.push_back("autoclick");
  disabled_features.push_back("virtualKeyboard");

  ASSERT_TRUE(
      InitPrefServiceForTest(GetPrefs(), enabled_features, disabled_features));

  std::string test_arg;
  ASSERT_TRUE(GenerateTestArg(
      "getterTest", enabled_features, disabled_features, &test_arg));
  EXPECT_TRUE(
      RunPlatformAppTestWithArg(GetTestExtensionPath(), test_arg.c_str()));
}

// Tests that an extension with modify permission can modify accessibility
// features, while an extension that doesn't have the permission can't.
IN_PROC_BROWSER_TEST_P(AccessibilityFeaturesApiTest, Set) {
  std::vector<std::string> enabled_features;
  enabled_features.push_back("spokenFeedback");
  enabled_features.push_back("stickyKeys");
  enabled_features.push_back("autoclick");
  enabled_features.push_back("virtualKeyboard");

  std::vector<std::string> disabled_features;
  disabled_features.push_back("largeCursor");
  disabled_features.push_back("highContrast");
  disabled_features.push_back("screenMagnifier");

  ASSERT_TRUE(
      InitPrefServiceForTest(GetPrefs(), enabled_features, disabled_features));

  std::string test_arg;
  ASSERT_TRUE(GenerateTestArg(
      "setterTest", enabled_features, disabled_features, &test_arg));

  // The test extension attempts to flip all feature values.
  ASSERT_TRUE(
      RunPlatformAppTestWithArg(GetTestExtensionPath(), test_arg.c_str()));

  // The test tries to flip the feature states.
  if (ShouldModifyingFeatureSucceed()) {
    VerifyPrefServiceState(GetPrefs(), disabled_features, enabled_features);
  } else {
    VerifyPrefServiceState(GetPrefs(), enabled_features, disabled_features);
  }
}

// Tests that an extension with read permission is notified when accessibility
// features change.
IN_PROC_BROWSER_TEST_F(AccessibilityFeaturesApiTest, ObserveFeatures) {
  std::vector<std::string> enabled_features;
  enabled_features.push_back("largeCursor");
  enabled_features.push_back("stickyKeys");
  enabled_features.push_back("highContrast");

  std::vector<std::string> disabled_features;
  disabled_features.push_back("screenMagnifier");

  ASSERT_TRUE(
      InitPrefServiceForTest(GetPrefs(), enabled_features, disabled_features));

  std::string test_arg;
  ASSERT_TRUE(GenerateTestArg(
      "observerTest", enabled_features, disabled_features, &test_arg));

  // The test extension is supposed to report result twice when runnign this
  // test. First time when in initializes it's feature listeners, and second
  // time, when gets all expected events. This is done so the extension is
  // running when the accessibility features are flipped; oterwise, the
  // extension may not see events.
  ASSERT_TRUE(RunPlatformAppTestWithArg(kTestExtensionPathReadPermission,
                                        test_arg.c_str()));

  // This should flip all features.
  ASSERT_TRUE(
      InitPrefServiceForTest(GetPrefs(), disabled_features, enabled_features));

  // Catch the second result notification sent by the test extension.
  ResultCatcher result_catcher;
  ASSERT_TRUE(result_catcher.GetNextResult()) << result_catcher.message();
}

}  // namespace

}  // namespace extensions

/* [<][>][^][v][top][bottom][index][help] */