1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/flags/flags_ui_handler.h"
#include "base/test/task_environment.h"
#include "components/webui/flags/flags_storage.h"
#include "components/webui/flags/flags_ui_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/test_web_ui.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
class TestFlagStorage : public flags_ui::FlagsStorage {
public:
// Retrieves the flags as a set of strings.
std::set<std::string> GetFlags() const override { return flags_; }
// Stores the |flags| and returns true on success.
bool SetFlags(const std::set<std::string>& flags) override {
flags_ = flags;
return true;
}
// Retrieves the serialized origin list corresponding to
// |internal_entry_name|. Does not check if the return value is well formed.
std::string GetOriginListFlag(
const std::string& internal_entry_name) const override {
if (origin_list_flags_.count(internal_entry_name) == 0) {
return "";
}
return origin_list_flags_.at(internal_entry_name);
}
// Sets the serialized |origin_list_value| corresponding to
// |internal_entry_name|. Does not check if |origin_list_value| is well
// formed.
void SetOriginListFlag(const std::string& internal_entry_name,
const std::string& origin_list_value) override {
origin_list_flags_[internal_entry_name] = origin_list_value;
}
std::string GetStringFlag(
const std::string& internal_entry_name) const override {
return GetOriginListFlag(internal_entry_name);
}
void SetStringFlag(const std::string& internal_entry_name,
const std::string& value) override {
SetOriginListFlag(internal_entry_name, value);
}
// Lands pending changes to disk immediately.
void CommitPendingWrites() override {}
private:
std::set<std::string> flags_;
std::map<std::string, std::string> origin_list_flags_;
};
class TestFlagsUIHandler : public FlagsUIHandler {
public:
// Make public for testing.
using FlagsUIHandler::set_web_ui;
};
class FlagsUIHandlerTest : public testing::Test {
public:
void SetUp() override {
std::unique_ptr<TestFlagStorage> storage =
std::make_unique<TestFlagStorage>();
storage_ = storage.get();
handler_ = std::make_unique<TestFlagsUIHandler>();
handler_->Init(std::move(storage),
flags_ui::FlagAccess::kOwnerAccessToFlags);
handler_->set_web_ui(&web_ui_);
handler_->RegisterMessages();
}
protected:
content::TestWebUI web_ui_;
std::unique_ptr<TestFlagsUIHandler> handler_;
raw_ptr<TestFlagStorage> storage_;
};
TEST_F(FlagsUIHandlerTest, HandlesSetString) {
// Need to use an actual feature name for ChromeOS.
const std::string kTestFeature = "protected-audience-debug-token";
EXPECT_EQ("", storage_->GetStringFlag(kTestFeature));
web_ui_.HandleReceivedMessage(
flags_ui::kSetStringFlag,
base::Value::List().Append(kTestFeature).Append("value"));
EXPECT_EQ("value", storage_->GetStringFlag(kTestFeature));
}
TEST_F(FlagsUIHandlerTest, HandlesSetOriginList) {
// Need to use an actual feature name for ChromeOS.
const std::string kTestFeature = "isolate-origins";
EXPECT_EQ("", storage_->GetOriginListFlag(kTestFeature));
web_ui_.HandleReceivedMessage(
flags_ui::kSetOriginListFlag,
base::Value::List()
.Append(kTestFeature)
.Append("https://foo.com,invalid,http://bar.org"));
EXPECT_EQ("https://foo.com,http://bar.org",
storage_->GetOriginListFlag(kTestFeature));
}
TEST_F(FlagsUIHandlerTest, HandleRequestExperimentalFeatures) {
base::Value::List args;
args.Append("callbackId");
web_ui_.HandleReceivedMessage(flags_ui::kRequestExperimentalFeatures, args);
EXPECT_EQ(1u, web_ui_.call_data().size());
auto& call_data = *(web_ui_.call_data().back());
EXPECT_EQ("cr.webUIResponse", call_data.function_name());
EXPECT_EQ("callbackId", call_data.arg1()->GetString());
EXPECT_TRUE(call_data.arg2()->GetBool());
const base::Value::Dict& response = call_data.arg3()->GetDict();
// Check that entries for both "supported_features" and "unsupported_features"
// exist.
const base::Value::List& supported =
*response.FindList(flags_ui::kSupportedFeatures);
EXPECT_GT(supported.size(), 0u);
const base::Value::List& unsupported =
*response.FindList(flags_ui::kUnsupportedFeatures);
EXPECT_GT(unsupported.size(), 0u);
}
// Tests for chrome://flags/deprecated
TEST_F(FlagsUIHandlerTest, HandleRequestDeprecatedFeatures) {
base::Value::List args;
args.Append("callbackId");
web_ui_.HandleReceivedMessage("requestDeprecatedFeatures", args);
EXPECT_EQ(1u, web_ui_.call_data().size());
auto& call_data = *(web_ui_.call_data().back());
EXPECT_EQ("cr.webUIResponse", call_data.function_name());
EXPECT_EQ("callbackId", call_data.arg1()->GetString());
EXPECT_TRUE(call_data.arg2()->GetBool());
const base::Value::Dict& response = call_data.arg3()->GetDict();
// Check that exactly 1 entry is returned as part of "supported_features".
const base::Value::List& supported =
*response.FindList(flags_ui::kSupportedFeatures);
EXPECT_EQ(1u, supported.size());
const base::Value::Dict& feature = supported[0].GetDict();
const std::string& internal_name = *feature.FindString("internal_name");
EXPECT_EQ("deprecate-unload", internal_name);
// Check that no entry is returned as part of "unsupported_features".
const base::Value::List& unsupported =
*response.FindList(flags_ui::kUnsupportedFeatures);
EXPECT_EQ(0u, unsupported.size());
}
} // namespace
|