diff --git a/src/WingetCreateCLI/Commands/BaseCommand.cs b/src/WingetCreateCLI/Commands/BaseCommand.cs
index 3c4ed842..737b59bc 100644
--- a/src/WingetCreateCLI/Commands/BaseCommand.cs
+++ b/src/WingetCreateCLI/Commands/BaseCommand.cs
@@ -422,6 +422,7 @@ protected static void RemoveEmptyStringFieldsInManifests(Manifests manifests)
///
/// Shifts common installer fields from manifest root to installer level.
+ /// If value is already defined at the installer level, then it should not be overwritten.
///
/// Wrapper object containing the installer manifest object models.
protected static void ShiftRootFieldsToInstallerLevel(InstallerManifest installerManifest)
@@ -439,8 +440,13 @@ protected static void ShiftRootFieldsToInstallerLevel(InstallerManifest installe
{
foreach (var installer in installerManifest.Installers)
{
- // Copy the value to installer level
- installer.GetType().GetProperty(property.Name).SetValue(installer, rootValue);
+ var installerProperty = installer.GetType().GetProperty(property.Name);
+
+ // Only set the value if it is null at the installer level
+ if (installerProperty.GetValue(installer) == null)
+ {
+ installerProperty.SetValue(installer, rootValue);
+ }
}
// Set root value to null
diff --git a/src/WingetCreateCLI/Commands/UpdateCommand.cs b/src/WingetCreateCLI/Commands/UpdateCommand.cs
index 391b340e..afd6b902 100644
--- a/src/WingetCreateCLI/Commands/UpdateCommand.cs
+++ b/src/WingetCreateCLI/Commands/UpdateCommand.cs
@@ -460,13 +460,6 @@ public Manifests DeserializeManifestContentAndApplyInitialUpdate(List la
UpdatePropertyForLocaleManifests(nameof(LocaleManifest.PackageVersion), this.Version, localeManifests);
}
- // TODO: Move relevant metadata from root node to installer node.
- if (installerManifest.InstallerType != null)
- {
- installerManifest.Installers.ForEach(i => i.InstallerType = installerManifest.InstallerType);
- installerManifest.InstallerType = null;
- }
-
return manifests;
}
diff --git a/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.OverwriteNullInstallerFields.yaml b/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.OverwriteNullInstallerFields.yaml
new file mode 100644
index 00000000..eb089e0e
--- /dev/null
+++ b/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.OverwriteNullInstallerFields.yaml
@@ -0,0 +1,88 @@
+PackageIdentifier: TestPublisher.OverwriteNullInstallerFields
+PackageVersion: 0.1.2
+PackageName: Overwrite installer level fields by root fields
+Publisher: Test publisher
+License: MIT
+ShortDescription: A manifest that verifies that installer level fields are overwritten by root fields.
+Description: |-
+ Expected flow:
+
+ 1) Installer level fields are overwritten by root fields at the start of the update.
+ 2) The update flow modifies the installer level fields if needed. (e.g. ProductCode in case of MSI upgrade)
+ 3) At the end of the update, the common installer fields are moved to the root level.
+InstallerLocale: en-US
+InstallerType: zip
+NestedInstallerType: exe
+NestedInstallerFiles:
+- RelativeFilePath: WingetCreateTestExeInstaller.exe
+ PortableCommandAlias: PortableCommandAlias1
+AppsAndFeaturesEntries:
+- DisplayName: TestDisplayName1
+ Publisher: TestPublisher1
+ DisplayVersion: 1.0.1
+ ProductCode: TestProductCode1
+ UpgradeCode: TestUpgradeCode1
+ InstallerType: msi
+InstallerSwitches:
+ Silent: /silent1
+ SilentWithProgress: /silentwithprogress1
+Dependencies:
+ PackageDependencies:
+ - PackageIdentifier: TestPackageDependency1
+ MinimumVersion: 1.0.1
+ WindowsFeatures:
+ - TestWindowsFeature1
+ ExternalDependencies:
+ - TestExternalDependency1
+ WindowsLibraries:
+ - TestWindowsLibrary1
+ExpectedReturnCodes:
+ - InstallerReturnCode: 1001
+ ReturnResponse: installInProgress
+MinimumOSVersion: 10.0.22000.0
+PackageFamilyName: TestPackageFamilyName1
+Platform:
+- Windows.Desktop
+Scope: machine
+UpgradeBehavior: install
+ElevationRequirement: elevationRequired
+Commands:
+ - fakeCommand1
+Protocols:
+ - fakeProtocol1
+FileExtensions:
+ - .exe
+# Uncomment when installer model gets updated to support these fields
+#Markets:
+# AllowedMarkets:
+# - fakeAllowedMarket
+# ExcludedMarkets:
+# - fakeExcludedMarket
+InstallerAbortsTerminal: true
+InstallLocationRequired: true
+RequireExplicitUpgrade: true
+UnsupportedOSArchitectures:
+ - arm64
+DisplayInstallWarnings: true
+InstallerSuccessCodes:
+ - 1
+UnsupportedArguments:
+ - log
+ - location
+InstallationMetadata:
+ DefaultInstallLocation: "%ProgramFiles%\\TestApp1"
+ Files:
+ - RelativeFilePath: "main1.exe"
+ FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82
+ FileType: launch
+ InvocationParameter: "/arg1"
+Installers:
+ - Architecture: x64
+ InstallerUrl: https://fakedomain.com/WingetCreateTestZipInstaller.zip
+ InstallerSha256: 8A052767127A6E2058BAAE03B551A807777BB1B726650E2C7E92C3E92C8DF80D
+ - Architecture: x86
+ InstallerUrl: https://fakedomain.com/WingetCreateTestZipInstaller.zip
+ InstallerSha256: 8A052767127A6E2058BAAE03B551A807777BB1B726650E2C7E92C3E92C8DF80D
+PackageLocale: en-US
+ManifestType: singleton
+ManifestVersion: 1.4.0
\ No newline at end of file
diff --git a/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.OverrideInstallerFields.yaml b/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.RetainInstallerFields.yaml
similarity index 60%
rename from src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.OverrideInstallerFields.yaml
rename to src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.RetainInstallerFields.yaml
index 062adbf1..ce0587b3 100644
--- a/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.OverrideInstallerFields.yaml
+++ b/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.RetainInstallerFields.yaml
@@ -1,21 +1,24 @@
-PackageIdentifier: TestPublisher.OverrideInstallerFields
+PackageIdentifier: TestPublisher.RetainInstallerFields
PackageVersion: 0.1.2
-PackageName: Override installer level fields by root fields
+PackageName: Retain installer level fields when copying over root values
Publisher: Test publisher
License: MIT
-ShortDescription: A manifest that verifies that installer level fields are overridden by root fields.
+ShortDescription: A manifest that verifies that non-null installer level fields are not overwritten by root fields.
Description: |-
Expected flow:
- 1) Installer level fields are overridden by root fields at the start of the update.
- 2) The update flow modifies the installer level fields if needed. (e.g. ProductCode in case of MSI upgrade)
- 3) At the end of the update, the common installer fields are moved to the root level.
+ 1) For the first installer, all root level fields are copied over and root fields are set to null.
+ 2) For the second installer, installer level fields are preserved since they are not null.
+ 3) InstallerType and NestedInstallerType are common across both installers, so they are moved to the root level at the end of the update.
+
+ TODO: Use different NestedInstallerType and RelativeFilePath for each installer once logic for handling multiple nested installers is improved.
+ Reference: https://github.com/microsoft/winget-create/issues/392
InstallerLocale: en-US
InstallerType: zip
NestedInstallerType: exe
NestedInstallerFiles:
- RelativeFilePath: WingetCreateTestExeInstaller.exe
- PortableCommandAlias: PortableCommandAlias1
+ PortableCommandAlias: TestAlias
AppsAndFeaturesEntries:
- DisplayName: TestDisplayName1
Publisher: TestPublisher1
@@ -78,80 +81,16 @@ InstallationMetadata:
InvocationParameter: "/arg1"
Installers:
- Architecture: x64
- InstallerType: zip
InstallerUrl: https://fakedomain.com/WingetCreateTestZipInstaller.zip
InstallerSha256: 8A052767127A6E2058BAAE03B551A807777BB1B726650E2C7E92C3E92C8DF80D
- NestedInstallerType: msi
- NestedInstallerFiles:
- - RelativeFilePath: WingetCreateTestExeInstaller.exe
- PortableCommandAlias: PortableCommandAlias2
- AppsAndFeaturesEntries:
- - DisplayName: TestDisplayName2
- Publisher: TestPublisher2
- DisplayVersion: 1.0.2
- ProductCode: TestProductCode2
- UpgradeCode: TestUpgradeCode2
- InstallerType: exe
- InstallerSwitches:
- Silent: /silent2
- SilentWithProgress: /silentwithprogress2
- Dependencies:
- PackageDependencies:
- - PackageIdentifier: TestPackageDependency2
- MinimumVersion: 1.0.2
- WindowsFeatures:
- - TestWindowsFeature2
- ExternalDependencies:
- - TestExternalDependency2
- WindowsLibraries:
- - TestWindowsLibrary2
- ExpectedReturnCodes:
- - InstallerReturnCode: 1002
- ReturnResponse: installInProgress
- MinimumOSVersion: 10.0.17763.0
- PackageFamilyName: TestPackageFamilyName2
- Platform:
- - Windows.Universal
- Scope: user
- UpgradeBehavior: uninstallPrevious
- ElevationRequirement: elevatesSelf
- Commands:
- - fakeCommand2
- Protocols:
- - fakeProtocol2
- FileExtensions:
- - .msi
- # Uncomment when installer model gets updated to support these fields
- #Markets:
- # AllowedMarkets:
- # - fakeAllowedMarket
- # ExcludedMarkets:
- # - fakeExcludedMarket
- InstallerAbortsTerminal: false
- InstallLocationRequired: false
- RequireExplicitUpgrade: false
- UnsupportedOSArchitectures:
- - arm
- DisplayInstallWarnings: false
- InstallerSuccessCodes:
- - 2
- UnsupportedArguments:
- - log
- InstallationMetadata:
- DefaultInstallLocation: "%ProgramFiles%\\TestApp2"
- Files:
- - RelativeFilePath: "main2.exe"
- FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82
- FileType: launch
- InvocationParameter: "/arg2"
- Architecture: x86
InstallerType: zip
InstallerUrl: https://fakedomain.com/WingetCreateTestZipInstaller.zip
InstallerSha256: 8A052767127A6E2058BAAE03B551A807777BB1B726650E2C7E92C3E92C8DF80D
- NestedInstallerType: msi
+ NestedInstallerType: exe
NestedInstallerFiles:
- RelativeFilePath: WingetCreateTestExeInstaller.exe
- PortableCommandAlias: PortableCommandAlias2
+ PortableCommandAlias: TestAlias
AppsAndFeaturesEntries:
- DisplayName: TestDisplayName2
Publisher: TestPublisher2
@@ -188,7 +127,7 @@ Installers:
- fakeProtocol2
FileExtensions:
- .msi
- # Uncomment when installer model gets updated to support these fields
+ # TODO: Uncomment when installer model gets updated to support these fields
#Markets:
# AllowedMarkets:
# - fakeAllowedMarket
diff --git a/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs b/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs
index 7610ffeb..cdf92714 100644
--- a/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs
+++ b/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs
@@ -1076,15 +1076,19 @@ public async Task DontMoveInstallerFieldsToRoot()
}
///
- /// Verifies that installer fields are overridden by root fields in update scenario.
+ /// Verifies that null installer fields are overwritten by root fields in update scenario.
+ /// Expected flow:
+ /// 1) Null installer level fields are overwritten by root fields at the start of the update.
+ /// 2) The update flow modifies the installer level fields if needed. (e.g. ProductCode in case of MSI upgrade)
+ /// 3) At the end of the update, the common installer fields are moved to the root level.
///
/// A representing the result of the asynchronous operation.
[Test]
- public async Task UpdateOverridesInstallerFields()
+ public async Task UpdateOverwritesNullInstallerFields()
{
TestUtils.InitializeMockDownloads(TestConstants.TestZipInstaller);
string installerUrl = $"https://fakedomain.com/{TestConstants.TestZipInstaller}";
- (UpdateCommand command, var initialManifestContent) = GetUpdateCommandAndManifestData("TestPublisher.OverrideInstallerFields", null, this.tempPath, new[] { $"{installerUrl}|x64", $"{installerUrl}|x86" });
+ (UpdateCommand command, var initialManifestContent) = GetUpdateCommandAndManifestData("TestPublisher.OverwriteNullInstallerFields", null, this.tempPath, new[] { $"{installerUrl}|x64", $"{installerUrl}|x86" });
var updatedManifests = await RunUpdateCommand(command, initialManifestContent);
Assert.IsNotNull(updatedManifests, "Command should have succeeded");
@@ -1162,6 +1166,138 @@ public async Task UpdateOverridesInstallerFields()
}
}
+ ///
+ /// Verifies that non-null installer fields are preserved when overwriting with root fields at the start of the update.
+ /// Expected flow:
+ /// 1) For the first installer, all root level fields are copied over and root fields are set to null.
+ /// 2) For the second installer, installer level fields are preserved since they are not null.
+ /// 3) InstallerType, NestedInstallerType and NestedInstallerFiles are common across both installers, so they are moved to the root level at the end of the update.
+ /// TODO: Use different NestedInstallerType and RelativeFilePath for each installer once logic for handling multiple nested installers is improved.
+ /// Reference: https://github.com/microsoft/winget-create/issues/392.
+ ///
+ /// A representing the result of the asynchronous operation.
+ [Test]
+ public async Task UpdateRetainsNonNullInstallerFields()
+ {
+ TestUtils.InitializeMockDownloads(TestConstants.TestZipInstaller);
+ string installerUrl = $"https://fakedomain.com/{TestConstants.TestZipInstaller}";
+ (UpdateCommand command, var initialManifestContent) = GetUpdateCommandAndManifestData("TestPublisher.RetainInstallerFields", null, this.tempPath, new[] { $"{installerUrl}|x64", $"{installerUrl}|x86" });
+ var updatedManifests = await RunUpdateCommand(command, initialManifestContent);
+ Assert.IsNotNull(updatedManifests, "Command should have succeeded");
+
+ InstallerManifest updatedInstallerManifest = updatedManifests.InstallerManifest;
+ Installer firstInstaller = updatedInstallerManifest.Installers[0];
+ Installer secondInstaller = updatedInstallerManifest.Installers[1];
+
+ // Fields for first installer should be copied over from root
+ Assert.IsTrue(firstInstaller.Scope == Scope.Machine, "Scope for the first installer should be copied over from root");
+ Assert.IsTrue(firstInstaller.MinimumOSVersion == "10.0.22000.0", "MinimumOSVersion for the first installer should be copied over from root");
+ Assert.IsTrue(firstInstaller.PackageFamilyName == "TestPackageFamilyName1", "PackageFamilyName for the first installer should be copied over from root");
+ Assert.IsTrue(firstInstaller.UpgradeBehavior == UpgradeBehavior.Install, "UpgradeBehavior for the first installer should be copied over from root");
+ Assert.IsTrue(firstInstaller.ElevationRequirement == ElevationRequirement.ElevationRequired, "ElevationRequirement for the first installer should be copied over from root");
+ Assert.IsTrue(firstInstaller.InstallerAbortsTerminal == true, "InstallerAbortsTerminal for the first installer should be copied over from root");
+ Assert.IsTrue(firstInstaller.InstallLocationRequired == true, "InstallLocation for the first installer should be copied over from root");
+ Assert.IsTrue(firstInstaller.RequireExplicitUpgrade == true, "RequireExplicitUpgrade for the first installer should be copied over from root");
+ Assert.IsTrue(firstInstaller.DisplayInstallWarnings == true, "DisplayInstallWarnings for the first installer should be copied over from root");
+ Assert.IsNotNull(firstInstaller.InstallerSwitches, "InstallerSwitches for the first installer should not be null");
+ Assert.IsTrue(firstInstaller.InstallerSwitches.Silent == "/silent1", "Silent installer switch for the first installer should be copied over from root");
+ Assert.IsNotNull(firstInstaller.Dependencies, "Dependencies for the first installer should not be null");
+ Assert.IsTrue(firstInstaller.Dependencies.PackageDependencies[0].PackageIdentifier == "TestPackageDependency1", "PackageDependencies PackageIdentifier for the first installer should be copied over from root");
+ Assert.IsNotNull(firstInstaller.AppsAndFeaturesEntries, "AppsAndFeaturesEntries for the first installer should not be null");
+ Assert.IsTrue(firstInstaller.AppsAndFeaturesEntries[0].ProductCode == "TestProductCode1", "AppsAndFeaturesEntries ProductCode for the first installer should be copied over from root");
+ Assert.IsNotNull(firstInstaller.Platform, "Platform for the first installer should not be null");
+ Assert.IsTrue(firstInstaller.Platform[0] == Platform.Windows_Desktop, "Platform for the first installer should be copied over from root");
+ Assert.IsNotNull(firstInstaller.ExpectedReturnCodes, "ExpectedReturnCodes afor the first installer should not be null");
+ Assert.IsTrue(firstInstaller.ExpectedReturnCodes[0].InstallerReturnCode == 1001, "ExpectedReturnCodes InstallerReturnCode for the first installer should be copied over from root");
+ Assert.IsNotNull(firstInstaller.Commands, "Commands for the first installer should not be null");
+ Assert.IsTrue(firstInstaller.Commands[0] == "fakeCommand1", "Commands for the first installer should be copied over from root");
+ Assert.IsNotNull(firstInstaller.Protocols, "Protocols for the first installer should not be null");
+ Assert.IsTrue(firstInstaller.Protocols[0] == "fakeProtocol1", "Protocols for the first installer should be copied over from root");
+ Assert.IsNotNull(firstInstaller.FileExtensions, "FileExtensions for the first installer should not be null");
+ Assert.IsTrue(firstInstaller.FileExtensions[0] == ".exe", "FileExtensions for the first installer should be copied over from root");
+
+ // TODO: Uncomment when installer model gets updated to support markets field.
+ // Assert.IsNotNull(firstInstaller.Markets, "Markets for the first installer should not be null");
+ Assert.IsNotNull(firstInstaller.UnsupportedOSArchitectures, "UnsupportedOSArchitectures for the first installer should not be null");
+ Assert.IsTrue(firstInstaller.UnsupportedOSArchitectures[0] == UnsupportedOSArchitecture.Arm64, "UnsupportedOSArchitectures for the first installer should be copied over from root");
+ Assert.IsNotNull(firstInstaller.InstallerSuccessCodes, "InstallerSuccessCodes for the first installer should not be null");
+ Assert.IsTrue(firstInstaller.InstallerSuccessCodes[0] == 1, "InstallerSuccessCodes for the first installer should contain be copied over from root");
+ Assert.IsNotNull(firstInstaller.UnsupportedArguments, "UnsupportedArguments for the first installer should not be null");
+ Assert.IsTrue(firstInstaller.UnsupportedArguments[1] == UnsupportedArgument.Location, "UnsupportedArguments for the first installer should be copied over from root");
+ Assert.IsNotNull(firstInstaller.InstallationMetadata, "InstallationMetadata for the first installer should not be null");
+ Assert.IsTrue(firstInstaller.InstallationMetadata.DefaultInstallLocation == "%ProgramFiles%\\TestApp1", "DefaultInstallLocation for the first installer should be copied over from root");
+
+ // Fields for second installer should be preserved
+ Assert.IsTrue(secondInstaller.Scope == Scope.User, "Scope for the second installer should be preserved");
+ Assert.IsTrue(secondInstaller.MinimumOSVersion == "10.0.17763.0", "MinimumOSVersion for the second installer should be preserved");
+ Assert.IsTrue(secondInstaller.PackageFamilyName == "TestPackageFamilyName2", "PackageFamilyName for the second installer should be preserved");
+ Assert.IsTrue(secondInstaller.UpgradeBehavior == UpgradeBehavior.UninstallPrevious, "UpgradeBehavior for the second installer should be preserved");
+ Assert.IsTrue(secondInstaller.ElevationRequirement == ElevationRequirement.ElevatesSelf, "ElevationRequirement for the second installer should be preserved");
+ Assert.IsTrue(secondInstaller.InstallerAbortsTerminal == false, "InstallerAbortsTerminal for the second installer should be preserved");
+ Assert.IsTrue(secondInstaller.InstallLocationRequired == false, "InstallLocation for the second installer should be preserved");
+ Assert.IsTrue(secondInstaller.RequireExplicitUpgrade == false, "RequireExplicitUpgrade for the second installer should be preserved");
+ Assert.IsTrue(secondInstaller.DisplayInstallWarnings == false, "DisplayInstallWarnings for the second installer should be preserved");
+ Assert.IsNotNull(secondInstaller.InstallerSwitches, "InstallerSwitches for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.InstallerSwitches.Silent == "/silent2", "Silent installer switch for the second installer should be preserved");
+ Assert.IsNotNull(secondInstaller.Dependencies, "Dependencies for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.Dependencies.PackageDependencies[0].PackageIdentifier == "TestPackageDependency2", "PackageDependencies PackageIdentifier for the second installer should be preserved");
+ Assert.IsNotNull(secondInstaller.AppsAndFeaturesEntries, "AppsAndFeaturesEntries for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.AppsAndFeaturesEntries[0].ProductCode == "TestProductCode2", "AppsAndFeaturesEntries ProductCode for the second installer should be preserved");
+ Assert.IsNotNull(secondInstaller.Platform, "Platform for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.Platform[0] == Platform.Windows_Universal, "Platform for the second installer should be preserved");
+ Assert.IsNotNull(secondInstaller.ExpectedReturnCodes, "ExpectedReturnCodes for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.ExpectedReturnCodes[0].InstallerReturnCode == 1002, "ExpectedReturnCodes InstallerReturnCode for the second installer should be preserved");
+ Assert.IsNotNull(secondInstaller.Commands, "Commands for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.Commands[0] == "fakeCommand2", "Commands for the second installer should be preserved");
+ Assert.IsNotNull(secondInstaller.Protocols, "Protocols for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.Protocols[0] == "fakeProtocol2", "Protocols for the second installer should be preserved");
+ Assert.IsNotNull(secondInstaller.FileExtensions, "FileExtensions for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.FileExtensions[0] == ".msi", "FileExtensions for the second installer should be preserved");
+
+ // TODO: Uncomment when installer model gets updated to support markets field.
+ // Assert.IsNotNull(secondInstaller.Markets, "Markets for the first installer should not be null");
+ Assert.IsNotNull(secondInstaller.UnsupportedOSArchitectures, "UnsupportedOSArchitectures for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.UnsupportedOSArchitectures[0] == UnsupportedOSArchitecture.Arm, "UnsupportedOSArchitectures for the second installer should be preserved");
+ Assert.IsNotNull(secondInstaller.InstallerSuccessCodes, "InstallerSuccessCodes for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.InstallerSuccessCodes[0] == 2, "InstallerSuccessCodes for the second installer should be preserved");
+ Assert.IsNotNull(secondInstaller.UnsupportedArguments, "UnsupportedArguments for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.UnsupportedArguments[0] == UnsupportedArgument.Log, "UnsupportedArguments for the second installer should be preserved");
+ Assert.IsNotNull(secondInstaller.InstallationMetadata, "InstallationMetadata for the second installer should not be null");
+ Assert.IsTrue(secondInstaller.InstallationMetadata.DefaultInstallLocation == "%ProgramFiles%\\TestApp2", "DefaultInstallLocation for the second installer should be preserved");
+
+ // Root fields should be null
+ Assert.IsNull(updatedInstallerManifest.Scope, "Scope at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.MinimumOSVersion, "MinimumOSVersion at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.PackageFamilyName, "PackageFamilyName at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.UpgradeBehavior, "UpgradeBehavior at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.ElevationRequirement, "ElevationRequirement at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.InstallerAbortsTerminal, "InstallerAbortsTerminal at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.InstallLocationRequired, "InstallLocation at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.RequireExplicitUpgrade, "RequireExplicitUpgrade at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.DisplayInstallWarnings, "DisplayInstallWarnings at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.InstallerSwitches, "InstallerSwitches at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.Dependencies, "Dependencies at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.AppsAndFeaturesEntries, "AppsAndFeaturesEntries at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.Platform, "Platform at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.ExpectedReturnCodes, "ExpectedReturnCodes at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.Commands, "Commands at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.Protocols, "Protocols at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.FileExtensions, "FileExtensions at the root level should be null");
+
+ // TODO: Uncomment when installer model gets updated to support markets field.
+ // Assert.IsNull(updatedInstallerManifest.Markets, "Markets at the root level should be null");
+ Assert.IsNull(updatedInstallerManifest.UnsupportedOSArchitectures, "UnsupportedOSArchitectures at the installer level should be null");
+ Assert.IsNull(updatedInstallerManifest.InstallerSuccessCodes, "InstallerSuccessCodes at the installer level should be null");
+ Assert.IsNull(updatedInstallerManifest.UnsupportedArguments, "UnsupportedArguments at the installer level should be null");
+ Assert.IsNull(updatedInstallerManifest.InstallationMetadata, "InstallationMetadata at the installer level should be null");
+
+ // Fields that should be moved to root
+ Assert.IsTrue(updatedInstallerManifest.InstallerType == InstallerType.Zip, "InstallerType at the root level should be ZIP");
+ Assert.IsTrue(updatedInstallerManifest.NestedInstallerType == NestedInstallerType.Exe, "NestedInstallerType at the root level should be EXE");
+ Assert.IsNotNull(updatedInstallerManifest.NestedInstallerFiles, "NestedInstallerFiles at the root level should not be null");
+ Assert.IsTrue(updatedInstallerManifest.NestedInstallerFiles[0].PortableCommandAlias == "TestAlias", "PortableCommandAlias at the root level should be TestAlias");
+ }
+
///
/// Verifies that the appropriate error message is displayed if the nested installer is not found.
///
diff --git a/src/WingetCreateTests/WingetCreateTests/WingetCreateTests.csproj b/src/WingetCreateTests/WingetCreateTests/WingetCreateTests.csproj
index afa8a83d..a21a583a 100644
--- a/src/WingetCreateTests/WingetCreateTests/WingetCreateTests.csproj
+++ b/src/WingetCreateTests/WingetCreateTests/WingetCreateTests.csproj
@@ -36,7 +36,10 @@
PreserveNewest
-
+
+ PreserveNewest
+
+
PreserveNewest