UserSettings.cpp (24691B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "TestCommon.h" 5 #include "TestSettings.h" 6 #include <AppInstallerRuntime.h> 7 #include <winget/Settings.h> 8 #include "AppInstallerLogging.h" 9 10 #include <AppInstallerErrors.h> 11 12 #include <filesystem> 13 #include <string> 14 #include <chrono> 15 16 using namespace AppInstaller::Settings; 17 using namespace AppInstaller::Logging; 18 using namespace AppInstaller::Runtime; 19 using namespace TestCommon; 20 using namespace std::string_literals; 21 using namespace std::string_view_literals; 22 using namespace std::chrono_literals; 23 24 namespace 25 { 26 static constexpr std::string_view s_goodJson = "{}"; 27 static constexpr std::string_view s_badJson = "{"; 28 static constexpr std::string_view s_settings = "settings.json"sv; 29 static constexpr std::string_view s_settingsBackup = "settings.json.backup"sv; 30 } 31 32 TEST_CASE("UserSettingsFilePaths", "[settings]") 33 { 34 auto settingsPath = UserSettings::SettingsFilePath(); 35 auto expectedPath = GetPathTo(PathName::UserFileSettings) / "settings.json"; 36 REQUIRE(settingsPath == expectedPath); 37 } 38 39 TEST_CASE("UserSettingsType", "[settings]") 40 { 41 // These are all the possible combinations between (7 of them are impossible): 42 // 1 - No settings.json file exists 43 // 2 - Bad settings.json file 44 // 3 - No settings.json.backup file exists 45 // 4 - Bad settings.json.backup file exists. 46 auto again = DeleteUserSettingsFiles(); 47 48 SECTION("No setting.json No setting.json.backup") 49 { 50 UserSettingsTest userSettingTest; 51 REQUIRE(userSettingTest.GetType() == UserSettingsType::Default); 52 } 53 SECTION("No setting.json Bad setting.json.backup") 54 { 55 SetSetting(Stream::BackupUserSettings, s_badJson); 56 57 UserSettingsTest userSettingTest; 58 REQUIRE(userSettingTest.GetType() == UserSettingsType::Default); 59 } 60 SECTION("No setting.json Good setting.json.backup") 61 { 62 SetSetting(Stream::BackupUserSettings, s_goodJson); 63 64 UserSettingsTest userSettingTest; 65 REQUIRE(userSettingTest.GetType() == UserSettingsType::Backup); 66 } 67 SECTION("Bad setting.json No setting.json.backup") 68 { 69 SetSetting(Stream::PrimaryUserSettings, s_badJson); 70 71 UserSettingsTest userSettingTest; 72 REQUIRE(userSettingTest.GetType() == UserSettingsType::Default); 73 } 74 SECTION("Bad setting.json Bad setting.json.backup") 75 { 76 SetSetting(Stream::PrimaryUserSettings, s_badJson); 77 SetSetting(Stream::BackupUserSettings, s_badJson); 78 79 UserSettingsTest userSettingTest; 80 REQUIRE(userSettingTest.GetType() == UserSettingsType::Default); 81 } 82 SECTION("Bad setting.json Good setting.json.backup") 83 { 84 SetSetting(Stream::PrimaryUserSettings, s_badJson); 85 SetSetting(Stream::BackupUserSettings, s_goodJson); 86 87 UserSettingsTest userSettingTest; 88 REQUIRE(userSettingTest.GetType() == UserSettingsType::Backup); 89 } 90 SECTION("Good setting.json No setting.json.backup") 91 { 92 SetSetting(Stream::PrimaryUserSettings, s_goodJson); 93 94 UserSettingsTest userSettingTest; 95 REQUIRE(userSettingTest.GetType() == UserSettingsType::Standard); 96 } 97 SECTION("Good setting.json Bad setting.json.backup") 98 { 99 SetSetting(Stream::PrimaryUserSettings, s_goodJson); 100 SetSetting(Stream::BackupUserSettings, s_badJson); 101 102 UserSettingsTest userSettingTest; 103 REQUIRE(userSettingTest.GetType() == UserSettingsType::Standard); 104 } 105 SECTION("Good setting.json Good setting.json.backup") 106 { 107 SetSetting(Stream::PrimaryUserSettings, s_goodJson); 108 SetSetting(Stream::BackupUserSettings, s_goodJson); 109 110 UserSettingsTest userSettingTest; 111 REQUIRE(userSettingTest.GetType() == UserSettingsType::Standard); 112 } 113 } 114 115 TEST_CASE("UserSettingsCreateFiles", "[settings]") 116 { 117 auto again = DeleteUserSettingsFiles(); 118 119 auto settingsPath = UserSettings::SettingsFilePath(); 120 auto settingsBackupPath = GetPathTo(Stream::BackupUserSettings); 121 122 SECTION("No settings.json create new") 123 { 124 REQUIRE(!std::filesystem::exists(settingsPath)); 125 REQUIRE(!std::filesystem::exists(settingsBackupPath)); 126 127 UserSettingsTest userSettingTest; 128 REQUIRE(userSettingTest.GetType() == UserSettingsType::Default); 129 userSettingTest.PrepareToShellExecuteFile(); 130 131 REQUIRE(std::filesystem::exists(settingsPath)); 132 REQUIRE(!std::filesystem::exists(settingsBackupPath)); 133 } 134 SECTION("Good settings.json create new backup") 135 { 136 SetSetting(Stream::PrimaryUserSettings, s_goodJson); 137 REQUIRE(std::filesystem::exists(settingsPath)); 138 REQUIRE(!std::filesystem::exists(settingsBackupPath)); 139 140 UserSettingsTest userSettingTest; 141 REQUIRE(userSettingTest.GetType() == UserSettingsType::Standard); 142 userSettingTest.PrepareToShellExecuteFile(); 143 144 REQUIRE(std::filesystem::exists(settingsPath)); 145 REQUIRE(std::filesystem::exists(settingsBackupPath)); 146 } 147 } 148 149 TEST_CASE("SettingProgressBar", "[settings]") 150 { 151 auto again = DeleteUserSettingsFiles(); 152 153 SECTION("Default value") 154 { 155 UserSettingsTest userSettingTest; 156 157 REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Accent); 158 REQUIRE(userSettingTest.GetWarnings().size() == 0); 159 } 160 SECTION("Accent") 161 { 162 std::string_view json = R"({ "visual": { "progressBar": "accent" } })"; 163 SetSetting(Stream::PrimaryUserSettings, json); 164 UserSettingsTest userSettingTest; 165 166 REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Accent); 167 REQUIRE(userSettingTest.GetWarnings().size() == 0); 168 } 169 SECTION("Rainbow") 170 { 171 std::string_view json = R"({ "visual": { "progressBar": "rainbow" } })"; 172 SetSetting(Stream::PrimaryUserSettings, json); 173 UserSettingsTest userSettingTest; 174 175 REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Rainbow); 176 REQUIRE(userSettingTest.GetWarnings().size() == 0); 177 } 178 SECTION("retro") 179 { 180 std::string_view json = R"({ "visual": { "progressBar": "retro" } })"; 181 SetSetting(Stream::PrimaryUserSettings, json); 182 UserSettingsTest userSettingTest; 183 184 REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Retro); 185 REQUIRE(userSettingTest.GetWarnings().size() == 0); 186 } 187 SECTION("Bad value") 188 { 189 std::string_view json = R"({ "visual": { "progressBar": "fake" } })"; 190 SetSetting(Stream::PrimaryUserSettings, json); 191 UserSettingsTest userSettingTest; 192 193 REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Accent); 194 REQUIRE(userSettingTest.GetWarnings().size() == 1); 195 } 196 SECTION("Bad value type") 197 { 198 std::string_view json = R"({ "visual": { "progressBar": 5 } })"; 199 SetSetting(Stream::PrimaryUserSettings, json); 200 UserSettingsTest userSettingTest; 201 202 REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Accent); 203 REQUIRE(userSettingTest.GetWarnings().size() == 1); 204 } 205 } 206 207 TEST_CASE("SettingsAnonymizePathForDisplay", "[settings]") 208 { 209 auto again = DeleteUserSettingsFiles(); 210 211 SECTION("Default") 212 { 213 UserSettingsTest userSettingTest; 214 215 REQUIRE(userSettingTest.Get<Setting::AnonymizePathForDisplay>() == true); 216 REQUIRE(userSettingTest.GetWarnings().size() == 0); 217 } 218 SECTION("True") 219 { 220 std::string_view json = R"({ "visual": { "anonymizeDisplayedPaths": true } })"; 221 SetSetting(Stream::PrimaryUserSettings, json); 222 UserSettingsTest userSettingTest; 223 224 REQUIRE(userSettingTest.Get<Setting::AnonymizePathForDisplay>() == true); 225 REQUIRE(userSettingTest.GetWarnings().size() == 0); 226 } 227 SECTION("False") 228 { 229 std::string_view json = R"({ "visual": { "anonymizeDisplayedPaths": false } })"; 230 SetSetting(Stream::PrimaryUserSettings, json); 231 UserSettingsTest userSettingTest; 232 233 REQUIRE(userSettingTest.Get<Setting::AnonymizePathForDisplay>() == false); 234 REQUIRE(userSettingTest.GetWarnings().size() == 0); 235 } 236 SECTION("Invalid Value") 237 { 238 std::string_view json = R"({ "visual": { "anonymizeDisplayedPaths": "notBoolean" } })"; 239 SetSetting(Stream::PrimaryUserSettings, json); 240 UserSettingsTest userSettingTest; 241 242 REQUIRE(userSettingTest.Get<Setting::AnonymizePathForDisplay>() == true); 243 REQUIRE(userSettingTest.GetWarnings().size() == 1); 244 } 245 } 246 247 TEST_CASE("SettingLoggingLevelPreference", "[settings]") 248 { 249 auto again = DeleteUserSettingsFiles(); 250 251 SECTION("Default value") 252 { 253 UserSettingsTest userSettingTest; 254 255 REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info); 256 REQUIRE(userSettingTest.GetWarnings().size() == 0); 257 } 258 SECTION("Info") 259 { 260 std::string_view json = R"({ "logging": { "level": "info" } })"; 261 SetSetting(Stream::PrimaryUserSettings, json); 262 UserSettingsTest userSettingTest; 263 264 REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info); 265 REQUIRE(userSettingTest.GetWarnings().size() == 0); 266 } 267 SECTION("Verbose") 268 { 269 std::string_view json = R"({ "logging": { "level": "verbose" } })"; 270 SetSetting(Stream::PrimaryUserSettings, json); 271 UserSettingsTest userSettingTest; 272 273 REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Verbose); 274 REQUIRE(userSettingTest.GetWarnings().size() == 0); 275 } 276 SECTION("Warning") 277 { 278 std::string_view json = R"({ "logging": { "level": "warning" } })"; 279 SetSetting(Stream::PrimaryUserSettings, json); 280 UserSettingsTest userSettingTest; 281 282 REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Warning); 283 REQUIRE(userSettingTest.GetWarnings().size() == 0); 284 } 285 SECTION("Error") 286 { 287 std::string_view json = R"({ "logging": { "level": "error" } })"; 288 SetSetting(Stream::PrimaryUserSettings, json); 289 UserSettingsTest userSettingTest; 290 291 REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Error); 292 REQUIRE(userSettingTest.GetWarnings().size() == 0); 293 } 294 SECTION("Critical") 295 { 296 std::string_view json = R"({ "logging": { "level": "critical" } })"; 297 SetSetting(Stream::PrimaryUserSettings, json); 298 UserSettingsTest userSettingTest; 299 300 REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Crit); 301 REQUIRE(userSettingTest.GetWarnings().size() == 0); 302 } 303 SECTION("Bad value") 304 { 305 std::string_view json = R"({ "logging": { "level": "fake" } })"; 306 SetSetting(Stream::PrimaryUserSettings, json); 307 UserSettingsTest userSettingTest; 308 309 REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info); 310 REQUIRE(userSettingTest.GetWarnings().size() == 1); 311 } 312 SECTION("Bad value type") 313 { 314 std::string_view json = R"({ "logging": { "level": 5 } })"; 315 SetSetting(Stream::PrimaryUserSettings, json); 316 UserSettingsTest userSettingTest; 317 318 REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info); 319 REQUIRE(userSettingTest.GetWarnings().size() == 1); 320 } 321 } 322 323 TEST_CASE("SettingAutoUpdateIntervalInMinutes", "[settings]") 324 { 325 auto again = DeleteUserSettingsFiles(); 326 327 constexpr static auto cinq = 5min; 328 constexpr static auto cero = 0min; 329 constexpr static auto threehundred = 300min; 330 331 std::chrono::minutes defaultAutoUpdateTime{}; 332 333 { 334 SetSetting(Stream::PrimaryUserSettings, ""); 335 UserSettingsTest userSettingTest; 336 defaultAutoUpdateTime = userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>(); 337 } 338 339 SECTION("Valid value 0") 340 { 341 std::string_view json = R"({ "source": { "autoUpdateIntervalInMinutes": 0 } })"; 342 SetSetting(Stream::PrimaryUserSettings, json); 343 UserSettingsTest userSettingTest; 344 345 REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == cero); 346 REQUIRE(userSettingTest.GetWarnings().size() == 0); 347 } 348 SECTION("Valid value 300") 349 { 350 std::string_view json = R"({ "source": { "autoUpdateIntervalInMinutes": 300 } })"; 351 SetSetting(Stream::PrimaryUserSettings, json); 352 UserSettingsTest userSettingTest; 353 354 REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == threehundred); 355 REQUIRE(userSettingTest.GetWarnings().size() == 0); 356 } 357 SECTION("Invalid type negative integer") 358 { 359 std::string_view json = R"({ "source": { "autoUpdateIntervalInMinutes": -20 } })"; 360 SetSetting(Stream::PrimaryUserSettings, json); 361 UserSettingsTest userSettingTest; 362 363 REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == defaultAutoUpdateTime); 364 REQUIRE(userSettingTest.GetWarnings().size() == 1); 365 } 366 SECTION("Invalid type string") 367 { 368 std::string_view json = R"({ "source": { "autoUpdateIntervalInMinutes": "not a number" } })"; 369 SetSetting(Stream::PrimaryUserSettings, json); 370 UserSettingsTest userSettingTest; 371 372 REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == defaultAutoUpdateTime); 373 REQUIRE(userSettingTest.GetWarnings().size() == 1); 374 } 375 SECTION("Overridden by Group Policy") 376 { 377 auto policiesKey = RegCreateVolatileTestRoot(); 378 SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, (DWORD)threehundred.count()); 379 GroupPolicyTestOverride policies{ policiesKey.get() }; 380 381 std::string_view json = R"({ "source": { "autoUpdateIntervalInMinutes": 5 } })"; 382 SetSetting(Stream::PrimaryUserSettings, json); 383 UserSettingsTest userSettingTest; 384 385 REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == threehundred); 386 REQUIRE(userSettingTest.GetWarnings().size() == 0); 387 } 388 SECTION("Invalid Group Policy") 389 { 390 auto policiesKey = RegCreateVolatileTestRoot(); 391 SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, L"Not a number"s); 392 GroupPolicyTestOverride policies{ policiesKey.get() }; 393 394 std::string_view json = R"({ "source": { "autoUpdateIntervalInMinutes": 5 } })"; 395 SetSetting(Stream::PrimaryUserSettings, json); 396 UserSettingsTest userSettingTest; 397 398 REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == cinq); 399 REQUIRE(userSettingTest.GetWarnings().size() == 0); 400 } 401 } 402 403 TEST_CASE("SettingsExperimentalCmd", "[settings]") 404 { 405 auto again = DeleteUserSettingsFiles(); 406 407 SECTION("Feature off default") 408 { 409 UserSettingsTest userSettingTest; 410 411 REQUIRE(!userSettingTest.Get<Setting::EFExperimentalCmd>()); 412 REQUIRE(userSettingTest.GetWarnings().size() == 0); 413 } 414 SECTION("Feature on") 415 { 416 std::string_view json = R"({ "experimentalFeatures": { "experimentalCmd": true } })"; 417 SetSetting(Stream::PrimaryUserSettings, json); 418 UserSettingsTest userSettingTest; 419 420 REQUIRE(userSettingTest.Get<Setting::EFExperimentalCmd>()); 421 REQUIRE(userSettingTest.GetWarnings().size() == 0); 422 } 423 SECTION("Feature off") 424 { 425 std::string_view json = R"({ "experimentalFeatures": { "experimentalCmd": false } })"; 426 SetSetting(Stream::PrimaryUserSettings, json); 427 UserSettingsTest userSettingTest; 428 429 REQUIRE(!userSettingTest.Get<Setting::EFExperimentalCmd>()); 430 REQUIRE(userSettingTest.GetWarnings().size() == 0); 431 } 432 SECTION("Invalid value") 433 { 434 std::string_view json = R"({ "experimentalFeatures": { "experimentalCmd": "string" } })"; 435 SetSetting(Stream::PrimaryUserSettings, json); 436 UserSettingsTest userSettingTest; 437 438 REQUIRE(!userSettingTest.Get<Setting::EFExperimentalCmd>()); 439 REQUIRE(userSettingTest.GetWarnings().size() == 1); 440 } 441 SECTION("Disabled by group policy") 442 { 443 auto policiesKey = RegCreateVolatileTestRoot(); 444 SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, L"Not a number"s); 445 GroupPolicyTestOverride policies{ policiesKey.get() }; 446 447 std::string_view json = R"({ "experimentalFeatures": { "experimentalCmd": true } })"; 448 SetSetting(Stream::PrimaryUserSettings, json); 449 UserSettingsTest userSettingTest; 450 451 // Experimental features group policy is applied at the ExperimentalFeature level, 452 // so it doesn't affect the settings. 453 REQUIRE(userSettingTest.Get<Setting::EFExperimentalCmd>()); 454 REQUIRE(userSettingTest.GetWarnings().size() == 0); 455 } 456 } 457 458 TEST_CASE("SettingsPortablePackageUserRoot", "[settings]") 459 { 460 auto again = DeleteUserSettingsFiles(); 461 462 SECTION("Relative path") 463 { 464 std::string_view json = R"({ "installBehavior": { "portablePackageUserRoot": "%LOCALAPPDATA%/Portable/Root" } })"; 465 SetSetting(Stream::PrimaryUserSettings, json); 466 UserSettingsTest userSettingTest; 467 468 REQUIRE(userSettingTest.Get<Setting::PortablePackageUserRoot>().empty()); 469 470 auto warnings = userSettingTest.GetWarnings(); 471 REQUIRE(warnings.size() == 1); 472 REQUIRE(warnings[0].Message == AppInstaller::StringResource::String::SettingsWarningInvalidFieldValue); 473 REQUIRE(warnings[0].Path == ".installBehavior.portablePackageUserRoot"); 474 } 475 SECTION("Valid path") 476 { 477 std::string_view json = R"({ "installBehavior": { "portablePackageUserRoot": "C:/Foo/Bar" } })"; 478 SetSetting(Stream::PrimaryUserSettings, json); 479 UserSettingsTest userSettingTest; 480 481 REQUIRE(userSettingTest.Get<Setting::PortablePackageUserRoot>() == "C:/Foo/Bar"); 482 REQUIRE(userSettingTest.GetWarnings().size() == 0); 483 } 484 } 485 486 TEST_CASE("SettingsPortablePackageMachineRoot", "[settings]") 487 { 488 auto again = DeleteUserSettingsFiles(); 489 490 SECTION("Relative path") 491 { 492 std::string_view json = R"({ "installBehavior": { "portablePackageMachineRoot": "%LOCALAPPDATA%/Portable/Root" } })"; 493 SetSetting(Stream::PrimaryUserSettings, json); 494 UserSettingsTest userSettingTest; 495 496 REQUIRE(userSettingTest.Get<Setting::PortablePackageMachineRoot>().empty()); 497 498 auto warnings = userSettingTest.GetWarnings(); 499 REQUIRE(warnings.size() == 1); 500 REQUIRE(warnings[0].Message == AppInstaller::StringResource::String::SettingsWarningInvalidFieldValue); 501 REQUIRE(warnings[0].Path == ".installBehavior.portablePackageMachineRoot"); 502 } 503 SECTION("Valid path") 504 { 505 std::string_view json = R"({ "installBehavior": { "portablePackageMachineRoot": "C:/Foo/Bar" } })"; 506 SetSetting(Stream::PrimaryUserSettings, json); 507 UserSettingsTest userSettingTest; 508 509 REQUIRE(userSettingTest.Get<Setting::PortablePackageMachineRoot>() == "C:/Foo/Bar"); 510 REQUIRE(userSettingTest.GetWarnings().size() == 0); 511 } 512 } 513 514 TEST_CASE("SettingsDownloadDefaultDirectory", "[settings]") 515 { 516 auto again = DeleteUserSettingsFiles(); 517 518 SECTION("Valid path") 519 { 520 std::string_view json = R"({ "downloadBehavior": { "defaultDownloadDirectory": "C:/Foo/Bar" } })"; 521 SetSetting(Stream::PrimaryUserSettings, json); 522 UserSettingsTest userSettingTest; 523 524 REQUIRE(userSettingTest.Get<Setting::DownloadDefaultDirectory>() == "C:/Foo/Bar"); 525 REQUIRE(userSettingTest.GetWarnings().size() == 0); 526 } 527 } 528 529 TEST_CASE("SettingsConfigureDefaultModuleRoot", "[settings]") 530 { 531 auto again = DeleteUserSettingsFiles(); 532 533 SECTION("Valid path") 534 { 535 std::string_view json = R"({ "configureBehavior": { "defaultModuleRoot": "C:/Foo/Bar" } })"; 536 SetSetting(Stream::PrimaryUserSettings, json); 537 UserSettingsTest userSettingTest; 538 539 REQUIRE(userSettingTest.Get<Setting::ConfigureDefaultModuleRoot>() == "C:/Foo/Bar"); 540 REQUIRE(userSettingTest.GetWarnings().size() == 0); 541 } 542 } 543 544 TEST_CASE("SettingsArchiveExtractionMethod", "[settings]") 545 { 546 auto again = DeleteUserSettingsFiles(); 547 548 SECTION("Shell api") 549 { 550 std::string_view json = R"({ "installBehavior": { "archiveExtractionMethod": "shellApi" } })"; 551 SetSetting(Stream::PrimaryUserSettings, json); 552 UserSettingsTest userSettingTest; 553 554 REQUIRE(userSettingTest.Get<Setting::ArchiveExtractionMethod>() == AppInstaller::Archive::ExtractionMethod::ShellApi); 555 } 556 SECTION("Shell api") 557 { 558 std::string_view json = R"({ "installBehavior": { "archiveExtractionMethod": "tar" } })"; 559 SetSetting(Stream::PrimaryUserSettings, json); 560 UserSettingsTest userSettingTest; 561 562 REQUIRE(userSettingTest.Get<Setting::ArchiveExtractionMethod>() == AppInstaller::Archive::ExtractionMethod::Tar); 563 } 564 } 565 566 TEST_CASE("SettingsInstallScope", "[settings]") 567 { 568 auto again = DeleteUserSettingsFiles(); 569 570 SECTION("User scope preference") 571 { 572 std::string_view json = R"({ "installBehavior": { "preferences": { "scope": "user" } } })"; 573 SetSetting(Stream::PrimaryUserSettings, json); 574 UserSettingsTest userSettingTest; 575 576 REQUIRE(userSettingTest.Get<Setting::InstallScopePreference>() == AppInstaller::Manifest::ScopeEnum::User); 577 } 578 SECTION("Machine scope preference") 579 { 580 std::string_view json = R"({ "installBehavior": { "preferences": { "scope": "machine" } } })"; 581 SetSetting(Stream::PrimaryUserSettings, json); 582 UserSettingsTest userSettingTest; 583 584 REQUIRE(userSettingTest.Get<Setting::InstallScopePreference>() == AppInstaller::Manifest::ScopeEnum::Machine); 585 } 586 SECTION("User scope requirement") 587 { 588 std::string_view json = R"({ "installBehavior": { "requirements": { "scope": "user" } } })"; 589 SetSetting(Stream::PrimaryUserSettings, json); 590 UserSettingsTest userSettingTest; 591 592 REQUIRE(userSettingTest.Get<Setting::InstallScopeRequirement>() == AppInstaller::Manifest::ScopeEnum::User); 593 } 594 SECTION("Machine scope requirement") 595 { 596 std::string_view json = R"({ "installBehavior": { "requirements": { "scope": "machine" } } })"; 597 SetSetting(Stream::PrimaryUserSettings, json); 598 UserSettingsTest userSettingTest; 599 600 REQUIRE(userSettingTest.Get<Setting::InstallScopeRequirement>() == AppInstaller::Manifest::ScopeEnum::Machine); 601 } 602 } 603 604 TEST_CASE("SettingsMaxResumes", "[settings]") 605 { 606 auto again = DeleteUserSettingsFiles(); 607 608 SECTION("Modify max number of resumes") 609 { 610 std::string_view json = R"({ "installBehavior": { "maxResumes": 5 } })"; 611 SetSetting(Stream::PrimaryUserSettings, json); 612 UserSettingsTest userSettingTest; 613 614 REQUIRE(userSettingTest.Get<Setting::MaxResumes>() == 5); 615 } 616 } 617 618 TEST_CASE("LoggingChannels", "[settings]") 619 { 620 auto again = DeleteUserSettingsFiles(); 621 622 SECTION("Not provided") 623 { 624 std::string_view json = R"({ })"; 625 SetSetting(Stream::PrimaryUserSettings, json); 626 UserSettingsTest userSettingTest; 627 628 REQUIRE(userSettingTest.Get<Setting::LoggingChannelPreference>() == Channel::Defaults); 629 } 630 SECTION("No channels") 631 { 632 std::string_view json = R"({ "logging": { "channels": [] } })"; 633 SetSetting(Stream::PrimaryUserSettings, json); 634 UserSettingsTest userSettingTest; 635 636 REQUIRE(userSettingTest.Get<Setting::LoggingChannelPreference>() == Channel::None); 637 } 638 SECTION("Default") 639 { 640 std::string_view json = R"({ "logging": { "channels": ["default"] } })"; 641 SetSetting(Stream::PrimaryUserSettings, json); 642 UserSettingsTest userSettingTest; 643 644 REQUIRE(userSettingTest.Get<Setting::LoggingChannelPreference>() == Channel::Defaults); 645 } 646 SECTION("Multiple") 647 { 648 std::string_view json = R"({ "logging": { "channels": ["core","Repo","YAML"] } })"; 649 SetSetting(Stream::PrimaryUserSettings, json); 650 UserSettingsTest userSettingTest; 651 652 REQUIRE(userSettingTest.Get<Setting::LoggingChannelPreference>() == (Channel::Core | Channel::Repo | Channel::YAML)); 653 } 654 SECTION("Some invalid") 655 { 656 std::string_view json = R"({ "logging": { "channels": ["cli","sql","INVALID"] } })"; 657 SetSetting(Stream::PrimaryUserSettings, json); 658 UserSettingsTest userSettingTest; 659 660 REQUIRE(userSettingTest.Get<Setting::LoggingChannelPreference>() == (Channel::CLI | Channel::SQL)); 661 } 662 }