From 93473ef02233c05d17910d7ae5f010e1ec893966 Mon Sep 17 00:00:00 2001 From: Muhammad Danish Date: Tue, 8 Aug 2023 19:56:49 +0500 Subject: [PATCH] Avoid creating installer node with duplicate NestedInstallerFile (#419) --- src/WingetCreateCore/Common/PackageParser.cs | 8 ++++ .../TestPublisher.ZipMultipleInstallers.yaml | 10 +++++ .../UnitTests/UpdateCommandTests.cs | 38 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/WingetCreateCore/Common/PackageParser.cs b/src/WingetCreateCore/Common/PackageParser.cs index 80773d67..85998312 100644 --- a/src/WingetCreateCore/Common/PackageParser.cs +++ b/src/WingetCreateCore/Common/PackageParser.cs @@ -501,6 +501,14 @@ private static bool ParsePackageAndGenerateInstallerNodes(InstallerMetadata inst foreach (NestedInstallerFile nestedInstallerFile in installerMetadata.NestedInstallerFiles) { + // Skip adding duplicate NestedInstallerFile object. + if (baseInstaller.NestedInstallerFiles.Any(i => + i.RelativeFilePath == nestedInstallerFile.RelativeFilePath && + i.PortableCommandAlias == nestedInstallerFile.PortableCommandAlias)) + { + continue; + } + baseInstaller.NestedInstallerFiles.Add(new NestedInstallerFile { RelativeFilePath = nestedInstallerFile.RelativeFilePath, diff --git a/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.ZipMultipleInstallers.yaml b/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.ZipMultipleInstallers.yaml index f3767c1c..f4ede0f4 100644 --- a/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.ZipMultipleInstallers.yaml +++ b/src/WingetCreateTests/WingetCreateTests/Resources/TestPublisher.ZipMultipleInstallers.yaml @@ -12,6 +12,7 @@ Installers: NestedInstallerType: exe NestedInstallerFiles: - RelativeFilePath: WingetCreateTestExeInstaller.exe + PortableCommandAlias: TestPortableCommandAlias - Architecture: x86 InstallerType: zip InstallerUrl: https://fakedomain.com/WingetCreateTestZipInstaller.zip @@ -19,6 +20,15 @@ Installers: NestedInstallerType: exe NestedInstallerFiles: - RelativeFilePath: WingetCreateTestExeInstaller.exe + PortableCommandAlias: TestPortableCommandAlias +- Architecture: arm64 + InstallerType: zip + InstallerUrl: https://fakedomain.com/WingetCreateTestZipInstaller.zip + InstallerSha256: 8A052767127A6E2058BAAE03B551A807777BB1B726650E2C7E92C3E92C8DF80D + NestedInstallerType: exe + NestedInstallerFiles: + - RelativeFilePath: WingetCreateTestExeInstaller.exe + PortableCommandAlias: TestPortableCommandAlias PackageLocale: en-US ManifestType: singleton ManifestVersion: 1.4.0 \ No newline at end of file diff --git a/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs b/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs index a82082d2..2db1b306 100644 --- a/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs +++ b/src/WingetCreateTests/WingetCreateTests/UnitTests/UpdateCommandTests.cs @@ -823,6 +823,44 @@ public async Task UpdateZipWithMsix() Assert.IsTrue(initialSecondInstaller.InstallerSha256 != updatedSecondInstaller.InstallerSha256, "InstallerSha256 should be updated"); } + /// + /// Verifies that updating a zip package with multiple zip installers works as expected. + /// + /// A representing the asynchronous unit test. + [Test] + public async Task UpdateMultipleZipInstallers() + { + TestUtils.InitializeMockDownloads(TestConstants.TestZipInstaller); + + string installerUrl = $"https://fakedomain.com/{TestConstants.TestZipInstaller}"; + (UpdateCommand command, var initialManifestContent) = GetUpdateCommandAndManifestData("TestPublisher.ZipMultipleInstallers", null, this.tempPath, new[] { $"{installerUrl}|x64", $"{installerUrl}|x86", $"{installerUrl}|arm64" }); + + var updatedManifests = await RunUpdateCommand(command, initialManifestContent); + Assert.IsNotNull(updatedManifests, "Command should have succeeded"); + + var initialManifests = Serialization.DeserializeManifestContents(initialManifestContent); + var initialInstallers = initialManifests.SingletonManifest.Installers; + var initialFirstInstaller = initialInstallers[0]; + var initialSecondInstaller = initialInstallers[1]; + var initialThirdInstaller = initialInstallers[2]; + + var updatedInstallerManifest = updatedManifests.InstallerManifest; + var updatedFirstInstaller = updatedInstallerManifest.Installers[0]; + var updatedSecondInstaller = updatedInstallerManifest.Installers[1]; + var updatedThirdInstaller = updatedInstallerManifest.Installers[2]; + + Assert.IsTrue(updatedInstallerManifest.InstallerType == InstallerType.Zip, "InstallerType should be ZIP"); + Assert.IsTrue(updatedInstallerManifest.NestedInstallerType == NestedInstallerType.Exe, "NestedInstallerType should be EXE"); + Assert.IsTrue(updatedInstallerManifest.NestedInstallerFiles.Count == 1, "NestedInstallerFiles list should contain only one member"); + + Assert.IsTrue(initialFirstInstaller.NestedInstallerFiles[0].RelativeFilePath == updatedInstallerManifest.NestedInstallerFiles[0].RelativeFilePath, "RelativeFilePath should be preserved."); + Assert.IsTrue(initialFirstInstaller.NestedInstallerFiles[0].PortableCommandAlias == updatedInstallerManifest.NestedInstallerFiles[0].PortableCommandAlias, "PortableCommandAlias should be preserved."); + + Assert.IsTrue(initialFirstInstaller.InstallerSha256 != updatedFirstInstaller.InstallerSha256, "InstallerSha256 should be updated"); + Assert.IsTrue(initialSecondInstaller.InstallerSha256 != updatedSecondInstaller.InstallerSha256, "InstallerSha256 should be updated"); + Assert.IsTrue(initialThirdInstaller.InstallerSha256 != updatedThirdInstaller.InstallerSha256, "InstallerSha256 should be updated"); + } + /// /// Verifies that moving common installer fields to the root of the manifest works as expected. ///