mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-15 01:25:36 -05:00
* Move call to STS move api into project.ts (#22071) * move call to STS move api into project.ts * remove undefined * Remove convert to sdk style code (#22081) * remove convert to sdk style code * remove from package.json * Merging latest from main (#22097) * [SQL-Migration] Login migrations telemetry (#22038) This PR enhances telemetry for login migrations (and in the following ways: Add details for starting migration (number of logins migrating, type of logins) Log Migration result (number of errors per step, duration of each step, type of logins, if system error occurred) Add sql-migration extension to our telemetry Adds details when trying to connect to target Tracks clicking "done" from the wizard Fixes bucketizing for navigating telemetry in the login migration wizard Sample usage of kusto query for new telemetry: RawEventsADS | where EventName contains 'sql-migration' | extend view = tostring(Properties['view']) | extend action = tostring(Properties['action']) | extend buttonPressed = tostring(Properties['buttonpressed']) | extend pageTitle = tostring(Properties['pagetitle']) | extend adsVersion = tostring(Properties['common.adsversion']) | extend targetType = tostring(Properties['targettype']) | extend tenantId = tostring(Properties['tenantid']) | extend subscriptionId = tostring(Properties['subscriptionid']) | where view contains "login" //| where adsVersion contains "1.42.0-insider" | where ClientTimestamp >= ago(18h) | project EventName, ClientTimestamp, SessionId, view, pageTitle, action, buttonPressed, targetType , tenantId, subscriptionId , adsVersion, OSVersion, Properties * Add Secure Enclaves dropdown with customizable Advanced options (#22019) * Update extension READMEs (#22079) * Fix query-history README images (#22084) * [Loc] update to mssql and sql-migration xlf files (#22087) * [Loc] small fix to Portuguese lcl file (#22088) * [Loc] small fix to Portuguese lcl file * remove newline * Adding None bindings to the sqlProjects service (#22085) * Adding None bindings * updating names of None bindings --------- Co-authored-by: AkshayMata <akam520@gmail.com> Co-authored-by: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com> Co-authored-by: Charles Gagnon <chgagnon@microsoft.com> Co-authored-by: Alex Ma <alma1@microsoft.com> * Swap add and update sqlcmd variables in sql projects to use STS apis (#22086) * delete sqlcmd variable working * undo add * remove variable from add and update sqlcmd variable apis * hookup add and edit sqlcmd variable * update vscode-mssql.d.ts * move add and edit to project.ts * update STS and tests * move delete sqlcmd variable to project.ts (#22104) * add test for add and edit sqlcmd variable (#22107) * Swapping property access to STS (#22115) * checkpoint * Adding sqlproj property bindings * Swapping out property loading and setting * consolidating to this.sqlProjService * Update dacpac reference to use STS api (#22116) * Update add dacpac reference to use STS api * remove changes for project ref * validate unset settings from add database reference dialog * update one more place getting sqlprojservice * addressing comments * fix path for dacpac reference (#22143) * Swap add project reference to call STS (#22148) * initial changes for swapping add project reference * fix include path * move common logic to helper function * read sqlcmd variables from STS (#22147) * Swapping .sqlproj- and crossplat compatibility-related functions to use STS (#22146) * Supporting roundtrip * Updating sqlproj style checks and cross-platform compatibility to use STS * removing unnecessary awaits * Fixing assertions * Adding roundtrip update confirmations * test cleanup * cleaning up comment; localizing error * Swap add system db reference (#22171) * swap adding system database references * fix tests * remove only in test * Read database references from STS (#22179) * Read database references from STS * fix system dacpac names * fix project reference name * Swap changeTargetPlatform to call STS (#22172) * swap changeTargetPlatform to call STS * Address comments * De-duplicating enum for SystemDatabase (#22196) * Deudping SystemDatabase enum * simplifying enum refs * Removing the now-unused imports code from SqlProjects (#22199) * Removing unused importTargets entries * whitespace; also to retrigger github checks on correct branch * Hooking in Move() for Nones and PublishProfiles (#22200) * Swap delete database reference to call STS (#22215) * initial changes * update contracts * remove unnecessary info from SystemDatabaseReferenceProjectEntry * uppercase master and msdb * cleanup * update test * update comment * undo change in projectController.ts * remove unused system dacpac helper functions (#22204) * more cleanup of project.ts (#22242) * fix a couple database reference tests (#22248) * Organizing sqlcmd variable and db reference code (#22284) * organize database references and sqlcmd variable functions * separate database reference tests * Script and folder get + add support (#22166) * Initial sqlobjectscripts * adding mock filter * test fixing * another test passing * swapping pre/post/none checkpoint * awaiters * convert addExistingItem * swapping folders * removing print * stripping out project folder and file readers * adding some regions * Updating sqlproj style checks and cross-platform compatibility to use STS * Updating sqlproj style checks and cross-platform compatibility to use STS * added type property to tree items * projectController swapovers * removing imported targets * Deleting the last of the TS XML parsing! * Removing old functions * renamed readNoneScripts to readNoneItems * fixing path passed to STS calls * remove system dacpac tests that were moved to DacFx (#22299) * fix error when opening file after adding a file to sql project (#22309) * fix error when opening file after adding a file to sql project * remove unused import * fix exclude for table and externalStreamingJob (#22310) * add reload project (#22313) * set DSP from STS (#22320) * fix adding post-deployment script and existing item (#22317) * Test cleanup for .sqlproj content operations (#22330) * Fixing up tests * sqlproj content operations tests * remove only * Cleanup * Correcting collation * cleanup constants.ts (#22336) * fix folders not showing in project tree (#22319) * Fix project controller tests (#22327) * fixing ProjectController tests after swap * remove only from database reference tests * change system dbs back to lowercase in sql projects (#22353) * Bump tools service * Updated yarn.lock file * pass SystemDacpacsLocation when building legacy style sql projects (#22329) * Benjin/fix types (#22365) * Updated yarn.lock file * Fixing types * fix projectController tests (#22375) * Fixing the deletion flow for files and folders (#22366) * checkpoint * PR feedback * Fixing up SDK-style operations project test group (#22377) * Fixing up SDK-style project test group * Removing .only * Fixing up database reference tests (#22380) * Fixing DB reference test group * Extra cleanup * removing only * Consolidating None and PublishProfile; lighting up test (#22382) * Lighting up project property tests (#22395) * Checkpoint * Lighting up project property tests * removing timeout * Fixing buildHelper test (#22400) * Unskipping up roundtrip test (#22397) * Refactoring database references to split literalVariable from databaseName (#22412) * refactoring database references to split databaseVariableLiteralValue out from databaseName * renaming more properties * Removing branch in entry population * removing only * Fixing baselines for delete test * PR feedback * Fixing up ProjectTree tests (#22419) * Fixing up projectTree tests * remove only * Updating projectController exclude test (#22413) * Updating test * moving filtering for external folders to readFolders() method * Removing EntryType import * fix ups (#22435) * adding extra info for test failure * hide exclude folder from context menu until it's supported (#22454) * Adding current test name to generated folder to avoid conflicts (#22478) * Adding current test name to generated folder to avoid conflicts * passing correct test parameter in * Adding trimming and entropy * Deleting unused baselines (#22497) * Replacing addToProject() with addSqlObjectScripts() (#22489) * checkpoint * Fixing test * Updating file scraper function to filter only to .sql files (no folders, no txt) * changing var names to reflect that the lists only contain .sql scripts --------- Co-authored-by: Kim Santiago <31145923+kisantia@users.noreply.github.com> Co-authored-by: AkshayMata <akam520@gmail.com> Co-authored-by: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com> Co-authored-by: Charles Gagnon <chgagnon@microsoft.com> Co-authored-by: Alex Ma <alma1@microsoft.com>
258 lines
14 KiB
TypeScript
258 lines
14 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import * as should from 'should';
|
|
import * as mssql from 'mssql';
|
|
import * as path from 'path';
|
|
import * as sinon from 'sinon';
|
|
import * as vscode from 'vscode';
|
|
import * as constants from '../../common/constants';
|
|
import * as utils from '../../common/utils'
|
|
import * as quickpickHelper from '../../dialogs/quickpickHelper'
|
|
import * as createProjectFromDatabaseQuickpick from '../../dialogs/createProjectFromDatabaseQuickpick';
|
|
import * as newProjectTool from '../../tools/newProjectTool';
|
|
import { createTestUtils, mockConnectionInfo, TestUtils } from './testUtils';
|
|
import { promises as fs } from 'fs';
|
|
import { ImportDataModel } from '../../models/api/import';
|
|
import { createTestFile, deleteGeneratedTestFolder, generateTestFolderPath } from '../testUtils';
|
|
|
|
let testUtils: TestUtils;
|
|
const projectFilePath = 'test';
|
|
const dbList: string[] = constants.systemDbs.concat(['OtherDatabase', 'Database', 'OtherDatabase2']);
|
|
|
|
describe('Create Project From Database Quickpick', () => {
|
|
beforeEach(function (): void {
|
|
testUtils = createTestUtils();
|
|
sinon.stub(utils, 'getVscodeMssqlApi').resolves(testUtils.vscodeMssqlIExtension.object); //set vscode mssql extension api
|
|
sinon.stub(newProjectTool, 'defaultProjectSaveLocation').returns(undefined);
|
|
sinon.stub(newProjectTool, 'defaultProjectNameFromDb').returns('DatabaseProjectTestProject');
|
|
sinon.stub(utils, 'sanitizeStringForFilename').returns('TestProject');
|
|
});
|
|
|
|
afterEach(async function (): Promise<void> {
|
|
sinon.restore();
|
|
await deleteGeneratedTestFolder();
|
|
});
|
|
|
|
it('Should prompt for connection and exit when connection is not selected', async function (): Promise<void> {
|
|
//promptForConnection spy to verify test
|
|
const promptForConnectionSpy = sinon.stub(testUtils.vscodeMssqlIExtension.object, 'promptForConnection').withArgs(sinon.match.any).resolves(undefined);
|
|
|
|
const model = await createProjectFromDatabaseQuickpick.createNewProjectFromDatabaseWithQuickpick();
|
|
|
|
//verify that prompt for connection was called
|
|
should(promptForConnectionSpy.calledOnce).be.true('promptForConnection should have been called');
|
|
|
|
//verify quickpick exited with undefined, since promptForConnection was set to cancel (resolves to undefined)
|
|
should.equal(model, undefined);
|
|
});
|
|
|
|
it('Should not prompt for connection when connectionInfo is provided and exit when db is not selected', async function (): Promise<void> {
|
|
//promptForConnection spy to verify test
|
|
const promptForConnectionSpy = sinon.stub(testUtils.vscodeMssqlIExtension.object, 'promptForConnection').withArgs(sinon.match.any).resolves(undefined);
|
|
|
|
//user chooses connection
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'connect').resolves('testConnectionURI');
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'listDatabases').withArgs(sinon.match.any).resolves(dbList);
|
|
// user chooses to cancel when prompted for database
|
|
sinon.stub(vscode.window, 'showQuickPick').resolves(undefined);
|
|
|
|
const model = await createProjectFromDatabaseQuickpick.createNewProjectFromDatabaseWithQuickpick(mockConnectionInfo);
|
|
|
|
//verify connection prompt wasn't presented, since connectionInfo was passed during the call
|
|
should(promptForConnectionSpy.notCalled).be.true('promptForConnection should not be called when connectionInfo is provided');
|
|
|
|
//verify quickpick exited with undefined, since database wasn't selected (resolved to undefined)
|
|
should.equal(model, undefined);
|
|
});
|
|
|
|
it('Should exit when project name is not selected', async function (): Promise<void> {
|
|
//user chooses connection and database
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'connect').resolves('testConnectionURI');
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'listDatabases').withArgs(sinon.match.any).resolves(dbList);
|
|
sinon.stub(vscode.window, 'showQuickPick').resolves('Database' as any);
|
|
// user chooses to provide empty project name when prompted
|
|
let inputBoxStub = sinon.stub(vscode.window, 'showInputBox').resolves('');
|
|
// user chooses to cancel when prompted to enter project name
|
|
inputBoxStub.onSecondCall().resolves(undefined);
|
|
|
|
const model = await createProjectFromDatabaseQuickpick.createNewProjectFromDatabaseWithQuickpick(mockConnectionInfo);
|
|
|
|
//verify showInputBox exited with undefined, since project name wasn't selected (resolved to undefined)
|
|
should.equal(model, undefined);
|
|
});
|
|
|
|
it('Should exit when project location is not selected', async function (): Promise<void> {
|
|
//user chooses connection and database
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'connect').resolves('testConnectionURI');
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'listDatabases').withArgs(sinon.match.any).resolves(dbList);
|
|
let quickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves('Database' as any);
|
|
//user chooses project name
|
|
sinon.stub(vscode.window, 'showInputBox').resolves('TestProject');
|
|
//user chooses to exit
|
|
quickPickStub.onSecondCall().resolves(undefined);
|
|
|
|
const model = await createProjectFromDatabaseQuickpick.createNewProjectFromDatabaseWithQuickpick(mockConnectionInfo);
|
|
|
|
//verify showQuickPick exited with undefined, since project location wasn't selected (resolved to undefined)
|
|
should.equal(model, undefined);
|
|
});
|
|
|
|
it('Should exit when project location is not selected (test repeatedness for project location)', async function (): Promise<void> {
|
|
//user chooses connection and database
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'connect').resolves('testConnectionURI');
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'listDatabases').withArgs(sinon.match.any).resolves(dbList);
|
|
let quickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves('Database' as any);
|
|
//user chooses project name
|
|
sinon.stub(vscode.window, 'showInputBox').resolves('TestProject');
|
|
// user chooses to browse for folder
|
|
quickPickStub.onSecondCall().resolves((constants.browseEllipsisWithIcon) as any);
|
|
// user doesn't choose any folder when prompted and exits the showOpenDialog
|
|
let openDialogStub = sinon.stub(vscode.window, 'showOpenDialog').withArgs(sinon.match.any).resolves(undefined);
|
|
// user chooses to browse for folder
|
|
quickPickStub.onThirdCall().resolves((constants.browseEllipsisWithIcon) as any);
|
|
// user doesn't choose any folder when prompted and exits the showOpenDialog
|
|
openDialogStub.onSecondCall().resolves(undefined);
|
|
// user chooses to browse for folder
|
|
quickPickStub.onCall(3).resolves((constants.browseEllipsisWithIcon) as any);
|
|
// user doesn't choose any folder when prompted and exits the showOpenDialog
|
|
openDialogStub.onSecondCall().resolves(undefined);
|
|
//user chooses to exit
|
|
quickPickStub.onCall(4).resolves(undefined);
|
|
|
|
const model = await createProjectFromDatabaseQuickpick.createNewProjectFromDatabaseWithQuickpick(mockConnectionInfo);
|
|
|
|
//verify showQuickPick exited with undefined, since project location wasn't selected (resolved to undefined)
|
|
should.equal(model, undefined);
|
|
});
|
|
|
|
it('Should exit when folder structure is not selected and folder is selected through browsing (test repeatedness for project location)', async function (): Promise<void> {
|
|
//user chooses connection and database
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'connect').resolves('testConnectionURI');
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'listDatabases').withArgs(sinon.match.any).resolves(dbList);
|
|
let quickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves('Database' as any);
|
|
//user chooses project name
|
|
sinon.stub(vscode.window, 'showInputBox').resolves('TestProject');
|
|
// user chooses to browse for folder
|
|
quickPickStub.onSecondCall().resolves((constants.browseEllipsisWithIcon) as any);
|
|
// user doesn't choose any folder when prompted and exits the showOpenDialog
|
|
let openDialogStub = sinon.stub(vscode.window, 'showOpenDialog').withArgs(sinon.match.any).resolves(undefined);
|
|
// user chooses to browse for folder again
|
|
quickPickStub.onThirdCall().resolves((constants.browseEllipsisWithIcon) as any);
|
|
// user chooses folder- stub out folder to be chosen (showOpenDialog)
|
|
openDialogStub.onSecondCall().resolves([vscode.Uri.file(projectFilePath)]);
|
|
//user chooses to exit when prompted for folder structure
|
|
quickPickStub.onCall(3).resolves(undefined);
|
|
|
|
const model = await createProjectFromDatabaseQuickpick.createNewProjectFromDatabaseWithQuickpick(mockConnectionInfo);
|
|
|
|
//verify showQuickPick exited with undefined, since folder structure wasn't selected (resolved to undefined)
|
|
should.equal(model, undefined);
|
|
});
|
|
|
|
it('Should exit when folder structure is not selected and existing folder/file location is selected', async function (): Promise<void> {
|
|
//create folder and project file
|
|
const projectFileName = 'TestProject';
|
|
const testProjectFilePath = await generateTestFolderPath(this.test);
|
|
await fs.rm(testProjectFilePath, { force: true, recursive: true }); //clean up if it already exists
|
|
await createTestFile(this.test, '', `${projectFileName}.sqlproj`, testProjectFilePath);
|
|
|
|
//user chooses connection and database
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'connect').resolves('testConnectionURI');
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'listDatabases').withArgs(sinon.match.any).resolves(dbList);
|
|
let quickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves('Database' as any);
|
|
//user chooses project name
|
|
sinon.stub(vscode.window, 'showInputBox').resolves(projectFileName);
|
|
// user chooses a folder/file combination that already exists
|
|
quickPickStub.onSecondCall().resolves(testProjectFilePath as any);
|
|
//user chooses another folder when prompted again
|
|
quickPickStub.onThirdCall().resolves(path.join(projectFilePath, 'test') as any);
|
|
//user chooses to exit when prompted for folder structure
|
|
quickPickStub.onCall(3).resolves(undefined);
|
|
|
|
const model = await createProjectFromDatabaseQuickpick.createNewProjectFromDatabaseWithQuickpick(mockConnectionInfo);
|
|
|
|
await deleteGeneratedTestFolder();
|
|
|
|
//verify showQuickPick exited with undefined, since folder structure wasn't selected (resolved to undefined)
|
|
should.equal(model, undefined);
|
|
});
|
|
|
|
it('Should exit when include permissions is not selected', async function (): Promise<void> {
|
|
//user chooses connection and database
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'connect').resolves('testConnectionURI');
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'listDatabases').withArgs(sinon.match.any).resolves(dbList);
|
|
let quickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves('Database' as any);
|
|
//user chooses project name
|
|
sinon.stub(vscode.window, 'showInputBox').resolves('TestProject');
|
|
// user chooses a folder
|
|
quickPickStub.onSecondCall().resolves(projectFilePath as any);
|
|
//user chooses Object type when prompted for folder structure
|
|
quickPickStub.onThirdCall().resolves(constants.objectType as any);
|
|
//user chooses to exit when prompted for include permissions
|
|
quickPickStub.onCall(3).resolves(undefined);
|
|
|
|
const model = await createProjectFromDatabaseQuickpick.createNewProjectFromDatabaseWithQuickpick(mockConnectionInfo);
|
|
|
|
//verify showQuickPick exited with undefined, since include permissions wasn't selected (resolved to undefined)
|
|
should.equal(model, undefined);
|
|
});
|
|
|
|
it('Should exit when sdk style project is not selected', async function (): Promise<void> {
|
|
//user chooses connection and database
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'connect').resolves('testConnectionURI');
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'listDatabases').withArgs(sinon.match.any).resolves(dbList);
|
|
let quickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves('Database' as any);
|
|
//user chooses project name
|
|
sinon.stub(vscode.window, 'showInputBox').resolves('TestProject');
|
|
// user chooses a folder
|
|
quickPickStub.onSecondCall().resolves(projectFilePath as any);
|
|
//user chooses Object type when prompted for folder structure
|
|
quickPickStub.onThirdCall().resolves(constants.objectType as any);
|
|
//user chooses No when prompted for include permissions
|
|
quickPickStub.onCall(3).resolves(constants.noStringDefault as any);
|
|
//user chooses to exit when prompted for sdk style project
|
|
sinon.stub(quickpickHelper, 'getSDKStyleProjectInfo').resolves(undefined);
|
|
|
|
const model = await createProjectFromDatabaseQuickpick.createNewProjectFromDatabaseWithQuickpick(mockConnectionInfo);
|
|
|
|
//verify showQuickPick exited with undefined, since sdk style project wasn't selected (resolved to undefined)
|
|
should.equal(model, undefined);
|
|
});
|
|
|
|
it('Should create correct import data model when all the information is provided', async function (): Promise<void> {
|
|
//user chooses connection and database
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'connect').resolves('testConnectionURI');
|
|
sinon.stub(testUtils.vscodeMssqlIExtension.object, 'listDatabases').withArgs(sinon.match.any).resolves(dbList);
|
|
let quickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves('Database' as any);
|
|
//user chooses project name
|
|
sinon.stub(vscode.window, 'showInputBox').resolves('TestProject');
|
|
// user chooses a folder
|
|
quickPickStub.onSecondCall().resolves(projectFilePath as any);
|
|
//user chooses Object type when prompted for folder structure
|
|
quickPickStub.onThirdCall().resolves(constants.objectType as any);
|
|
//user chooses No when prompted for include permissions
|
|
quickPickStub.onCall(3).resolves(constants.noStringDefault as any);
|
|
//user chooses sdk style project to be true
|
|
sinon.stub(quickpickHelper, 'getSDKStyleProjectInfo').resolves(true);
|
|
|
|
const model = await createProjectFromDatabaseQuickpick.createNewProjectFromDatabaseWithQuickpick(mockConnectionInfo);
|
|
|
|
const expectedImportDataModel: ImportDataModel = {
|
|
connectionUri: 'testConnectionURI',
|
|
database: 'Database',
|
|
projName: 'TestProject',
|
|
filePath: projectFilePath,
|
|
version: '1.0.0.0',
|
|
extractTarget: mssql.ExtractTarget.objectType,
|
|
sdkStyle: true,
|
|
includePermissions: false
|
|
};
|
|
|
|
//verify the model is correctly generated
|
|
should(model!).deepEqual(expectedImportDataModel);
|
|
});
|
|
});
|