Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -965,60 +965,65 @@ internal async void ExecutePackageDownload(string name, PackageVersion package,
}

// Determine if there are any dependencies that have a newer dynamo version, (this includes the root package).
// We assume this means this package is compatibile with that dynamo version, but we should warn the user it
// We assume this means this package is compatible with that dynamo version, but we should warn the user it
// may not work with the current version of Dynamo.

//wrap in try catch as it's possible version info could be missing. If so, we install the package and log an error.
try
// If the compatibility matrix already indicates compatibility, skip the engine_version heuristic.
// Only perform engine_version based warnings when compatibility is not explicitly true.
if (compatible != true)
{
var dynamoVersion = Version.Parse(DynamoModel.Version);
var futureDeps = newPackageHeaders.Where(dep => Version.Parse(dep.engine_version) > dynamoVersion);
// also identify packages that have a dynamo engine version less than 3.x as a special case,
// as Dynamo 3.x uses .net8 and older versions used .net framework - these packages may not be compatible.
// This check will return empty if the current major version is not 3.
var preDYN4Deps = newPackageHeaders.Where(dep => dynamoVersion.Major == 4 && Version.Parse(dep.engine_version).Major < dynamoVersion.Major);

// If any of the required packages use a newer version of Dynamo, show a dialog to the user
// allowing them to cancel the package download
if (futureDeps.Any())
//wrap in try catch as it's possible version info could be missing. If so, we install the package and log an error.
try
{
var res = MessageBoxService.Show(ViewModelOwner,
$"{string.Format(Resources.MessagePackageNewerDynamo, DynamoViewModel.BrandingResourceProvider.ProductName)} {Resources.MessagePackOlderDynamoLink}",
string.Format(Resources.PackageUseNewerDynamoMessageBoxTitle, DynamoViewModel.BrandingResourceProvider.ProductName),
var dynamoVersion = Version.Parse(DynamoModel.Version);
var futureDeps = newPackageHeaders.Where(dep => Version.Parse(dep.engine_version) > dynamoVersion);
// also identify packages that have a Dynamo engine version from a different major version as a special case,
// as different major Dynamo versions may use different runtime frameworks - these packages may not be compatible.
// This check will return empty if the current major version does not require this validation.
Comment on lines +980 to +982
var preDYNDeps = newPackageHeaders.Where(dep => Version.Parse(dep.engine_version).Major < dynamoVersion.Major);

// If any of the required packages use a newer version of Dynamo, show a dialog to the user
// allowing them to cancel the package download
if (futureDeps.Any())
{
var res = MessageBoxService.Show(ViewModelOwner,
$"{string.Format(Resources.MessagePackageNewerDynamo, DynamoViewModel.BrandingResourceProvider.ProductName)} {Resources.MessagePackOlderDynamoLink}",
string.Format(Resources.PackageUseNewerDynamoMessageBoxTitle, DynamoViewModel.BrandingResourceProvider.ProductName),
//this message has a url link so we use the rich text box version of the message box.
showRichTextBox: true,
MessageBoxButton.OKCancel,
MessageBoxImage.Warning);
if (res == MessageBoxResult.Cancel || res == MessageBoxResult.None)
{
return;
}
}

//if any of the required packages use a pre 3.x version of Dynamo, show a dialog to the user
//allowing them to cancel the package download
Comment on lines +1002 to +1003
if (preDYNDeps.Any())
{
var res = MessageBoxService.Show(ViewModelOwner,
$"{string.Format(Resources.MessagePackageOlderDynamo, DynamoViewModel.BrandingResourceProvider.ProductName)} {Resources.MessagePackOlderDynamoLink}",
string.Format(Resources.PackageUseOlderDynamoMessageBoxTitle, DynamoViewModel.BrandingResourceProvider.ProductName),
//this message has a url link so we use the rich text box version of the message box.
showRichTextBox: true,
MessageBoxButton.OKCancel,
MessageBoxImage.Warning);
if (res == MessageBoxResult.Cancel || res == MessageBoxResult.None)
{
return;
if (res == MessageBoxResult.Cancel || res == MessageBoxResult.None)
{
return;
}
}
}

//if any of the required packages use a pre 3.x version of Dynamo, show a dialog to the user
//allowing them to cancel the package download
if (preDYN4Deps.Any())
catch (ArgumentException ex)
{
var res = MessageBoxService.Show(ViewModelOwner,
$"{string.Format(Resources.MessagePackageOlderDynamo, DynamoViewModel.BrandingResourceProvider.ProductName)} {Resources.MessagePackOlderDynamoLink}",
string.Format(Resources.PackageUseOlderDynamoMessageBoxTitle, DynamoViewModel.BrandingResourceProvider.ProductName),
//this message has a url link so we use the rich text box version of the message box.
showRichTextBox: true,
MessageBoxButton.OKCancel,
MessageBoxImage.Warning);
if (res == MessageBoxResult.Cancel || res == MessageBoxResult.None)
{
return;
}
DynamoConsoleLogger.OnLogMessageToDynamoConsole($"exception while trying to compare version info between package and dynamo {ex}");
}
catch (FormatException ex)
{
DynamoConsoleLogger.OnLogMessageToDynamoConsole($"exception while trying to compare version info between package and dynamo {ex}");
}
}
catch (ArgumentException ex)
{
DynamoConsoleLogger.OnLogMessageToDynamoConsole($"exception while trying to compare version info between package and dynamo {ex}");
}
catch (FormatException ex)
{
DynamoConsoleLogger.OnLogMessageToDynamoConsole($"exception while trying to compare version info between package and dynamo {ex}");
}

// add custom path to custom package folder list
Expand Down
146 changes: 146 additions & 0 deletions test/DynamoCoreWpf2Tests/PackageManager/PackageManagerUITests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1626,6 +1626,152 @@ public void PackageManagerShowsWarningWhenDownloadingLegacyPackage()
MessageBoxButton.OKCancel,MessageBoxImage.Exclamation), Times.Exactly(1));

}

