1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System;
6 using System.Collections.Generic;
7 using Xunit;
8 
9 namespace Microsoft.Win32.RegistryTests
10 {
11     public class Registry_SetValue_str_str_obj : RegistryTestsBase
12     {
13         [Fact]
Test01()14         public void Test01()
15         {
16             // [] Passing in null should throw ArgumentNullException
17             //UPDATE: This sets the default value. We should move this test to a newly defined reg key so as not to screw up the system
18             const string expected = "This is a test";
19             Registry.SetValue(TestRegistryKey.Name, null, expected);
20             Assert.Equal(expected, TestRegistryKey.GetValue(null));
21         }
22 
23         [Fact]
NegativeTests()24         public void NegativeTests()
25         {
26             // Should throw if passed value is null
27             Assert.Throws<ArgumentNullException>(() => Registry.SetValue(TestRegistryKey.Name, "test", value: null));
28 
29             // Should throw if passed keyName is null
30             Assert.Throws<ArgumentNullException>(() => Registry.SetValue(keyName: null, valueName: "test", value: "test"));
31 
32             // Should throw if passed string does NOT start with one of the valid base key names
33             AssertExtensions.Throws<ArgumentException>("keyName", null, () => Registry.SetValue("HHHH_MMMM", "test", "test"));
34 
35             // Should throw if passed string which only starts with one of the valid base key names but actually it isn't valid.
36             AssertExtensions.Throws<ArgumentException>("keyName", null, () => Registry.SetValue("HKEY_LOCAL_MACHINE_FOOBAR", "test", "test"));
37 
38             // Should throw if key length above 255 characters but prior to V4, the limit is 16383
39             const int maxValueNameLength = 16383;
40             AssertExtensions.Throws<ArgumentException>("name", null, () => Registry.SetValue(TestRegistryKey.Name, new string('a', maxValueNameLength + 1), 5));
41 
42             // Should throw if passed value is array with uninitialized elements
43             AssertExtensions.Throws<ArgumentException>(null, () => Registry.SetValue(TestRegistryKey.Name, "StringArr", value: new string[1]));
44 
45             // Should throw because only String[] (REG_MULTI_SZ) and byte[] (REG_BINARY) are supported.
46             // RegistryKey.SetValue does not support arrays of type UInt32[].
47             AssertExtensions.Throws<ArgumentException>(null, () => Registry.SetValue(TestRegistryKey.Name, "IntArray", new[] { 1, 2, 3 }));
48         }
49 
50         public static IEnumerable<object[]> TestValueTypes { get { return TestData.TestValueTypes; } }
51 
52         [Theory]
53         [MemberData(nameof(TestValueTypes))]
SetValueWithValueTypes(string valueName, object testValue)54         public void SetValueWithValueTypes(string valueName, object testValue)
55         {
56             Registry.SetValue(TestRegistryKey.Name, valueName, testValue);
57             Assert.Equal(testValue.ToString(), TestRegistryKey.GetValue(valueName).ToString());
58             TestRegistryKey.DeleteValue(valueName);
59         }
60 
61         [Fact]
SetValueWithInt32()62         public void SetValueWithInt32()
63         {
64             const string testValueName = "Int32";
65             const int expected = -5;
66 
67             Registry.SetValue(TestRegistryKey.Name, testValueName, expected);
68             Assert.Equal(expected, (int)TestRegistryKey.GetValue(testValueName));
69             TestRegistryKey.DeleteValue(testValueName);
70         }
71 
72         [Fact]
SetValueWithUInt64()73         public void SetValueWithUInt64()
74         {
75             // This will be written as REG_SZ
76             const string testValueName = "UInt64";
77             const ulong expected = ulong.MaxValue;
78 
79             Registry.SetValue(TestRegistryKey.Name, testValueName, expected);
80             Assert.Equal(expected, Convert.ToUInt64(TestRegistryKey.GetValue(testValueName)));
81             TestRegistryKey.DeleteValue(testValueName);
82         }
83 
84         [Fact]
SetValueWithByteArray()85         public void SetValueWithByteArray()
86         {
87             // This will be written as  REG_BINARY
88             const string testValueName = "UBArr";
89             byte[] expected = { 1, 2, 3 };
90 
91             Registry.SetValue(TestRegistryKey.Name, testValueName, expected);
92             Assert.Equal(expected, (byte[])TestRegistryKey.GetValue(testValueName));
93             TestRegistryKey.DeleteValue(testValueName);
94         }
95 
96         [Fact]
SetValueWithMultiString()97         public void SetValueWithMultiString()
98         {
99             // This will be written as  REG_MULTI_SZ
100             const string testValueName = "StringArr";
101             string[] expected =
102             {
103                 "This is a public",
104                 "broadcast intend to test",
105                 "lot of things. one of which"
106             };
107 
108             Registry.SetValue(TestRegistryKey.Name, testValueName, expected);
109             Assert.Equal(expected, (string[])TestRegistryKey.GetValue(testValueName));
110             TestRegistryKey.DeleteValue(testValueName);
111         }
112 
113         public static IEnumerable<object[]> TestEnvironment { get { return TestData.TestEnvironment; } }
114 
115         [Theory]
116         [MemberData(nameof(TestEnvironment))]
SetValueWithEnvironmentVariable(string valueName, string envVariableName, string expectedVariableValue)117         public void SetValueWithEnvironmentVariable(string valueName, string envVariableName, string expectedVariableValue)
118         {
119             string value = "%" + envVariableName + "%";
120             Registry.SetValue(TestRegistryKey.Name, valueName, value);
121 
122             string result = (string)TestRegistryKey.GetValue(valueName);
123             //we don't expand for the user, REG_SZ_EXPAND not supported
124             Assert.Equal(expectedVariableValue, Environment.ExpandEnvironmentVariables(result));
125             TestRegistryKey.DeleteValue(valueName);
126         }
127 
128         [Fact]
SetValueWithEmptyString()129         public void SetValueWithEmptyString()
130         {
131             // Creating REG_SZ key with an empty string value does not add a null terminating char.
132             const string testValueName = "test_122018";
133             string expected = string.Empty;
134 
135             Registry.SetValue(TestRegistryKey.Name, testValueName, expected);
136             Assert.Equal(expected, (string)TestRegistryKey.GetValue(testValueName));
137             TestRegistryKey.DeleteValue(testValueName);
138         }
139     }
140 }
141