From 9fe3aeddc31dbfc744d82a65f0a00ab18cce62b3 Mon Sep 17 00:00:00 2001 From: Benjin Dubishar Date: Tue, 31 Jan 2023 16:52:07 -0800 Subject: [PATCH] Support for database references in SqlProjects service (#1832) * initial checkin * Initial * Adding test * Adding comments * PR feedback --- .../AddDacpacReferenceParams.cs | 32 +++++++ .../AddDatabaseReferenceParams.cs | 23 +++++ .../AddSqlProjectReferenceParams.cs | 38 ++++++++ .../AddSystemDatabaseReference.cs | 27 ++++++ .../DeleteDatabaseReference.cs | 26 ++++++ .../Contracts/Projects/CloseSqlProject.cs | 2 +- .../Contracts/Projects/NewSqlProject.cs | 2 +- .../Contracts/Projects/OpenSqlProject.cs | 2 +- .../SqlCmdVariables/AddSqlCmdVariable.cs | 2 +- .../SqlCmdVariables/DeleteSqlCmdVariable.cs | 2 +- .../SqlCmdVariables/UpdateSqlCmdvariable.cs | 2 +- .../SqlObjects/AddSqlObjectScript.cs | 2 +- .../SqlObjects/DeleteSqlObjectScript.cs | 2 +- .../SqlObjects/ExcludeSqlObjectScript.cs | 2 +- .../SqlProjects/SqlProjectsService.cs | 42 +++++++++ .../SqlProjects/SqlProjectsServiceTests.cs | 93 ++++++++++++++++++- 16 files changed, 289 insertions(+), 10 deletions(-) create mode 100644 src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddDacpacReferenceParams.cs create mode 100644 src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddDatabaseReferenceParams.cs create mode 100644 src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddSqlProjectReferenceParams.cs create mode 100644 src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddSystemDatabaseReference.cs create mode 100644 src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/DeleteDatabaseReference.cs diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddDacpacReferenceParams.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddDacpacReferenceParams.cs new file mode 100644 index 00000000..f23a563e --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddDacpacReferenceParams.cs @@ -0,0 +1,32 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.Utility; + +namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts +{ + /// + /// Parameters for adding a Dacpac reference to a SQL project + /// + public class AddDacpacReferenceParams : AddDatabaseReferenceParams + { + /// + /// Path to the .dacpac file + /// + public string DacpacPath { get; set; } + + /// + /// SQLCMD variable name for specifying the other server this reference is to, if different from that of the current project. + /// If this is set, DatabaseVariable must also be set. + /// + public string? ServerVariable { get; set; } + } + + public class AddDacpacReferenceRequest + { + public static readonly RequestType Type = RequestType.Create("sqlprojects/addDacpacReference"); + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddDatabaseReferenceParams.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddDatabaseReferenceParams.cs new file mode 100644 index 00000000..c47df2d0 --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddDatabaseReferenceParams.cs @@ -0,0 +1,23 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts +{ + /// + /// Base class for add database reference request paramaters + /// + public abstract class AddDatabaseReferenceParams : SqlProjectParams + { + /// + /// Whether to suppress missing dependencies + /// + public bool SuppressMissingDependencies { get; set; } + + /// + /// SQLCMD variable name for specifying the other database this reference is to, if different from that of the current project + /// + public string? DatabaseVariable { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddSqlProjectReferenceParams.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddSqlProjectReferenceParams.cs new file mode 100644 index 00000000..e166a061 --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddSqlProjectReferenceParams.cs @@ -0,0 +1,38 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.Utility; + +namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts +{ + /// + /// Parameters for adding a reference to another SQL project + /// + public class AddSqlProjectReferenceParams : AddDatabaseReferenceParams + { + /// + /// Path to the referenced .sqlproj file + /// + public string ProjectPath { get; set; } + + /// + /// GUID for the referenced SQL project + /// + public string? ProjectGuid { get; set; } + + /// + /// SQLCMD variable name for specifying the other server this reference is to, if different from that of the current project. + /// If this is set, DatabaseVariable must also be set. + /// + public string? ServerVariable { get; set; } + } + + + public class AddSqlProjectReferenceRequest + { + public static readonly RequestType Type = RequestType.Create("sqlprojects/addSqlProjectReference"); + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddSystemDatabaseReference.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddSystemDatabaseReference.cs new file mode 100644 index 00000000..3e2c4446 --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/AddSystemDatabaseReference.cs @@ -0,0 +1,27 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using Microsoft.SqlServer.Dac.Projects; +using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.Utility; + +namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts +{ + /// + /// Parameters for adding a reference to a system database + /// + public class AddSystemDatabaseReferenceParams : AddDatabaseReferenceParams + { + /// + /// Type of system database + /// + public SystemDatabase SystemDatabase { get; set; } + } + + public class AddSystemDatabaseReferenceRequest + { + public static readonly RequestType Type = RequestType.Create("sqlprojects/addSystemDatabaseReference"); + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/DeleteDatabaseReference.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/DeleteDatabaseReference.cs new file mode 100644 index 00000000..90e8d0be --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/DatabaseReferences/DeleteDatabaseReference.cs @@ -0,0 +1,26 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using Microsoft.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.ServiceLayer.Utility; + +namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts +{ + /// + /// Parameters for deleting a database reference + /// + public class DeleteDatabaseReferenceParams : SqlProjectParams + { + /// + /// Name of the reference to be deleted. Name of the System DB, path of the sqlproj, or path of the dacpac + /// + public string Name { get; set; } + } + + public class DeleteDatabaseReferenceRequest + { + public static readonly RequestType Type = RequestType.Create("sqlprojects/deleteDatabaseReference"); + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/CloseSqlProject.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/CloseSqlProject.cs index 2b08003d..f6b3d7d1 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/CloseSqlProject.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/CloseSqlProject.cs @@ -10,6 +10,6 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts { public class CloseSqlProjectRequest { - public static readonly RequestType Type = RequestType.Create("sqlprojects/closeProject"); + public static readonly RequestType Type = RequestType.Create("sqlProjects/closeProject"); } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/NewSqlProject.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/NewSqlProject.cs index 069e3c7f..5bb93594 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/NewSqlProject.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/NewSqlProject.cs @@ -34,6 +34,6 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts public class NewSqlProjectRequest { - public static readonly RequestType Type = RequestType.Create("sqlprojects/newProject"); + public static readonly RequestType Type = RequestType.Create("sqlProjects/newProject"); } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/OpenSqlProject.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/OpenSqlProject.cs index 33c77aea..3d0af8e5 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/OpenSqlProject.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/Projects/OpenSqlProject.cs @@ -10,6 +10,6 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts { public class OpenSqlProjectRequest { - public static readonly RequestType Type = RequestType.Create("sqlprojects/openProject"); + public static readonly RequestType Type = RequestType.Create("sqlProjects/openProject"); } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/AddSqlCmdVariable.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/AddSqlCmdVariable.cs index 5230948e..9fa72dd9 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/AddSqlCmdVariable.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/AddSqlCmdVariable.cs @@ -31,6 +31,6 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts public class AddSqlCmdVariableRequest { - public static readonly RequestType Type = RequestType.Create("sqlprojects/addSqlCmdVariable"); + public static readonly RequestType Type = RequestType.Create("sqlProjects/addSqlCmdVariable"); } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/DeleteSqlCmdVariable.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/DeleteSqlCmdVariable.cs index 21c86e0e..099279ce 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/DeleteSqlCmdVariable.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/DeleteSqlCmdVariable.cs @@ -21,6 +21,6 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts public class DeleteSqlCmdVariableRequest { - public static readonly RequestType Type = RequestType.Create("sqlprojects/deleteSqlCmdVariable"); + public static readonly RequestType Type = RequestType.Create("sqlProjects/deleteSqlCmdVariable"); } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/UpdateSqlCmdvariable.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/UpdateSqlCmdvariable.cs index 10a6f59a..05bae35a 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/UpdateSqlCmdvariable.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlCmdVariables/UpdateSqlCmdvariable.cs @@ -10,6 +10,6 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts { public class UpdateSqlCmdVariableRequest { - public static readonly RequestType Type = RequestType.Create("sqlprojects/updateSqlCmdVariable"); + public static readonly RequestType Type = RequestType.Create("sqlProjects/updateSqlCmdVariable"); } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/AddSqlObjectScript.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/AddSqlObjectScript.cs index 5f6ea9df..54d828ac 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/AddSqlObjectScript.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/AddSqlObjectScript.cs @@ -10,6 +10,6 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts { public class AddSqlObjectScriptRequest { - public static readonly RequestType Type = RequestType.Create("sqlprojects/addSqlObjectScript"); + public static readonly RequestType Type = RequestType.Create("sqlProjects/addSqlObjectScript"); } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/DeleteSqlObjectScript.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/DeleteSqlObjectScript.cs index 409e0422..fce63055 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/DeleteSqlObjectScript.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/DeleteSqlObjectScript.cs @@ -10,6 +10,6 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts { public class DeleteSqlObjectScriptRequest { - public static readonly RequestType Type = RequestType.Create("sqlprojects/deleteSqlObjectScript"); + public static readonly RequestType Type = RequestType.Create("sqlProjects/deleteSqlObjectScript"); } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/ExcludeSqlObjectScript.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/ExcludeSqlObjectScript.cs index d75aa75d..2405e7a2 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/ExcludeSqlObjectScript.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/Contracts/SqlObjects/ExcludeSqlObjectScript.cs @@ -10,6 +10,6 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts { public class ExcludeSqlObjectScriptRequest { - public static readonly RequestType Type = RequestType.Create("sqlprojects/excludeSqlObjectScript"); + public static readonly RequestType Type = RequestType.Create("sqlProjects/excludeSqlObjectScript"); } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/SqlProjectsService.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/SqlProjectsService.cs index d55f6cc6..04e71ba6 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/SqlProjectsService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SqlProjects/SqlProjectsService.cs @@ -99,6 +99,48 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects #endregion + #region Database Reference calls + + internal async Task HandleAddSystemDatabaseReferenceRequest(AddSystemDatabaseReferenceParams requestParams, RequestContext requestContext) + { + await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri).DatabaseReferences.Add( + new SystemDatabaseReference( + requestParams.SystemDatabase, + requestParams.SuppressMissingDependencies, + requestParams.DatabaseVariable)), + requestContext); + } + + internal async Task HandleAddDacpacReferenceRequest(AddDacpacReferenceParams requestParams, RequestContext requestContext) + { + await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri).DatabaseReferences.Add( + new DacpacReference( + requestParams.DacpacPath, + requestParams.SuppressMissingDependencies, + requestParams.DatabaseVariable, + requestParams.ServerVariable)), + requestContext); + } + + internal async Task HandleAddSqlProjectReferenceRequest(AddSqlProjectReferenceParams requestParams, RequestContext requestContext) + { + await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri).DatabaseReferences.Add( + new SqlProjectReference( + requestParams.ProjectPath, + requestParams.ProjectGuid, + requestParams.SuppressMissingDependencies, + requestParams.DatabaseVariable, + requestParams.ServerVariable)), + requestContext); + } + + internal async Task HandleDeleteDatabaseReferenceRequest(DeleteDatabaseReferenceParams requestParams, RequestContext requestContext) + { + await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri).DatabaseReferences.Delete(requestParams.Name), requestContext); + } + + #endregion + #region SQLCMD variable functions internal async Task HandleAddSqlCmdVariableRequest(AddSqlCmdVariableParams requestParams, RequestContext requestContext) diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SqlProjects/SqlProjectsServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SqlProjects/SqlProjectsServiceTests.cs index d661c2e7..faca4dc7 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SqlProjects/SqlProjectsServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SqlProjects/SqlProjectsServiceTests.cs @@ -18,6 +18,8 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SqlProjects { public class SqlProjectsServiceTests : TestBase { + internal const string TEST_GUID = "BA5EBA11-C0DE-5EA7-ACED-BABB1E70A575"; + [Test] public async Task TestErrorDuringExecution() { @@ -157,6 +159,95 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SqlProjects Assert.IsFalse(File.Exists(scriptFullPath), $"{scriptFullPath} expected to have been deleted from disk"); } + [Test] + public async Task TestDatabaseReferenceAddDelete() + { + // Setup + SqlProjectsService service = new(); + string projectUri = await service.CreateSqlProject(); + + SqlCmdVariable databaseVar = new SqlCmdVariable("$(OtherDb)", "OtherDbDefaultValue", "OtherDbValue"); + SqlCmdVariable serverVar = new SqlCmdVariable("$(OtherServer)", "OtherServerDefaultValue", "OtherServerValue"); + + service.Projects[projectUri].SqlCmdVariables.Add(databaseVar); + service.Projects[projectUri].SqlCmdVariables.Add(serverVar); + + Assert.AreEqual(0, service.Projects[projectUri].DatabaseReferences.Count, "Baseline number of database references"); + + // Validate adding a system database reference + MockRequest requestMock = new(); + await service.HandleAddSystemDatabaseReferenceRequest(new AddSystemDatabaseReferenceParams() + { + ProjectUri = projectUri, + SystemDatabase = SystemDatabase.MSDB, + DatabaseVariable = "$(EmEssDeeBee)", + SuppressMissingDependencies = false + }, requestMock.Object); + + requestMock.AssertSuccess(nameof(service.HandleAddSystemDatabaseReferenceRequest)); + Assert.AreEqual(1, service.Projects[projectUri].DatabaseReferences.Count, "Database references after adding system db reference"); + SystemDatabaseReference systemDbRef = (SystemDatabaseReference)service.Projects[projectUri].DatabaseReferences.First(x => x is SystemDatabaseReference); + Assert.AreEqual(SystemDatabase.MSDB, systemDbRef.SystemDb, "Referenced system DB"); + Assert.AreEqual("$(EmEssDeeBee)", systemDbRef.DatabaseVariable); + Assert.IsFalse(systemDbRef.SuppressMissingDependencies, nameof(systemDbRef.SuppressMissingDependencies)); + + // Validate adding a dacpac reference + string mockReferencePath = Path.Join(Path.GetDirectoryName(projectUri), "OtherDatabase.dacpac"); + + requestMock = new(); + await service.HandleAddDacpacReferenceRequest(new AddDacpacReferenceParams() + { + ProjectUri = projectUri, + DacpacPath = mockReferencePath, + SuppressMissingDependencies = false, + DatabaseVariable = databaseVar.Name, + ServerVariable = serverVar.Name + }, requestMock.Object); + + requestMock.AssertSuccess(nameof(service.HandleAddDacpacReferenceRequest)); + Assert.AreEqual(2, service.Projects[projectUri].DatabaseReferences.Count, "Database references after adding dacpac reference"); + DacpacReference dacpacRef = (DacpacReference)service.Projects[projectUri].DatabaseReferences.First(x => x is DacpacReference); + Assert.AreEqual(mockReferencePath, dacpacRef.DacpacPath, "Referenced dacpac"); + Assert.AreEqual(databaseVar.Name, dacpacRef.DatabaseVariable); + Assert.AreEqual(serverVar.Name, dacpacRef.ServerVariable); + Assert.IsFalse(dacpacRef.SuppressMissingDependencies, nameof(dacpacRef.SuppressMissingDependencies)); + + // Validate adding a project reference + mockReferencePath = Path.Join(Path.GetDirectoryName(projectUri), "..", "OtherDatabase", "OtherDatabase.sqlproj"); + + requestMock = new(); + await service.HandleAddSqlProjectReferenceRequest(new AddSqlProjectReferenceParams() + { + ProjectUri = projectUri, + ProjectPath = mockReferencePath, + ProjectGuid = TEST_GUID, + SuppressMissingDependencies = false, + DatabaseVariable = databaseVar.Name, + ServerVariable = serverVar.Name + }, requestMock.Object); + + requestMock.AssertSuccess(nameof(service.HandleAddSqlProjectReferenceRequest)); + Assert.AreEqual(3, service.Projects[projectUri].DatabaseReferences.Count, "Database references after adding SQL project reference"); + SqlProjectReference projectRef = (SqlProjectReference)service.Projects[projectUri].DatabaseReferences.First(x => x is SqlProjectReference); + Assert.AreEqual(mockReferencePath, projectRef.ProjectPath, "Referenced project"); + Assert.AreEqual(TEST_GUID, projectRef.ProjectGuid, "Referenced project GUID"); + Assert.AreEqual(databaseVar.Name, projectRef.DatabaseVariable); + Assert.AreEqual(serverVar.Name, projectRef.ServerVariable); + Assert.IsFalse(projectRef.SuppressMissingDependencies, nameof(projectRef.SuppressMissingDependencies)); + + // Validate deleting a reference + requestMock = new(); + await service.HandleDeleteDatabaseReferenceRequest(new DeleteDatabaseReferenceParams() + { + ProjectUri = projectUri, + Name = mockReferencePath + }, requestMock.Object); + + requestMock.AssertSuccess(nameof(service.HandleDeleteDatabaseReferenceRequest)); + Assert.AreEqual(2, service.Projects[projectUri].DatabaseReferences.Count, "Database references after deleting SQL project reference"); + Assert.IsFalse(service.Projects[projectUri].DatabaseReferences.Any(x => x is SqlProjectReference), "Database references list expected to not contain the SQL Project reference"); + } + [Test] public async Task TestSqlCmdVariablesAddDelete() { @@ -232,7 +323,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SqlProjects }, requestMock.Object); - Assert.IsTrue(requestMock.Result.Success, $"Failed to create project: {requestMock.Result.ErrorMessage}"); + requestMock.AssertSuccess(nameof(CreateSqlProject)); return projectUri; }