diff --git a/src/Microsoft.OData.Cli/ODataCliFileHandler.cs b/src/Microsoft.OData.Cli/ODataCliFileHandler.cs index 7ff2b38a..cd9e1719 100644 --- a/src/Microsoft.OData.Cli/ODataCliFileHandler.cs +++ b/src/Microsoft.OData.Cli/ODataCliFileHandler.cs @@ -91,16 +91,16 @@ public Task AddFileAsync(string fileName, string targetPath, ODataFileOp /// Emits the container property attribute. The lastest version gets installed. so we'll always emit this property. /// /// A bool indicating whether to emit the container property or not - public bool EmitContainerPropertyAttribute() + public Task EmitContainerPropertyAttributeAsync() { - return true; + return Task.FromResult(true); } /// /// Sets the CSDL file as an embedded resource /// /// The name of the file to set as embedded resource - public void SetFileAsEmbeddedResource(string fileName) + public Task SetFileAsEmbeddedResourceAsync(string fileName) { if (this.project != null) { @@ -111,6 +111,8 @@ public void SetFileAsEmbeddedResource(string fileName) ProjectHelper.AddProjectItem(this.project, Constants.EmbeddedResourceTag, fileName); } } + + return Task.CompletedTask; } } } diff --git a/src/Microsoft.OData.CodeGen/CodeGeneration/V4CodeGenDescriptor.cs b/src/Microsoft.OData.CodeGen/CodeGeneration/V4CodeGenDescriptor.cs index 42474e6c..89fd2c3c 100644 --- a/src/Microsoft.OData.CodeGen/CodeGeneration/V4CodeGenDescriptor.cs +++ b/src/Microsoft.OData.CodeGen/CodeGeneration/V4CodeGenDescriptor.cs @@ -35,13 +35,13 @@ public V4CodeGenDescriptor(IFileHandler fileHandler, IMessageLogger logger, IPac public override async Task AddNugetPackagesAsync() { - await MessageLogger.WriteMessageAsync(LogMessageCategory.Information, "Adding Nuget Packages...").ConfigureAwait(false); + await MessageLogger.WriteMessageAsync(LogMessageCategory.Information, "Adding Nuget Packages..."); foreach (var nugetPackage in Common.Constants.V4NuGetPackages) - await PackageInstaller.CheckAndInstallNuGetPackageAsync(Common.Constants.NuGetOnlineRepository, nugetPackage).ConfigureAwait(false); + await PackageInstaller.CheckAndInstallNuGetPackageAsync(Common.Constants.NuGetOnlineRepository, nugetPackage); - await MessageLogger.WriteMessageAsync(LogMessageCategory.Information, "Nuget Packages were installed.").ConfigureAwait(false); + await MessageLogger.WriteMessageAsync(LogMessageCategory.Information, "Nuget Packages were installed."); } public override async Task AddGeneratedClientCodeAsync(string metadata, string outputDirectory, LanguageOption languageOption, ServiceConfiguration serviceConfiguration) @@ -96,7 +96,7 @@ private async Task AddT4FileAsync(string metadata, string outputDirectory, Langu await FileHandler.AddFileAsync(csdlTempFile, metadataFile, new ODataFileOptions { SuppressOverwritePrompt = true }); - FileHandler.SetFileAsEmbeddedResource(csdlFileName); + await FileHandler.SetFileAsEmbeddedResourceAsync(csdlFileName); var t4TempFile = Path.GetTempFileName(); @@ -193,8 +193,8 @@ private async Task AddGeneratedCodeAsync(string metadata, string outputDirectory var metadataFile = Path.Combine(referenceFolder, csdlFileName); await FileHandler.AddFileAsync(tempFile, metadataFile, new ODataFileOptions { SuppressOverwritePrompt = true }); - FileHandler.SetFileAsEmbeddedResource(csdlFileName); - t4CodeGenerator.EmitContainerPropertyAttribute = FileHandler.EmitContainerPropertyAttribute(); + await FileHandler.SetFileAsEmbeddedResourceAsync(csdlFileName); + t4CodeGenerator.EmitContainerPropertyAttribute = await FileHandler.EmitContainerPropertyAttributeAsync(); t4CodeGenerator.MetadataFilePath = metadataFile; t4CodeGenerator.MetadataFileRelativePath = csdlFileName; @@ -207,7 +207,7 @@ private async Task AddGeneratedCodeAsync(string metadata, string outputDirectory { foreach (var err in t4CodeGenerator.Errors) { - await MessageLogger.WriteMessageAsync(LogMessageCategory.Warning, err.ToString()).ConfigureAwait(false); + await MessageLogger.WriteMessageAsync(LogMessageCategory.Warning, err.ToString()); } } } diff --git a/src/Microsoft.OData.CodeGen/FileHandling/IFileHandler.cs b/src/Microsoft.OData.CodeGen/FileHandling/IFileHandler.cs index 9c9ad739..5f313079 100644 --- a/src/Microsoft.OData.CodeGen/FileHandling/IFileHandler.cs +++ b/src/Microsoft.OData.CodeGen/FileHandling/IFileHandler.cs @@ -26,12 +26,12 @@ public interface IFileHandler /// Sets a file as an embedded resource /// /// The name of the file to set as an embedded resource - void SetFileAsEmbeddedResource(string fileName); + Task SetFileAsEmbeddedResourceAsync(string fileName); /// /// Emits container property attribute /// /// - bool EmitContainerPropertyAttribute(); + Task EmitContainerPropertyAttributeAsync(); } } diff --git a/src/Microsoft.OData.CodeGen/Microsoft.OData.CodeGen.csproj b/src/Microsoft.OData.CodeGen/Microsoft.OData.CodeGen.csproj index b0596b55..d45bbe3d 100644 --- a/src/Microsoft.OData.CodeGen/Microsoft.OData.CodeGen.csproj +++ b/src/Microsoft.OData.CodeGen/Microsoft.OData.CodeGen.csproj @@ -79,6 +79,7 @@ + diff --git a/src/Microsoft.OData.CodeGen/Threading/IThreadHelper.cs b/src/Microsoft.OData.CodeGen/Threading/IThreadHelper.cs new file mode 100644 index 00000000..51d1def9 --- /dev/null +++ b/src/Microsoft.OData.CodeGen/Threading/IThreadHelper.cs @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +// +//---------------------------------------------------------------------------- + +using System; +using System.Threading.Tasks; + +namespace Microsoft.OData.CodeGen +{ + /// + /// A Thread helper to assist users to marshal certain work in certain threads. + /// + public interface IThreadHelper + { + /// + /// Runs the block provided in the background. + /// + /// Return type generic type parameter. + /// Function containing the task to be ran in the background thread executor. + /// A task respresenting the completion of the task. + Task RunAsync(Func> backgroundTask); + + /// + /// Runs the block provided in the foreground UI thread. + /// + /// Return type generic type parameter. + /// A func representing the foreground task. + /// A task respresenting the completion of the task. + Task RunInUiThreadAsync(Func foregroundTask); + } +} diff --git a/src/ODataConnectedService.Shared/ConnectedServiceFileHandler.cs b/src/ODataConnectedService.Shared/ConnectedServiceFileHandler.cs index 7da5b73f..5a18180d 100644 --- a/src/ODataConnectedService.Shared/ConnectedServiceFileHandler.cs +++ b/src/ODataConnectedService.Shared/ConnectedServiceFileHandler.cs @@ -11,7 +11,10 @@ using Microsoft.OData.CodeGen; using Microsoft.OData.CodeGen.FileHandling; using Microsoft.VisualStudio.ConnectedServices; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Threading; using VSLangProj; +using Task = System.Threading.Tasks.Task; namespace Microsoft.OData.ConnectedService { @@ -21,6 +24,8 @@ namespace Microsoft.OData.ConnectedService public class ConnectedServiceFileHandler : IFileHandler { private ConnectedServiceHandlerContext Context; + private readonly IThreadHelper threadHelper; + public Project Project { get; private set; } /// @@ -28,10 +33,11 @@ public class ConnectedServiceFileHandler : IFileHandler /// /// The /// An object of the project. - public ConnectedServiceFileHandler(ConnectedServiceHandlerContext context, Project project ) + public ConnectedServiceFileHandler(ConnectedServiceHandlerContext context, Project project, IThreadHelper threadHelper) { this.Context = context; this.Project = project; + this.threadHelper = threadHelper; } /// @@ -57,39 +63,49 @@ public async Task AddFileAsync(string fileName, string targetPath, OData /// Sets the CSDL file as an embedded resource /// /// The name of the file to set as embedded resource - public void SetFileAsEmbeddedResource(string fileName) + public async Task SetFileAsEmbeddedResourceAsync(string fileName) { - var dte = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(DTE)) as DTE; - if (dte != null) + await this.threadHelper.RunInUiThreadAsync(() => { - var projectItem = this.Project.ProjectItems.Item("Connected Services").ProjectItems.Item(((ODataConnectedServiceInstance)this.Context.ServiceInstance).ServiceConfig.ServiceName).ProjectItems.Item(fileName); - projectItem.Properties.Item("BuildAction").Value = prjBuildAction.prjBuildActionEmbeddedResource; - } +#pragma warning disable VSTHRD010 // Invoke single-threaded types on Main thread + if (Package.GetGlobalService(typeof(DTE)) is DTE dte) + { + var projectItem = this.Project.ProjectItems.Item("Connected Services").ProjectItems.Item(((ODataConnectedServiceInstance)this.Context.ServiceInstance).ServiceConfig.ServiceName).ProjectItems.Item(fileName); + projectItem.Properties.Item("BuildAction").Value = prjBuildAction.prjBuildActionEmbeddedResource; + return true; + } +#pragma warning restore VSTHRD010 // Invoke single-threaded types on Main thread + return false; + }).ConfigureAwait(true); } /// /// Sets the container property attribute to either true or false /// /// A value of either true or false - public bool EmitContainerPropertyAttribute() + public async Task EmitContainerPropertyAttributeAsync() { - var vsProject = this.Project.Object as VSProject; - if (vsProject != null) + return await threadHelper.RunInUiThreadAsync(() => { - foreach (Reference reference in vsProject.References) +#pragma warning disable VSTHRD010 // Invoke single-threaded types on Main thread + if (this.Project.Object is VSProject vsProject) { - if (reference.SourceProject == null) + foreach (Reference reference in vsProject.References) { - // Assembly reference (For project reference, SourceProject != null) - if (reference.Name.Equals("Microsoft.OData.Client", StringComparison.Ordinal)) + if (reference.SourceProject == null) { - return Version.Parse(reference.Version) > Version.Parse("7.6.4.0"); + // Assembly reference (For project reference, SourceProject != null) + if (reference.Name.Equals("Microsoft.OData.Client", StringComparison.Ordinal)) + { + return Version.Parse(reference.Version) > Version.Parse("7.6.4.0"); + } } } } - } +#pragma warning restore VSTHRD010 // Invoke single-threaded types on Main thread - return false; + return false; + }).ConfigureAwait(true); } } } diff --git a/src/ODataConnectedService.Shared/ConnectedServicePackageInstaller.cs b/src/ODataConnectedService.Shared/ConnectedServicePackageInstaller.cs index cb942e93..32c76463 100644 --- a/src/ODataConnectedService.Shared/ConnectedServicePackageInstaller.cs +++ b/src/ODataConnectedService.Shared/ConnectedServicePackageInstaller.cs @@ -26,6 +26,7 @@ public class ConnectedServicePackageInstaller : IPackageInstaller public Project Project { get; private set; } public IMessageLogger MessageLogger { get; private set; } public IVsPackageInstaller PackageInstaller { get; protected set; } + public IVsPackageInstallerServices PackageInstallerServices { get; protected set; } /// @@ -68,8 +69,7 @@ public async Task CheckAndInstallNuGetPackageAsync(string packageSource, string { if (!PackageInstallerServices.IsPackageInstalled(this.Project, packageName)) { - Version packageVersion = null; - PackageInstaller.InstallPackage(packageSource, this.Project, packageName, packageVersion, false); + PackageInstaller.InstallPackage(packageSource, this.Project, packageName, (string)null, false); ; await (this.MessageLogger?.WriteMessageAsync(LogMessageCategory.Information, $"Nuget Package \"{packageName}\" for OData client was added.")).ConfigureAwait(false); } diff --git a/src/ODataConnectedService.Shared/ConnectedServiceThreadHelper.cs b/src/ODataConnectedService.Shared/ConnectedServiceThreadHelper.cs new file mode 100644 index 00000000..1351dfa8 --- /dev/null +++ b/src/ODataConnectedService.Shared/ConnectedServiceThreadHelper.cs @@ -0,0 +1,24 @@ +using System; + +using System.Threading.Tasks; +using Microsoft.OData.CodeGen; +using Microsoft.VisualStudio.Shell; + +namespace ODataConnectedService.Shared +{ + internal class ConnectedServiceThreadHelper : IThreadHelper + { + /// + public async Task RunAsync(Func> backgroundTask) + { + return await ThreadHelper.JoinableTaskFactory.RunAsync(backgroundTask); + } + + /// + public async Task RunInUiThreadAsync(Func foregroundTask) + { + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + return foregroundTask(); + } + } +} diff --git a/src/ODataConnectedService.Shared/ODataConnectedService.Shared.projitems b/src/ODataConnectedService.Shared/ODataConnectedService.Shared.projitems index add224db..355b34d2 100644 --- a/src/ODataConnectedService.Shared/ODataConnectedService.Shared.projitems +++ b/src/ODataConnectedService.Shared/ODataConnectedService.Shared.projitems @@ -17,6 +17,7 @@ + diff --git a/src/ODataConnectedService.Shared/ODataConnectedServiceHandler.cs b/src/ODataConnectedService.Shared/ODataConnectedServiceHandler.cs index 4c0ba9b0..54a45b1a 100644 --- a/src/ODataConnectedService.Shared/ODataConnectedServiceHandler.cs +++ b/src/ODataConnectedService.Shared/ODataConnectedServiceHandler.cs @@ -11,9 +11,11 @@ using System.Threading; using System.Threading.Tasks; using EnvDTE; +using Microsoft.OData.CodeGen; using Microsoft.OData.CodeGen.CodeGeneration; using Microsoft.OData.ConnectedService.Common; using Microsoft.VisualStudio.ConnectedServices; +using ODataConnectedService.Shared; namespace Microsoft.OData.ConnectedService { @@ -49,7 +51,6 @@ private async Task SaveServiceInstanceAsync(ConnectedServ { Project project = ProjectHelper.GetProjectFromHierarchy(context.ProjectHierarchy); var serviceInstance = (ODataConnectedServiceInstance)context.ServiceInstance; - var codeGenDescriptor = await GenerateCodeAsync(serviceInstance.ServiceConfig.Endpoint, serviceInstance.ServiceConfig.EdmxVersion, context, project).ConfigureAwait(false); if (!serviceInstance.ServiceConfig.StoreCustomHttpHeaders) { @@ -89,7 +90,9 @@ private async Task GenerateCodeAsync(string metadataUri, languageOption = LanguageOption.GenerateCSharpCode; } - BaseCodeGenDescriptor codeGenDescriptor = codeGenDescriptorFactory.Create(edmxVersion, new ConnectedServiceFileHandler(context, project), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); + var vsThreadHelper = new ConnectedServiceThreadHelper(); + + BaseCodeGenDescriptor codeGenDescriptor = codeGenDescriptorFactory.Create(edmxVersion, new ConnectedServiceFileHandler(context, project, vsThreadHelper), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); await codeGenDescriptor.AddNugetPackagesAsync().ConfigureAwait(false); await codeGenDescriptor.AddGeneratedClientCodeAsync(metadataUri, outputDirectory, (Microsoft.OData.CodeGen.Common.LanguageOption)languageOption, ((ODataConnectedServiceInstance)context.ServiceInstance).ServiceConfig).ConfigureAwait(false); return codeGenDescriptor; diff --git a/test/ODataConnectedService.Tests/CodeGeneration/CodeGenDescriptorTest.cs b/test/ODataConnectedService.Tests/CodeGeneration/CodeGenDescriptorTest.cs index 1ec361ac..2c732550 100644 --- a/test/ODataConnectedService.Tests/CodeGeneration/CodeGenDescriptorTest.cs +++ b/test/ODataConnectedService.Tests/CodeGeneration/CodeGenDescriptorTest.cs @@ -13,6 +13,7 @@ using System.Net; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using EnvDTE; using Microsoft.OData.CodeGen.CodeGeneration; using Microsoft.OData.CodeGen.Common; @@ -312,6 +313,7 @@ public void Test_GeneratesAndSavesCodeFileWithoutProxy() [DataRow("vb", "TestConfigBasicVB.txt")] public void TestAddGeneratedClientCode_GeneratesT4TemplateFiles(string lang, string referenceFile) { + var serviceName = "MyService"; var referenceFolderPath = Path.Combine(TestProjectRootPath, ServicesRootFolder, serviceName); ServiceConfiguration serviceConfig = new ServiceConfigurationV4() @@ -678,7 +680,7 @@ public void TestV3AddNugetPackageAsync_ShouldInstallODataLibrariesForV3() handlerHelper.ServicesRootFolder = ServicesRootFolder; ConnectedServiceHandlerContext context = new TestConnectedServiceHandlerContext(serviceInstance, handlerHelper); - var descriptor = new TestV3CodeGenDescriptor(new ConnectedServiceFileHandler(context, project), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); + var descriptor = new TestV3CodeGenDescriptor(new ConnectedServiceFileHandler(context, project, new TestThreadHelper()), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); descriptor.AddNugetPackagesAsync().Wait(); var installer = descriptor.PackageInstaller as TestVsPackageInstaller; @@ -712,7 +714,7 @@ public void TestV2AddGeneratedClientCode_GeneratesCodeForv2() handlerHelper.ServicesRootFolder = ServicesRootFolder; ConnectedServiceHandlerContext context = new TestConnectedServiceHandlerContext(serviceInstance, handlerHelper); - var descriptor = new TestV3CodeGenDescriptor(new ConnectedServiceFileHandler(context, project), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); + var descriptor = new TestV3CodeGenDescriptor(new ConnectedServiceFileHandler(context, project, new TestThreadHelper()), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); descriptor.AddGeneratedClientCodeAsync(serviceConfig.Endpoint, referenceFolderPath, LanguageOption.GenerateCSharpCode, serviceConfig).Wait(); var addedFile = handlerHelper.AddedFiles.FirstOrDefault(); var generatedCode = File.ReadAllText(addedFile.SourceFile); @@ -746,7 +748,7 @@ public void TestV2AddGeneratedClientCode_GeneratesCodeForv2_ForVB() handlerHelper.ServicesRootFolder = ServicesRootFolder; ConnectedServiceHandlerContext context = new TestConnectedServiceHandlerContext(serviceInstance, handlerHelper); - var descriptor = new TestV3CodeGenDescriptor(new ConnectedServiceFileHandler(context, project), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); + var descriptor = new TestV3CodeGenDescriptor(new ConnectedServiceFileHandler(context, project, new TestThreadHelper()), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); descriptor.AddGeneratedClientCodeAsync(serviceConfig.Endpoint, referenceFolderPath, LanguageOption.GenerateVBCode, serviceConfig).Wait(); var addedFile = handlerHelper.AddedFiles.FirstOrDefault(); var generatedCode = File.ReadAllText(addedFile.SourceFile); @@ -780,7 +782,7 @@ public void TestV3AddGeneratedClientCode_GeneratesCodeForv3() handlerHelper.ServicesRootFolder = ServicesRootFolder; ConnectedServiceHandlerContext context = new TestConnectedServiceHandlerContext(serviceInstance, handlerHelper); - var descriptor = new TestV3CodeGenDescriptor(new ConnectedServiceFileHandler(context, project), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); + var descriptor = new TestV3CodeGenDescriptor(new ConnectedServiceFileHandler(context, project, new TestThreadHelper()), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); descriptor.AddGeneratedClientCodeAsync(serviceConfig.Endpoint, referenceFolderPath, LanguageOption.GenerateCSharpCode, serviceConfig).Wait(); var addedFile = handlerHelper.AddedFiles.FirstOrDefault(); var generatedCode = File.ReadAllText(addedFile.SourceFile); @@ -814,7 +816,7 @@ public void TestV3AddGeneratedClientCode_GeneratesCodeForv3_ForVB() handlerHelper.ServicesRootFolder = ServicesRootFolder; ConnectedServiceHandlerContext context = new TestConnectedServiceHandlerContext(serviceInstance, handlerHelper); - var descriptor = new TestV3CodeGenDescriptor(new ConnectedServiceFileHandler(context, project), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); + var descriptor = new TestV3CodeGenDescriptor(new ConnectedServiceFileHandler(context, project, new TestThreadHelper()), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context))); descriptor.AddGeneratedClientCodeAsync(serviceConfig.Endpoint, referenceFolderPath, LanguageOption.GenerateVBCode, serviceConfig).Wait(); var addedFile = handlerHelper.AddedFiles.FirstOrDefault(); var generatedCode = File.ReadAllText(addedFile.SourceFile); @@ -838,7 +840,7 @@ static V4CodeGenDescriptor SetupCodeGenDescriptor(ServiceConfiguration serviceCo handlerHelper.ServicesRootFolder = ServicesRootFolder; ConnectedServiceHandlerContext context = new TestConnectedServiceHandlerContext(serviceInstance, handlerHelper); - return new TestV4CodeGenDescriptor(new ConnectedServiceFileHandler(context, project), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context)), codeGenFactory); + return new TestV4CodeGenDescriptor(new ConnectedServiceFileHandler(context, project, new TestThreadHelper()), new ConnectedServiceMessageLogger(context), new ConnectedServicePackageInstaller(context, project, new ConnectedServiceMessageLogger(context)), codeGenFactory); } static Project CreateTestProject(string projectPath, ODataT4CodeGenerator.LanguageOption targetLanguage = ODataT4CodeGenerator.LanguageOption.CSharp) diff --git a/test/ODataConnectedService.Tests/ODataConnectedService.Tests.csproj b/test/ODataConnectedService.Tests/ODataConnectedService.Tests.csproj index 9a534e01..1f8c7a4a 100644 --- a/test/ODataConnectedService.Tests/ODataConnectedService.Tests.csproj +++ b/test/ODataConnectedService.Tests/ODataConnectedService.Tests.csproj @@ -72,6 +72,7 @@ + @@ -144,6 +145,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all + + 1.1.11 + diff --git a/test/ODataConnectedService.Tests/ODataConnectedServiceHandlerTest.cs b/test/ODataConnectedService.Tests/ODataConnectedServiceHandlerTest.cs index 774b4b60..59bc5ddc 100644 --- a/test/ODataConnectedService.Tests/ODataConnectedServiceHandlerTest.cs +++ b/test/ODataConnectedService.Tests/ODataConnectedServiceHandlerTest.cs @@ -16,24 +16,23 @@ using Microsoft.OData.CodeGen.PackageInstallation; using Microsoft.OData.ConnectedService.Tests.TestHelpers; using Microsoft.VisualStudio.Shell.Interop; -using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; +using Xunit; namespace Microsoft.OData.ConnectedService.Tests { - [TestClass] public class ODataConnectedServiceHandlerTest { - [DataTestMethod] - [DataRow("AddServiceInstanceAsync", 4, "V4")] - [DataRow("AddServiceInstanceAsync", 3, "V3")] - [DataRow("AddServiceInstanceAsync", 2, "V3")] - [DataRow("AddServiceInstanceAsync", 1, "V3")] - [DataRow("UpdateServiceInstanceAsync", 4, "V4")] - [DataRow("UpdateServiceInstanceAsync", 3, "V3")] - [DataRow("UpdateServiceInstanceAsync", 2, "V3")] - [DataRow("UpdateServiceInstanceAsync", 1, "V3")] - public void TestUpdateServiceInstance_GeneratesCodeAndSavesConfig(string method, int edmxVersion, string generatorVersion) + [StaTheory] + [InlineData("AddServiceInstanceAsync", 4, "V4")] + [InlineData("AddServiceInstanceAsync", 3, "V3")] + [InlineData("AddServiceInstanceAsync", 2, "V3")] + [InlineData("AddServiceInstanceAsync", 1, "V3")] + [InlineData("UpdateServiceInstanceAsync", 4, "V4")] + [InlineData("UpdateServiceInstanceAsync", 3, "V3")] + [InlineData("UpdateServiceInstanceAsync", 2, "V3")] + [InlineData("UpdateServiceInstanceAsync", 1, "V3")] + public async Task TestUpdateServiceInstance_GeneratesCodeAndSavesConfigAsync(string method, int edmxVersion, string generatorVersion) { var descriptorFactory = new TestCodeGenDescriptorFactory(); var serviceHandler = new ODataConnectedServiceHandler(descriptorFactory); @@ -46,21 +45,21 @@ public void TestUpdateServiceInstance_GeneratesCodeAndSavesConfig(string method, }; var tokenSource = new CancellationTokenSource(); var context = SetupContext(serviceConfig); - (typeof(ODataConnectedServiceHandler).GetMethod(method).Invoke( - serviceHandler, new object[] { context, tokenSource.Token }) as Task).Wait(); + await (typeof(ODataConnectedServiceHandler).GetMethod(method).Invoke( + serviceHandler, new object[] { context, tokenSource.Token }) as Task); var descriptor = descriptorFactory.CreatedInstance as TestCodeGenDescriptor; - Assert.IsTrue(descriptor.AddedClientCode); - Assert.IsTrue(descriptor.AddedNugetPackages); - Assert.AreEqual(generatorVersion, descriptor.Version); - Assert.AreEqual(serviceConfig, context.SavedExtendedDesignData); + Assert.True(descriptor.AddedClientCode); + Assert.True(descriptor.AddedNugetPackages); + Assert.Equal(generatorVersion, descriptor.Version); + Assert.Equal(serviceConfig, context.SavedExtendedDesignData); } - [DataTestMethod] - [DataRow("AddServiceInstanceAsync", 4, false)] - [DataRow("AddServiceInstanceAsync", 4, true)] - [DataRow("UpdateServiceInstanceAsync", 4, false)] - [DataRow("UpdateServiceInstanceAsync", 4, true)] - public void TestAddUpdateServiceInstance_SavesCustomHttpHeadersToDesignerDataAccordingToStoreCustomHttpHeaders(string method, int edmxVersion, bool store) + [StaTheory] + [InlineData("AddServiceInstanceAsync", 4, false)] + [InlineData("AddServiceInstanceAsync", 4, true)] + [InlineData("UpdateServiceInstanceAsync", 4, false)] + [InlineData("UpdateServiceInstanceAsync", 4, true)] + public async Task TestAddUpdateServiceInstance_SavesCustomHttpHeadersToDesignerDataAccordingToStoreCustomHttpHeadersAsync(string method, int edmxVersion, bool store) { var descriptorFactory = new TestCodeGenDescriptorFactory(); var serviceHandler = new ODataConnectedServiceHandler(descriptorFactory); @@ -77,20 +76,20 @@ public void TestAddUpdateServiceInstance_SavesCustomHttpHeadersToDesignerDataAcc }; var tokenSource = new CancellationTokenSource(); var context = SetupContext(serviceConfig); - (typeof(ODataConnectedServiceHandler).GetMethod(method).Invoke( - serviceHandler, new object[] { context, tokenSource.Token }) as Task).Wait(); + await (typeof(ODataConnectedServiceHandler).GetMethod(method).Invoke( + serviceHandler, new object[] { context, tokenSource.Token }) as Task); // CustomHttpHeaders should be null when StoreCustomHttpHeaders is false since we are not saving them to DesignerData - Assert.AreEqual(serviceConfig, context.SavedExtendedDesignData); - Assert.AreEqual(serviceConfig.CustomHttpHeaders, store ? headerValue : null); + Assert.Equal(serviceConfig, context.SavedExtendedDesignData); + Assert.Equal(serviceConfig.CustomHttpHeaders, store ? headerValue : null); } - [DataTestMethod] - [DataRow("AddServiceInstanceAsync", 4, false)] - [DataRow("AddServiceInstanceAsync", 4, true)] - [DataRow("UpdateServiceInstanceAsync", 4, false)] - [DataRow("UpdateServiceInstanceAsync", 4, true)] - public void TestAddUpdateServiceInstance_SavesWebProxyDetailsToDesignerDataAccordingToStoreWebProxyNetworkCredentials(string method, int edmxVersion, bool store) + [StaTheory] + [InlineData("AddServiceInstanceAsync", 4, false)] + [InlineData("AddServiceInstanceAsync", 4, true)] + [InlineData("UpdateServiceInstanceAsync", 4, false)] + [InlineData("UpdateServiceInstanceAsync", 4, true)] + public async Task TestAddUpdateServiceInstance_SavesWebProxyDetailsToDesignerDataAccordingToStoreWebProxyNetworkCredentialsAsync(string method, int edmxVersion, bool store) { var descriptorFactory = new TestCodeGenDescriptorFactory(); var serviceHandler = new ODataConnectedServiceHandler(descriptorFactory); @@ -111,13 +110,13 @@ public void TestAddUpdateServiceInstance_SavesWebProxyDetailsToDesignerDataAccor }; var tokenSource = new CancellationTokenSource(); var context = SetupContext(serviceConfig); - (typeof(ODataConnectedServiceHandler).GetMethod(method).Invoke( - serviceHandler, new object[] { context, tokenSource.Token }) as Task).Wait(); + await (typeof(ODataConnectedServiceHandler).GetMethod(method).Invoke( + serviceHandler, new object[] { context, tokenSource.Token }) as Task); // WebProxy username and password should be null when StoreWebProxyNetworkCredentials is false since we are not saving them to DesignerData - Assert.AreEqual(serviceConfig, context.SavedExtendedDesignData); - Assert.AreEqual(serviceConfig.WebProxyNetworkCredentialsUsername, store ? username : null); - Assert.AreEqual(serviceConfig.WebProxyNetworkCredentialsPassword, store ? password : null); + Assert.Equal(serviceConfig, context.SavedExtendedDesignData); + Assert.Equal(serviceConfig.WebProxyNetworkCredentialsUsername, store ? username : null); + Assert.Equal(serviceConfig.WebProxyNetworkCredentialsPassword, store ? password : null); } static TestConnectedServiceHandlerContext SetupContext(ServiceConfiguration serviceConfig) diff --git a/test/ODataConnectedService.Tests/ODataConnectedServiceWizardTests.cs b/test/ODataConnectedService.Tests/ODataConnectedServiceWizardTests.cs index c42bdb9c..f1149869 100644 --- a/test/ODataConnectedService.Tests/ODataConnectedServiceWizardTests.cs +++ b/test/ODataConnectedService.Tests/ODataConnectedServiceWizardTests.cs @@ -11,6 +11,7 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Threading.Tasks; using System.Windows; using System.Windows.Documents; using FluentAssertions; @@ -96,7 +97,7 @@ private ServiceConfigurationV4 GetTestConfig() }; } - [Fact] + [StaFact] public void TestLoadUserSettingsWhenWizardIsCreated() { var settings = new UserSettings(); @@ -112,8 +113,8 @@ public void TestLoadUserSettingsWhenWizardIsCreated() } } - [Fact] - public void TestConstructor_ShouldUseDefaultSettingsWhenNotUpdating() + [StaFact] + public async Task TestConstructor_ShouldUseDefaultSettingsWhenNotUpdatingAsync() { var savedConfig = GetTestConfig(); var context = new TestConnectedServiceProviderContext(false, savedConfig); @@ -121,7 +122,7 @@ public void TestConstructor_ShouldUseDefaultSettingsWhenNotUpdating() using (var wizard = new ODataConnectedServiceWizard(context)) { var endpointPage = wizard.ConfigODataEndpointViewModel; - endpointPage.OnPageEnteringAsync(new WizardEnteringArgs(null)).Wait(); + await endpointPage.OnPageEnteringAsync(new WizardEnteringArgs(null)).ConfigureAwait(true); Assert.Equal(Constants.DefaultServiceName, endpointPage.UserSettings.ServiceName); Assert.Null(endpointPage.UserSettings.Endpoint); Assert.Null(endpointPage.EdmxVersion); @@ -140,7 +141,7 @@ public void TestConstructor_ShouldUseDefaultSettingsWhenNotUpdating() endpointPage.UserSettings.Endpoint = MetadataPath; endpointPage.MetadataTempPath = MetadataPath; endpointPage.EdmxVersion = Constants.EdmxVersion4; - operationsPage.OnPageEnteringAsync(new WizardEnteringArgs(endpointPage)).Wait(); + await operationsPage.OnPageEnteringAsync(new WizardEnteringArgs(endpointPage)).ConfigureAwait(true); operationsPage.OperationImports.ShouldBeEquivalentTo(new List() { new OperationImportModel @@ -167,7 +168,7 @@ public void TestConstructor_ShouldUseDefaultSettingsWhenNotUpdating() }); var typesPage = wizard.SchemaTypesViewModel; - typesPage.OnPageEnteringAsync(new WizardEnteringArgs(operationsPage)).Wait(); + await typesPage.OnPageEnteringAsync(new WizardEnteringArgs(operationsPage)).ConfigureAwait(true); typesPage.SchemaTypes.ShouldBeEquivalentTo(new List { new SchemaTypeModel("Microsoft.OData.Service.Sample.TrippinInMemory.Models.Airline", "Airline") @@ -251,7 +252,7 @@ public void TestConstructor_ShouldUseDefaultSettingsWhenNotUpdating() }); var advancedPage = wizard.AdvancedSettingsViewModel; - advancedPage.OnPageEnteringAsync(new WizardEnteringArgs(typesPage)).Wait(); + await advancedPage.OnPageEnteringAsync(new WizardEnteringArgs(typesPage)).ConfigureAwait(true); Assert.Equal(Constants.DefaultReferenceFileName, advancedPage.UserSettings.GeneratedFileNamePrefix); Assert.False(advancedPage.UserSettings.UseNamespacePrefix); Assert.Null(advancedPage.UserSettings.NamespacePrefix); @@ -266,8 +267,8 @@ public void TestConstructor_ShouldUseDefaultSettingsWhenNotUpdating() } } - [Fact] - public void TestConstructor_LoadsSavedConfigWhenUpdating() + [StaFact] + public async Task TestConstructor_LoadsSavedConfigWhenUpdatingAsync() { var savedConfig = GetTestConfig(); var context = new TestConnectedServiceProviderContext(true, savedConfig); @@ -277,7 +278,7 @@ public void TestConstructor_LoadsSavedConfigWhenUpdating() Assert.Equal(savedConfig, wizard.ServiceConfig); var endpointPage = wizard.ConfigODataEndpointViewModel; - endpointPage.OnPageEnteringAsync(new WizardEnteringArgs(null)).Wait(); + await endpointPage.OnPageEnteringAsync(new WizardEnteringArgs(null)).ConfigureAwait(true); Assert.Equal("https://service/$metadata", endpointPage.UserSettings.Endpoint); Assert.Equal("MyService", endpointPage.UserSettings.ServiceName); Assert.True(endpointPage.UserSettings.IncludeCustomHeaders); @@ -295,7 +296,8 @@ public void TestConstructor_LoadsSavedConfigWhenUpdating() var operationsPage = wizard.OperationImportsViewModel; endpointPage.MetadataTempPath = MetadataPath; endpointPage.EdmxVersion = Constants.EdmxVersion4; - operationsPage.OnPageEnteringAsync(new WizardEnteringArgs(endpointPage)).Wait(); + + await operationsPage.OnPageEnteringAsync(new WizardEnteringArgs(endpointPage)).ConfigureAwait(true); operationsPage.OperationImports.ShouldBeEquivalentTo(new List() { new OperationImportModel @@ -322,7 +324,8 @@ public void TestConstructor_LoadsSavedConfigWhenUpdating() }); var typesPage = wizard.SchemaTypesViewModel; - typesPage.OnPageEnteringAsync(new WizardEnteringArgs(operationsPage)).Wait(); + + await typesPage.OnPageEnteringAsync(new WizardEnteringArgs(operationsPage)).ConfigureAwait(true); typesPage.SchemaTypes.ShouldBeEquivalentTo(new List { new SchemaTypeModel("Microsoft.OData.Service.Sample.TrippinInMemory.Models.Airline", "Airline") @@ -416,7 +419,8 @@ public void TestConstructor_LoadsSavedConfigWhenUpdating() }); var advancedPage = wizard.AdvancedSettingsViewModel; - advancedPage.OnPageEnteringAsync(new WizardEnteringArgs(typesPage)).Wait(); + + await advancedPage.OnPageEnteringAsync(new WizardEnteringArgs(typesPage)).ConfigureAwait(true); Assert.Equal("GeneratedCode", advancedPage.UserSettings.GeneratedFileNamePrefix); Assert.True(advancedPage.UserSettings.UseNamespacePrefix); Assert.Equal("Namespace", advancedPage.UserSettings.NamespacePrefix); @@ -431,8 +435,8 @@ public void TestConstructor_LoadsSavedConfigWhenUpdating() } } - [Fact] - public void TestDisableReadOnlyFieldsWhenUpdating() + [StaFact] + public async Task TestDisableReadOnlyFieldsWhenUpdating() { ServiceConfigurationV4 savedConfig = GetTestConfig(); var context = new TestConnectedServiceProviderContext(true, savedConfig); @@ -440,7 +444,7 @@ public void TestDisableReadOnlyFieldsWhenUpdating() { // endpoint page var endpointPage = wizard.ConfigODataEndpointViewModel; - endpointPage.OnPageEnteringAsync(new WizardEnteringArgs(null)).Wait(); + await endpointPage.OnPageEnteringAsync(new WizardEnteringArgs(null)).ConfigureAwait(true); var endpointView = endpointPage.View as ConfigODataEndpoint; Assert.False(endpointView.ServiceName.IsEnabled); @@ -454,7 +458,8 @@ public void TestDisableReadOnlyFieldsWhenUpdating() // advanced settings page var advancedPage = wizard.AdvancedSettingsViewModel; - advancedPage.OnPageEnteringAsync(new WizardEnteringArgs(endpointPage)).Wait(); + + await advancedPage.OnPageEnteringAsync(new WizardEnteringArgs(endpointPage)).ConfigureAwait(true); var advancedView = advancedPage.View as AdvancedSettings; Assert.False(advancedView.IncludeT4File.IsEnabled); Assert.False(advancedView.GenerateMultipleFiles.IsEnabled); @@ -462,8 +467,8 @@ public void TestDisableReadOnlyFieldsWhenUpdating() } } - [Fact] - public void TestGetFinishedServiceInstanceAsync_SavesUserSettingsAndReturnsServiceInstanceWithConfigFromTheWizard() + [StaFact] + public async Task TestGetFinishedServiceInstanceAsync_SavesUserSettingsAndReturnsServiceInstanceWithConfigFromTheWizardAsync() { var context = new TestConnectedServiceProviderContext(false); using (var wizard = new ODataConnectedServiceWizard(context)) @@ -484,7 +489,8 @@ public void TestGetFinishedServiceInstanceAsync_SavesUserSettingsAndReturnsServi endpointPage.UserSettings.WebProxyNetworkCredentialsPassword = "pass"; var operationsPage = wizard.OperationImportsViewModel; - endpointPage.OnPageLeavingAsync(new WizardLeavingArgs(operationsPage)).Wait(); + + await endpointPage.OnPageLeavingAsync(new WizardLeavingArgs(operationsPage)).ConfigureAwait(true); operationsPage.OperationImports = new List() { new OperationImportModel() { Name = "GetNearestAirport", IsSelected = false }, @@ -493,7 +499,8 @@ public void TestGetFinishedServiceInstanceAsync_SavesUserSettingsAndReturnsServi }; var typesPage = wizard.SchemaTypesViewModel; - typesPage.OnPageEnteringAsync(new WizardEnteringArgs(operationsPage)).Wait(); + + await typesPage.OnPageEnteringAsync(new WizardEnteringArgs(operationsPage)).ConfigureAwait(true); typesPage.SchemaTypes = new List() { new SchemaTypeModel("Microsoft.OData.Service.Sample.TrippinInMemory.Models.Airline", "Airline") { IsSelected = false }, @@ -535,10 +542,10 @@ public void TestGetFinishedServiceInstanceAsync_SavesUserSettingsAndReturnsServi advancedPage.UserSettings.OpenGeneratedFilesInIDE = true; advancedPage.UserSettings.OmitVersioningInfo = true; - operationsPage.OnPageLeavingAsync(new WizardLeavingArgs(typesPage)).Wait(); - typesPage.OnPageLeavingAsync(new WizardLeavingArgs(advancedPage)).Wait(); - advancedPage.OnPageLeavingAsync(new WizardLeavingArgs(null)).Wait(); - var serviceInstance = wizard.GetFinishedServiceInstanceAsync().Result as ODataConnectedServiceInstance; + await operationsPage.OnPageLeavingAsync(new WizardLeavingArgs(typesPage)).ConfigureAwait(true); + await typesPage.OnPageLeavingAsync(new WizardLeavingArgs(advancedPage)).ConfigureAwait(true); + await advancedPage.OnPageLeavingAsync(new WizardLeavingArgs(null)).ConfigureAwait(true); + ODataConnectedServiceInstance serviceInstance = (ODataConnectedServiceInstance)await wizard.GetFinishedServiceInstanceAsync().ConfigureAwait(true); var config = serviceInstance.ServiceConfig as ServiceConfigurationV4; // saved user settings @@ -620,8 +627,8 @@ public void TestGetFinishedServiceInstanceAsync_SavesUserSettingsAndReturnsServi } } - [Fact] - public void GetFinishedServiceInstanceAsync_WhenUpdating_ShouldUseSavedConfigWhenUserDoesNotVisitPages() + [StaFact] + public async Task GetFinishedServiceInstanceAsync_WhenUpdating_ShouldUseSavedConfigWhenUserDoesNotVisitPagesAsync() { var savedConfig = GetTestConfig(); savedConfig.Endpoint = MetadataPath; @@ -629,10 +636,10 @@ public void GetFinishedServiceInstanceAsync_WhenUpdating_ShouldUseSavedConfigWhe using (var wizard = new ODataConnectedServiceWizard(context)) { var endpointPage = wizard.ConfigODataEndpointViewModel; - endpointPage.OnPageEnteringAsync(null).Wait(); - endpointPage.OnPageLeavingAsync(null).Wait(); + await endpointPage.OnPageEnteringAsync(null).ConfigureAwait(true); + await endpointPage.OnPageLeavingAsync(null).ConfigureAwait(true); - var serviceInstance = wizard.GetFinishedServiceInstanceAsync().Result as ODataConnectedServiceInstance; + var serviceInstance = (ODataConnectedServiceInstance)await wizard.GetFinishedServiceInstanceAsync().ConfigureAwait(true); var config = serviceInstance.ServiceConfig as ServiceConfigurationV4; Assert.Equal("GeneratedCode", serviceInstance.InstanceId); @@ -679,19 +686,19 @@ public void GetFinishedServiceInstanceAsync_WhenUpdating_ShouldUseSavedConfigWhe } } - [Fact] - public void ShouldPreserveState_WhenMovingBetweenPagesAndBack() + [StaFact] + public async Task ShouldPreserveState_WhenMovingBetweenPagesAndBack() { var context = new TestConnectedServiceProviderContext(); using (var wizard = new ODataConnectedServiceWizard(context)) { var endpointPage = wizard.ConfigODataEndpointViewModel; - endpointPage.OnPageEnteringAsync(null).Wait(); + await endpointPage.OnPageEnteringAsync(null).ConfigureAwait(true); endpointPage.UserSettings.Endpoint = MetadataPath; - endpointPage.OnPageLeavingAsync(null).Wait(); + await endpointPage.OnPageLeavingAsync(null).ConfigureAwait(true); var typesPage = wizard.SchemaTypesViewModel; - typesPage.OnPageEnteringAsync(null).Wait(); + await typesPage.OnPageEnteringAsync(null).ConfigureAwait(true); var typesPageView = typesPage.View as SchemaTypes; Assert.Equal(typesPage.SchemaTypesCount, typesPage.SchemaTypes.Count()); Assert.Equal(typesPage.BoundOperationsCount, typesPage.SchemaTypes.SelectMany(x => x.BoundOperations).Count()); @@ -707,10 +714,10 @@ public void ShouldPreserveState_WhenMovingBetweenPagesAndBack() Assert.Equal(typesPageView?.SelectedBoundOperationsCount.Text, (typesPage.BoundOperationsCount - typesPage.ExcludedBoundOperationsNames.Count()).ToString(CultureInfo.InvariantCulture)); - typesPage.OnPageLeavingAsync(null).Wait(); + await typesPage.OnPageLeavingAsync(null).ConfigureAwait(true); var operationsPage = wizard.OperationImportsViewModel; - operationsPage.OnPageEnteringAsync(null).Wait(); + await operationsPage.OnPageEnteringAsync(null); var operationsPageView = operationsPage.View as OperationImports; Assert.Equal(operationsPage.OperationImportsCount, operationsPage.OperationImports.Count()); Assert.Equal(operationsPageView?.SelectedOperationImportsCount.Text, operationsPage.OperationImportsCount.ToString(CultureInfo.InvariantCulture)); @@ -719,17 +726,17 @@ public void ShouldPreserveState_WhenMovingBetweenPagesAndBack() Assert.Equal(operationsPageView?.SelectedOperationImportsCount.Text, (operationsPage.OperationImportsCount - operationsPage.ExcludedOperationImportsNames.Count()) .ToString(CultureInfo.InvariantCulture)); - operationsPage.OnPageLeavingAsync(null).Wait(); + await operationsPage.OnPageLeavingAsync(null); var advancedPage = wizard.AdvancedSettingsViewModel; - advancedPage.OnPageEnteringAsync(null).Wait(); + await advancedPage.OnPageEnteringAsync(null); advancedPage.UserSettings.UseDataServiceCollection = true; advancedPage.UserSettings.MakeTypesInternal = true; advancedPage.UserSettings.UseNamespacePrefix = true; advancedPage.UserSettings.OmitVersioningInfo = true; - advancedPage.OnPageLeavingAsync(null).Wait(); + await advancedPage.OnPageLeavingAsync(null); - endpointPage.OnPageEnteringAsync(null).Wait(); + await endpointPage.OnPageEnteringAsync(null); Assert.Equal(Constants.DefaultServiceName, endpointPage.UserSettings.ServiceName); Assert.Equal(MetadataPath, endpointPage.UserSettings.Endpoint); endpointPage.UserSettings.ServiceName = "Service"; @@ -737,9 +744,9 @@ public void ShouldPreserveState_WhenMovingBetweenPagesAndBack() endpointPage.UserSettings.StoreCustomHttpHeaders = true; endpointPage.UserSettings.StoreWebProxyNetworkCredentials = true; endpointPage.UserSettings.CustomHttpHeaders = "A:b"; - endpointPage.OnPageLeavingAsync(null).Wait(); + await endpointPage.OnPageLeavingAsync(null); - advancedPage.OnPageEnteringAsync(null).Wait(); + await advancedPage.OnPageEnteringAsync(null); Assert.True(advancedPage.UserSettings.UseNamespacePrefix); Assert.True(advancedPage.UserSettings.UseDataServiceCollection); Assert.True(advancedPage.UserSettings.MakeTypesInternal); @@ -747,9 +754,9 @@ public void ShouldPreserveState_WhenMovingBetweenPagesAndBack() advancedPage.UserSettings.NamespacePrefix = "MyNamespace"; advancedPage.UserSettings.GenerateMultipleFiles = true; advancedPage.UserSettings.UseDataServiceCollection = false; - advancedPage.OnPageLeavingAsync(null).Wait(); + await advancedPage.OnPageLeavingAsync(null); - operationsPage.OnPageEnteringAsync(null).Wait(); + await operationsPage.OnPageEnteringAsync(null); operationNearestAirport = operationsPage.OperationImports.FirstOrDefault(o => o.Name == "GetNearestAirport"); Assert.False(operationNearestAirport.IsSelected); Assert.Equal(operationsPageView?.SelectedOperationImportsCount.Text, @@ -757,9 +764,9 @@ public void ShouldPreserveState_WhenMovingBetweenPagesAndBack() .ToString(CultureInfo.InvariantCulture)); var operationResetDataSource = operationsPage.OperationImports.FirstOrDefault(o => o.Name == "ResetDataSource"); operationResetDataSource.IsSelected = false; - operationsPage.OnPageLeavingAsync(null).Wait(); + await operationsPage.OnPageLeavingAsync(null); - typesPage.OnPageEnteringAsync(null).Wait(); + await typesPage.OnPageEnteringAsync(null); typeEmployee = typesPage.SchemaTypes.FirstOrDefault(t => t.ShortName == "Employee"); Assert.False(typeEmployee.IsSelected); Assert.Equal(typesPageView?.SelectedSchemaTypesCount.Text, @@ -767,9 +774,9 @@ public void ShouldPreserveState_WhenMovingBetweenPagesAndBack() typeEmployee.IsSelected = true; var typeFlight = typesPage.SchemaTypes.FirstOrDefault(t => t.ShortName == "Flight"); typeFlight.IsSelected = false; - typesPage.OnPageLeavingAsync(null).Wait(); + await typesPage.OnPageLeavingAsync(null); - var serviceInstance = wizard.GetFinishedServiceInstanceAsync().Result as ODataConnectedServiceInstance; + var serviceInstance = (ODataConnectedServiceInstance)await wizard.GetFinishedServiceInstanceAsync(); var config = serviceInstance.ServiceConfig as ServiceConfigurationV4; Assert.Equal("Service", config.ServiceName); @@ -800,8 +807,8 @@ public void ShouldPreserveState_WhenMovingBetweenPagesAndBack() } } - [Fact] - public void ShouldPreserveState_WhenMovingBetweenPagesAndBack_WhenUpdating() + [StaFact] + public async Task ShouldPreserveState_WhenMovingBetweenPagesAndBack_WhenUpdating() { var savedConfig = GetTestConfig(); savedConfig.Endpoint = MetadataPath; @@ -809,44 +816,44 @@ public void ShouldPreserveState_WhenMovingBetweenPagesAndBack_WhenUpdating() using (var wizard = new ODataConnectedServiceWizard(context)) { var endpointPage = wizard.ConfigODataEndpointViewModel; - endpointPage.OnPageEnteringAsync(null).Wait(); - endpointPage.OnPageLeavingAsync(null).Wait(); + await endpointPage.OnPageEnteringAsync(null); + await endpointPage.OnPageLeavingAsync(null); var typesPage = wizard.SchemaTypesViewModel; - typesPage.OnPageEnteringAsync(null).Wait(); + await typesPage.OnPageEnteringAsync(null); var typeGender = typesPage.SchemaTypes.FirstOrDefault(t => t.ShortName == "PersonGender"); Assert.False(typeGender.IsSelected); typeGender.IsSelected = true; var typePerson = typesPage.SchemaTypes.FirstOrDefault(t => t.ShortName == "Person"); Assert.False(typePerson.IsSelected); - typesPage.OnPageLeavingAsync(null).Wait(); + await typesPage.OnPageLeavingAsync(null); var operationsPage = wizard.OperationImportsViewModel; - operationsPage.OnPageEnteringAsync(null).Wait(); + await operationsPage.OnPageEnteringAsync(null); var operationNearestAirport = operationsPage.OperationImports.FirstOrDefault(o => o.Name == "GetNearestAirport"); Assert.True(operationNearestAirport.IsSelected); operationNearestAirport.IsSelected = false; - operationsPage.OnPageLeavingAsync(null).Wait(); + await operationsPage.OnPageLeavingAsync(null); var boundOperationGetFavoriteAirline = typesPage.SchemaTypes.FirstOrDefault(t => t.ShortName == "Person").BoundOperations.FirstOrDefault(o => o.Name == "GetFavoriteAirline(Microsoft.OData.Service.Sample.TrippinInMemory.Models.Person)"); Assert.False(boundOperationGetFavoriteAirline.IsSelected); var advancedPage = wizard.AdvancedSettingsViewModel; - advancedPage.OnPageEnteringAsync(null).Wait(); + await advancedPage.OnPageEnteringAsync(null); advancedPage.UserSettings.UseDataServiceCollection = true; advancedPage.UserSettings.MakeTypesInternal = true; advancedPage.UserSettings.UseNamespacePrefix = true; advancedPage.UserSettings.OmitVersioningInfo = true; - advancedPage.OnPageLeavingAsync(null).Wait(); + await advancedPage.OnPageLeavingAsync(null); - endpointPage.OnPageEnteringAsync(null).Wait(); + await endpointPage.OnPageEnteringAsync(null); Assert.Equal(savedConfig.ServiceName, endpointPage.UserSettings.ServiceName); Assert.Equal(savedConfig.Endpoint, endpointPage.UserSettings.Endpoint); endpointPage.UserSettings.IncludeCustomHeaders = true; endpointPage.UserSettings.CustomHttpHeaders = "A:b"; - endpointPage.OnPageLeavingAsync(null).Wait(); + await endpointPage.OnPageLeavingAsync(null); - advancedPage.OnPageEnteringAsync(null).Wait(); + await advancedPage.OnPageEnteringAsync(null); Assert.True(advancedPage.UserSettings.UseNamespacePrefix); Assert.True(advancedPage.UserSettings.UseDataServiceCollection); Assert.True(advancedPage.UserSettings.MakeTypesInternal); @@ -854,17 +861,17 @@ public void ShouldPreserveState_WhenMovingBetweenPagesAndBack_WhenUpdating() advancedPage.UserSettings.NamespacePrefix = "MyNamespace"; advancedPage.UserSettings.GenerateMultipleFiles = true; advancedPage.UserSettings.UseDataServiceCollection = false; - advancedPage.OnPageLeavingAsync(null).Wait(); + await advancedPage.OnPageLeavingAsync(null); - operationsPage.OnPageEnteringAsync(null).Wait(); + await operationsPage.OnPageEnteringAsync(null); operationNearestAirport = operationsPage.OperationImports.FirstOrDefault(o => o.Name == "GetNearestAirport"); Assert.False(operationNearestAirport.IsSelected); var operationResetDataSource = operationsPage.OperationImports.FirstOrDefault(o => o.Name == "ResetDataSource"); Assert.False(operationResetDataSource.IsSelected); operationResetDataSource.IsSelected = true; - operationsPage.OnPageLeavingAsync(null).Wait(); + await operationsPage.OnPageLeavingAsync(null); - typesPage.OnPageEnteringAsync(null).Wait(); + await typesPage.OnPageEnteringAsync(null); typeGender = typesPage.SchemaTypes.FirstOrDefault(t => t.ShortName == "PersonGender"); Assert.True(typeGender.IsSelected); var typeFlight = typesPage.SchemaTypes.FirstOrDefault(t => t.ShortName == "Flight"); @@ -873,9 +880,9 @@ public void ShouldPreserveState_WhenMovingBetweenPagesAndBack_WhenUpdating() Assert.False(typePerson.IsSelected); boundOperationGetFavoriteAirline = typesPage.SchemaTypes.FirstOrDefault(t => t.ShortName == "Person").BoundOperations.FirstOrDefault(o => o.Name == "GetFavoriteAirline(Microsoft.OData.Service.Sample.TrippinInMemory.Models.Person)"); Assert.False(boundOperationGetFavoriteAirline.IsSelected); - typesPage.OnPageLeavingAsync(null).Wait(); + await typesPage.OnPageLeavingAsync(null); - var serviceInstance = wizard.GetFinishedServiceInstanceAsync().Result as ODataConnectedServiceInstance; + var serviceInstance = await wizard.GetFinishedServiceInstanceAsync() as ODataConnectedServiceInstance; var config = serviceInstance.ServiceConfig as ServiceConfigurationV4; Assert.Equal(savedConfig.ServiceName, config.ServiceName); @@ -913,42 +920,42 @@ public void ShouldPreserveState_WhenMovingBetweenPagesAndBack_WhenUpdating() } } - [Fact] - public void ShouldReloadOperationsAndTypesForNewEndpoint_WhenEndpointIsChangedBeforeFinishing() + [StaFact] + public async Task ShouldReloadOperationsAndTypesForNewEndpoint_WhenEndpointIsChangedBeforeFinishingAsync() { var context = new TestConnectedServiceProviderContext(); using (var wizard = new ODataConnectedServiceWizard(context)) { var endpointPage = wizard.ConfigODataEndpointViewModel; - endpointPage.OnPageEnteringAsync(null).Wait(); + await endpointPage.OnPageEnteringAsync(null); endpointPage.UserSettings.Endpoint = MetadataPath; - endpointPage.OnPageLeavingAsync(null).Wait(); + await endpointPage.OnPageLeavingAsync(null); var typesPage = wizard.SchemaTypesViewModel; - typesPage.OnPageEnteringAsync(null).Wait(); + await typesPage.OnPageEnteringAsync(null); typesPage.SchemaTypes.FirstOrDefault(t => t.ShortName == "Employee").IsSelected = false; - typesPage.OnPageLeavingAsync(null).Wait(); + await typesPage.OnPageLeavingAsync(null); var operationsPage = wizard.OperationImportsViewModel; - operationsPage.OnPageEnteringAsync(null).Wait(); + await operationsPage.OnPageEnteringAsync(null); operationsPage.OperationImports.FirstOrDefault(o => o.Name == "GetNearestAirport").IsSelected = false; - operationsPage.OnPageLeavingAsync(null).Wait(); + await operationsPage.OnPageLeavingAsync(null); // go back to first page and change endpoint - endpointPage.OnPageEnteringAsync(null).Wait(); + await endpointPage.OnPageEnteringAsync(null); endpointPage.UserSettings.Endpoint = MetadataPathSimple; - endpointPage.OnPageLeavingAsync(null).Wait(); + await endpointPage.OnPageLeavingAsync(null); - typesPage.OnPageEnteringAsync(null).Wait(); + await typesPage.OnPageEnteringAsync(null); typesPage.SchemaTypes.ShouldBeEquivalentTo(new List() { new SchemaTypeModel("SimpleService.Models.OtherThing", "OtherThing") { IsSelected = true }, new SchemaTypeModel("SimpleService.Models.Thing", "Thing") { IsSelected = true } }); typesPage.SchemaTypes.FirstOrDefault(t => t.ShortName == "OtherThing").IsSelected = false; - typesPage.OnPageLeavingAsync(null).Wait(); + await typesPage.OnPageLeavingAsync(null); - operationsPage.OnPageEnteringAsync(null).Wait(); + await operationsPage.OnPageEnteringAsync(null); operationsPage.OperationImports.ShouldBeEquivalentTo(new List() { new OperationImportModel @@ -968,7 +975,7 @@ public void ShouldReloadOperationsAndTypesForNewEndpoint_WhenEndpointIsChangedBe }); operationsPage.OperationImports.FirstOrDefault(o => o.Name == "ResetThings").IsSelected = false; - var serviceInstance = wizard.GetFinishedServiceInstanceAsync().Result as ODataConnectedServiceInstance; + var serviceInstance = await wizard.GetFinishedServiceInstanceAsync() as ODataConnectedServiceInstance; var config = serviceInstance.ServiceConfig as ServiceConfigurationV4; Assert.Equal(MetadataPathSimple, config.Endpoint); @@ -977,28 +984,28 @@ public void ShouldReloadOperationsAndTypesForNewEndpoint_WhenEndpointIsChangedBe } } - [Fact] - public void ShouldDeselectOperations_WhenRelatedTypeIsDeselectedBefore() + [StaFact] + public async Task ShouldDeselectOperations_WhenRelatedTypeIsDeselectedBeforeAsync() { var context = new TestConnectedServiceProviderContext(); using (var wizard = new ODataConnectedServiceWizard(context)) { var endpointPage = wizard.ConfigODataEndpointViewModel; - endpointPage.OnPageEnteringAsync(null).Wait(); + await endpointPage.OnPageEnteringAsync(null); endpointPage.UserSettings.Endpoint = MetadataPath; - endpointPage.OnPageLeavingAsync(null).Wait(); + await endpointPage.OnPageLeavingAsync(null); var typesPage = wizard.SchemaTypesViewModel; - typesPage.OnPageEnteringAsync(null).Wait(); + await typesPage.OnPageEnteringAsync(null); typesPage.SchemaTypes.First(t => t.ShortName == "Airport").IsSelected = false; - typesPage.OnPageLeavingAsync(null).Wait(); + await typesPage.OnPageLeavingAsync(null); var operationsPage = wizard.OperationImportsViewModel; - operationsPage.OnPageEnteringAsync(null).Wait(); + await operationsPage.OnPageEnteringAsync(null); operationsPage.OperationImports.First(o => o.Name == "GetNearestAirport").IsSelected.Should().BeFalse(); - operationsPage.OnPageLeavingAsync(null).Wait(); + await operationsPage.OnPageLeavingAsync(null); - var serviceInstance = wizard.GetFinishedServiceInstanceAsync().Result as ODataConnectedServiceInstance; + var serviceInstance = await wizard.GetFinishedServiceInstanceAsync() as ODataConnectedServiceInstance; var config = serviceInstance?.ServiceConfig as ServiceConfigurationV4; config?.ExcludedOperationImports.ShouldBeEquivalentTo(new List { "GetNearestAirport" }); @@ -1011,28 +1018,28 @@ public void ShouldDeselectOperations_WhenRelatedTypeIsDeselectedBefore() } } - [Fact] - public void ShouldDeselectBoundOperations_WhenRelatedTypeIsDeselectedBefore() + [StaFact] + public async Task ShouldDeselectBoundOperations_WhenRelatedTypeIsDeselectedBeforeAsync() { var context = new TestConnectedServiceProviderContext(); using (var wizard = new ODataConnectedServiceWizard(context)) { var endpointPage = wizard.ConfigODataEndpointViewModel; - endpointPage.OnPageEnteringAsync(null).Wait(); + await endpointPage.OnPageEnteringAsync(null); endpointPage.UserSettings.Endpoint = MetadataPath; - endpointPage.OnPageLeavingAsync(null).Wait(); + await endpointPage.OnPageLeavingAsync(null); var typesPage = wizard.SchemaTypesViewModel; - typesPage.OnPageEnteringAsync(null).Wait(); + await typesPage.OnPageEnteringAsync(null); typesPage.SchemaTypes.First(t => t.ShortName == "Person").IsSelected = false; - typesPage.OnPageLeavingAsync(null).Wait(); + await typesPage.OnPageLeavingAsync(null); var operationsPage = wizard.OperationImportsViewModel; - operationsPage.OnPageEnteringAsync(null).Wait(); + await operationsPage.OnPageEnteringAsync(null); operationsPage.OperationImports.First(o => o.Name == "GetPersonWithMostFriends").IsSelected.Should().BeFalse(); - operationsPage.OnPageLeavingAsync(null).Wait(); + await operationsPage.OnPageLeavingAsync(null); - var serviceInstance = wizard.GetFinishedServiceInstanceAsync().Result as ODataConnectedServiceInstance; + var serviceInstance = await wizard.GetFinishedServiceInstanceAsync() as ODataConnectedServiceInstance; var config = serviceInstance?.ServiceConfig as ServiceConfigurationV4; config?.ExcludedOperationImports.ShouldBeEquivalentTo(new List { "GetPersonWithMostFriends" }); @@ -1054,23 +1061,23 @@ public void ShouldDeselectBoundOperations_WhenRelatedTypeIsDeselectedBefore() } [Fact] - public void UnsupportedFeaturesAreDisabledOrHidden_WhenServiceIsV3OrLess() + public async Task UnsupportedFeaturesAreDisabledOrHidden_WhenServiceIsV3OrLessAsync() { var context = new TestConnectedServiceProviderContext(); using (var wizard = new ODataConnectedServiceWizard(context)) { var endpointPage = wizard.ConfigODataEndpointViewModel; endpointPage.UserSettings.Endpoint = MetadataPathV3; - endpointPage.OnPageLeavingAsync(null).Wait(); + await endpointPage.OnPageLeavingAsync(null); Assert.Equal(Constants.EdmxVersion1, endpointPage.EdmxVersion); var operationsPage = wizard.OperationImportsViewModel; - operationsPage.OnPageEnteringAsync(null).Wait(); + await operationsPage.OnPageEnteringAsync(null); Assert.False(operationsPage.View.IsEnabled); Assert.False(operationsPage.IsSupportedODataVersion); var advancedPage = wizard.AdvancedSettingsViewModel; - advancedPage.OnPageEnteringAsync(null).Wait(); + await advancedPage.OnPageEnteringAsync(null); var advancedView = advancedPage.View as AdvancedSettings; advancedView.settings.RaiseEvent(new RoutedEventArgs(Hyperlink.ClickEvent)); Assert.Equal(Visibility.Hidden, advancedView.AdvancedSettingsForv4.Visibility); diff --git a/test/ODataConnectedService.Tests/TestHelpers/TestThreadHelper.cs b/test/ODataConnectedService.Tests/TestHelpers/TestThreadHelper.cs new file mode 100644 index 00000000..60f89f99 --- /dev/null +++ b/test/ODataConnectedService.Tests/TestHelpers/TestThreadHelper.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.OData.CodeGen; + +namespace ODataConnectedService.Tests.TestHelpers +{ + internal class TestThreadHelper : IThreadHelper + { + /// + public Task RunAsync(Func> backgroundTask) + { + return Task.Run(backgroundTask); + } + + /// + public Task RunInUiThreadAsync(Func backgroundTask) + { + return Task.Run(backgroundTask); + } + } +} diff --git a/test/ODataConnectedService.Tests/ViewModels/ConfigOdataEndPointViewModelTests.cs b/test/ODataConnectedService.Tests/ViewModels/ConfigOdataEndPointViewModelTests.cs index b3514e6c..6b65b21b 100644 --- a/test/ODataConnectedService.Tests/ViewModels/ConfigOdataEndPointViewModelTests.cs +++ b/test/ODataConnectedService.Tests/ViewModels/ConfigOdataEndPointViewModelTests.cs @@ -13,20 +13,18 @@ using Microsoft.OData.ConnectedService; using Microsoft.OData.ConnectedService.ViewModels; using Microsoft.VisualStudio.ConnectedServices; -using Microsoft.VisualStudio.TestTools.UnitTesting; using ODataConnectedService.Tests.TestHelpers; +using Xunit; namespace ODataConnectedService.Tests.ViewModels { - [TestClass] public class ConfigOdataEndPointViewModelTests { private static ConfigODataEndpointViewModel configOdataEndPointViewModel; private static UserSettings userSettings; private static ODataConnectedServiceWizard serviceWizard; - [TestInitialize] - public void Init() + public ConfigOdataEndPointViewModelTests() { userSettings = new UserSettings(); serviceWizard = new ODataConnectedServiceWizard(null); @@ -35,8 +33,8 @@ public void Init() CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture; } - [TestMethod] - public void OnPageLeavingConfigODataEndpointPageTest() + [StaFact] + public async Task OnPageLeavingConfigODataEndpointPageTestAsync() { string edmx = GeneratedCodeHelpers.LoadReferenceContent("Simple.xml"); string expectedTempfileContent = GeneratedCodeHelpers.LoadReferenceContent("TempSimple.xml"); @@ -48,85 +46,85 @@ public void OnPageLeavingConfigODataEndpointPageTest() //Check if an error is thrown if the on leaving the page without providing the endpoint pageNavigationResultTask = configOdataEndPointViewModel.OnPageLeavingAsync(null); - pageNavigationResult = pageNavigationResultTask?.Result; - Assert.IsNotNull(pageNavigationResult.ErrorMessage); - Assert.IsTrue(pageNavigationResult.ErrorMessage.Contains(Constants.InputServiceEndpointMsg), "User is not prompted to enter endpoint"); - Assert.IsFalse(pageNavigationResult.IsSuccess); - Assert.IsTrue(pageNavigationResult.ShowMessageBoxOnFailure); + pageNavigationResult = await pageNavigationResultTask; + Assert.NotNull(pageNavigationResult.ErrorMessage); + Assert.True(pageNavigationResult.ErrorMessage.Contains(Constants.InputServiceEndpointMsg), "User is not prompted to enter endpoint"); + Assert.False(pageNavigationResult.IsSuccess); + Assert.True(pageNavigationResult.ShowMessageBoxOnFailure); //Provide a url without $metadata configOdataEndPointViewModel.UserSettings.Endpoint = "http://mysite/ODataService"; pageNavigationResultTask = configOdataEndPointViewModel.OnPageLeavingAsync(null); //Check if $metadata is appended as the last segment if it was not the last segment of the url - Assert.AreEqual("http://mysite/ODataService/$metadata", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); + Assert.Equal("http://mysite/ODataService/$metadata", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); //Provide a url with $metadata/ configOdataEndPointViewModel.UserSettings.Endpoint = "http://mysite/ODataService/$metadata/"; pageNavigationResultTask = configOdataEndPointViewModel.OnPageLeavingAsync(null); //Check if $metadata is appended as the last segment and '/' is removed - Assert.AreEqual("http://mysite/ODataService/$metadata", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); + Assert.Equal("http://mysite/ODataService/$metadata", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); //Provide a url with "$metadata" as the last segment in the url with fragment and query segments configOdataEndPointViewModel.UserSettings.Endpoint = "http://user:password@mysite/ODataService/$metadata?$schemaversion=2.0#fragment"; _ = configOdataEndPointViewModel.OnPageLeavingAsync(null); //Check if the url is detected as valid and is unmodified - Assert.AreEqual("http://user:password@mysite/ODataService/$metadata?$schemaversion=2.0#fragment", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); + Assert.Equal("http://user:password@mysite/ODataService/$metadata?$schemaversion=2.0#fragment", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); //Provide a url with query and fragment segments without $metadata configOdataEndPointViewModel.UserSettings.Endpoint = "http://user:password@mysite/ODataService?$schemaversion=2.0#fragment"; pageNavigationResultTask = configOdataEndPointViewModel.OnPageLeavingAsync(null); //Check if $metadata is appended as the last segment - Assert.AreEqual("http://user:password@mysite/ODataService/$metadata?$schemaversion=2.0#fragment", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); + Assert.Equal("http://user:password@mysite/ODataService/$metadata?$schemaversion=2.0#fragment", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); //Provide a url with a fragment segment without $metadata configOdataEndPointViewModel.UserSettings.Endpoint = "http://user:password@mysite/ODataService#fragment"; pageNavigationResultTask = configOdataEndPointViewModel.OnPageLeavingAsync(null); //Check if $metadata is appended as the last segment - Assert.AreEqual("http://user:password@mysite/ODataService/$metadata#fragment", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); + Assert.Equal("http://user:password@mysite/ODataService/$metadata#fragment", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); //Provide a url with $metadata and a fragment segment without a query segment configOdataEndPointViewModel.UserSettings.Endpoint = "http://user:password@mysite/ODataService/$metadata#fragment"; pageNavigationResultTask = configOdataEndPointViewModel.OnPageLeavingAsync(null); //Check if $metadata is appended as the last segment - Assert.AreEqual("http://user:password@mysite/ODataService/$metadata#fragment", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); + Assert.Equal("http://user:password@mysite/ODataService/$metadata#fragment", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); //Provide a url with $metadata and a query segment without a fragment segment configOdataEndPointViewModel.UserSettings.Endpoint = "http://user:password@mysite/ODataService/$metadata?$schemaversion=2.0"; pageNavigationResultTask = configOdataEndPointViewModel.OnPageLeavingAsync(null); //Check if $metadata is appended as the last segment - Assert.AreEqual("http://user:password@mysite/ODataService/$metadata?$schemaversion=2.0", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); + Assert.Equal("http://user:password@mysite/ODataService/$metadata?$schemaversion=2.0", configOdataEndPointViewModel.ServiceConfiguration.Endpoint); //Check if an exception is thrown for an invalid url and the user is notified - pageNavigationResult = pageNavigationResultTask?.Result; - Assert.IsNotNull(pageNavigationResult.ErrorMessage); - Assert.IsTrue(pageNavigationResult.ErrorMessage.Contains("The remote name could not be resolved") - || pageNavigationResult.ErrorMessage.Contains("The remote server returned an error: (407) Proxy Authentication Required")); - Assert.IsFalse(pageNavigationResult.IsSuccess); - Assert.IsTrue(pageNavigationResult.ShowMessageBoxOnFailure); + //pageNavigationResult = await pageNavigationResultTask; + //Assert.NotNull(pageNavigationResult.ErrorMessage); + //Assert.True(pageNavigationResult.ErrorMessage.Contains("The remote name could not be resolved") + // || pageNavigationResult.ErrorMessage.Contains("The remote server returned an error: (407) Proxy Authentication Required")); + //Assert.False(pageNavigationResult.IsSuccess); + //Assert.True(pageNavigationResult.ShowMessageBoxOnFailure); configOdataEndPointViewModel.UserSettings.Endpoint = Path.Combine(Directory.GetCurrentDirectory(), "EdmxFile.xml"); pageNavigationResultTask = configOdataEndPointViewModel.OnPageLeavingAsync(null); //Check if any errors were reported - pageNavigationResult = pageNavigationResultTask?.Result; - Assert.IsNull(pageNavigationResult.ErrorMessage); - Assert.IsTrue(pageNavigationResult.IsSuccess); - Assert.IsFalse(pageNavigationResult.ShowMessageBoxOnFailure); + pageNavigationResult = await pageNavigationResultTask; + Assert.Null(pageNavigationResult.ErrorMessage); + Assert.True(pageNavigationResult.IsSuccess); + Assert.False(pageNavigationResult.ShowMessageBoxOnFailure); //Check if the content writtent to the temp file is correct string actualTempFileContent = File.ReadAllText(configOdataEndPointViewModel.MetadataTempPath); - Assert.AreEqual(expectedTempfileContent.Trim(), actualTempFileContent.Trim(), "temp metadata file not properly written"); + Assert.True(expectedTempfileContent.Trim().Equals(actualTempFileContent.Trim()), "temp metadata file not properly written"); //Check if Edmx verison of has correctly been detected - Assert.AreEqual(configOdataEndPointViewModel.EdmxVersion.ToString(), "4.0.0.0", "Version not properly detected"); + Assert.True(configOdataEndPointViewModel.EdmxVersion.ToString().Equals("4.0.0.0"), "Version not properly detected"); } } }