[Test]
[Description("If the package compatibility matrix explicitly marks the package as compatible, do NOT show engine_version newer/older warnings even when engine_version differs.")]
public void PackageManagerDoesNotShowEngineVersionWarningWhenCompatibilityMatrixIsCompatible()
Comment thread
johnpierson marked this conversation as resolved.
{
var mockGreg = new Mock<IGregClient>();
var clientMock = new Mock<Dynamo.PackageManager.PackageManagerClient>(mockGreg.Object, MockMaker.Empty<IPackageUploadBuilder>(), string.Empty, false);
var pmVmMock = new Mock<PackageManagerClientViewModel>(ViewModel, clientMock.Object);
var pmMock = new Mock<PackageManagerExtension>();

// When we attempt a download, return a valid download path so we never hit the real Greg client.
pmVmMock.Setup(x => x.Download(It.IsAny<PackageDownloadHandle>())).Returns<PackageDownloadHandle>(h => Task.Factory.StartNew(() => (h, h.Name)));
pmVmMock.Setup(x => x.InstallPackage(It.IsAny<PackageDownloadHandle>(), It.IsAny<string>(), It.IsAny<string>()));

var pkgVer = new Version(1, 0, 0).ToString();
// An engine_version that would normally trip the older/newer Dynamo warning heuristic.
var pkgEngineVersion = "1.0.0";
var id =Guid.NewGuid().ToString();
var name = "test-123-name";
var deps = new List<Dependency>() { new Dependency() { _id = id, name = name } };
var depVersions = new List<string>() { pkgVer };

// A compatibility matrix that explicitly marks the package as compatible with the current Dynamo version.
var compatibilityMatrix = new List<Greg.Responses.Compatibility>
{
new Greg.Responses.Compatibility { name = "Dynamo", min = "1.0", max = "100.0" }
};

var pkgVersionObject = new PackageVersion()
{
version = pkgVer,
engine_version = pkgEngineVersion,
name = name,
id = id,
full_dependency_ids = deps,
full_dependency_versions = depVersions,
compatibility_matrix = compatibilityMatrix
};

// When headers are retrieved for the package, return the correct header (carrying the compatibility matrix).
clientMock.Setup(x => x.GetPackageVersionHeader(It.IsAny<string>(), It.IsAny<string>())).Returns<string, string>((i, v) =>
{
return i == id ? pkgVersionObject : null;
});

// Wire up the PackageManagerExtension so CheckIfPackagesTargetOtherHosts can resolve known hosts.
clientMock.Setup(x => x.GetKnownHosts()).Returns(new List<string>() { "Revit", "Civil 3D", "FormIt" });
pmMock.Setup(x => x.PackageManagerClient).Returns(clientMock.Object);
pmMock.Setup(x => x.Host).Returns("");
pmVmMock.Setup(x => x.PackageManagerExtension).Returns(pmMock.Object);
var dlgMock = new Mock<MessageBoxService.IMessageBox>();

// Click OK on the download consent dialog.
dlgMock.Setup(m => m.Show(It.IsAny<Window>(), It.IsAny<string>(), It.IsAny<string>(),
It.Is<MessageBoxButton>(x => x == MessageBoxButton.OKCancel || x == MessageBoxButton.OK), It.IsAny<MessageBoxImage>()))
.Returns(MessageBoxResult.OK);
dlgMock.Setup(m => m.Show(It.IsAny<Window>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(),
It.IsAny<MessageBoxButton>(), It.IsAny<MessageBoxImage>()))
.Returns(MessageBoxResult.OK);
MessageBoxService.OverrideMessageBoxDuringTests(dlgMock.Object);

var productName = ViewModel.BrandingResourceProvider.ProductName;
var newerDynamoMessage = $"{string.Format(Dynamo.Wpf.Properties.Resources.MessagePackageNewerDynamo, productName)} {Dynamo.Wpf.Properties.Resources.MessagePackOlderDynamoLink}";
var olderDynamoMessage = $"{string.Format(Dynamo.Wpf.Properties.Resources.MessagePackageOlderDynamo, productName)} {Dynamo.Wpf.Properties.Resources.MessagePackOlderDynamoLink}";

// Actually perform the download & install operations.
pmVmMock.Object.ExecutePackageDownload(id, pkgVersionObject, "");

// Because the compatibility matrix marks the package as compatible (compatible == true),
// the engine_version heuristic is skipped entirely, so neither
// the "newer Dynamo" nor the "older/legacy Dynamo" warning should be shown.
dlgMock.Verify(x => x.Show(It.IsAny<Window>(), newerDynamoMessage, It.IsAny<string>(),
It.IsAny<bool>(), It.IsAny<MessageBoxButton>(), It.IsAny<MessageBoxImage>()), Times.Never);
dlgMock.Verify(x => x.Show(It.IsAny<Window>(), olderDynamoMessage, It.IsAny<string>(),
It.IsAny<bool>(), It.IsAny<MessageBoxButton>(), It.IsAny<MessageBoxImage>()), Times.Never);
}

