From dcc032cccf752f686f246754c6e9ce6ccdd487fc Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Mon, 10 Feb 2025 21:38:53 -0800 Subject: [PATCH 1/7] rest client 1.10 parsing --- src/AppInstallerCLITests/RestClient.cpp | 2 +- .../AppInstallerRepositoryCore.vcxproj | 4 +++ ...AppInstallerRepositoryCore.vcxproj.filters | 18 +++++++++++ .../ManifestJSONParser.cpp | 7 ++++- .../Rest/RestClient.cpp | 7 ++++- .../Rest/Schema/1_10/Interface.h | 21 +++++++++++++ .../Schema/1_10/Json/ManifestDeserializer.h | 17 +++++++++++ .../1_10/Json/ManifestDeserializer_1_10.cpp | 30 +++++++++++++++++++ .../Rest/Schema/1_10/RestInterface_1_10.cpp | 26 ++++++++++++++++ .../Rest/Schema/CommonRestConstants.h | 1 + 10 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_10/Interface.h create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_10/Json/ManifestDeserializer.h create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_10/Json/ManifestDeserializer_1_10.cpp create mode 100644 src/AppInstallerRepositoryCore/Rest/Schema/1_10/RestInterface_1_10.cpp diff --git a/src/AppInstallerCLITests/RestClient.cpp b/src/AppInstallerCLITests/RestClient.cpp index 7713d791d5..4bd534794b 100644 --- a/src/AppInstallerCLITests/RestClient.cpp +++ b/src/AppInstallerCLITests/RestClient.cpp @@ -61,7 +61,7 @@ TEST_CASE("GetSupportedInterface", "[RestSource]") REQUIRE(RestClient::GetSupportedInterface(TestRestUri, {}, info, {}, version, {})->GetVersion() == version); // Update this test to next version so that we don't forget to add to supported versions before rest e2e tests are available. - Version invalid{ "1.10.0" }; + Version invalid{ "1.11.0" }; REQUIRE_THROWS_HR(RestClient::GetSupportedInterface(TestRestUri, {}, info, {}, invalid, {}), APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION); Authentication::AuthenticationArguments authArgs; diff --git a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj index d70fb30e56..8ffaf09a66 100644 --- a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj +++ b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj @@ -439,6 +439,8 @@ <ClInclude Include="Rest\Schema\1_0\Json\ManifestDeserializer.h" /> <ClInclude Include="Rest\Schema\1_0\Json\SearchRequestSerializer.h" /> <ClInclude Include="Rest\Schema\1_0\Json\SearchResponseDeserializer.h" /> + <ClInclude Include="Rest\Schema\1_10\Interface.h" /> + <ClInclude Include="Rest\Schema\1_10\Json\ManifestDeserializer.h" /> <ClInclude Include="Rest\Schema\1_1\Interface.h" /> <ClInclude Include="Rest\Schema\1_1\Json\ManifestDeserializer.h" /> <ClInclude Include="Rest\Schema\1_1\Json\SearchRequestSerializer.h" /> @@ -534,6 +536,8 @@ <ClCompile Include="Rest\Schema\1_0\Json\ManifestDeserializer_1_0.cpp" /> <ClCompile Include="Rest\Schema\1_0\Json\SearchRequestSerializer_1_0.cpp" /> <ClCompile Include="Rest\Schema\1_0\Json\SearchResponseDeserializer_1_0.cpp" /> + <ClCompile Include="Rest\Schema\1_10\Json\ManifestDeserializer_1_10.cpp" /> + <ClCompile Include="Rest\Schema\1_10\RestInterface_1_10.cpp" /> <ClCompile Include="Rest\Schema\1_1\Json\ManifestDeserializer_1_1.cpp" /> <ClCompile Include="Rest\Schema\1_1\Json\SearchRequestSerializer_1_1.cpp" /> <ClCompile Include="Rest\Schema\1_1\RestInterface_1_1.cpp" /> diff --git a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters index 1b91d82bcf..60b6b9b6c3 100644 --- a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters +++ b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters @@ -109,6 +109,12 @@ <Filter Include="Rest\Schema\1_9\Json"> <UniqueIdentifier>{7464e3ff-7a60-4bb6-8806-70562382043b}</UniqueIdentifier> </Filter> + <Filter Include="Rest\Schema\1_10"> + <UniqueIdentifier>{da801426-6d3b-40ca-b204-152e7e18067b}</UniqueIdentifier> + </Filter> + <Filter Include="Rest\Schema\1_10\Json"> + <UniqueIdentifier>{1a1efb9f-7332-4094-bb98-a4c51ea68b24}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClInclude Include="pch.h"> @@ -474,6 +480,12 @@ <ClInclude Include="Rest\Schema\1_9\Interface.h"> <Filter>Rest\Schema\1_9</Filter> </ClInclude> + <ClInclude Include="Rest\Schema\1_10\Interface.h"> + <Filter>Rest\Schema\1_10</Filter> + </ClInclude> + <ClInclude Include="Rest\Schema\1_10\Json\ManifestDeserializer.h"> + <Filter>Rest\Schema\1_10\Json</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="pch.cpp"> @@ -740,6 +752,12 @@ <ClCompile Include="Rest\Schema\1_9\RestInterface_1_9.cpp"> <Filter>Rest\Schema\1_9</Filter> </ClCompile> + <ClCompile Include="Rest\Schema\1_10\RestInterface_1_10.cpp"> + <Filter>Rest\Schema\1_10</Filter> + </ClCompile> + <ClCompile Include="Rest\Schema\1_10\Json\ManifestDeserializer_1_10.cpp"> + <Filter>Rest\Schema\1_10\Json</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <None Include="PropertySheet.props" /> diff --git a/src/AppInstallerRepositoryCore/ManifestJSONParser.cpp b/src/AppInstallerRepositoryCore/ManifestJSONParser.cpp index d30a871cdf..b9a6eac39c 100644 --- a/src/AppInstallerRepositoryCore/ManifestJSONParser.cpp +++ b/src/AppInstallerRepositoryCore/ManifestJSONParser.cpp @@ -9,6 +9,7 @@ #include "Rest/Schema/1_6/Json/ManifestDeserializer.h" #include "Rest/Schema/1_7/Json/ManifestDeserializer.h" #include "Rest/Schema/1_9/Json/ManifestDeserializer.h" +#include "Rest/Schema/1_10/Json/ManifestDeserializer.h" namespace AppInstaller::Repository::JSON { @@ -51,10 +52,14 @@ namespace AppInstaller::Repository::JSON { m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_7::Json::ManifestDeserializer>(); } - else + else if (parts.size() > 1 && parts[1].Integer < 10) { m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_9::Json::ManifestDeserializer>(); } + else + { + m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_10::Json::ManifestDeserializer>(); + } } else { diff --git a/src/AppInstallerRepositoryCore/Rest/RestClient.cpp b/src/AppInstallerRepositoryCore/Rest/RestClient.cpp index c7f0bfd79c..e4442df051 100644 --- a/src/AppInstallerRepositoryCore/Rest/RestClient.cpp +++ b/src/AppInstallerRepositoryCore/Rest/RestClient.cpp @@ -9,6 +9,7 @@ #include "Rest/Schema/1_6/Interface.h" #include "Rest/Schema/1_7/Interface.h" #include "Rest/Schema/1_9/Interface.h" +#include "Rest/Schema/1_10/Interface.h" #include "Rest/Schema/InformationResponseDeserializer.h" #include "Rest/Schema/CommonRestConstants.h" #include <winget/HttpClientHelper.h> @@ -23,7 +24,7 @@ using namespace AppInstaller::Http; namespace AppInstaller::Repository::Rest { // Supported versions - std::set<Version> WingetSupportedContracts = { Version_1_0_0, Version_1_1_0, Version_1_4_0, Version_1_5_0, Version_1_6_0, Version_1_7_0, Version_1_9_0 }; + std::set<Version> WingetSupportedContracts = { Version_1_0_0, Version_1_1_0, Version_1_4_0, Version_1_5_0, Version_1_6_0, Version_1_7_0, Version_1_9_0, Version_1_10_0 }; constexpr std::string_view WindowsPackageManagerHeader = "Windows-Package-Manager"sv; constexpr size_t WindowsPackageManagerHeaderMaxLength = 1024; @@ -181,6 +182,10 @@ namespace AppInstaller::Repository::Rest { return std::make_unique<Schema::V1_9::Interface>(api, helper, information, additionalHeaders, authArgs); } + else if (version == Version_1_10_0) + { + return std::make_unique<Schema::V1_10::Interface>(api, helper, information, additionalHeaders, authArgs); + } THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION); } diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_10/Interface.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_10/Interface.h new file mode 100644 index 0000000000..7ff88a28e3 --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_10/Interface.h @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "Rest/Schema/1_9/Interface.h" + +namespace AppInstaller::Repository::Rest::Schema::V1_10 +{ + // Interface to this schema version exposed through IRestClient. + struct Interface : public V1_9::Interface + { + Interface(const std::string& restApi, const Http::HttpClientHelper& helper, IRestClient::Information information, const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders = {}, Authentication::AuthenticationArguments authArgs = {}); + + Interface(const Interface&) = delete; + Interface& operator=(const Interface&) = delete; + + Interface(Interface&&) = default; + Interface& operator=(Interface&&) = default; + + Utility::Version GetVersion() const override; + }; +} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_10/Json/ManifestDeserializer.h b/src/AppInstallerRepositoryCore/Rest/Schema/1_10/Json/ManifestDeserializer.h new file mode 100644 index 0000000000..202440543f --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_10/Json/ManifestDeserializer.h @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include "Rest/Schema/1_9/Json/ManifestDeserializer.h" + +namespace AppInstaller::Repository::Rest::Schema::V1_10::Json +{ + // Manifest Deserializer. + struct ManifestDeserializer : public V1_9::Json::ManifestDeserializer + { + protected: + + std::optional<Manifest::ManifestInstaller> DeserializeInstaller(const web::json::value& installerJsonObject) const override; + + Manifest::ManifestVer GetManifestVersion() const override; + }; +} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_10/Json/ManifestDeserializer_1_10.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_10/Json/ManifestDeserializer_1_10.cpp new file mode 100644 index 0000000000..d4d5ce643c --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_10/Json/ManifestDeserializer_1_10.cpp @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "ManifestDeserializer.h" +#include "Rest/Schema/AuthenticationInfoParser.h" +#include <winget/JsonUtil.h> + +using namespace AppInstaller::Manifest; + +namespace AppInstaller::Repository::Rest::Schema::V1_10::Json +{ + std::optional<Manifest::ManifestInstaller> ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const + { + auto result = V1_9::Json::ManifestDeserializer::DeserializeInstaller(installerJsonObject); + + if (result) + { + auto& installer = result.value(); + + installer.AuthInfo = ParseAuthenticationInfo(installerJsonObject, ParseAuthenticationInfoType::Installer, GetManifestVersion()); + } + + return result; + } + + Manifest::ManifestVer ManifestDeserializer::GetManifestVersion() const + { + return Manifest::s_ManifestVersionV1_10; + } +} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/1_10/RestInterface_1_10.cpp b/src/AppInstallerRepositoryCore/Rest/Schema/1_10/RestInterface_1_10.cpp new file mode 100644 index 0000000000..c53f1387d2 --- /dev/null +++ b/src/AppInstallerRepositoryCore/Rest/Schema/1_10/RestInterface_1_10.cpp @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "Rest/Schema/1_10/Interface.h" +#include "Rest/Schema/CommonRestConstants.h" +#include "Rest/Schema/IRestClient.h" +#include <winget/HttpClientHelper.h> +#include <winget/JsonUtil.h> + +namespace AppInstaller::Repository::Rest::Schema::V1_10 +{ + Interface::Interface( + const std::string& restApi, + const Http::HttpClientHelper& httpClientHelper, + IRestClient::Information information, + const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders, + Authentication::AuthenticationArguments authArgs) : V1_9::Interface(restApi, httpClientHelper, std::move(information), additionalHeaders, std::move(authArgs)) + { + m_requiredRestApiHeaders[JSON::GetUtilityString(ContractVersion)] = JSON::GetUtilityString(Version_1_10_0.ToString()); + } + + Utility::Version Interface::GetVersion() const + { + return Version_1_10_0; + } +} diff --git a/src/AppInstallerRepositoryCore/Rest/Schema/CommonRestConstants.h b/src/AppInstallerRepositoryCore/Rest/Schema/CommonRestConstants.h index 6ee979b7aa..6f02692843 100644 --- a/src/AppInstallerRepositoryCore/Rest/Schema/CommonRestConstants.h +++ b/src/AppInstallerRepositoryCore/Rest/Schema/CommonRestConstants.h @@ -13,6 +13,7 @@ namespace AppInstaller::Repository::Rest::Schema const Utility::Version Version_1_6_0{ "1.6.0" }; const Utility::Version Version_1_7_0{ "1.7.0" }; const Utility::Version Version_1_9_0{ "1.9.0" }; + const Utility::Version Version_1_10_0{ "1.10.0" }; // General API response constants constexpr std::string_view Data = "Data"sv; From d44b7434948c948be3d284bcef5ac7b4abe15e21 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:24:59 -0800 Subject: [PATCH 2/7] rest 110 test --- .../AppInstallerCLITests.vcxproj | 1 + .../AppInstallerCLITests.vcxproj.filters | 3 + .../RestInterface_1_10.cpp | 411 ++++++++++++++++++ 3 files changed, 415 insertions(+) create mode 100644 src/AppInstallerCLITests/RestInterface_1_10.cpp diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj index 538c2f6367..ddacac2ee2 100644 --- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj +++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj @@ -319,6 +319,7 @@ <ClCompile Include="RestClient.cpp" /> <ClCompile Include="RestInterface_1_0.cpp" /> <ClCompile Include="RestInterface_1_1.cpp" /> + <ClCompile Include="RestInterface_1_10.cpp" /> <ClCompile Include="RestInterface_1_4.cpp" /> <ClCompile Include="RestInterface_1_5.cpp" /> <ClCompile Include="RestInterface_1_6.cpp" /> diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters index 5da81fec15..bd0da2c2dc 100644 --- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters +++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters @@ -374,6 +374,9 @@ <ClCompile Include="Fonts.cpp"> <Filter>Source Files\Common</Filter> </ClCompile> + <ClCompile Include="RestInterface_1_10.cpp"> + <Filter>Source Files\Repository</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <None Include="PropertySheet.props" /> diff --git a/src/AppInstallerCLITests/RestInterface_1_10.cpp b/src/AppInstallerCLITests/RestInterface_1_10.cpp new file mode 100644 index 0000000000..87130fd366 --- /dev/null +++ b/src/AppInstallerCLITests/RestInterface_1_10.cpp @@ -0,0 +1,411 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" +#include "TestCommon.h" +#include "TestRestRequestHandler.h" +#include <Rest/Schema/1_10/Interface.h> +#include <Rest/Schema/IRestClient.h> +#include <AppInstallerVersions.h> +#include <AppInstallerErrors.h> + +using namespace TestCommon; +using namespace AppInstaller::Http; +using namespace AppInstaller::Utility; +using namespace AppInstaller::Manifest; +using namespace AppInstaller::Repository; +using namespace AppInstaller::Repository::Rest; +using namespace AppInstaller::Repository::Rest::Schema; +using namespace AppInstaller::Repository::Rest::Schema::V1_10; + +namespace +{ + const std::string TestRestUriString = "http://restsource.com/api"; + + struct GoodManifest_AllFields + { + utility::string_t GetSampleManifest_AllFields() + { + return _XPLATSTR( + R"delimiter( + { + "Data": { + "PackageIdentifier": "Foo.Bar", + "Versions": [ + { + "PackageVersion": "3.0.0abc", + "DefaultLocale": { + "PackageLocale": "en-US", + "Publisher": "Foo", + "PublisherUrl": "http://publisher.net", + "PublisherSupportUrl": "http://publisherSupport.net", + "PrivacyUrl": "http://packagePrivacyUrl.net", + "Author": "FooBar", + "PackageName": "Bar", + "PackageUrl": "http://packageUrl.net", + "License": "Foo Bar License", + "LicenseUrl": "http://licenseUrl.net", + "Copyright": "Foo Bar Copyright", + "CopyrightUrl": "http://copyrightUrl.net", + "ShortDescription": "Foo bar is a foo bar.", + "Description": "Foo bar is a placeholder.", + "Tags": [ + "FooBar", + "Foo", + "Bar" + ], + "Moniker": "FooBarMoniker", + "ReleaseNotes": "Default release notes", + "ReleaseNotesUrl": "https://DefaultReleaseNotes.net", + "Agreements": [{ + "AgreementLabel": "DefaultLabel", + "Agreement": "DefaultText", + "AgreementUrl": "https://DefaultAgreementUrl.net" + }], + "PurchaseUrl": "http://DefaultPurchaseUrl.net", + "InstallationNotes": "Default Installation Notes", + "Documentations": [{ + "DocumentLabel": "Default Document Label", + "DocumentUrl": "http://DefaultDocumentUrl.net" + }], + "Icons": [{ + "IconUrl": "https://DefaultTestIcon", + "IconFileType": "ico", + "IconResolution": "custom", + "IconTheme": "default", + "IconSha256": "69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123" + }] + }, + "Channel": "", + "Locales": [ + { + "PackageLocale": "fr-Fr", + "Publisher": "Foo French", + "PublisherUrl": "http://publisher-fr.net", + "PublisherSupportUrl": "http://publisherSupport-fr.net", + "PrivacyUrl": "http://packagePrivacyUrl-fr.net", + "Author": "FooBar French", + "PackageName": "Bar", + "PackageUrl": "http://packageUrl-fr.net", + "License": "Foo Bar License", + "LicenseUrl": "http://licenseUrl-fr.net", + "Copyright": "Foo Bar Copyright", + "CopyrightUrl": "http://copyrightUrl-fr.net", + "ShortDescription": "Foo bar is a foo bar French.", + "Description": "Foo bar is a placeholder French.", + "Tags": [ + "FooBarFr", + "FooFr", + "BarFr" + ], + "ReleaseNotes": "Release notes", + "ReleaseNotesUrl": "https://ReleaseNotes.net", + "Agreements": [{ + "AgreementLabel": "Label", + "Agreement": "Text", + "AgreementUrl": "https://AgreementUrl.net" + }], + "PurchaseUrl": "http://purchaseUrl.net", + "InstallationNotes": "Installation Notes", + "Documentations": [{ + "DocumentLabel": "Document Label", + "DocumentUrl": "http://documentUrl.net" + }], + "Icons": [{ + "IconUrl": "https://testIcon", + "IconFileType": "png", + "IconResolution": "32x32", + "IconTheme": "light", + "IconSha256": "69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321" + }] + } + ],)delimiter") _XPLATSTR(R"delimiter( + "Installers": [ + { + "InstallerSha256": "011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6", + "InstallerUrl": "http://foobar.zip", + "Architecture": "x86", + "InstallerLocale": "en-US", + "Platform": [ + "Windows.Desktop" + ], + "MinimumOSVersion": "1078", + "InstallerType": "zip", + "Scope": "user", + "InstallModes": [ + "interactive" + ], + "InstallerSwitches": { + "Silent": "/s", + "SilentWithProgress": "/s", + "Interactive": "/i", + "InstallLocation": "C:\\Users\\User1", + "Log": "/l", + "Upgrade": "/u", + "Custom": "/custom", + "Repair": "/repair" + }, + "InstallerSuccessCodes": [ + 0 + ], + "UpgradeBehavior": "deny", + "Commands": [ + "command1" + ], + "Protocols": [ + "protocol1" + ], + "FileExtensions": [ + ".file-extension" + ], + "Dependencies": { + "WindowsFeatures": [ + "feature1" + ], + "WindowsLibraries": [ + "library1" + ], + "PackageDependencies": [ + { + "PackageIdentifier": "Foo.Baz", + "MinimumVersion": "2.0.0" + } + ], + "ExternalDependencies": [ + "FooBarBaz" + ] + }, + "ProductCode": "5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d", + "ReleaseDate": "2021-01-01", + "InstallerAbortsTerminal": true, + "InstallLocationRequired": true, + "RequireExplicitUpgrade": true, + "UnsupportedOSArchitectures": [ "arm" ], + "ElevationRequirement": "elevatesSelf", + "AppsAndFeaturesEntries": [{ + "DisplayName": "DisplayName", + "DisplayVersion": "DisplayVersion", + "Publisher": "Publisher", + "ProductCode": "ProductCode", + "UpgradeCode": "UpgradeCode", + "InstallerType": "exe" + }], + "Markets" : { + "AllowedMarkets": [ "US" ] + }, + "ExpectedReturnCodes": [{ + "InstallerReturnCode": 3, + "ReturnResponse": "custom", + "ReturnResponseUrl": "http://returnResponseUrl.net" + }], + "NestedInstallerType": "portable", + "DisplayInstallWarnings": true, + "UnsupportedArguments": [ "log" ], + "NestedInstallerFiles": [{ + "RelativeFilePath": "test\\app.exe", + "PortableCommandAlias": "test.exe" + }], + "InstallationMetadata": { + "DefaultInstallLocation": "%TEMP%\\DefaultInstallLocation", + "Files": [{ + "RelativeFilePath": "test\\app.exe", + "FileSha256": "011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6", + "FileType": "launch", + "InvocationParameter": "/parameter", + "DisplayName": "test" + }] + }, + "DownloadCommandProhibited": true, + "RepairBehavior": "uninstaller", + "ArchiveBinariesDependOnPath": true, + "Authentication": { + "AuthenticationType": "microsoftEntraId", + "MicrosoftEntraIdAuthenticationInfo" : { + "Resource": "TestResource", + "Scope" : "TestScope" + } + } + } + ] + } + ] + }, + "ContinuationToken": "abcd" + })delimiter"); + } + + void VerifyLocalizations_AllFields(const AppInstaller::Manifest::Manifest& manifest) + { + REQUIRE(manifest.DefaultLocalization.Locale == "en-US"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == "Foo"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherUrl>() == "http://publisher.net"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherSupportUrl>() == "http://publisherSupport.net"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::PrivacyUrl>() == "http://packagePrivacyUrl.net"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == "FooBar"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == "Bar"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == "http://packageUrl.net"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == "Foo Bar License"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == "http://licenseUrl.net"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Copyright>() == "Foo Bar Copyright"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::CopyrightUrl>() == "http://copyrightUrl.net"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == "Foo bar is a foo bar."); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == "Foo bar is a placeholder."); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().size() == 3); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(0) == "FooBar"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(1) == "Foo"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(2) == "Bar"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotes>() == "Default release notes"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotesUrl>() == "https://DefaultReleaseNotes.net"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().size() == 1); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).Label == "DefaultLabel"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementText == "DefaultText"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == "https://DefaultAgreementUrl.net"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::PurchaseUrl>() == "http://DefaultPurchaseUrl.net"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::InstallationNotes>() == "Default Installation Notes"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().size() == 1); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == "Default Document Label"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == "http://DefaultDocumentUrl.net"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().size() == 1); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Url == "https://DefaultTestIcon"); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Ico); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Custom); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Default); + REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes("69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123")); + + REQUIRE(manifest.Localizations.size() == 1); + ManifestLocalization frenchLocalization = manifest.Localizations.at(0); + REQUIRE(frenchLocalization.Locale == "fr-Fr"); + REQUIRE(frenchLocalization.Get<Localization::Publisher>() == "Foo French"); + REQUIRE(frenchLocalization.Get<Localization::PublisherUrl>() == "http://publisher-fr.net"); + REQUIRE(frenchLocalization.Get<Localization::PublisherSupportUrl>() == "http://publisherSupport-fr.net"); + REQUIRE(frenchLocalization.Get<Localization::PrivacyUrl>() == "http://packagePrivacyUrl-fr.net"); + REQUIRE(frenchLocalization.Get<Localization::Author>() == "FooBar French"); + REQUIRE(frenchLocalization.Get<Localization::PackageName>() == "Bar"); + REQUIRE(frenchLocalization.Get<Localization::PackageUrl>() == "http://packageUrl-fr.net"); + REQUIRE(frenchLocalization.Get<Localization::License>() == "Foo Bar License"); + REQUIRE(frenchLocalization.Get<Localization::LicenseUrl>() == "http://licenseUrl-fr.net"); + REQUIRE(frenchLocalization.Get<Localization::Copyright>() == "Foo Bar Copyright"); + REQUIRE(frenchLocalization.Get<Localization::CopyrightUrl>() == "http://copyrightUrl-fr.net"); + REQUIRE(frenchLocalization.Get<Localization::ShortDescription>() == "Foo bar is a foo bar French."); + REQUIRE(frenchLocalization.Get<Localization::Description>() == "Foo bar is a placeholder French."); + REQUIRE(frenchLocalization.Get<Localization::Tags>().size() == 3); + REQUIRE(frenchLocalization.Get<Localization::Tags>().at(0) == "FooBarFr"); + REQUIRE(frenchLocalization.Get<Localization::Tags>().at(1) == "FooFr"); + REQUIRE(frenchLocalization.Get<Localization::Tags>().at(2) == "BarFr"); + REQUIRE(frenchLocalization.Get<Localization::ReleaseNotes>() == "Release notes"); + REQUIRE(frenchLocalization.Get<Localization::ReleaseNotesUrl>() == "https://ReleaseNotes.net"); + REQUIRE(frenchLocalization.Get<Localization::Agreements>().size() == 1); + REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).Label == "Label"); + REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementText == "Text"); + REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == "https://AgreementUrl.net"); + REQUIRE(frenchLocalization.Get<Localization::PurchaseUrl>() == "http://purchaseUrl.net"); + REQUIRE(frenchLocalization.Get<Localization::InstallationNotes>() == "Installation Notes"); + REQUIRE(frenchLocalization.Get<Localization::Documentations>().size() == 1); + REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == "Document Label"); + REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == "http://documentUrl.net"); + REQUIRE(frenchLocalization.Get<Localization::Icons>().size() == 1); + REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Url == "https://testIcon"); + REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Png); + REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square32); + REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Light); + REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes("69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321")); + } + + void VerifyInstallers_AllFields(const AppInstaller::Manifest::Manifest& manifest) + { + REQUIRE(manifest.Installers.size() == 1); + + ManifestInstaller actualInstaller = manifest.Installers.at(0); + REQUIRE(actualInstaller.Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes("011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6")); + REQUIRE(actualInstaller.Url == "http://foobar.zip"); + REQUIRE(actualInstaller.Arch == Architecture::X86); + REQUIRE(actualInstaller.Locale == "en-US"); + REQUIRE(actualInstaller.Platform.size() == 1); + REQUIRE(actualInstaller.Platform[0] == PlatformEnum::Desktop); + REQUIRE(actualInstaller.MinOSVersion == "1078"); + REQUIRE(actualInstaller.BaseInstallerType == InstallerTypeEnum::Zip); + REQUIRE(actualInstaller.Scope == ScopeEnum::User); + REQUIRE(actualInstaller.InstallModes.size() == 1); + REQUIRE(actualInstaller.InstallModes.at(0) == InstallModeEnum::Interactive); + REQUIRE(actualInstaller.Switches.size() == 8); + REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Silent) == "/s"); + REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::SilentWithProgress) == "/s"); + REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Interactive) == "/i"); + REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::InstallLocation) == "C:\\Users\\User1"); + REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Log) == "/l"); + REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Update) == "/u"); + REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Custom) == "/custom"); + REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Repair) == "/repair"); + REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1); + REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0); + REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Deny); + REQUIRE(actualInstaller.Commands.at(0) == "command1"); + REQUIRE(actualInstaller.Protocols.at(0) == "protocol1"); + REQUIRE(actualInstaller.FileExtensions.at(0) == ".file-extension"); + REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsFeature, "feature1")); + REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsLibrary, "library1")); + REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::Package, "Foo.Baz", "2.0.0")); + REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::External, "FooBarBaz")); + REQUIRE(actualInstaller.PackageFamilyName == ""); + REQUIRE(actualInstaller.ProductCode == "5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d"); + REQUIRE(actualInstaller.ReleaseDate == "2021-01-01"); + REQUIRE(actualInstaller.InstallerAbortsTerminal); + REQUIRE(actualInstaller.InstallLocationRequired); + REQUIRE(actualInstaller.RequireExplicitUpgrade); + REQUIRE(actualInstaller.ElevationRequirement == ElevationRequirementEnum::ElevatesSelf); + REQUIRE(actualInstaller.UnsupportedOSArchitectures.size() == 1); + REQUIRE(actualInstaller.UnsupportedOSArchitectures.at(0) == Architecture::Arm); + REQUIRE(actualInstaller.AppsAndFeaturesEntries.size() == 1); + REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayName == "DisplayName"); + REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayVersion == "DisplayVersion"); + REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).Publisher == "Publisher"); + REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).ProductCode == "ProductCode"); + REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).UpgradeCode == "UpgradeCode"); + REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).InstallerType == InstallerTypeEnum::Exe); + REQUIRE(actualInstaller.Markets.AllowedMarkets.size() == 1); + REQUIRE(actualInstaller.Markets.AllowedMarkets.at(0) == "US"); + REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseEnum == ExpectedReturnCodeEnum::Custom); + REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseUrl == "http://returnResponseUrl.net"); + REQUIRE(actualInstaller.NestedInstallerType == InstallerTypeEnum::Portable); + REQUIRE(actualInstaller.DisplayInstallWarnings); + REQUIRE(actualInstaller.UnsupportedArguments.size() == 1); + REQUIRE(actualInstaller.UnsupportedArguments.at(0) == UnsupportedArgumentEnum::Log); + REQUIRE(actualInstaller.NestedInstallerFiles.size() == 1); + REQUIRE(actualInstaller.NestedInstallerFiles.at(0).RelativeFilePath == "test\\app.exe"); + REQUIRE(actualInstaller.NestedInstallerFiles.at(0).PortableCommandAlias == "test.exe"); + REQUIRE(actualInstaller.InstallationMetadata.DefaultInstallLocation == "%TEMP%\\DefaultInstallLocation"); + REQUIRE(actualInstaller.InstallationMetadata.Files.size() == 1); + REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).RelativeFilePath == "test\\app.exe"); + REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileType == InstalledFileTypeEnum::Launch); + REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileSha256 == AppInstaller::Utility::SHA256::ConvertToBytes("011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6")); + REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).InvocationParameter == "/parameter"); + REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).DisplayName == "test"); + REQUIRE(actualInstaller.DownloadCommandProhibited); + REQUIRE(actualInstaller.RepairBehavior == RepairBehaviorEnum::Uninstaller); + REQUIRE(actualInstaller.ArchiveBinariesDependOnPath); + REQUIRE(actualInstaller.AuthInfo.Type == AppInstaller::Authentication::AuthenticationType::MicrosoftEntraId); + REQUIRE(actualInstaller.AuthInfo.MicrosoftEntraIdInfo.has_value()); + REQUIRE(actualInstaller.AuthInfo.MicrosoftEntraIdInfo->Resource == "TestResource"); + REQUIRE(actualInstaller.AuthInfo.MicrosoftEntraIdInfo->Scope == "TestScope"); + } + }; +} + +TEST_CASE("GetManifests_GoodResponse_V1_10", "[RestSource][Interface_1_10]") +{ + GoodManifest_AllFields sampleManifest; + utility::string_t sample = sampleManifest.GetSampleManifest_AllFields(); + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) }; + Interface v1_10{ TestRestUriString, std::move(helper), {} }; + std::vector<Manifest> manifests = v1_10.GetManifests("Foo.Bar"); + REQUIRE(manifests.size() == 1); + + // Verify manifest is populated + Manifest& manifest = manifests[0]; + REQUIRE(manifest.Id == "Foo.Bar"); + REQUIRE(manifest.Version == "3.0.0abc"); + REQUIRE(manifest.Moniker == "FooBarMoniker"); + REQUIRE(manifest.Channel == ""); + REQUIRE(manifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ "1.10.0" }); + sampleManifest.VerifyLocalizations_AllFields(manifest); + sampleManifest.VerifyInstallers_AllFields(manifest); +} From 5d4883d5dbe478aa8f979ca5419c1b47898305f4 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:03:54 -0800 Subject: [PATCH 3/7] utilinterop update --- .../Manifest/V1/InstallerAuthentication.cs | 24 +++++++++++++++++++ ...allerMicrosoftEntraIdAuthenticationInfo.cs | 24 +++++++++++++++++++ src/WinGetUtilInterop/Manifest/V1/Manifest.cs | 7 +++++- .../Manifest/V1/ManifestInstaller.cs | 7 +++++- 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 src/WinGetUtilInterop/Manifest/V1/InstallerAuthentication.cs create mode 100644 src/WinGetUtilInterop/Manifest/V1/InstallerMicrosoftEntraIdAuthenticationInfo.cs diff --git a/src/WinGetUtilInterop/Manifest/V1/InstallerAuthentication.cs b/src/WinGetUtilInterop/Manifest/V1/InstallerAuthentication.cs new file mode 100644 index 0000000000..163ac6d2dd --- /dev/null +++ b/src/WinGetUtilInterop/Manifest/V1/InstallerAuthentication.cs @@ -0,0 +1,24 @@ +// ----------------------------------------------------------------------------- +// <copyright file="InstallerAuthentication.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + /// <summary> + /// Installer authentication info. + /// </summary> + public class InstallerAuthentication + { + /// <summary> + /// Gets or sets the authentication type. + /// </summary> + public string AuthenticationType { get; set; } + + /// <summary> + /// Gets or sets the Microsoft Entra Id authentication info. + /// </summary> + public InstallerMicrosoftEntraIdAuthenticationInfo MicrosoftEntraIdAuthenticationInfo { get; set; } + } +} diff --git a/src/WinGetUtilInterop/Manifest/V1/InstallerMicrosoftEntraIdAuthenticationInfo.cs b/src/WinGetUtilInterop/Manifest/V1/InstallerMicrosoftEntraIdAuthenticationInfo.cs new file mode 100644 index 0000000000..2c06220a02 --- /dev/null +++ b/src/WinGetUtilInterop/Manifest/V1/InstallerMicrosoftEntraIdAuthenticationInfo.cs @@ -0,0 +1,24 @@ +// ----------------------------------------------------------------------------- +// <copyright file="InstallerMicrosoftEntraIdAuthenticationInfo.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGetUtil.Models.V1 +{ + /// <summary> + /// Microsoft Entra Id authentication info. + /// </summary> + public class InstallerMicrosoftEntraIdAuthenticationInfo + { + /// <summary> + /// Gets or sets the authentication resource. + /// </summary> + public string Resource { get; set; } + + /// <summary> + /// Gets or sets the authentication scope. + /// </summary> + public string Scope { get; set; } + } +} diff --git a/src/WinGetUtilInterop/Manifest/V1/Manifest.cs b/src/WinGetUtilInterop/Manifest/V1/Manifest.cs index 811081064c..8b80fa4940 100644 --- a/src/WinGetUtilInterop/Manifest/V1/Manifest.cs +++ b/src/WinGetUtilInterop/Manifest/V1/Manifest.cs @@ -333,7 +333,12 @@ public class Manifest /// <summary> /// Gets or sets the default repair behavior. /// </summary> - public string RepairBehavior { get; set; } + public string RepairBehavior { get; set; } + + /// <summary> + /// Gets or sets the default installer authentication info. + /// </summary> + public InstallerAuthentication Authentication { get; set; } /// <summary> /// Gets or sets collection of ManifestInstaller. At least one is required. diff --git a/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs b/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs index c6e326e3e3..172bb0de58 100644 --- a/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs +++ b/src/WinGetUtilInterop/Manifest/V1/ManifestInstaller.cs @@ -214,7 +214,12 @@ public class ManifestInstaller /// <summary> /// Gets or sets the repair behavior. /// </summary> - public string RepairBehavior { get; set; } + public string RepairBehavior { get; set; } + + /// <summary> + /// Gets or sets the installer authentication info. + /// </summary> + public InstallerAuthentication Authentication { get; set; } /// <summary> /// Returns a List of strings containing the URIs contained within this installer. From 181667b24539219d9ddd56140bd4c66eb7b7299e Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:17:57 -0800 Subject: [PATCH 4/7] utilinterop tests --- .../ManifestUnitTest/V1ManifestReadTest.cs | 25 ++ .../TestCollateral/V1_10ManifestMerged.yaml | 263 ++++++++++++++++++ .../WinGetUtilInterop.UnitTests.csproj | 3 + 3 files changed, 291 insertions(+) create mode 100644 src/WinGetUtilInterop.UnitTests/TestCollateral/V1_10ManifestMerged.yaml diff --git a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs index 72f24a5272..0ce596eec0 100644 --- a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs +++ b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs @@ -36,6 +36,7 @@ private enum TestManifestVersion V160, V170, V190, + V1100, } /// <summary> @@ -69,6 +70,11 @@ public void ReadV1ManifestsAndVerifyContents() Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V190ManifestMerged)); this.ValidateManifestFields(v190manifest, TestManifestVersion.V190); + + Manifest v1100manifest = Manifest.CreateManifestFromPath( + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V1100ManifestMerged)); + + this.ValidateManifestFields(v1100manifest, TestManifestVersion.V1100); } /// <summary> @@ -279,6 +285,13 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.True(manifest.ArchiveBinariesDependOnPath); } + if (manifestVersion >= TestManifestVersion.V1100) + { + Assert.Equal("microsoftEntraId", manifest.Authentication.AuthenticationType); + Assert.Equal("DefaultResource", manifest.Authentication.MicrosoftEntraIdAuthenticationInfo.Resource); + Assert.Equal("DefaultScope", manifest.Authentication.MicrosoftEntraIdAuthenticationInfo.Scope); + } + // Individual installers Assert.Equal(2, manifest.Installers.Count); ManifestInstaller installer1 = manifest.Installers[0]; @@ -391,6 +404,13 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("fakeIdentifier", installer2.ProductId); } + if (manifestVersion >= TestManifestVersion.V1100) + { + Assert.Equal("microsoftEntraId", installer1.Authentication.AuthenticationType); + Assert.Equal("DefaultResource", installer1.Authentication.MicrosoftEntraIdAuthenticationInfo.Resource); + Assert.Equal("DefaultScope", installer1.Authentication.MicrosoftEntraIdAuthenticationInfo.Scope); + } + // Additional Localizations Assert.Single(manifest.Localization); ManifestLocalization localization1 = manifest.Localization[0]; @@ -474,6 +494,11 @@ internal class ManifestStrings /// </summary> public const string V190ManifestMerged = "V1_9ManifestMerged.yaml"; + /// <summary> + /// Merged v1.10 manifest. + /// </summary> + public const string V1100ManifestMerged = "V1_10ManifestMerged.yaml"; + /// <summary> /// Merged v1 manifest without localization. /// </summary> diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_10ManifestMerged.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_10ManifestMerged.yaml new file mode 100644 index 0000000000..7c06202ddf --- /dev/null +++ b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_10ManifestMerged.yaml @@ -0,0 +1,263 @@ +PackageIdentifier: microsoft.msixsdk +PackageVersion: 1.7.32 +PackageLocale: en-US +Publisher: Microsoft +PublisherUrl: https://www.microsoft.com +PublisherSupportUrl: https://www.microsoft.com/support +PrivacyUrl: https://www.microsoft.com/privacy +Author: Microsoft +PackageName: MSIX SDK +PackageUrl: https://www.microsoft.com/msixsdk/home +License: MIT License +LicenseUrl: https://www.microsoft.com/msixsdk/license +Copyright: Copyright Microsoft Corporation +CopyrightUrl: https://www.microsoft.com/msixsdk/copyright +ShortDescription: This is MSIX SDK +Description: The MSIX SDK project is an effort to enable developers +Moniker: msixsdk +Tags: + - "appxsdk" + - "msixsdk" +ReleaseNotes: Default release notes +ReleaseNotesUrl: https://DefaultReleaseNotes.net +PurchaseUrl: https://DefaultPurchaseUrl.com +InstallationNotes: Default installation notes +Documentations: + - DocumentLabel: Default document label + DocumentUrl: https://DefaultDocumentUrl.com +Icons: + - IconUrl: https://testIcon + IconFileType: ico + IconResolution: custom + IconTheme: default + IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123 +Agreements: + - AgreementLabel: DefaultLabel + Agreement: DefaultText + AgreementUrl: https://DefaultAgreementUrl.net +InstallerLocale: en-US +Platform: + - Windows.Desktop + - Windows.Universal +MinimumOSVersion: 10.0.0.0 +InstallerType: zip +Scope: machine +InstallModes: + - interactive + - silent + - silentWithProgress +InstallerSwitches: + Custom: /custom + SilentWithProgress: /silentwithprogress + Silent: /silence + Interactive: /interactive + Log: /log=<LOGPATH> + InstallLocation: /dir=<INSTALLPATH> + Upgrade: /upgrade + Repair: /repair +InstallerSuccessCodes: + - 1 + - 0x80070005 +UpgradeBehavior: uninstallPrevious +Commands: + - makemsix + - makeappx +Protocols: + - protocol1 + - protocol2 +FileExtensions: + - appx + - msix + - appxbundle + - msixbundle +Dependencies: + WindowsFeatures: + - IIS + WindowsLibraries: + - VC Runtime + PackageDependencies: + - PackageIdentifier: Microsoft.MsixSdkDep + MinimumVersion: 1.0.0 + ExternalDependencies: + - Outside dependencies +Capabilities: + - internetClient +RestrictedCapabilities: + - runFullTrust +PackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe +ProductCode: "{Foo}" +ReleaseDate: 2021-01-01 +InstallerAbortsTerminal: true +InstallLocationRequired: true +RequireExplicitUpgrade: true +DisplayInstallWarnings: true +ElevationRequirement: elevatesSelf +UnsupportedOSArchitectures: + - arm +AppsAndFeaturesEntries: + - DisplayName: DisplayName + DisplayVersion: DisplayVersion + Publisher: Publisher + ProductCode: ProductCode + UpgradeCode: UpgradeCode + InstallerType: exe +Markets: + AllowedMarkets: + - US +ExpectedReturnCodes: + - InstallerReturnCode: 2 + ReturnResponse: contactSupport + ReturnResponseUrl: https://defaultReturnResponseUrl.com + - InstallerReturnCode: 3 + ReturnResponse: custom +UnsupportedArguments: + - log +NestedInstallerType: msi +NestedInstallerFiles: + - RelativeFilePath: RelativeFilePath + PortableCommandAlias: PortableCommandAlias +InstallationMetadata: + DefaultInstallLocation: "%ProgramFiles%\\TestApp" + Files: + - RelativeFilePath: "main.exe" + FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + FileType: launch + InvocationParameter: "/arg" + DisplayName: "DisplayName" +DownloadCommandProhibited: true +ArchiveBinariesDependOnPath: true +RepairBehavior: uninstaller +Authentication: + AuthenticationType: microsoftEntraId + MicrosoftEntraIdAuthenticationInfo: + Resource: DefaultResource + Scope: DefaultScope +Localization: +- Agreements: + - Agreement: Text + AgreementLabel: Label + AgreementUrl: https://AgreementUrl.net + Author: Microsoft UK + Copyright: Copyright Microsoft Corporation UK + CopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK + Description: The MSIX SDK project is an effort to enable developers UK + License: MIT License UK + LicenseUrl: https://www.microsoft.com/msixsdk/license/UK + PackageLocale: en-GB + PackageName: MSIX SDK UK + PackageUrl: https://www.microsoft.com/msixsdk/home/UK + PrivacyUrl: https://www.microsoft.com/privacy/UK + Publisher: Microsoft UK + PublisherSupportUrl: https://www.microsoft.com/support/UK + PublisherUrl: https://www.microsoft.com/UK + ReleaseNotes: Release notes + ReleaseNotesUrl: https://ReleaseNotes.net + ShortDescription: This is MSIX SDK UK + Tags: + - appxsdkUK + - msixsdkUK + PurchaseUrl: https://PurchaseUrl.com + InstallationNotes: Installation notes + Documentations: + - DocumentLabel: Document label + DocumentUrl: https://DocumentUrl.com + Icons: + - IconUrl: https://testIcon2 + IconFileType: png + IconResolution: 32x32 + IconTheme: dark + IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321 +Installers: + - Architecture: x86 + InstallerLocale: en-GB + Platform: + - Windows.Desktop + MinimumOSVersion: 10.0.1.0 + InstallerType: msix + InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix + InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + Scope: user + InstallModes: + - interactive + InstallerSwitches: + Custom: /c + SilentWithProgress: /sp + Silent: /s + Interactive: /i + Log: /l=<LOGPATH> + InstallLocation: /d=<INSTALLPATH> + Upgrade: /u + Repair: /r + UpgradeBehavior: install + Commands: + - makemsixPreview + - makeappxPreview + Protocols: + - protocol1preview + - protocol2preview + FileExtensions: + - appxbundle + - msixbundle + - appx + - msix + Dependencies: + WindowsFeatures: + - PreviewIIS + WindowsLibraries: + - Preview VC Runtime + PackageDependencies: + - PackageIdentifier: Microsoft.MsixSdkDepPreview + MinimumVersion: 1.0.0 + ExternalDependencies: + - Preview Outside dependencies + PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe + Capabilities: + - internetClientPreview + RestrictedCapabilities: + - runFullTrustPreview + ReleaseDate: 2021-02-02 + InstallerAbortsTerminal: false + InstallLocationRequired: false + NestedInstallerFiles: + - RelativeFilePath: RelativeFilePath2 + PortableCommandAlias: PortableCommandAlias2 + RequireExplicitUpgrade: false + DisplayInstallWarnings: true + ElevationRequirement: elevationRequired + NestedInstallerType: msi + UnsupportedArguments: + - location + UnsupportedOSArchitectures: + - arm64 + Markets: + ExcludedMarkets: + - "US" + ExpectedReturnCodes: + - InstallerReturnCode: 2 + ReturnResponse: contactSupport + ReturnResponseUrl: https://returnResponseUrl.com + DownloadCommandProhibited: true + ArchiveBinariesDependOnPath: false + RepairBehavior: modify + InstallationMetadata: + DefaultInstallLocation: "%ProgramFiles%\\TestApp" + Files: + - RelativeFilePath: "main2.exe" + FileSha256: 79D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + FileType: launch2 + InvocationParameter: "/arg2" + DisplayName: "DisplayName2" + Authentication: + AuthenticationType: microsoftEntraId + MicrosoftEntraIdAuthenticationInfo: + Resource: Resource + Scope: Scope + - Architecture: x64 + InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82 + InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe + InstallerType: exe + ProductCode: '{Bar}' + MSStoreProductIdentifier: fakeIdentifier +ManifestType: merged +ManifestVersion: 1.7.0 diff --git a/src/WinGetUtilInterop.UnitTests/WinGetUtilInterop.UnitTests.csproj b/src/WinGetUtilInterop.UnitTests/WinGetUtilInterop.UnitTests.csproj index 5b8e0d0784..595b6231c5 100644 --- a/src/WinGetUtilInterop.UnitTests/WinGetUtilInterop.UnitTests.csproj +++ b/src/WinGetUtilInterop.UnitTests/WinGetUtilInterop.UnitTests.csproj @@ -99,6 +99,9 @@ <None Update="TestCollateral\V1_9ManifestMerged.yaml"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </None> + <None Update="TestCollateral\V1_10ManifestMerged.yaml"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> <None Update="xunit.runner.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> From 56dd3c1485c4b97aa8b15119edf13d6009c59834 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:19:50 -0800 Subject: [PATCH 5/7] Fix tests --- .../ManifestUnitTest/V1ManifestReadTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs index 0ce596eec0..54c039d4cb 100644 --- a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs +++ b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs @@ -407,8 +407,8 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif if (manifestVersion >= TestManifestVersion.V1100) { Assert.Equal("microsoftEntraId", installer1.Authentication.AuthenticationType); - Assert.Equal("DefaultResource", installer1.Authentication.MicrosoftEntraIdAuthenticationInfo.Resource); - Assert.Equal("DefaultScope", installer1.Authentication.MicrosoftEntraIdAuthenticationInfo.Scope); + Assert.Equal("Resource", installer1.Authentication.MicrosoftEntraIdAuthenticationInfo.Resource); + Assert.Equal("Scope", installer1.Authentication.MicrosoftEntraIdAuthenticationInfo.Scope); } // Additional Localizations From 684fa35d88cc1365da462c760e7a87354e7afe09 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:30:47 -0800 Subject: [PATCH 6/7] Enum name change --- .../ManifestUnitTest/V1ManifestReadTest.cs | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs index 54c039d4cb..986c03fe4a 100644 --- a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs +++ b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs @@ -31,12 +31,12 @@ public V1ManifestReadTest(ITestOutputHelper log) private enum TestManifestVersion { - V100, - V110, - V160, - V170, - V190, - V1100, + V1_0_0, + V1_1_0, + V1_6_0, + V1_7_0, + V1_9_0, + V1_10_0, } /// <summary> @@ -46,35 +46,35 @@ private enum TestManifestVersion [DisplayTestMethodName] public void ReadV1ManifestsAndVerifyContents() { - Manifest v100manifest = Manifest.CreateManifestFromPath( - Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V100ManifestMerged)); + Manifest v1_0_0manifest = Manifest.CreateManifestFromPath( + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V1_0_0ManifestMerged)); - this.ValidateManifestFields(v100manifest, TestManifestVersion.V100); + this.ValidateManifestFields(v1_0_0manifest, TestManifestVersion.V1_0_0); - Manifest v110manifest = Manifest.CreateManifestFromPath( - Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V110ManifestMerged)); + Manifest v1_1_0manifest = Manifest.CreateManifestFromPath( + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V1_1_0ManifestMerged)); - this.ValidateManifestFields(v110manifest, TestManifestVersion.V110); + this.ValidateManifestFields(v1_1_0manifest, TestManifestVersion.V1_1_0); - Manifest v160manifest = Manifest.CreateManifestFromPath( - Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V160ManifestMerged)); + Manifest v1_6_0manifest = Manifest.CreateManifestFromPath( + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V1_6_0ManifestMerged)); - this.ValidateManifestFields(v160manifest, TestManifestVersion.V160); + this.ValidateManifestFields(v1_6_0manifest, TestManifestVersion.V1_6_0); - Manifest v170manifest = Manifest.CreateManifestFromPath( - Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V170ManifestMerged)); + Manifest v1_7_0manifest = Manifest.CreateManifestFromPath( + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V1_7_0ManifestMerged)); - this.ValidateManifestFields(v170manifest, TestManifestVersion.V170); + this.ValidateManifestFields(v1_7_0manifest, TestManifestVersion.V1_7_0); - Manifest v190manifest = Manifest.CreateManifestFromPath( - Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V190ManifestMerged)); + Manifest v1_9_0manifest = Manifest.CreateManifestFromPath( + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V1_9_0ManifestMerged)); - this.ValidateManifestFields(v190manifest, TestManifestVersion.V190); + this.ValidateManifestFields(v1_9_0manifest, TestManifestVersion.V1_9_0); - Manifest v1100manifest = Manifest.CreateManifestFromPath( - Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V1100ManifestMerged)); + Manifest v1_10_0manifest = Manifest.CreateManifestFromPath( + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestCollateral", ManifestStrings.V1_10_0ManifestMerged)); - this.ValidateManifestFields(v1100manifest, TestManifestVersion.V1100); + this.ValidateManifestFields(v1_10_0manifest, TestManifestVersion.V1_10_0); } /// <summary> @@ -134,7 +134,7 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("appxsdk", manifest.Tags[0]); Assert.Equal("msixsdk", manifest.Tags[1]); - if (manifestVersion >= TestManifestVersion.V110) + if (manifestVersion >= TestManifestVersion.V1_1_0) { Assert.Equal("Default release notes", manifest.ReleaseNotes); Assert.Equal("https://DefaultReleaseNotes.net", manifest.ReleaseNotesUrl); @@ -144,7 +144,7 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("https://DefaultAgreementUrl.net", manifest.Agreements[0].AgreementUrl); } - if (manifestVersion >= TestManifestVersion.V160) + if (manifestVersion >= TestManifestVersion.V1_6_0) { Assert.Equal("Default installation notes", manifest.InstallationNotes); Assert.Equal("https://DefaultPurchaseUrl.com", manifest.PurchaseUrl); @@ -221,7 +221,7 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("Microsoft.DesktopAppInstaller_8wekyb3d8bbwe", manifest.PackageFamilyName); Assert.Equal("{Foo}", manifest.ProductCode); - if (manifestVersion >= TestManifestVersion.V110) + if (manifestVersion >= TestManifestVersion.V1_1_0) { Assert.Equal("2021-01-01", manifest.ReleaseDate); Assert.True(manifest.InstallerAbortsTerminal); @@ -244,7 +244,7 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("contactSupport", manifest.ExpectedReturnCodes[0].ReturnResponse); } - if (manifestVersion >= TestManifestVersion.V160) + if (manifestVersion >= TestManifestVersion.V1_6_0) { Assert.Equal("msi", manifest.NestedInstallerType); Assert.Single(manifest.NestedInstallerFiles); @@ -274,18 +274,18 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("https://defaultReturnResponseUrl.com", manifest.ExpectedReturnCodes[0].ReturnResponseUrl); } - if (manifestVersion >= TestManifestVersion.V170) + if (manifestVersion >= TestManifestVersion.V1_7_0) { Assert.Equal("/repair", defaultSwitches.Repair); Assert.Equal("uninstaller", manifest.RepairBehavior); } - if (manifestVersion >= TestManifestVersion.V190) + if (manifestVersion >= TestManifestVersion.V1_9_0) { Assert.True(manifest.ArchiveBinariesDependOnPath); } - if (manifestVersion >= TestManifestVersion.V1100) + if (manifestVersion >= TestManifestVersion.V1_10_0) { Assert.Equal("microsoftEntraId", manifest.Authentication.AuthenticationType); Assert.Equal("DefaultResource", manifest.Authentication.MicrosoftEntraIdAuthenticationInfo.Resource); @@ -345,7 +345,7 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("runFullTrustPreview", installer1.RestrictedCapabilities[0]); Assert.Equal("Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe", installer1.PackageFamilyName); - if (manifestVersion >= TestManifestVersion.V110) + if (manifestVersion >= TestManifestVersion.V1_1_0) { Assert.Equal("2021-02-02", installer1.ReleaseDate); Assert.True(!installer1.InstallerAbortsTerminal); @@ -368,7 +368,7 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82", installer2.Sha256); Assert.Equal("{Bar}", installer2.ProductCode); - if (manifestVersion >= TestManifestVersion.V160) + if (manifestVersion >= TestManifestVersion.V1_6_0) { Assert.Single(installer1.InstallationMetadata.Files); ManifestInstallerFile installerFile2 = installer1.InstallationMetadata.Files[0]; @@ -392,19 +392,19 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("https://returnResponseUrl.com", installer1.ExpectedReturnCodes[0].ReturnResponseUrl); } - if (manifestVersion >= TestManifestVersion.V170) + if (manifestVersion >= TestManifestVersion.V1_7_0) { Assert.Equal("/r", installer1Switches.Repair); Assert.Equal("modify", installer1.RepairBehavior); } - if (manifestVersion >= TestManifestVersion.V190) + if (manifestVersion >= TestManifestVersion.V1_9_0) { Assert.False(installer1.ArchiveBinariesDependOnPath); Assert.Equal("fakeIdentifier", installer2.ProductId); } - if (manifestVersion >= TestManifestVersion.V1100) + if (manifestVersion >= TestManifestVersion.V1_10_0) { Assert.Equal("microsoftEntraId", installer1.Authentication.AuthenticationType); Assert.Equal("Resource", installer1.Authentication.MicrosoftEntraIdAuthenticationInfo.Resource); @@ -432,7 +432,7 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("appxsdkUK", localization1.Tags[0]); Assert.Equal("msixsdkUK", localization1.Tags[1]); - if (manifestVersion >= TestManifestVersion.V110) + if (manifestVersion >= TestManifestVersion.V1_1_0) { Assert.Equal("Release notes", localization1.ReleaseNotes); Assert.Equal("https://ReleaseNotes.net", localization1.ReleaseNotesUrl); @@ -442,7 +442,7 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif Assert.Equal("https://AgreementUrl.net", localization1.Agreements[0].AgreementUrl); } - if (manifestVersion >= TestManifestVersion.V160) + if (manifestVersion >= TestManifestVersion.V1_6_0) { Assert.Equal("Installation notes", localization1.InstallationNotes); Assert.Equal("https://PurchaseUrl.com", localization1.PurchaseUrl); @@ -472,32 +472,32 @@ internal class ManifestStrings /// <summary> /// Merged v1 manifest. /// </summary> - public const string V100ManifestMerged = "V1ManifestMerged.yaml"; + public const string V1_0_0ManifestMerged = "V1ManifestMerged.yaml"; /// <summary> /// Merged v1.1 manifest. /// </summary> - public const string V110ManifestMerged = "V1_1ManifestMerged.yaml"; + public const string V1_1_0ManifestMerged = "V1_1ManifestMerged.yaml"; /// <summary> /// Merged v1.6 manifest. /// </summary> - public const string V160ManifestMerged = "V1_6ManifestMerged.yaml"; + public const string V1_6_0ManifestMerged = "V1_6ManifestMerged.yaml"; /// <summary> /// Merged v1.7 manifest. /// </summary> - public const string V170ManifestMerged = "V1_7ManifestMerged.yaml"; + public const string V1_7_0ManifestMerged = "V1_7ManifestMerged.yaml"; /// <summary> /// Merged v1.9 manifest. /// </summary> - public const string V190ManifestMerged = "V1_9ManifestMerged.yaml"; + public const string V1_9_0ManifestMerged = "V1_9ManifestMerged.yaml"; /// <summary> /// Merged v1.10 manifest. /// </summary> - public const string V1100ManifestMerged = "V1_10ManifestMerged.yaml"; + public const string V1_10_0ManifestMerged = "V1_10ManifestMerged.yaml"; /// <summary> /// Merged v1 manifest without localization. From 9ad58c46f35c163789d3222e9155cb0ccfb680f1 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Tue, 11 Feb 2025 19:25:21 -0800 Subject: [PATCH 7/7] Fix build warnings --- .../ManifestUnitTest/V1ManifestReadTest.cs | 2 ++ src/WinGetUtilInterop/Api/WinGetManifest.cs | 3 +-- src/WinGetUtilInterop/Manifest/V1/Manifest.cs | 1 - src/WinGetUtilInterop/WinGetUtilInterop.csproj | 5 +++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs index 986c03fe4a..81905518bf 100644 --- a/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs +++ b/src/WinGetUtilInterop.UnitTests/ManifestUnitTest/V1ManifestReadTest.cs @@ -469,6 +469,7 @@ private void ValidateManifestFields(Manifest manifest, TestManifestVersion manif /// </summary> internal class ManifestStrings { +#pragma warning disable SA1310 // FieldNamesMustNotContainUnderscore /// <summary> /// Merged v1 manifest. /// </summary> @@ -498,6 +499,7 @@ internal class ManifestStrings /// Merged v1.10 manifest. /// </summary> public const string V1_10_0ManifestMerged = "V1_10ManifestMerged.yaml"; +#pragma warning restore SA1310 // FieldNamesMustNotContainUnderscore /// <summary> /// Merged v1 manifest without localization. diff --git a/src/WinGetUtilInterop/Api/WinGetManifest.cs b/src/WinGetUtilInterop/Api/WinGetManifest.cs index 156959eeb8..9d20e67f7a 100644 --- a/src/WinGetUtilInterop/Api/WinGetManifest.cs +++ b/src/WinGetUtilInterop/Api/WinGetManifest.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- // <copyright file="WinGetManifest.cs" company="Microsoft Corporation"> // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // </copyright> @@ -25,7 +25,6 @@ public sealed class WinGetManifest : IWinGetManifest /// Initializes a new instance of the <see cref="WinGetManifest"/> class. /// </summary> /// <param name="manifestHandle">Handle of the manifest.</param> - /// <param name="loggingContext">Logging Context.</param> internal WinGetManifest(IntPtr manifestHandle) { this.manifestHandle = manifestHandle; diff --git a/src/WinGetUtilInterop/Manifest/V1/Manifest.cs b/src/WinGetUtilInterop/Manifest/V1/Manifest.cs index 8b80fa4940..9df3343f84 100644 --- a/src/WinGetUtilInterop/Manifest/V1/Manifest.cs +++ b/src/WinGetUtilInterop/Manifest/V1/Manifest.cs @@ -228,7 +228,6 @@ public class Manifest /// </summary> public string ProductCode { get; set; } - /// <summary> /// <summary> /// Gets or sets the default list of capabilities. For msix only. /// </summary> diff --git a/src/WinGetUtilInterop/WinGetUtilInterop.csproj b/src/WinGetUtilInterop/WinGetUtilInterop.csproj index 6b66270457..54f0ba7547 100644 --- a/src/WinGetUtilInterop/WinGetUtilInterop.csproj +++ b/src/WinGetUtilInterop/WinGetUtilInterop.csproj @@ -1,8 +1,9 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.1</TargetFramework> - <RootNamespace>Microsoft.WinGetUtil</RootNamespace> + <RootNamespace>Microsoft.WinGetUtil</RootNamespace> + <GenerateDocumentationFile>true</GenerateDocumentationFile> </PropertyGroup> <ItemGroup>