mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-04-23 10:04:14 +01:00
256 lines
11 KiB
TypeScript
256 lines
11 KiB
TypeScript
import { shallow } from "enzyme";
|
|
import React from "react";
|
|
import { SettingsComponentProps, SettingsComponent, SettingsComponentState } from "./SettingsComponent";
|
|
import * as ViewModels from "../../../Contracts/ViewModels";
|
|
import { CollectionSettingsTabV2 } from "../../Tabs/SettingsTabV2";
|
|
import { collection } from "./TestUtils";
|
|
import * as DataModels from "../../../Contracts/DataModels";
|
|
import ko from "knockout";
|
|
import { TtlType, isDirty } from "./SettingsUtils";
|
|
import Explorer from "../../Explorer";
|
|
jest.mock("../../../Common/dataAccess/getIndexTransformationProgress", () => ({
|
|
getIndexTransformationProgress: jest.fn().mockReturnValue(undefined),
|
|
}));
|
|
import { updateCollection, updateMongoDBCollectionThroughRP } from "../../../Common/dataAccess/updateCollection";
|
|
jest.mock("../../../Common/dataAccess/updateCollection", () => ({
|
|
updateCollection: jest.fn().mockReturnValue({
|
|
id: undefined,
|
|
defaultTtl: undefined,
|
|
indexingPolicy: undefined,
|
|
conflictResolutionPolicy: undefined,
|
|
changeFeedPolicy: undefined,
|
|
analyticalStorageTtl: undefined,
|
|
geospatialConfig: undefined,
|
|
} as DataModels.Collection),
|
|
updateMongoDBCollectionThroughRP: jest.fn().mockReturnValue({
|
|
id: undefined,
|
|
shardKey: undefined,
|
|
indexes: [],
|
|
analyticalStorageTtl: undefined,
|
|
} as MongoDBCollectionResource),
|
|
}));
|
|
import { updateOffer } from "../../../Common/dataAccess/updateOffer";
|
|
import { MongoDBCollectionResource } from "../../../Utils/arm/generatedClients/2020-04-01/types";
|
|
jest.mock("../../../Common/dataAccess/updateOffer", () => ({
|
|
updateOffer: jest.fn().mockReturnValue({} as DataModels.Offer),
|
|
}));
|
|
|
|
describe("SettingsComponent", () => {
|
|
const baseProps: SettingsComponentProps = {
|
|
settingsTab: new CollectionSettingsTabV2({
|
|
collection: collection,
|
|
tabKind: ViewModels.CollectionTabKind.CollectionSettingsV2,
|
|
title: "Scale & Settings",
|
|
tabPath: "",
|
|
node: undefined,
|
|
hashLocation: "settings",
|
|
isActive: ko.observable(false),
|
|
onUpdateTabsButtons: undefined,
|
|
}),
|
|
};
|
|
|
|
it("renders", () => {
|
|
const wrapper = shallow(<SettingsComponent {...baseProps} />);
|
|
expect(wrapper).toMatchSnapshot();
|
|
});
|
|
|
|
it("dirty value enables save button and discard button", () => {
|
|
const wrapper = shallow(<SettingsComponent {...baseProps} />);
|
|
const settingsComponentInstance = wrapper.instance() as SettingsComponent;
|
|
expect(settingsComponentInstance.isSaveSettingsButtonEnabled()).toEqual(false);
|
|
expect(settingsComponentInstance.isDiscardSettingsButtonEnabled()).toEqual(false);
|
|
wrapper.setState({ isScaleSaveable: true, isScaleDiscardable: true });
|
|
wrapper.update();
|
|
expect(settingsComponentInstance.isSaveSettingsButtonEnabled()).toEqual(true);
|
|
expect(settingsComponentInstance.isDiscardSettingsButtonEnabled()).toEqual(true);
|
|
wrapper.setState({
|
|
isScaleSaveable: false,
|
|
isScaleDiscardable: false,
|
|
isSubSettingsSaveable: true,
|
|
isSubSettingsDiscardable: true,
|
|
});
|
|
wrapper.update();
|
|
expect(settingsComponentInstance.isSaveSettingsButtonEnabled()).toEqual(true);
|
|
expect(settingsComponentInstance.isDiscardSettingsButtonEnabled()).toEqual(true);
|
|
wrapper.setState({ isSubSettingsSaveable: false, isSubSettingsDiscardable: false, isIndexingPolicyDirty: true });
|
|
wrapper.update();
|
|
expect(settingsComponentInstance.isSaveSettingsButtonEnabled()).toEqual(true);
|
|
expect(settingsComponentInstance.isDiscardSettingsButtonEnabled()).toEqual(true);
|
|
wrapper.setState({ isIndexingPolicyDirty: false, isConflictResolutionDirty: true });
|
|
wrapper.update();
|
|
expect(settingsComponentInstance.isSaveSettingsButtonEnabled()).toEqual(true);
|
|
expect(settingsComponentInstance.isDiscardSettingsButtonEnabled()).toEqual(true);
|
|
});
|
|
|
|
it("auto pilot helper functions pass on correct value", () => {
|
|
const newCollection = { ...collection };
|
|
newCollection.offer = ko.observable<DataModels.Offer>({
|
|
autoscaleMaxThroughput: 10000,
|
|
manualThroughput: undefined,
|
|
minimumThroughput: 400,
|
|
id: "test",
|
|
offerReplacePending: false,
|
|
});
|
|
|
|
const props = { ...baseProps };
|
|
props.settingsTab.collection = newCollection;
|
|
|
|
const wrapper = shallow(<SettingsComponent {...props} />);
|
|
const settingsComponentInstance = wrapper.instance() as SettingsComponent;
|
|
expect(settingsComponentInstance.hasProvisioningTypeChanged()).toEqual(false);
|
|
wrapper.setState({
|
|
userCanChangeProvisioningTypes: true,
|
|
isAutoPilotSelected: true,
|
|
wasAutopilotOriginallySet: false,
|
|
autoPilotThroughput: 1000,
|
|
});
|
|
wrapper.update();
|
|
expect(settingsComponentInstance.hasProvisioningTypeChanged()).toEqual(true);
|
|
});
|
|
|
|
it("shouldShowKeyspaceSharedThroughputMessage", () => {
|
|
let settingsComponentInstance = new SettingsComponent(baseProps);
|
|
expect(settingsComponentInstance.shouldShowKeyspaceSharedThroughputMessage()).toEqual(false);
|
|
|
|
const newContainer = new Explorer();
|
|
newContainer.isPreferredApiCassandra = ko.computed(() => true);
|
|
|
|
const newCollection = { ...collection };
|
|
newCollection.container = newContainer;
|
|
const newDatabase = {
|
|
nodeKind: undefined,
|
|
rid: undefined,
|
|
container: newContainer,
|
|
self: undefined,
|
|
id: undefined,
|
|
collections: undefined,
|
|
offer: undefined,
|
|
isDatabaseExpanded: undefined,
|
|
isDatabaseShared: ko.computed(() => true),
|
|
selectedSubnodeKind: undefined,
|
|
selectDatabase: undefined,
|
|
expandDatabase: undefined,
|
|
collapseDatabase: undefined,
|
|
loadCollections: undefined,
|
|
findCollectionWithId: undefined,
|
|
openAddCollection: undefined,
|
|
onDeleteDatabaseContextMenuClick: undefined,
|
|
readSettings: undefined,
|
|
onSettingsClick: undefined,
|
|
loadOffer: undefined,
|
|
getPendingThroughputSplitNotification: undefined,
|
|
} as ViewModels.Database;
|
|
newCollection.getDatabase = () => newDatabase;
|
|
newCollection.offer = ko.observable(undefined);
|
|
|
|
const props = { ...baseProps };
|
|
props.settingsTab.collection = newCollection;
|
|
|
|
settingsComponentInstance = new SettingsComponent(props);
|
|
expect(settingsComponentInstance.shouldShowKeyspaceSharedThroughputMessage()).toEqual(true);
|
|
});
|
|
|
|
it("hasConflictResolution", () => {
|
|
let settingsComponentInstance = new SettingsComponent(baseProps);
|
|
expect(settingsComponentInstance.hasConflictResolution()).toEqual(undefined);
|
|
|
|
const newContainer = new Explorer();
|
|
newContainer.databaseAccount = ko.observable({
|
|
id: undefined,
|
|
name: undefined,
|
|
location: undefined,
|
|
type: undefined,
|
|
kind: undefined,
|
|
tags: undefined,
|
|
properties: {
|
|
documentEndpoint: undefined,
|
|
tableEndpoint: undefined,
|
|
gremlinEndpoint: undefined,
|
|
cassandraEndpoint: undefined,
|
|
enableMultipleWriteLocations: true,
|
|
},
|
|
});
|
|
const newCollection = { ...collection };
|
|
newCollection.container = newContainer;
|
|
newCollection.conflictResolutionPolicy = ko.observable({
|
|
mode: DataModels.ConflictResolutionMode.Custom,
|
|
conflictResolutionProcedure: undefined,
|
|
} as DataModels.ConflictResolutionPolicy);
|
|
|
|
const props = { ...baseProps };
|
|
props.settingsTab.collection = newCollection;
|
|
|
|
settingsComponentInstance = new SettingsComponent(props);
|
|
expect(settingsComponentInstance.hasConflictResolution()).toEqual(true);
|
|
});
|
|
|
|
it("save calls updateCollection, updateMongoDBCollectionThroughRP and updateOffer", async () => {
|
|
const wrapper = shallow(<SettingsComponent {...baseProps} />);
|
|
wrapper.setState({ isSubSettingsSaveable: true, isScaleSaveable: true, isMongoIndexingPolicySaveable: true });
|
|
wrapper.update();
|
|
const settingsComponentInstance = wrapper.instance() as SettingsComponent;
|
|
settingsComponentInstance.mongoDBCollectionResource = {
|
|
id: "id",
|
|
};
|
|
await settingsComponentInstance.onSaveClick();
|
|
expect(updateCollection).toBeCalled();
|
|
expect(updateMongoDBCollectionThroughRP).toBeCalled();
|
|
expect(updateOffer).toBeCalled();
|
|
});
|
|
|
|
it("revert resets state values", async () => {
|
|
const wrapper = shallow(<SettingsComponent {...baseProps} />);
|
|
wrapper.setState({ timeToLive: TtlType.OnNoDefault, throughput: 10 });
|
|
wrapper.update();
|
|
let state = wrapper.state() as SettingsComponentState;
|
|
expect(isDirty(state.timeToLive, state.timeToLiveBaseline)).toEqual(true);
|
|
expect(isDirty(state.throughput, state.throughputBaseline)).toEqual(true);
|
|
|
|
const settingsComponentInstance = wrapper.instance() as SettingsComponent;
|
|
settingsComponentInstance.onRevertClick();
|
|
state = wrapper.state() as SettingsComponentState;
|
|
expect(isDirty(state.timeToLive, state.timeToLiveBaseline)).toEqual(false);
|
|
expect(isDirty(state.throughput, state.throughputBaseline)).toEqual(false);
|
|
});
|
|
|
|
it("getAnalyticalStorageTtl", () => {
|
|
const newCollection = { ...collection };
|
|
newCollection.analyticalStorageTtl = ko.observable(10);
|
|
const props = { ...baseProps };
|
|
props.settingsTab.collection = newCollection;
|
|
const wrapper = shallow(<SettingsComponent {...props} />);
|
|
const settingsComponentInstance = wrapper.instance() as SettingsComponent;
|
|
expect(settingsComponentInstance.getAnalyticalStorageTtl()).toEqual(10);
|
|
wrapper.setState({ analyticalStorageTtlSelection: TtlType.Off });
|
|
wrapper.update();
|
|
expect(settingsComponentInstance.getAnalyticalStorageTtl()).toEqual(-1);
|
|
});
|
|
|
|
it("getUpdatedConflictResolutionPolicy", () => {
|
|
const wrapper = shallow(<SettingsComponent {...baseProps} />);
|
|
const conflictResolutionPolicyPath = "/_ts";
|
|
const conflictResolutionPolicyProcedure = "sample_sproc";
|
|
const expectSprocPath =
|
|
"/dbs/" + collection.databaseId + "/colls/" + collection.id() + "/sprocs/" + conflictResolutionPolicyProcedure;
|
|
|
|
wrapper.setState({
|
|
conflictResolutionPolicyMode: DataModels.ConflictResolutionMode.LastWriterWins,
|
|
conflictResolutionPolicyPath: conflictResolutionPolicyPath,
|
|
});
|
|
wrapper.update();
|
|
const settingsComponentInstance = wrapper.instance() as SettingsComponent;
|
|
let conflictResolutionPolicy = settingsComponentInstance.getUpdatedConflictResolutionPolicy();
|
|
expect(conflictResolutionPolicy.mode).toEqual(DataModels.ConflictResolutionMode.LastWriterWins);
|
|
expect(conflictResolutionPolicy.conflictResolutionPath).toEqual(conflictResolutionPolicyPath);
|
|
|
|
wrapper.setState({
|
|
conflictResolutionPolicyMode: DataModels.ConflictResolutionMode.Custom,
|
|
conflictResolutionPolicyProcedure: conflictResolutionPolicyProcedure,
|
|
});
|
|
wrapper.update();
|
|
conflictResolutionPolicy = settingsComponentInstance.getUpdatedConflictResolutionPolicy();
|
|
expect(conflictResolutionPolicy.mode).toEqual(DataModels.ConflictResolutionMode.Custom);
|
|
expect(conflictResolutionPolicy.conflictResolutionProcedure).toEqual(expectSprocPath);
|
|
});
|
|
});
|