winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

DSCv3UserSettingsFileResourceCommand.cs (14835B)


      1 // -----------------------------------------------------------------------------
      2 // <copyright file="DSCv3UserSettingsFileResourceCommand.cs" company="Microsoft Corporation">
      3 //     Copyright (c) Microsoft Corporation. Licensed under the MIT License.
      4 // </copyright>
      5 // -----------------------------------------------------------------------------
      6 
      7 namespace AppInstallerCLIE2ETests;
      8 
      9 using AppInstallerCLIE2ETests.Helpers;
     10 using NUnit.Framework;
     11 using System.Collections.Generic;
     12 using System.IO;
     13 using System.Text.Json.Nodes;
     14 using System.Text.Json.Serialization;
     15 
     16 /// <summary>
     17 /// `Configure` command tests.
     18 /// </summary>
     19 [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1010:Opening square brackets should be spaced correctly", Justification = "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release")]
     20 [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1011:Closing square brackets should be spaced correctly", Justification = "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release")]
     21 public class DSCv3UserSettingsFileResourceCommand : DSCv3ResourceTestBase
     22 {
     23     private const string UserSettingsFileResource = "user-settings-file";
     24     private const string SettingsPropertyName = "settings";
     25     private const string ActionPropertyValueFull = "Full";
     26     private const string ActionPropertyValuePartial = "Partial";
     27     private const string SettingsMock = "mock";
     28     private const string SettingsMockObject = "mockObject";
     29     private const string SettingsMockNested = "mockNested";
     30 
     31     /// <summary>
     32     /// Setup done once before all the tests here.
     33     /// </summary>
     34     [OneTimeSetUp]
     35     public void OneTimeSetup()
     36     {
     37         TestCommon.SetupTestSource();
     38         EnsureTestResourcePresence();
     39     }
     40 
     41     /// <summary>
     42     /// Teardown done once after all the tests here.
     43     /// </summary>
     44     [OneTimeTearDown]
     45     public void OneTimeTeardown()
     46     {
     47         WinGetSettingsHelper.InitializeWingetSettings();
     48     }
     49 
     50     /// <summary>
     51     /// Set up.
     52     /// </summary>
     53     [SetUp]
     54     public void Setup()
     55     {
     56         // Reset the settings to default before each test.
     57         WinGetSettingsHelper.InitializeWingetSettings();
     58         WinGetSettingsHelper.ConfigureFeature("dsc3", true);
     59     }
     60 
     61     /// <summary>
     62     /// Calls `get` on the `user-settings-file` resource.
     63     /// </summary>
     64     [Test]
     65     public void UserSettingsFile_Get()
     66     {
     67         var expected = GetCurrentUserSettings();
     68         var getOutput = Get(new ());
     69 
     70         Assert.IsNotNull(getOutput);
     71         Assert.IsNull(getOutput.Action);
     72         AssertSettingsAreEqual(expected, getOutput.Settings);
     73     }
     74 
     75     /// <summary>
     76     /// Calls `set` on the `user-settings-file` resource with no diff.
     77     /// </summary>
     78     /// <param name="action">The action value.</param>
     79     [Test]
     80     [TestCase(ActionPropertyValueFull)]
     81     [TestCase(ActionPropertyValuePartial)]
     82     public void UserSettingsFile_Set_NoDiff(string action)
     83     {
     84         var setSettings = GetSettingsArg(action);
     85 
     86         (var setOutput, var setDiff) = Set(new () { Action = action, Settings = setSettings });
     87 
     88         var expected = GetCurrentUserSettings();
     89 
     90         Assert.IsNotNull(setOutput);
     91         Assert.AreEqual(action, setOutput.Action);
     92         AssertSettingsAreEqual(expected, setOutput.Settings);
     93         AssertDiffState(setDiff, []);
     94     }
     95 
     96     /// <summary>
     97     /// Calls `set` on the `user-settings-file` resource to add fields.
     98     /// </summary>
     99     /// <param name="action">The action value.</param>
    100     [Test]
    101     [TestCase(ActionPropertyValueFull)]
    102     [TestCase(ActionPropertyValuePartial)]
    103     public void UserSettingsFile_Set_AddFields(string action)
    104     {
    105         // Call `set` to add mock properties to the settings
    106         var setSettings = GetSettingsArg(action);
    107         AddOrModifyMockProperties(setSettings, "mock");
    108 
    109         (var setOutput, var setDiff) = Set(new () { Action = action, Settings = setSettings });
    110 
    111         var expected = GetCurrentUserSettings();
    112 
    113         // Assert that the settings are added
    114         Assert.IsNotNull(setOutput);
    115         Assert.AreEqual(action, setOutput.Action);
    116         AssertMockProperties(setOutput.Settings, "mock");
    117         AssertSettingsAreEqual(expected, setOutput.Settings);
    118         AssertDiffState(setDiff, [ SettingsPropertyName ]);
    119     }
    120 
    121     /// <summary>
    122     /// Calls `set` on the `user-settings-file` resource to ensure action is partial by default.
    123     /// </summary>
    124     [Test]
    125     public void UserSettingsFile_Set_ActionIsPartialByDefault()
    126     {
    127         // Call `set` to add mock properties to the settings
    128         var setSettings = GetSettingsArg(ActionPropertyValuePartial);
    129         AddOrModifyMockProperties(setSettings, "mock");
    130 
    131         var expected = GetCurrentUserSettings();
    132         AddOrModifyMockProperties(expected, "mock");
    133 
    134         (var setOutput, var setDiff) = Set(new () { Settings = setSettings });
    135 
    136         // Assert that the settings are added
    137         Assert.IsNotNull(setOutput);
    138         Assert.AreEqual(setOutput.Action, ActionPropertyValuePartial);
    139         AssertMockProperties(setOutput.Settings, "mock");
    140         AssertSettingsAreEqual(expected, setOutput.Settings);
    141         AssertDiffState(setDiff, [ SettingsPropertyName ]);
    142     }
    143 
    144     /// <summary>
    145     /// Calls `set` on the `user-settings-file` resource to update fields.
    146     /// </summary>
    147     /// <param name="action">The action value.</param>
    148     [Test]
    149     [TestCase(ActionPropertyValueFull)]
    150     [TestCase(ActionPropertyValuePartial)]
    151     public void UserSettingsFile_Set_UpdateFields(string action)
    152     {
    153         // Add mock properties to the settings
    154         var set1Settings = new JsonObject();
    155         AddOrModifyMockProperties(set1Settings, "mock_old");
    156         Set(new () { Action = ActionPropertyValuePartial, Settings = set1Settings });
    157 
    158         // Call `set` to update the settings
    159         var set2Settings = GetSettingsArg(action);
    160         AddOrModifyMockProperties(set2Settings, "mock_new");
    161 
    162         (var setOutput, var setDiff) = Set(new () { Action = action, Settings = set2Settings });
    163 
    164         var expected = GetCurrentUserSettings();
    165 
    166         // Assert that the settings are updated
    167         Assert.IsNotNull(setOutput);
    168         Assert.AreEqual(action, setOutput.Action);
    169         AssertMockProperties(setOutput.Settings, "mock_new");
    170         AssertSettingsAreEqual(expected, setOutput.Settings);
    171         AssertDiffState(setDiff, [ SettingsPropertyName ]);
    172     }
    173 
    174     /// <summary>
    175     /// Calls `test` on the `user-settings-file` resource to check if the settings are in desired state.
    176     /// </summary>
    177     /// <param name="action">The action value.</param>
    178     [Test]
    179     [TestCase(ActionPropertyValueFull)]
    180     [TestCase(ActionPropertyValuePartial)]
    181     public void UserSettingsFile_Test_InDesiredState(string action)
    182     {
    183         // Add mock properties to the settings
    184         var setSettings = new JsonObject();
    185         AddOrModifyMockProperties(setSettings, "mock");
    186         Set(new () { Action = ActionPropertyValuePartial, Settings = setSettings });
    187 
    188         // Call `test` to check the settings
    189         var testSettings = GetSettingsArg(action);
    190         AddOrModifyMockProperties(testSettings, "mock");
    191 
    192         (var testOutput, var testDiff) = Test(new () { Action = action, Settings = testSettings });
    193 
    194         var expected = GetCurrentUserSettings();
    195 
    196         // Assert that the settings are in desired state
    197         Assert.IsNotNull(testOutput);
    198         Assert.AreEqual(action, testOutput.Action);
    199         AssertMockProperties(testOutput.Settings, "mock");
    200         AssertSettingsAreEqual(expected, testOutput.Settings);
    201         Assert.IsTrue(testOutput.InDesiredState);
    202         AssertDiffState(testDiff, []);
    203     }
    204 
    205     /// <summary>
    206     /// Calls `test` on the `user-settings-file` resource to check if the settings are not in desired state.
    207     /// </summary>
    208     /// <param name="action">The action value.</param>
    209     [Test]
    210     [TestCase(ActionPropertyValueFull)]
    211     [TestCase(ActionPropertyValuePartial)]
    212     public void UserSettingsFile_Test_NotInDesiredState(string action)
    213     {
    214         // Add mock properties to the settings
    215         var setSettings = new JsonObject();
    216         AddOrModifyMockProperties(setSettings, "mock_set");
    217         Set(new () { Action = ActionPropertyValuePartial, Settings = setSettings });
    218 
    219         // Call `test` to check the settings
    220         var testSettings = GetSettingsArg(action);
    221         AddOrModifyMockProperties(testSettings, "mock_test");
    222 
    223         (var testOutput, var testDiff) = Test(new () { Action = action, Settings = testSettings });
    224 
    225         var expected = GetCurrentUserSettings();
    226 
    227         // Assert that the settings are not in desired state
    228         Assert.IsNotNull(testOutput);
    229         Assert.AreEqual(action, testOutput.Action);
    230         AssertMockProperties(testOutput.Settings, "mock_set");
    231         AssertSettingsAreEqual(expected, testOutput.Settings);
    232         Assert.IsFalse(testOutput.InDesiredState);
    233         AssertDiffState(testDiff, [ SettingsPropertyName ]);
    234     }
    235 
    236     /// <summary>
    237     /// Calls `export` on the `user-settings-file` resource to export the settings.
    238     /// </summary>
    239     [Test]
    240     public void UserSettingsFile_Export()
    241     {
    242         var expected = GetCurrentUserSettings();
    243         var exportOutput = Export(new ());
    244 
    245         Assert.IsNotNull(exportOutput);
    246         Assert.IsNull(exportOutput.Action);
    247         AssertSettingsAreEqual(expected, exportOutput.Settings);
    248     }
    249 
    250     /// <summary>
    251     /// Calls `get` on the `user-settings-file` resource.
    252     /// </summary>
    253     /// <param name="resourceData">The input resource data.</param>
    254     /// <returns>The output resource data.</returns>
    255     private static UserSettingsFileResourceData Get(UserSettingsFileResourceData resourceData)
    256     {
    257         var result = RunDSCv3Command(UserSettingsFileResource, GetFunction, resourceData);
    258         AssertSuccessfulResourceRun(ref result);
    259         return GetSingleOutputLineAs<UserSettingsFileResourceData>(result.StdOut);
    260     }
    261 
    262     /// <summary>
    263     /// Calls `set` on the `user-settings-file` resource.
    264     /// </summary>
    265     /// <param name="resourceData">The input resource data.</param>
    266     /// <returns>The output resource data and the diff.</returns>
    267     private static (UserSettingsFileResourceData, List<string>) Set(UserSettingsFileResourceData resourceData)
    268     {
    269         var result = RunDSCv3Command(UserSettingsFileResource, SetFunction, resourceData);
    270         AssertSuccessfulResourceRun(ref result);
    271         return GetSingleOutputLineAndDiffAs<UserSettingsFileResourceData>(result.StdOut);
    272     }
    273 
    274     /// <summary>
    275     /// Calls `test` on the `user-settings-file` resource.
    276     /// </summary>
    277     /// <param name="resourceData">The input resource data.</param>
    278     /// <returns>The output resource data and the diff.</returns>
    279     private static (UserSettingsFileResourceData, List<string>) Test(UserSettingsFileResourceData resourceData)
    280     {
    281         var result = RunDSCv3Command(UserSettingsFileResource, TestFunction, resourceData);
    282         AssertSuccessfulResourceRun(ref result);
    283         return GetSingleOutputLineAndDiffAs<UserSettingsFileResourceData>(result.StdOut);
    284     }
    285 
    286     /// <summary>
    287     /// Calls `export` on the `user-settings-file` resource.
    288     /// </summary>
    289     /// <param name="resourceData">The input resource data.</param>
    290     /// <returns>The output resource data.</returns>
    291     private static UserSettingsFileResourceData Export(UserSettingsFileResourceData resourceData)
    292     {
    293         var result = RunDSCv3Command(UserSettingsFileResource, ExportFunction, resourceData);
    294         AssertSuccessfulResourceRun(ref result);
    295         return GetSingleOutputLineAs<UserSettingsFileResourceData>(result.StdOut);
    296     }
    297 
    298     /// <summary>
    299     /// Gets the current user settings from the settings file.
    300     /// </summary>
    301     /// <returns>The current user settings as a JsonObject.</returns>
    302     private static JsonObject GetCurrentUserSettings()
    303     {
    304         var settingsContent = File.ReadAllText(WinGetSettingsHelper.GetUserSettingsPath());
    305         return JsonNode.Parse(settingsContent).AsObject();
    306     }
    307 
    308     /// <summary>
    309     /// Adds or modifies mock properties in the settings.
    310     /// </summary>
    311     /// <param name="settings">Target settings.</param>
    312     /// <param name="value">The mock value.</param>
    313     private static void AddOrModifyMockProperties(JsonObject settings, string value)
    314     {
    315         settings[SettingsMock] = value;
    316         settings[SettingsMockObject] ??= new JsonObject();
    317         settings[SettingsMockObject][SettingsMockNested] = value;
    318     }
    319 
    320     /// <summary>
    321     /// Asserts that the settings contain the expected mock properties.
    322     /// </summary>
    323     /// <param name="settings">Target settings.</param>
    324     /// <param name="value">The expected mock value.</param>
    325     private static void AssertMockProperties(JsonObject settings, string value)
    326     {
    327         Assert.IsNotNull(settings);
    328         Assert.IsTrue(settings.ContainsKey(SettingsMock));
    329         Assert.AreEqual(settings[SettingsMock].ToString(), value);
    330         Assert.IsTrue(settings.ContainsKey(SettingsMockObject));
    331         Assert.IsTrue(settings[SettingsMockObject].AsObject().ContainsKey(SettingsMockNested));
    332         Assert.AreEqual(settings[SettingsMockObject][SettingsMockNested].ToString(), value);
    333     }
    334 
    335     /// <summary>
    336     /// Asserts that the diff state is as expected.
    337     /// </summary>
    338     /// <param name="expected">The expected settings.</param>
    339     /// <param name="actual">The actual settings.</param>
    340     private static void AssertSettingsAreEqual(JsonObject expected, JsonObject actual)
    341     {
    342         Assert.IsTrue(JsonNode.DeepEquals(expected, actual));
    343     }
    344 
    345     /// <summary>
    346     /// Gets the settings argument based on the action.
    347     /// </summary>
    348     /// <param name="action">The action value.</param>
    349     /// <returns>The settings argument as a JsonObject.</returns>
    350     private static JsonObject GetSettingsArg(string action) => action == ActionPropertyValueFull ? GetCurrentUserSettings() : new ();
    351 
    352     private class UserSettingsFileResourceData
    353     {
    354         [JsonPropertyName(InDesiredStatePropertyName)]
    355         public bool? InDesiredState { get; set; }
    356 
    357         [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
    358         public string Action { get; set; }
    359 
    360         public JsonObject Settings { get; set; }
    361     }
    362 }