1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <UIKit/UIKit.h>
7 #include "base/basictypes.h"
8 #include "base/callback.h"
9 #include "base/files/file_path.h"
10 #include "base/ios/ios_util.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "base/test/test_simple_task_runner.h"
13 #include "base/values.h"
14 #include "components/policy/core/common/async_policy_provider.h"
15 #include "components/policy/core/common/configuration_policy_provider_test.h"
16 #include "components/policy/core/common/policy_bundle.h"
17 #include "components/policy/core/common/policy_loader_ios.h"
18 #include "components/policy/core/common/policy_map.h"
19 #include "components/policy/core/common/policy_test_utils.h"
20 #include "testing/gtest/include/gtest/gtest.h"
26 // Key in the NSUserDefaults that contains the managed app configuration.
27 NSString* const kConfigurationKey = @"com.apple.configuration.managed";
29 class TestHarness : public PolicyProviderTestHarness {
31 // If |use_encoded_key| is true then AddPolicies() serializes and encodes
32 // the policies, and publishes them under the EncodedChromePolicy key.
33 explicit TestHarness(bool use_encoded_key);
34 virtual ~TestHarness();
36 virtual void SetUp() OVERRIDE;
38 virtual ConfigurationPolicyProvider* CreateProvider(
39 SchemaRegistry* registry,
40 scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE;
42 virtual void InstallEmptyPolicy() OVERRIDE;
43 virtual void InstallStringPolicy(const std::string& policy_name,
44 const std::string& policy_value) OVERRIDE;
45 virtual void InstallIntegerPolicy(const std::string& policy_name,
46 int policy_value) OVERRIDE;
47 virtual void InstallBooleanPolicy(const std::string& policy_name,
48 bool policy_value) OVERRIDE;
49 virtual void InstallStringListPolicy(
50 const std::string& policy_name,
51 const base::ListValue* policy_value) OVERRIDE;
52 virtual void InstallDictionaryPolicy(
53 const std::string& policy_name,
54 const base::DictionaryValue* policy_value) OVERRIDE;
56 static PolicyProviderTestHarness* Create();
57 static PolicyProviderTestHarness* CreateWithEncodedKey();
60 // Merges the policies in |policy| into the current policy dictionary
61 // in NSUserDefaults, after making sure that the policy dictionary
63 void AddPolicies(NSDictionary* policy);
64 void AddChromePolicy(NSDictionary* policy);
65 void AddEncodedChromePolicy(NSDictionary* policy);
67 bool use_encoded_key_;
69 DISALLOW_COPY_AND_ASSIGN(TestHarness);
72 TestHarness::TestHarness(bool use_encoded_key)
73 : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE),
74 use_encoded_key_(use_encoded_key) {}
76 TestHarness::~TestHarness() {
77 // Cleanup any policies left from the test.
78 [[NSUserDefaults standardUserDefaults] removeObjectForKey:kConfigurationKey];
81 void TestHarness::SetUp() {
82 // Make sure there is no pre-existing policy present.
83 [[NSUserDefaults standardUserDefaults] removeObjectForKey:kConfigurationKey];
86 ConfigurationPolicyProvider* TestHarness::CreateProvider(
87 SchemaRegistry* registry,
88 scoped_refptr<base::SequencedTaskRunner> task_runner) {
89 scoped_ptr<AsyncPolicyLoader> loader(new PolicyLoaderIOS(task_runner));
90 return new AsyncPolicyProvider(registry, loader.Pass());
93 void TestHarness::InstallEmptyPolicy() {
97 void TestHarness::InstallStringPolicy(const std::string& policy_name,
98 const std::string& policy_value) {
99 NSString* key = base::SysUTF8ToNSString(policy_name);
100 NSString* value = base::SysUTF8ToNSString(policy_value);
106 void TestHarness::InstallIntegerPolicy(const std::string& policy_name,
108 NSString* key = base::SysUTF8ToNSString(policy_name);
110 key: [NSNumber numberWithInt:policy_value]
114 void TestHarness::InstallBooleanPolicy(const std::string& policy_name,
116 NSString* key = base::SysUTF8ToNSString(policy_name);
118 key: [NSNumber numberWithBool:policy_value]
122 void TestHarness::InstallStringListPolicy(const std::string& policy_name,
123 const base::ListValue* policy_value) {
124 NSString* key = base::SysUTF8ToNSString(policy_name);
125 base::ScopedCFTypeRef<CFPropertyListRef> value(ValueToProperty(policy_value));
127 key: static_cast<NSArray*>(value.get())
131 void TestHarness::InstallDictionaryPolicy(
132 const std::string& policy_name,
133 const base::DictionaryValue* policy_value) {
134 NSString* key = base::SysUTF8ToNSString(policy_name);
135 base::ScopedCFTypeRef<CFPropertyListRef> value(ValueToProperty(policy_value));
137 key: static_cast<NSDictionary*>(value.get())
142 PolicyProviderTestHarness* TestHarness::Create() {
143 return new TestHarness(false);
147 PolicyProviderTestHarness* TestHarness::CreateWithEncodedKey() {
148 if (base::ios::IsRunningOnIOS7OrLater())
149 return new TestHarness(true);
150 // Earlier versions of iOS don't have the APIs to support this test.
151 // Unfortunately it's not possible to conditionally run this harness using
152 // gtest, so we just fallback to running the non-encoded version.
153 NSLog(@"Skipping test");
154 return new TestHarness(false);
157 void TestHarness::AddPolicies(NSDictionary* policy) {
158 if (use_encoded_key_)
159 AddEncodedChromePolicy(policy);
161 AddChromePolicy(policy);
164 void TestHarness::AddChromePolicy(NSDictionary* policy) {
165 NSString* key = @"ChromePolicy";
166 NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
167 base::scoped_nsobject<NSMutableDictionary> chromePolicy(
168 [[NSMutableDictionary alloc] init]);
170 NSDictionary* previous = [defaults dictionaryForKey:key];
172 [chromePolicy addEntriesFromDictionary:previous];
174 [chromePolicy addEntriesFromDictionary:policy];
176 NSDictionary* wrapper = @{
179 [[NSUserDefaults standardUserDefaults] setObject:wrapper
180 forKey:kConfigurationKey];
183 void TestHarness::AddEncodedChromePolicy(NSDictionary* policy) {
184 NSString* key = @"EncodedChromePolicy";
185 NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
187 base::scoped_nsobject<NSMutableDictionary> chromePolicy(
188 [[NSMutableDictionary alloc] init]);
190 NSString* previous = [defaults stringForKey:key];
192 base::scoped_nsobject<NSData> data(
193 [[NSData alloc] initWithBase64EncodedString:previous options:0]);
194 NSDictionary* properties = [NSPropertyListSerialization
195 propertyListWithData:data.get()
196 options:NSPropertyListImmutable
199 [chromePolicy addEntriesFromDictionary:properties];
202 [chromePolicy addEntriesFromDictionary:policy];
204 NSData* data = [NSPropertyListSerialization
205 dataWithPropertyList:chromePolicy
206 format:NSPropertyListXMLFormat_v1_0
209 NSString* encoded = [data base64EncodedStringWithOptions:0];
211 NSDictionary* wrapper = @{
214 [[NSUserDefaults standardUserDefaults] setObject:wrapper
215 forKey:kConfigurationKey];
220 INSTANTIATE_TEST_CASE_P(
221 PolicyProviderIOSChromePolicyTest,
222 ConfigurationPolicyProviderTest,
223 testing::Values(TestHarness::Create));
225 INSTANTIATE_TEST_CASE_P(
226 PolicyProviderIOSEncodedChromePolicyTest,
227 ConfigurationPolicyProviderTest,
228 testing::Values(TestHarness::CreateWithEncodedKey));
230 TEST(PolicyProviderIOSTest, ChromePolicyOverEncodedChromePolicy) {
231 // This test verifies that if the "ChromePolicy" key is present then the
232 // "EncodedChromePolicy" key is ignored.
234 if (!base::ios::IsRunningOnIOS7OrLater()) {
235 // Skip this test if running on a version earlier than iOS 7.
236 NSLog(@"Skipping test");
240 NSDictionary* policy = @{
244 NSData* data = [NSPropertyListSerialization
245 dataWithPropertyList:policy
246 format:NSPropertyListXMLFormat_v1_0
249 NSString* encodedChromePolicy = [data base64EncodedStringWithOptions:0];
251 NSDictionary* chromePolicy = @{
256 NSDictionary* wrapper = @{
257 @"ChromePolicy": chromePolicy,
258 @"EncodedChromePolicy": encodedChromePolicy,
261 [[NSUserDefaults standardUserDefaults] setObject:wrapper
262 forKey:kConfigurationKey];
264 PolicyBundle expected;
265 PolicyMap& expectedMap =
266 expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, ""));
267 expectedMap.Set("shared", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
268 new base::StringValue("right"), NULL);
269 expectedMap.Set("key2", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
270 new base::StringValue("value2"), NULL);
272 scoped_refptr<base::TestSimpleTaskRunner> taskRunner =
273 new base::TestSimpleTaskRunner();
274 PolicyLoaderIOS loader(taskRunner);
275 scoped_ptr<PolicyBundle> bundle = loader.Load();
277 EXPECT_TRUE(bundle->Equals(expected));
280 } // namespace policy