Refactor DocumentClientUtilityBase to not be a class (#115)

This commit is contained in:
Steve Faulkner
2020-07-27 12:58:27 -05:00
committed by GitHub
parent 6d142f16f9
commit 2e49ed45c3
48 changed files with 1567 additions and 1754 deletions

View File

@@ -41,7 +41,7 @@ describe("Add Collection Pane", () => {
};
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
explorer.hasAutoPilotV2FeatureFlag = ko.computed<boolean>(() => true);
});

View File

@@ -20,6 +20,7 @@ import { createMongoCollectionWithARM, createMongoCollectionWithProxy } from "..
import { DynamicListItem } from "../Controls/DynamicList/DynamicListComponent";
import { HashMap } from "../../Common/HashMap";
import { PlatformType } from "../../PlatformType";
import { refreshCachedResources, getOrCreateDatabaseAndCollection } from "../../Common/DocumentClientUtilityBase";
export default class AddCollectionPane extends ContextualPaneBase {
public defaultExperience: ko.Computed<string>;
@@ -941,8 +942,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
)
);
} else {
createCollectionFunc = () =>
this.container.documentClientUtility.getOrCreateDatabaseAndCollection(createRequest, options);
createCollectionFunc = () => getOrCreateDatabaseAndCollection(createRequest, options);
}
createCollectionFunc().then(
@@ -978,7 +978,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
};
TelemetryProcessor.traceSuccess(Action.CreateCollection, addCollectionPaneSuccessMessage, startKey);
this.resetData();
return this.container.documentClientUtility.refreshCachedResources().then(() => {
return refreshCachedResources().then(() => {
this.container.refreshAllDatabases();
});
},

View File

@@ -40,7 +40,6 @@ describe("Add Database Pane", () => {
beforeEach(() => {
explorer = new Explorer({
documentClientUtility: null,
notificationsClient: null,
isEmulator: false
});

View File

@@ -16,6 +16,7 @@ import { CassandraAPIDataClient } from "../Tables/TableDataClient";
import { ContextualPaneBase } from "./ContextualPaneBase";
import { CosmosClient } from "../../Common/CosmosClient";
import { PlatformType } from "../../PlatformType";
import { refreshCachedOffers, refreshCachedResources, createDatabase } from "../../Common/DocumentClientUtilityBase";
export default class AddDatabasePane extends ContextualPaneBase {
public defaultExperience: ko.Computed<string>;
@@ -334,10 +335,7 @@ export default class AddDatabasePane extends ContextualPaneBase {
) {
AddDbUtilities.createSqlDatabase(this.container.armEndpoint(), createDatabaseParameters, autoPilotSettings).then(
() => {
Promise.all([
this.container.documentClientUtility.refreshCachedOffers(),
this.container.documentClientUtility.refreshCachedResources()
]).then(() => {
Promise.all([refreshCachedOffers(), refreshCachedResources()]).then(() => {
this._onCreateDatabaseSuccess(createDatabaseParameters.offerThroughput, startKey);
});
}
@@ -354,10 +352,7 @@ export default class AddDatabasePane extends ContextualPaneBase {
createDatabaseParameters,
autoPilotSettings
).then(() => {
Promise.all([
this.container.documentClientUtility.refreshCachedOffers(),
this.container.documentClientUtility.refreshCachedResources()
]).then(() => {
Promise.all([refreshCachedOffers(), refreshCachedResources()]).then(() => {
this._onCreateDatabaseSuccess(createDatabaseParameters.offerThroughput, startKey);
});
});
@@ -373,10 +368,7 @@ export default class AddDatabasePane extends ContextualPaneBase {
createDatabaseParameters,
autoPilotSettings
).then(() => {
Promise.all([
this.container.documentClientUtility.refreshCachedOffers(),
this.container.documentClientUtility.refreshCachedResources()
]).then(() => {
Promise.all([refreshCachedOffers(), refreshCachedResources()]).then(() => {
this._onCreateDatabaseSuccess(createDatabaseParameters.offerThroughput, startKey);
});
});
@@ -413,7 +405,7 @@ export default class AddDatabasePane extends ContextualPaneBase {
autoPilot,
hasAutoPilotV2FeatureFlag: this.hasAutoPilotV2FeatureFlag()
};
this.container.documentClientUtility.createDatabase(createRequest).then(
createDatabase(createRequest).then(
(database: DataModels.Database) => {
this._onCreateDatabaseSuccess(offerThroughput, telemetryStartKey);
},
@@ -464,10 +456,7 @@ export default class AddDatabasePane extends ContextualPaneBase {
startKey: number
): void {
AddDbUtilities.createCassandraKeyspace(armEndpoint, createKeyspaceParameters, autoPilotSettings).then(() => {
Promise.all([
this.container.documentClientUtility.refreshCachedOffers(),
this.container.documentClientUtility.refreshCachedResources()
]).then(() => {
Promise.all([refreshCachedOffers(), refreshCachedResources()]).then(() => {
this._onCreateDatabaseSuccess(createKeyspaceParameters.offerThroughput, startKey);
});
});

View File

@@ -5,7 +5,6 @@ import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstan
import { KeyCodes } from "../../Common/Constants";
import { WaitsForTemplateViewModel } from "../WaitsForTemplateViewModel";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
import Explorer from "../Explorer";
// TODO: Use specific actions for logging telemetry data
@@ -17,14 +16,12 @@ export abstract class ContextualPaneBase extends WaitsForTemplateViewModel imple
public formErrors: ko.Observable<string>;
public title: ko.Observable<string>;
public visible: ko.Observable<boolean>;
public documentClientUtility: DocumentClientUtilityBase;
public isExecuting: ko.Observable<boolean>;
constructor(options: ViewModels.PaneOptions) {
super();
this.id = options.id;
this.container = options.container;
this.documentClientUtility = options.documentClientUtility;
this.visible = options.visible || ko.observable(false);
this.firstFieldHasFocus = ko.observable<boolean>(false);
this.formErrors = ko.observable<string>();

View File

@@ -1,3 +1,4 @@
jest.mock("../../Common/DocumentClientUtilityBase");
import * as ko from "knockout";
import * as sinon from "sinon";
import Q from "q";
@@ -6,7 +7,7 @@ import * as ViewModels from "../../Contracts/ViewModels";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
import DeleteCollectionConfirmationPane from "./DeleteCollectionConfirmationPane";
import DeleteFeedback from "../../Common/DeleteFeedback";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
import { deleteCollection } from "../../Common/DocumentClientUtilityBase";
import Explorer from "../Explorer";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { TreeNode } from "../../Contracts/ViewModels";
@@ -16,7 +17,7 @@ describe("Delete Collection Confirmation Pane", () => {
let explorer: Explorer;
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
});
it("should be true if 1 database and 1 collection", () => {
@@ -55,15 +56,11 @@ describe("Delete Collection Confirmation Pane", () => {
describe("shouldRecordFeedback()", () => {
it("should return true if last collection and database does not have shared throughput else false", () => {
let fakeDocumentClientUtility = sinon.createStubInstance<DocumentClientUtilityBase>(
DocumentClientUtilityBase as any
);
let fakeExplorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
let fakeExplorer = new Explorer({ notificationsClient: null, isEmulator: false });
fakeExplorer.isNotificationConsoleExpanded = ko.observable<boolean>(false);
fakeExplorer.refreshAllDatabases = () => Q.resolve();
let pane = new DeleteCollectionConfirmationPane({
documentClientUtility: fakeDocumentClientUtility as any,
id: "deletecollectionconfirmationpane",
visible: ko.observable<boolean>(false),
container: fakeExplorer
@@ -96,8 +93,7 @@ describe("Delete Collection Confirmation Pane", () => {
it("it should log feedback if last collection and database is not shared", () => {
let selectedCollectionId = "testCol";
let fakeDocumentClientUtility = {} as DocumentClientUtilityBase;
fakeDocumentClientUtility.deleteCollection = () => Q(null);
(deleteCollection as jest.Mock).mockResolvedValue(null);
let fakeExplorer = {} as Explorer;
fakeExplorer.findSelectedCollection = () => {
return {
@@ -120,14 +116,12 @@ describe("Delete Collection Confirmation Pane", () => {
return false;
});
fakeExplorer.documentClientUtility = fakeDocumentClientUtility;
fakeExplorer.selectedNode = ko.observable<TreeNode>();
fakeExplorer.isLastCollection = () => true;
fakeExplorer.isSelectedDatabaseShared = () => false;
fakeExplorer.refreshAllDatabases = () => Q.resolve();
let pane = new DeleteCollectionConfirmationPane({
documentClientUtility: fakeDocumentClientUtility as any,
id: "deletecollectionconfirmationpane",
visible: ko.observable<boolean>(false),
container: fakeExplorer as any

View File

@@ -11,6 +11,7 @@ import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility"
import DeleteFeedback from "../../Common/DeleteFeedback";
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { deleteCollection } from "../../Common/DocumentClientUtilityBase";
export default class DeleteCollectionConfirmationPane extends ContextualPaneBase {
public collectionIdConfirmationText: ko.Observable<string>;
@@ -58,7 +59,7 @@ export default class DeleteCollectionConfirmationPane extends ContextualPaneBase
this.container
);
} else {
promise = this.container.documentClientUtility.deleteCollection(selectedCollection);
promise = deleteCollection(selectedCollection);
}
return promise.then(
() => {

View File

@@ -1,23 +1,28 @@
jest.mock("../../Common/DocumentClientUtilityBase");
jest.mock("../../Shared/Telemetry/TelemetryProcessor");
import * as ko from "knockout";
import * as sinon from "sinon";
import Q from "q";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels";
import DeleteDatabaseConfirmationPane from "./DeleteDatabaseConfirmationPane";
import DeleteFeedback from "../../Common/DeleteFeedback";
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
import Explorer from "../Explorer";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { TreeNode } from "../../Contracts/ViewModels";
import { TabsManager } from "../Tabs/TabsManager";
import { deleteDatabase } from "../../Common/DocumentClientUtilityBase";
describe("Delete Database Confirmation Pane", () => {
describe("Explorer.isLastDatabase() and Explorer.isLastNonEmptyDatabase()", () => {
let explorer: Explorer;
beforeAll(() => {
(deleteDatabase as jest.Mock).mockResolvedValue(undefined);
});
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
});
it("should be true if only 1 database", () => {
@@ -49,12 +54,10 @@ describe("Delete Database Confirmation Pane", () => {
describe("shouldRecordFeedback()", () => {
it("should return true if last non empty database or is last database that has shared throughput, else false", () => {
let fakeDocumentClientUtility = {} as DocumentClientUtilityBase;
let fakeExplorer = {} as Explorer;
fakeExplorer.isNotificationConsoleExpanded = ko.observable<boolean>(false);
let pane = new DeleteDatabaseConfirmationPane({
documentClientUtility: fakeDocumentClientUtility as any,
id: "deletedatabaseconfirmationpane",
visible: ko.observable<boolean>(false),
container: fakeExplorer as any
@@ -78,20 +81,8 @@ describe("Delete Database Confirmation Pane", () => {
});
describe("submit()", () => {
let telemetryProcessorSpy: sinon.SinonSpy;
beforeEach(() => {
telemetryProcessorSpy = sinon.spy(TelemetryProcessor, "trace");
});
afterEach(() => {
telemetryProcessorSpy.restore();
});
it("on submit() it should log feedback if last non empty database or is last database that has shared throughput", () => {
let selectedDatabaseId = "testDB";
let fakeDocumentClientUtility = {} as DocumentClientUtilityBase;
fakeDocumentClientUtility.deleteDatabase = () => Q.resolve(null);
let fakeExplorer = {} as Explorer;
fakeExplorer.findSelectedDatabase = () => {
return {
@@ -114,13 +105,11 @@ describe("Delete Database Confirmation Pane", () => {
fakeExplorer.isPreferredApiCassandra = ko.computed(() => {
return false;
});
fakeExplorer.documentClientUtility = fakeDocumentClientUtility;
fakeExplorer.selectedNode = ko.observable<TreeNode>();
fakeExplorer.tabsManager = new TabsManager();
fakeExplorer.isLastNonEmptyDatabase = () => true;
let pane = new DeleteDatabaseConfirmationPane({
documentClientUtility: fakeDocumentClientUtility as any,
id: "deletedatabaseconfirmationpane",
visible: ko.observable<boolean>(false),
container: fakeExplorer as any
@@ -130,15 +119,12 @@ describe("Delete Database Confirmation Pane", () => {
pane.databaseDeleteFeedback(Feedback);
return pane.submit().then(() => {
expect(telemetryProcessorSpy.called).toBe(true);
let deleteFeedback = new DeleteFeedback(SubscriptionId, AccountName, DataModels.ApiKind.SQL, Feedback);
expect(
telemetryProcessorSpy.calledWith(
Action.DeleteDatabase,
ActionModifiers.Mark,
JSON.stringify(deleteFeedback, Object.getOwnPropertyNames(deleteFeedback))
)
).toBe(true);
expect(TelemetryProcessor.trace).toHaveBeenCalledWith(
Action.DeleteDatabase,
ActionModifiers.Mark,
JSON.stringify(deleteFeedback, Object.getOwnPropertyNames(deleteFeedback))
);
});
});
});

View File

@@ -12,6 +12,7 @@ import DeleteFeedback from "../../Common/DeleteFeedback";
import { NotificationConsoleUtils } from "../../Utils/NotificationConsoleUtils";
import TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { deleteDatabase } from "../../Common/DocumentClientUtilityBase";
export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
public databaseIdConfirmationText: ko.Observable<string>;
@@ -59,7 +60,7 @@ export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
this.container
);
} else {
promise = this.container.documentClientUtility.deleteDatabase(selectedDatabase);
promise = deleteDatabase(selectedDatabase);
}
return promise.then(
() => {

View File

@@ -7,7 +7,7 @@ describe("Settings Pane", () => {
let explorer: Explorer;
beforeEach(() => {
explorer = new Explorer({ documentClientUtility: null, notificationsClient: null, isEmulator: false });
explorer = new Explorer({ notificationsClient: null, isEmulator: false });
});
it("should be true for SQL API", () => {