winget-cli

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

PinFlow.cpp (8079B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "WorkflowCommon.h"
      5 #include "TestHooks.h"
      6 #include <Commands/PinCommand.h>
      7 #include <Workflows/PinFlow.h>
      8 #include <Microsoft/PinningIndex.h>
      9 #include <AppInstallerRuntime.h>
     10 #include <AppInstallerVersions.h>
     11 #include <winget/PinningData.h>
     12 
     13 using namespace TestCommon;
     14 using namespace AppInstaller::CLI;
     15 using namespace AppInstaller::CLI::Workflow;
     16 using namespace AppInstaller::Repository::Microsoft;
     17 using namespace AppInstaller::Utility;
     18 using namespace AppInstaller::Pinning;
     19 using namespace AppInstaller::SQLite;
     20 
     21 TEST_CASE("PinFlow_Add", "[PinFlow][workflow]")
     22 {
     23     TempFile indexFile("pinningIndex", ".db");
     24     TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());
     25 
     26     std::ostringstream pinAddOutput;
     27     TestContext addContext{ pinAddOutput, std::cin };
     28     OverrideForCompositeInstalledSource(addContext, CreateTestSource({ TSR::TestInstaller_Exe }));
     29     addContext.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);
     30     addContext.Args.AddArg(Execution::Args::Type::BlockingPin);
     31 
     32     PinAddCommand pinAdd({});
     33     pinAdd.Execute(addContext);
     34     INFO(pinAddOutput.str());
     35 
     36     SECTION("Pin is saved")
     37     {
     38         auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);
     39         auto pins = index.GetAllPins();
     40         REQUIRE(pins.size() == 1);
     41         REQUIRE(pins[0].GetType() == PinType::Blocking);
     42         REQUIRE(pins[0].GetGatedVersion().ToString() == "");
     43         REQUIRE(pins[0].GetKey().PackageId == "AppInstallerCliTest.TestExeInstaller");
     44         REQUIRE(pins[0].GetKey().SourceId == "*TestSource");
     45 
     46         std::ostringstream pinListOutput;
     47         TestContext listContext{ pinListOutput, std::cin };
     48         OverrideForCompositeInstalledSource(listContext, CreateTestSource({ TSR::TestInstaller_Exe }));
     49         listContext.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);
     50 
     51         PinListCommand pinList({});
     52         pinList.Execute(listContext);
     53 
     54         INFO(pinListOutput.str());
     55         REQUIRE(pinListOutput.str().find("AppInstallerCliTest.TestExeInstaller"));
     56         REQUIRE(pinListOutput.str().find("Blocking"));
     57     }
     58     SECTION("Remove pin")
     59     {
     60         std::ostringstream pinRemoveOutput;
     61         TestContext removeContext{ pinRemoveOutput, std::cin };
     62         OverrideForCompositeInstalledSource(removeContext, CreateTestSource({ TSR::TestInstaller_Exe }));
     63         removeContext.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);
     64 
     65         PinRemoveCommand pinRemove({});
     66         pinRemove.Execute(removeContext);
     67         INFO(pinRemoveOutput.str());
     68 
     69         auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);
     70         auto pins = index.GetAllPins();
     71         REQUIRE(pins.empty());
     72     }
     73     SECTION("Reset pins")
     74     {
     75         std::ostringstream pinResetOutput;
     76         TestContext resetContext{ pinResetOutput, std::cin };
     77 
     78         SECTION("Without --force")
     79         {
     80             OverrideForCompositeInstalledSource(resetContext, CreateTestSource({ TSR::TestInstaller_Exe }));
     81             PinResetCommand pinReset({});
     82             pinReset.Execute(resetContext);
     83             INFO(pinResetOutput.str());
     84 
     85             auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);
     86             auto pins = index.GetAllPins();
     87             REQUIRE(pins.size() == 1);
     88         }
     89         SECTION("With --force")
     90         {
     91             resetContext.Args.AddArg(Execution::Args::Type::Force);
     92 
     93             PinResetCommand pinReset({});
     94             pinReset.Execute(resetContext);
     95             INFO(pinResetOutput.str());
     96 
     97             auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);
     98             auto pins = index.GetAllPins();
     99             REQUIRE(pins.empty());
    100         }
    101     }
    102     SECTION("Update pin")
    103     {
    104         std::ostringstream pinUpdateOutput;
    105         TestContext updateContext{ pinUpdateOutput, std::cin };
    106         OverrideForCompositeInstalledSource(updateContext, CreateTestSource({ TSR::TestInstaller_Exe }));
    107         updateContext.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);
    108 
    109         SECTION("Without --force")
    110         {
    111             PinAddCommand pinUpdate({});
    112             pinUpdate.Execute(updateContext);
    113             INFO(pinUpdateOutput.str());
    114             REQUIRE_TERMINATED_WITH(updateContext, APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS);
    115 
    116             auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);
    117             auto pins = index.GetAllPins();
    118             REQUIRE(pins.size() == 1);
    119             REQUIRE(pins[0].GetType() == PinType::Blocking);
    120         }
    121         SECTION("With --force")
    122         {
    123             updateContext.Args.AddArg(Execution::Args::Type::Force);
    124 
    125             PinAddCommand pinUpdate({});
    126             pinUpdate.Execute(updateContext);
    127             INFO(pinUpdateOutput.str());
    128 
    129             auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);
    130             auto pins = index.GetAllPins();
    131             REQUIRE(pins.size() == 1);
    132             REQUIRE(pins[0].GetType() == PinType::Pinning);
    133         }
    134     }
    135 }
    136 
    137 TEST_CASE("PinFlow_Add_NotFound", "[PinFlow][workflow]")
    138 {
    139     TempFile indexFile("pinningIndex", ".db");
    140     TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());
    141 
    142     std::ostringstream pinAddOutput;
    143     TestContext addContext{ pinAddOutput, std::cin };
    144     OverrideForCompositeInstalledSource(addContext, CreateTestSource({}));
    145     addContext.Args.AddArg(Execution::Args::Type::Query, "This package doesn't exist"sv);
    146 
    147     PinAddCommand pinAdd({});
    148     pinAdd.Execute(addContext);
    149     INFO(pinAddOutput.str());
    150 
    151     REQUIRE_TERMINATED_WITH(addContext, APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND);
    152 }
    153 
    154 TEST_CASE("PinFlow_ListEmpty", "[PinFlow][workflow]")
    155 {
    156     TempFile indexFile("pinningIndex", ".db");
    157     TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());
    158 
    159     std::ostringstream pinListOutput;
    160     TestContext listContext{ pinListOutput, std::cin };
    161     OverrideForCompositeInstalledSource(listContext, CreateTestSource({}));
    162 
    163     PinListCommand pinList({});
    164     pinList.Execute(listContext);
    165     INFO(pinListOutput.str());
    166 
    167      REQUIRE(pinListOutput.str().find(Resource::LocString(Resource::String::PinNoPinsExist)) != std::string::npos);
    168 }
    169 
    170 TEST_CASE("PinFlow_RemoveNonExisting", "[PinFlow][workflow]")
    171 {
    172     TempFile indexFile("pinningIndex", ".db");
    173     TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());
    174 
    175     std::ostringstream pinRemoveOutput;
    176     TestContext removeContext{ pinRemoveOutput, std::cin };
    177     OverrideForCompositeInstalledSource(removeContext, CreateTestSource({ TSR::TestInstaller_Exe }));
    178     removeContext.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);
    179 
    180     PinRemoveCommand pinRemove({});
    181     pinRemove.Execute(removeContext);
    182     INFO(pinRemoveOutput.str());
    183 
    184     REQUIRE_TERMINATED_WITH(removeContext, APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST);
    185 }
    186 
    187 TEST_CASE("PinFlow_ResetEmpty", "[PinFlow][workflow]")
    188 {
    189     TempFile indexFile("pinningIndex", ".db");
    190     TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());
    191 
    192     std::ostringstream pinResetOutput;
    193     TestContext resetContext{ pinResetOutput, std::cin };
    194     resetContext.Args.AddArg(Execution::Args::Type::Force);
    195 
    196     PinResetCommand pinReset({});
    197     pinReset.Execute(resetContext);
    198     INFO(pinResetOutput.str());
    199 
    200     REQUIRE(pinResetOutput.str().find(Resource::LocString(Resource::String::PinNoPinsExist)) != std::string::npos);
    201 }