// // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; using System.Threading.Tasks; using Microsoft.SqlTools.Hosting.Protocol; using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility; using Moq; using Xunit; namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer { public class ObjectExplorerServiceTests : ObjectExplorerTestBase { private ObjectExplorerService service; private Mock connectionServiceMock; private Mock serviceHostMock; public ObjectExplorerServiceTests() { connectionServiceMock = new Mock(); serviceHostMock = new Mock(); service = CreateOEService(connectionServiceMock.Object); service.InitializeService(serviceHostMock.Object); } [Fact] public async Task CreateSessionRequestErrorsIfConnectionDetailsIsNull() { object errorResponse = null; var contextMock = RequestContextMocks.Create(null) .AddErrorHandling((errorMessage, errorCode, obj) => errorResponse = errorMessage); await service.HandleCreateSessionRequest(null, contextMock.Object); VerifyErrorSent(contextMock); Assert.True(((string)errorResponse).Contains("ArgumentNullException")); } [Fact] public async Task CreateSessionRequestReturnsFalseOnConnectionFailure() { // Given the connection service fails to connect ConnectionDetails details = TestObjects.GetTestConnectionDetails(); ConnectionCompleteParams completeParams = null; serviceHostMock.AddEventHandling(ConnectionCompleteNotification.Type, (et, p) => completeParams = p); string expectedExceptionText = "Error!!!"; connectionServiceMock.Setup(c => c.Connect(It.IsAny())) .Throws(new Exception(expectedExceptionText)); // when creating a new session // then expect the create session request to return false await RunAndVerify( test: (requestContext) => service.HandleCreateSessionRequest(details, requestContext), verify: (actual => { Assert.False(actual.Success); Assert.Null(actual.SessionId); Assert.Null(actual.RootNode); })); // And expect error notification to be sent serviceHostMock.Verify(x => x.SendEvent(ConnectionCompleteNotification.Type, It.IsAny()), Times.Once()); Assert.NotNull(completeParams); Assert.True(completeParams.Messages.Contains(expectedExceptionText)); } [Fact] public async Task CreateSessionRequestReturnsSuccessAndNodeInfo() { // Given the connection service fails to connect ConnectionDetails details = TestObjects.GetTestConnectionDetails(); serviceHostMock.AddEventHandling(ConnectionCompleteNotification.Type, null); connectionServiceMock.Setup(c => c.Connect(It.IsAny())) .Returns((ConnectParams connectParams) => Task.FromResult(GetCompleteParamsForConnection(connectParams.OwnerUri, details))); // when creating a new session // then expect the create session request to return false await RunAndVerify( test: (requestContext) => service.HandleCreateSessionRequest(details, requestContext), verify: (actual => { Assert.True(actual.Success); Assert.NotNull(actual.SessionId); VerifyServerNode(actual.RootNode, details); })); // And expect no error notification to be sent serviceHostMock.Verify(x => x.SendEvent(ConnectionCompleteNotification.Type, It.IsAny()), Times.Never()); } private void VerifyServerNode(NodeInfo serverNode, ConnectionDetails details) { Assert.NotNull(serverNode); Assert.Equal(NodeTypes.ServerInstance.ToString(), serverNode.NodeType); string[] pathParts = serverNode.NodePath.Split(TreeNode.PathPartSeperator); Assert.Equal(1, pathParts.Length); Assert.Equal(details.ServerName, pathParts[0]); Assert.True(serverNode.Label.Contains(details.ServerName)); Assert.False(serverNode.IsLeaf); } private static ConnectionCompleteParams GetCompleteParamsForConnection(string uri, ConnectionDetails details) { return new ConnectionCompleteParams() { ConnectionId = Guid.NewGuid().ToString(), OwnerUri = uri, ConnectionSummary = new ConnectionSummary() { ServerName = details.ServerName, DatabaseName = details.DatabaseName, UserName = details.UserName }, ServerInfo = TestObjects.GetTestServerInfo() }; } private async Task RunAndVerify(Func, Task> test, Action verify) { T result = default(T); var contextMock = RequestContextMocks.Create(r => result = r).AddErrorHandling(null); await test(contextMock.Object); VerifyResult(contextMock, verify, result); } private void VerifyResult(Mock> contextMock, Action verify, T actual) { contextMock.Verify(c => c.SendResult(It.IsAny()), Times.Once); contextMock.Verify(c => c.SendError(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); verify(actual); } private void VerifyErrorSent(Mock> contextMock) { contextMock.Verify(c => c.SendResult(It.IsAny()), Times.Never); contextMock.Verify(c => c.SendError(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); } } }