[Test]
[Description("If the package compatibility matrix is null, engine_version warnings should still appear when engine_version differs from the current Dynamo version.")]
public void PackageManagerShowsEngineVersionWarningWhenCompatibilityMatrixIsNull()
{
var mockGreg = new Mock<IGregClient>();
var clientMock = new Mock<Dynamo.PackageManager.PackageManagerClient>(mockGreg.Object, MockMaker.Empty<IPackageUploadBuilder>(), string.Empty, false);
var pmVmMock = new Mock<PackageManagerClientViewModel>(ViewModel, clientMock.Object);
var pmMock = new Mock<PackageManagerExtension>();

// When we attempt a download, return a valid download path so we never hit the real Greg client.
pmVmMock.Setup(x => x.Download(It.IsAny<PackageDownloadHandle>())).Returns<PackageDownloadHandle>(h => Task.Factory.StartNew(() => (h, h.Name)));
pmVmMock.Setup(x => x.InstallPackage(It.IsAny<PackageDownloadHandle>(), It.IsAny<string>(), It.IsAny<string>()));

var pkgVer = new Version(1, 0, 0).ToString();
// An engine_version that would normally trip the older/newer Dynamo warning heuristic.
var pkgEngineVersion = "1.0.0";
var id = Guid.NewGuid().ToString();
var name = "test-123-name";
var deps = new List<Dependency>() { new Dependency() { _id = id, name = name } };
var depVersions = new List<string>() { pkgVer };

// No compatibility matrix — the engine_version heuristic should still fire.
var pkgVersionObject = new PackageVersion()
{
version = pkgVer,
engine_version = pkgEngineVersion,
name = name,
id = id,
full_dependency_ids = deps,
full_dependency_versions = depVersions,
compatibility_matrix = null
};

// When headers are retrieved for the package, return the correct header (carrying the compatibility matrix).
clientMock.Setup(x => x.GetPackageVersionHeader(It.IsAny<string>(), It.IsAny<string>())).Returns<string, string>((i, v) =>
{
return i == id ? pkgVersionObject : null;
});

// Wire up the PackageManagerExtension so CheckIfPackagesTargetOtherHosts can resolve known hosts.
clientMock.Setup(x => x.GetKnownHosts()).Returns(new List<string>() { "Revit", "Civil 3D", "FormIt" });
pmMock.Setup(x => x.PackageManagerClient).Returns(clientMock.Object);
pmMock.Setup(x => x.Host).Returns("");
pmVmMock.Setup(x => x.PackageManagerExtension).Returns(pmMock.Object);
var dlgMock = new Mock<MessageBoxService.IMessageBox>();

// Click OK on the download consent dialog.
dlgMock.Setup(m => m.Show(It.IsAny<Window>(), It.IsAny<string>(), It.IsAny<string>(),
It.Is<MessageBoxButton>(x => x == MessageBoxButton.OKCancel || x == MessageBoxButton.OK), It.IsAny<MessageBoxImage>()))
.Returns(MessageBoxResult.OK);
dlgMock.Setup(m => m.Show(It.IsAny<Window>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(),
It.IsAny<MessageBoxButton>(), It.IsAny<MessageBoxImage>()))
.Returns(MessageBoxResult.OK);
MessageBoxService.OverrideMessageBoxDuringTests(dlgMock.Object);

var productName = ViewModel.BrandingResourceProvider.ProductName;
var newerDynamoMessage = $"{string.Format(Dynamo.Wpf.Properties.Resources.MessagePackageNewerDynamo, productName)} {Dynamo.Wpf.Properties.Resources.MessagePackOlderDynamoLink}";
var olderDynamoMessage = $"{string.Format(Dynamo.Wpf.Properties.Resources.MessagePackageOlderDynamo, productName)} {Dynamo.Wpf.Properties.Resources.MessagePackOlderDynamoLink}";

// Actually perform the download & install operations.
pmVmMock.Object.ExecutePackageDownload(id, pkgVersionObject, "");

// Because the compatibility matrix is null, the engine_version heuristic is NOT skipped,
// so either the "newer Dynamo" or the "older/legacy Dynamo" warning should be shown exactly once.
var newerShown = dlgMock.Invocations.Any(i => i.Method.Name == "Show" && i.Arguments.Count > 1 && i.Arguments[1]?.ToString() == newerDynamoMessage);
var olderShown = dlgMock.Invocations.Any(i => i.Method.Name == "Show" && i.Arguments.Count > 1 && i.Arguments[1]?.ToString() == olderDynamoMessage);

Assert.IsTrue(newerShown || olderShown, "Neither the newer-Dynamo or older-Dynamo engine_version warning were shown when compatibility_matrix is null.");
}
#endregion

#region PackageManagerSearchView
Expand Down
Loading