diff --git a/extensions/sql-database-projects/src/dialogs/updateProjectFromDatabaseDialog.ts b/extensions/sql-database-projects/src/dialogs/updateProjectFromDatabaseDialog.ts index 1d60f0fbc7..a6f7f40375 100644 --- a/extensions/sql-database-projects/src/dialogs/updateProjectFromDatabaseDialog.ts +++ b/extensions/sql-database-projects/src/dialogs/updateProjectFromDatabaseDialog.ts @@ -536,6 +536,9 @@ export class UpdateProjectFromDatabaseDialog { connection.password = connection.options.password = credentials.password; } + const projectFilePath = this.projectFileDropdown!.value! as string; + this.project = await Project.openProject(projectFilePath); + const connectionDetails: azdata.IConnectionProfile = { id: connection.connectionId, userName: connection.userName, @@ -569,10 +572,10 @@ export class UpdateProjectFromDatabaseDialog { const targetEndpointInfo: mssql.SchemaCompareEndpointInfo = { endpointType: mssql.SchemaCompareEndpointType.Project, - projectFilePath: this.projectFileDropdown!.value! as string, + projectFilePath: projectFilePath, extractTarget: mapExtractTargetEnum(this.folderStructureDropDown!.value), targetScripts: [], - dataSchemaProvider: this.project!.getProjectTargetVersion(), + dataSchemaProvider: this.project.getProjectTargetVersion(), connectionDetails: connectionDetails, databaseName: '', serverDisplayName: '', diff --git a/extensions/sql-database-projects/src/test/dialogs/updateProjectFromDatabaseDialog.test.ts b/extensions/sql-database-projects/src/test/dialogs/updateProjectFromDatabaseDialog.test.ts index 204b3c79d3..ab869a537c 100644 --- a/extensions/sql-database-projects/src/test/dialogs/updateProjectFromDatabaseDialog.test.ts +++ b/extensions/sql-database-projects/src/test/dialogs/updateProjectFromDatabaseDialog.test.ts @@ -6,11 +6,14 @@ import * as azdata from 'azdata'; import * as should from 'should'; import * as sinon from 'sinon'; +import * as vscode from 'vscode'; +import * as mssql from 'mssql'; import * as baselines from '../baselines/baselines'; import * as testUtils from '../testUtils'; import { UpdateProjectFromDatabaseDialog } from '../../dialogs/updateProjectFromDatabaseDialog'; -import { mockConnectionProfile, mockURIList } from '../testContext'; +import { mockConnectionProfile, mockDatabaseEndpointInfo, mockProjectEndpointInfo, mockURIList } from '../testContext'; +import { UpdateProjectDataModel } from '../../models/api/updateProject'; describe('Update Project From Database Dialog', () => { before(async function (): Promise { @@ -82,4 +85,59 @@ describe('Update Project From Database Dialog', () => { should.deepEqual(dialog.projectFileDropdown!.values, uriList, `Project file dropdown list should be the sqlproj path (${mockURIList}), but instead was "${dialog.projectFileDropdown!.values}".`); should.equal(dialog.dialog.okButton.enabled, true, 'Okay button should be enabled when dialog is complete.'); }); + + it('Should populate endpoints correctly when Connection context and workspace with projects is provided', async function (): Promise { + sinon.stub(azdata.connection, 'getConnections').resolves([mockConnectionProfile]); + sinon.stub(azdata.connection, 'listDatabases').resolves([mockConnectionProfile.databaseName!]); + + const profile = mockConnectionProfile; + const dialog = new UpdateProjectFromDatabaseDialog(profile, undefined, mockURIList); + await dialog.openDialog(); + await dialog.populatedInputsPromise; + + let uriList: string[] = []; + mockURIList.forEach(projectUri => { + uriList.push(projectUri.fsPath as string); + }); + + should.equal((dialog.serverDropdown!.value).displayName, profile.options['connectionName'], `Server dropdown should be "${profile.options['connectionName']}", but instead was "${(dialog.serverDropdown!.value).displayName}".`); + should.equal(dialog.databaseDropdown!.value, profile.databaseName, `Database dropdown should be "${profile.databaseName}", but instead was "${dialog.databaseDropdown!.value}".`); + should.equal(dialog.projectFileDropdown!.value, uriList[0], `Project file dropdown should be the first project listed in the workspace URI list (${uriList[0]}), but instead was "${dialog.projectFileDropdown!.value}".`); + should.deepEqual(dialog.projectFileDropdown!.values, uriList, `Project file dropdown list should be the workspace URI list (${mockURIList}), but instead was "${dialog.projectFileDropdown!.values}".`); + should.equal(dialog.dialog.okButton.enabled, true, 'Okay button should be enabled when dialog is complete.'); + }); + + it('Should successfully complete the handleUpdateButtonClick method call and connect to appropriate call back properties when Connection context and workspace with projects is provided', async function (): Promise { + const project = await testUtils.createTestProject(this.test, baselines.openProjectFileBaseline); + sinon.stub(azdata.connection, 'getConnections').resolves([mockConnectionProfile]); + sinon.stub(azdata.connection, 'listDatabases').resolves([mockConnectionProfile.databaseName!]); + sinon.stub(azdata.connection, 'getUriForConnection').resolves('MockUri'); + sinon.stub(azdata.connection, 'getCredentials').resolves({ ['credentials']: 'credentials' }); + + const projectFilePath = project.projectFilePath.toLowerCase(); + const profile = mockConnectionProfile; + mockURIList.unshift(vscode.Uri.file(projectFilePath)); + const dialog = new UpdateProjectFromDatabaseDialog(profile, undefined, mockURIList); + await dialog.openDialog(); + await dialog.populatedInputsPromise; + + let uriList: string[] = []; + mockURIList.forEach(projectUri => { + uriList.push(projectUri.fsPath as string); + }); + + // verify the handleUpdateButtonClick method goes through successfully + let model: UpdateProjectDataModel; + const testProjectEndpointInfo: mssql.SchemaCompareEndpointInfo = { ...mockProjectEndpointInfo }; + testProjectEndpointInfo.projectFilePath = projectFilePath; + const expectedUpdateProjectDataModel: UpdateProjectDataModel = { + sourceEndpointInfo: mockDatabaseEndpointInfo, + targetEndpointInfo: testProjectEndpointInfo, + action: 0 + }; + dialog.updateProjectFromDatabaseCallback = (m) => { model = m; }; + await dialog.handleUpdateButtonClick(); + + should(model!).deepEqual(expectedUpdateProjectDataModel); + }); }); diff --git a/extensions/sql-database-projects/src/test/testContext.ts b/extensions/sql-database-projects/src/test/testContext.ts index 4777a282aa..5c95d7b637 100644 --- a/extensions/sql-database-projects/src/test/testContext.ts +++ b/extensions/sql-database-projects/src/test/testContext.ts @@ -139,3 +139,55 @@ export const mockURIList: vscode.Uri[] = [ vscode.Uri.file('/test/folder/folder1/abc1.sqlproj'), vscode.Uri.file('/test/folder/folder2/abc2.sqlproj') ]; + +export const mockConnectionInfo = { + id: undefined, + userName: 'My User', + password: 'My Pwd', + serverName: 'My Server', + databaseName: 'My Database', + connectionName: 'My Connection', + providerName: undefined, + groupId: 'My GroupId', + groupFullName: 'My groupName', + authenticationType: azdata.connection.AuthenticationType.SqlLogin, + savePassword: false, + saveProfile: true, + options: { + server: 'My Server', + database: 'My Database', + user: 'My User', + password: 'My Pwd', + authenticationType: 'SqlLogin', + connectionName: 'My Connection Name' + } +}; + +export const mockProjectEndpointInfo: mssql.SchemaCompareEndpointInfo = { + endpointType: mssql.SchemaCompareEndpointType.Project, + projectFilePath: '', + extractTarget: mssql.ExtractTarget.schemaObjectType, + targetScripts: [], + dataSchemaProvider: '150', + connectionDetails: mockConnectionInfo, + databaseName: '', + serverDisplayName: '', + serverName: '', + ownerUri: '', + packageFilePath: '' +}; + +export const mockDatabaseEndpointInfo: mssql.SchemaCompareEndpointInfo = { + endpointType: mssql.SchemaCompareEndpointType.Database, + databaseName: 'My Database', + serverDisplayName: 'My Connection Name', + serverName: 'My Server', + connectionDetails: mockConnectionInfo, + ownerUri: 'MockUri', + projectFilePath: '', + extractTarget: mssql.ExtractTarget.schemaObjectType, + targetScripts: [], + dataSchemaProvider: '', + packageFilePath: '', + connectionName: 'My Connection Name' +};