winget-cli

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

Settings.cpp (8145B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "TestCommon.h"
      5 
      6 #include <AppInstallerRuntime.h>
      7 #include <AppInstallerStrings.h>
      8 #include <winget/Settings.h>
      9 
     10 using namespace AppInstaller::Runtime;
     11 using namespace AppInstaller::Settings;
     12 using namespace AppInstaller::Utility;
     13 
     14 TEST_CASE("ReadEmptySetting", "[settings]")
     15 {
     16     StreamDefinition name{ Type::Standard, "nonexistentsetting" };
     17 
     18     auto result = Stream{ name }.Get();
     19     REQUIRE(!result);
     20 }
     21 
     22 TEST_CASE("SetAndReadSetting", "[settings]")
     23 {
     24     StreamDefinition name{ Type::Standard, "testsettingname" };
     25     std::string value = "This is the test setting value";
     26 
     27     Stream stream{ name };
     28     REQUIRE(stream.Set(value));
     29 
     30     auto result = stream.Get();
     31     REQUIRE(static_cast<bool>(result));
     32 
     33     std::string settingValue = ReadEntireStream(*result);
     34     REQUIRE(value == settingValue);
     35 }
     36 
     37 TEST_CASE("SetAndReadSettingInContainer", "[settings]")
     38 {
     39     StreamDefinition name{ Type::Standard, "testcontainer/testsettingname" };
     40     std::string value = "This is the test setting value from inside a container";
     41 
     42     Stream stream{ name };
     43     REQUIRE(stream.Set(value));
     44 
     45     auto result = stream.Get();
     46     REQUIRE(static_cast<bool>(result));
     47 
     48     std::string settingValue = ReadEntireStream(*result);
     49     REQUIRE(value == settingValue);
     50 }
     51 
     52 TEST_CASE("RemoveSetting", "[settings]")
     53 {
     54     StreamDefinition name{ Type::Standard, "testsettingname" };
     55     std::string value = "This is the test setting value to be removed";
     56 
     57     Stream stream{ name };
     58     REQUIRE(stream.Set(value));
     59 
     60     {
     61         auto result = stream.Get();
     62         REQUIRE(static_cast<bool>(result));
     63 
     64         std::string settingValue = ReadEntireStream(*result);
     65         REQUIRE(value == settingValue);
     66     }
     67 
     68     stream.Remove();
     69 
     70     auto result = stream.Get();
     71     REQUIRE(!static_cast<bool>(result));
     72 }
     73 
     74 TEST_CASE("SetAndReadUserFileSetting", "[settings]")
     75 {
     76     StreamDefinition name{ Type::UserFile, "userfilesetting" };
     77     std::string value = "This is the test setting value for a user file";
     78 
     79     Stream stream{ name };
     80     REQUIRE(stream.Set(value));
     81 
     82     auto result = stream.Get();
     83     REQUIRE(static_cast<bool>(result));
     84 
     85     std::string settingValue = ReadEntireStream(*result);
     86     REQUIRE(value == settingValue);
     87 }
     88 
     89 TEST_CASE("ReadEmptySecureSetting", "[settings]")
     90 {
     91     StreamDefinition name{ Type::Secure, "secure_nonexistentsetting" };
     92 
     93     auto result = Stream{ name }.Get();
     94     REQUIRE(!result);
     95 }
     96 
     97 TEST_CASE("SetAndReadSecureSetting", "[settings]")
     98 {
     99     StreamDefinition name{ Type::Secure, "secure_testsettingname" };
    100     std::string value = "This is the test setting value";
    101 
    102     Stream stream{ name };
    103     REQUIRE(stream.Set(value));
    104 
    105     auto result = stream.Get();
    106     REQUIRE(static_cast<bool>(result));
    107 
    108     std::string settingValue = ReadEntireStream(*result);
    109     REQUIRE(value == settingValue);
    110 }
    111 
    112 TEST_CASE("SetAndReadSecureSettingInContainer", "[settings]")
    113 {
    114     StreamDefinition name{ Type::Secure, "testcontainer/secure_testsettingname" };
    115     std::string value = "This is the test setting value from inside a container";
    116 
    117     Stream stream{ name };
    118     REQUIRE(stream.Set(value));
    119 
    120     auto result = stream.Get();
    121     REQUIRE(static_cast<bool>(result));
    122 
    123     std::string settingValue = ReadEntireStream(*result);
    124     REQUIRE(value == settingValue);
    125 }
    126 
    127 TEST_CASE("RemoveSecureSetting", "[settings]")
    128 {
    129     StreamDefinition name{ Type::Secure, "secure_testsettingname" };
    130     std::string value = "This is the test setting value to be removed";
    131 
    132     Stream stream{ name };
    133     REQUIRE(stream.Set(value));
    134 
    135     {
    136         auto result = stream.Get();
    137         REQUIRE(static_cast<bool>(result));
    138 
    139         std::string settingValue = ReadEntireStream(*result);
    140         REQUIRE(value == settingValue);
    141     }
    142 
    143     stream.Remove();
    144 
    145     auto result = stream.Get();
    146     REQUIRE(!static_cast<bool>(result));
    147 }
    148 
    149 TEST_CASE("SetAndReadSecureSetting_SecureDataRemoved", "[settings]")
    150 {
    151     StreamDefinition name{ Type::Secure, "secure_testsettingname" };
    152     std::string value = "This is the test setting value";
    153 
    154     Stream stream{ name };
    155     REQUIRE(stream.Set(value));
    156 
    157     auto result = stream.Get();
    158     REQUIRE(static_cast<bool>(result));
    159 
    160     std::string settingValue = ReadEntireStream(*result);
    161     REQUIRE(value == settingValue);
    162 
    163     std::filesystem::remove(GetPathTo(PathName::SecureSettingsForRead) / name.Name);
    164 
    165     REQUIRE_THROWS_HR(stream.Get(), SPAPI_E_FILE_HASH_NOT_IN_CATALOG);
    166 }
    167 
    168 TEST_CASE("SetAndReadSecureSetting_DataTampered", "[settings]")
    169 {
    170     StreamDefinition name{ Type::Secure, "secure_testsettingname" };
    171     std::string value = "This is the test setting value";
    172 
    173     Stream stream{ name };
    174     REQUIRE(stream.Set(value));
    175 
    176     auto result = stream.Get();
    177     REQUIRE(static_cast<bool>(result));
    178 
    179     std::string settingValue = ReadEntireStream(*result);
    180     REQUIRE(value == settingValue);
    181 
    182     StreamDefinition insecureName = name;
    183     insecureName.Type = Type::Standard;
    184 
    185     REQUIRE(Stream{ insecureName }.Set("Tampered data"));
    186 
    187     REQUIRE_THROWS_HR(stream.Get(), HRESULT_FROM_WIN32(ERROR_DATA_CHECKSUM_ERROR));
    188 }
    189 
    190 TEST_CASE("SetChangeAndReadSetting", "[settings]")
    191 {
    192     StreamDefinition name{ Type::Standard, "testsettingname" };
    193     std::string value1 = "This is the test setting value1";
    194     std::string value2 = "This is the test setting value2, which is different";
    195     std::string value3 = "This is the test setting value3; also different";
    196 
    197     name.Type = GENERATE(Type::Standard, Type::Secure);
    198     INFO(ToString(name.Type));
    199 
    200     // Set the value on stream 1
    201     Stream stream1{ name };
    202     REQUIRE(stream1.Set(value1));
    203 
    204     // Read the value on stream 2 to verify
    205     {
    206         Stream stream2{ name };
    207 
    208         auto result = stream2.Get();
    209         REQUIRE(static_cast<bool>(result));
    210 
    211         std::string settingValue = ReadEntireStream(*result);
    212         REQUIRE(value1 == settingValue);
    213 
    214         // Set the value on stream 2
    215         REQUIRE(stream2.Set(value2));
    216     }
    217 
    218     // Attempt to set the value on stream 1 again
    219     REQUIRE(!stream1.Set(value3));
    220 
    221     // Attempting to set again should still not work
    222     REQUIRE(!stream1.Set(value3));
    223 
    224     // Ensure that the value remains value 2
    225     auto result = stream1.Get();
    226     REQUIRE(static_cast<bool>(result));
    227 
    228     std::string settingValue = ReadEntireStream(*result);
    229     REQUIRE(value2 == settingValue);
    230 
    231     // Now that we have read it, we can update it
    232     REQUIRE(stream1.Set(value3));
    233 
    234     result = stream1.Get();
    235     REQUIRE(static_cast<bool>(result));
    236 
    237     settingValue = ReadEntireStream(*result);
    238     REQUIRE(value3 == settingValue);
    239 }
    240 
    241 TEST_CASE("AttemptSetOnNewValue", "[settings]")
    242 {
    243     StreamDefinition name{ Type::Standard, "testsettingname" };
    244     std::string value1 = "This is the test setting value1";
    245     std::string value2 = "This is the test setting value2, which is different";
    246 
    247     name.Type = GENERATE(Type::Standard, Type::Secure);
    248     INFO(ToString(name.Type));
    249 
    250     // Remove the stream
    251     Stream{ name }.Remove();
    252 
    253     Stream stream1{ name };
    254     REQUIRE(!stream1.Get());
    255 
    256     // Set the value on stream 2
    257     {
    258         Stream stream2{ name };
    259         REQUIRE(stream2.Set(value1));
    260     }
    261 
    262     // Attempt to set the value on stream 1 again
    263     REQUIRE(!stream1.Set(value2));
    264 
    265     // Attempting to set again should still not work
    266     REQUIRE(!stream1.Set(value2));
    267 
    268     // Ensure that the value remains value 2
    269     auto result = stream1.Get();
    270     REQUIRE(static_cast<bool>(result));
    271 
    272     std::string settingValue = ReadEntireStream(*result);
    273     REQUIRE(value1 == settingValue);
    274 
    275     // Now that we have read it, we can update it
    276     REQUIRE(stream1.Set(value2));
    277 
    278     result = stream1.Get();
    279     REQUIRE(static_cast<bool>(result));
    280 
    281     settingValue = ReadEntireStream(*result);
    282     REQUIRE(value2 == settingValue);
    283 }