diff --git a/src/js/components/modals/InstallPackageModal.js b/src/js/components/modals/InstallPackageModal.js index 4869a3359d..c00a6c34bf 100644 --- a/src/js/components/modals/InstallPackageModal.js +++ b/src/js/components/modals/InstallPackageModal.js @@ -4,7 +4,6 @@ import mixin from "reactjs-mixin"; import React from "react"; import { StoreMixin } from "mesosphere-shared-reactjs"; -import BetaOptInUtil from "../../utils/BetaOptInUtil"; import CosmosErrorHeader from "../CosmosErrorHeader"; import CosmosErrorMessage from "../CosmosErrorMessage"; import CosmosPackagesStore from "../../stores/CosmosPackagesStore"; @@ -17,6 +16,7 @@ import Loader from "../Loader"; import ReviewConfig from "../ReviewConfig"; import SchemaForm from "../SchemaForm"; import SchemaUtil from "../../utils/SchemaUtil"; +import SchemaFormUtil from "../../utils/SchemaFormUtil"; import StringUtil from "../../utils/StringUtil"; import TabsMixin from "../../mixins/TabsMixin"; import UniversePackage from "../../structs/UniversePackage"; @@ -25,7 +25,6 @@ const PREINSTALL_NOTES_CHAR_LIMIT = 140; const METHODS_TO_BIND = [ "getAdvancedSubmit", - "handleAcceptBetaTerms", "handleChangeTab", "handleInstallPackage", "handleAdvancedFormChange", @@ -39,8 +38,7 @@ class InstallPackageModal super(...arguments); this.tabs_tabs = { - betaTerms: "BetaTerms", - defaultInstall: "DefaultInstall", + installError: "InstallError", advancedInstall: "AdvancedInstall", reviewAdvancedConfig: "ReviewAdvancedConfig", packageInstalled: "PackageInstalled" @@ -54,7 +52,7 @@ class InstallPackageModal }); this.state = { - currentTab: "defaultInstall", + currentTab: "reviewAdvancedConfig", schemaIncorrect: false, truncatedPreInstallNotes: true }; @@ -95,34 +93,10 @@ class InstallPackageModal // Reset our trigger submit for advanced install this.triggerAdvancedSubmit = undefined; this.setState({ - currentTab: "defaultInstall", + currentTab: "reviewAdvancedConfig", truncatedPreInstallNotes: true }); - - return; - } - - // If opening - - if (nextProps.isBetaPackage) { - this.setState({ - betaTermsAccepted: false, - betaOptInProperties: BetaOptInUtil.getProperty( - nextProps.cosmosPackage.getConfig() - ), - currentTab: "betaTerms" - }); - - return; } - - if (nextProps.advancedConfig) { - this.setState({ currentTab: "advancedInstall" }); - - return; - } - - this.handleInstallPackage(); } componentDidUpdate() { @@ -156,7 +130,7 @@ class InstallPackageModal installError, pendingRequest: false }); - this.setState({ currentTab: "defaultInstall" }); + this.setState({ currentTab: "installError" }); } onCosmosPackagesStoreInstallSuccess(name, version, appId) { @@ -168,20 +142,6 @@ class InstallPackageModal this.setState({ currentTab: "packageInstalled" }); } - handleAcceptBetaTerms() { - if (this.props.advancedConfig) { - // Accept terms and move to advanced install tab - this.setState({ - betaTermsAccepted: true, - currentTab: "advancedInstall" - }); - - return; - } - // Auto-install - this.setState({ betaTermsAccepted: true }, this.handleInstallPackage); - } - handleAdvancedFormChange(formObject) { this.internalStorage_update({ hasFormErrors: !formObject.isValidated }); this.forceUpdate(); @@ -209,15 +169,10 @@ class InstallPackageModal } handleInstallPackage() { - const { betaTermsAccepted } = this.state; - const { cosmosPackage, isBetaPackage } = this.props; + const { cosmosPackage } = this.props; const name = cosmosPackage.getName(); const version = cosmosPackage.getVersion(); - let configuration = this.getPackageConfiguration(); - - if (isBetaPackage && betaTermsAccepted) { - configuration = BetaOptInUtil.setBetaOptIn(configuration); - } + const configuration = this.getPackageConfiguration(); CosmosPackagesStore.installPackage(name, version, configuration); this.internalStorage_update({ pendingRequest: true }); @@ -240,25 +195,20 @@ class InstallPackageModal getPackageConfiguration() { const { advancedConfiguration } = this.internalStorage_get(); - const { currentTab } = this.state; const { cosmosPackage } = this.props; - const isAdvancedInstall = - currentTab === "advancedInstall" || currentTab === "reviewAdvancedConfig"; - - if (isAdvancedInstall && advancedConfiguration) { + if (advancedConfiguration) { return advancedConfiguration; } - if (isAdvancedInstall && !advancedConfiguration) { - return SchemaUtil.definitionToJSONDocument( - SchemaUtil.schemaToMultipleDefinition({ - schema: cosmosPackage.getConfig() - }) - ); - } + const definitions = SchemaUtil.schemaToMultipleDefinition({ + schema: cosmosPackage.getConfig() + }); - return {}; + return SchemaFormUtil.processFormModel( + SchemaUtil.definitionToJSONDocument(definitions), + definitions + ); } getLoadingScreen() { @@ -336,44 +286,8 @@ class InstallPackageModal ); } - renderBetaTermsTabView() { - const { title, description } = this.state.betaOptInProperties; - - return ( -
-
-
-

- {title} -

-

- {description} -

-
-
-
-
- - -
-
-
- ); - } - - renderDefaultInstallTabView() { - const { - descriptionError, - pendingRequest, - installError - } = this.internalStorage_get(); + renderInstallErrorTabView() { + const { descriptionError, installError } = this.internalStorage_get(); const { cosmosPackage } = this.props; const preInstallNotes = cosmosPackage.getPreInstallNotes(); const name = cosmosPackage.getName(); @@ -387,10 +301,6 @@ class InstallPackageModal return this.getInstallErrorScreen(); } - if (pendingRequest) { - return this.getLoadingScreen(); - } - let error; if (descriptionError) { error = ( @@ -443,10 +353,10 @@ class InstallPackageModal @@ -458,7 +368,7 @@ class InstallPackageModal const { cosmosPackage } = this.props; const name = cosmosPackage.getName(); const version = cosmosPackage.getVersion(); - let buttonText = "Deploy"; + let buttonText = "Run Service"; if (pendingRequest) { buttonText = "Deploying..."; @@ -474,19 +384,24 @@ class InstallPackageModal />
- - +
+ + +
@@ -570,19 +485,13 @@ class InstallPackageModal getModalContents() { const { currentTab, schemaIncorrect } = this.state; - const { cosmosPackage, isBetaPackage } = this.props; + const { cosmosPackage } = this.props; if (schemaIncorrect) { return this.getIncorrectSchemaWarning(cosmosPackage); } - let schema = cosmosPackage.getConfig(); - - if (isBetaPackage) { - // Remove beta opt-in from schema for better UX - schema = BetaOptInUtil.filterProperty(cosmosPackage.getConfig()); - } - + const schema = cosmosPackage.getConfig(); const name = cosmosPackage.getName(); const version = cosmosPackage.getVersion(); const advancedConfigClasses = classNames( @@ -649,16 +558,12 @@ class InstallPackageModal } InstallPackageModal.defaultProps = { - advancedConfig: false, - isBetaPackage: false, onClose() {}, open: false }; InstallPackageModal.propTypes = { - advancedConfig: React.PropTypes.bool, cosmosPackage: React.PropTypes.instanceOf(UniversePackage).isRequired, - isBetaPackage: React.PropTypes.bool, open: React.PropTypes.bool, onClose: React.PropTypes.func }; diff --git a/src/js/pages/catalog/PackageDetailTab.js b/src/js/pages/catalog/PackageDetailTab.js index 8b3bbe958c..e05af67916 100644 --- a/src/js/pages/catalog/PackageDetailTab.js +++ b/src/js/pages/catalog/PackageDetailTab.js @@ -6,7 +6,6 @@ import React from "react"; /* eslint-enable no-unused-vars */ import { StoreMixin } from "mesosphere-shared-reactjs"; -import BetaOptInUtil from "../../utils/BetaOptInUtil"; import Breadcrumb from "../../components/Breadcrumb"; import BreadcrumbTextContent from "../../components/BreadcrumbTextContent"; import CosmosPackagesStore from "../../stores/CosmosPackagesStore"; @@ -43,11 +42,7 @@ const PackageDetailBreadcrumbs = ({ cosmosPackage }) => { return ; }; -const METHODS_TO_BIND = [ - "handleInstallModalClose", - "handleConfigureInstallModalOpen", - "handleInstallModalOpen" -]; +const METHODS_TO_BIND = ["handleInstallModalClose", "handleInstallModalOpen"]; class PackageDetailTab extends mixin(StoreMixin) { constructor() { @@ -100,11 +95,7 @@ class PackageDetailTab extends mixin(StoreMixin) { } handleInstallModalOpen() { - this.setState({ openInstallModal: true, advancedConfig: false }); - } - - handleConfigureInstallModalOpen() { - this.setState({ openInstallModal: true, advancedConfig: true }); + this.setState({ openInstallModal: true }); } getErrorScreen() { @@ -223,17 +214,11 @@ class PackageDetailTab extends mixin(StoreMixin) { return (
-
); @@ -343,8 +328,6 @@ class PackageDetailTab extends mixin(StoreMixin) { diff --git a/src/js/utils/BetaOptInUtil.js b/src/js/utils/BetaOptInUtil.js deleted file mode 100644 index fe177ece10..0000000000 --- a/src/js/utils/BetaOptInUtil.js +++ /dev/null @@ -1,85 +0,0 @@ -import Util from "./Util"; - -// SDK sets/reads this property within package config. -const BETA_OPTIN_PROPERTY_NAME = "beta-optin"; -const DOT_NOTATION_SCHEMA_PATH = "properties.service.properties.beta-optin"; - -const BetaOptInUtil = { - /** - * Finds beta-optin property within cosmos package config schema. - * - * @param {Object} configSchema - cosmos package config schema - * @return {Boolean} Returns true if configSchema contains beta-optin property - */ - isBeta(configSchema) { - return BetaOptInUtil.getProperty(configSchema) != null; - }, - - /** - * Get beta-optin property within config Object - * - * @param {Object} configSchema - cosmos package config schema - * @return {Object} Returns property if found or null. - */ - getProperty(configSchema) { - if (!Util.isObject(configSchema)) { - return null; - } - - return Util.findNestedPropertyInObject( - configSchema, - DOT_NOTATION_SCHEMA_PATH - ); - }, - - /** - * Removes beta-optin property within config schema - * - * @param {Object} configSchema - cosmos package config schema - * @return {Object} Returns new config Object without opt-in property - */ - filterProperty(configSchema) { - if (!BetaOptInUtil.isBeta(configSchema)) { - return configSchema; - } - - const filteredConfig = Util.deepCopy(configSchema); - const service = filteredConfig["properties"]["service"]; - - // Filter out required property as this will cause validation - // errors in the schema form if we remove the beta-optin schema Object - if (Array.isArray(service.required)) { - service.required = service.required.filter(function(key) { - return key !== BETA_OPTIN_PROPERTY_NAME; - }); - } - delete service["properties"][BETA_OPTIN_PROPERTY_NAME]; - - return filteredConfig; - }, - - /** - * Inserts beta-optin property at path within config model - * - * @param {Object} config - cosmos package config model - * @return {Object} Returns new cosmos package config with beta - * opt-in property set to true - */ - setBetaOptIn(config) { - if (!Util.isObject(config)) { - return config; - } - - const betaConfig = Util.deepCopy(config); - - if (!Util.isObject(betaConfig["service"])) { - betaConfig["service"] = {}; - } - - betaConfig["service"][BETA_OPTIN_PROPERTY_NAME] = true; - - return betaConfig; - } -}; - -module.exports = BetaOptInUtil; diff --git a/src/js/utils/SchemaUtil.js b/src/js/utils/SchemaUtil.js index add12756bd..c3c901a65e 100644 --- a/src/js/utils/SchemaUtil.js +++ b/src/js/utils/SchemaUtil.js @@ -268,7 +268,7 @@ const SchemaUtil = { Object.keys(schemaProperties).forEach(function(topLevelProp) { const topLevelPropertyObject = schemaProperties[topLevelProp]; - const secondLevelProperties = topLevelPropertyObject.properties; + const secondLevelProperties = topLevelPropertyObject.properties || {}; const requiredProps = topLevelPropertyObject.required; const definitionForm = (multipleDefinition[topLevelProp] = {}); diff --git a/src/js/utils/__tests__/BetaOptInUtil-test.js b/src/js/utils/__tests__/BetaOptInUtil-test.js deleted file mode 100644 index dac1e93707..0000000000 --- a/src/js/utils/__tests__/BetaOptInUtil-test.js +++ /dev/null @@ -1,101 +0,0 @@ -const BetaOptInUtil = require("../BetaOptInUtil"); - -describe("BetaOptInUtil", function() { - const betaSchema = { - properties: { - service: { - required: ["beta-optin", "foo"], - properties: { - "beta-optin": { - type: "boolean" - }, - foo: { - type: "string" - } - } - } - } - }; - - const nonBetaSchema = { - properties: { - service: { - required: ["foo"], - properties: { - foo: { - type: "string" - } - } - } - } - }; - - describe("#isBeta", function() { - it("returns true for beta package schema", function() { - expect(BetaOptInUtil.isBeta(betaSchema)).toEqual(true); - }); - - it("returns false for non-beta package schema", function() { - expect(BetaOptInUtil.isBeta(nonBetaSchema)).toEqual(false); - }); - }); - - describe("#getProperty", function() { - it("returns beta-optin property for beta package schema", function() { - expect(BetaOptInUtil.getProperty(betaSchema)).toEqual({ - type: "boolean" - }); - }); - - it("returns undefined for non-beta package schema", function() { - expect(BetaOptInUtil.getProperty(nonBetaSchema)).toEqual(undefined); - }); - }); - - describe("#filterProperty", function() { - it("does not mutuate original schema", function() { - expect(BetaOptInUtil.filterProperty(betaSchema)).not.toEqual(betaSchema); - }); - - it("returns schema object with beta-optin removed for beta package schema", function() { - expect(BetaOptInUtil.filterProperty(betaSchema)).toEqual(nonBetaSchema); - }); - - it("returns original package schema for non-beta package schema", function() { - expect(BetaOptInUtil.filterProperty(nonBetaSchema)).toEqual( - nonBetaSchema - ); - }); - }); - - describe("#setBetaOptIn", function() { - it("returns config argument if config is not an object", function() { - expect(BetaOptInUtil.setBetaOptIn()).toEqual(undefined); - }); - - it("returns config with beta-optin set to true on emtpy config", function() { - expect(BetaOptInUtil.setBetaOptIn({})).toEqual({ - service: { - "beta-optin": true - } - }); - }); - - it("returns config with beta-optin set to true on existing config", function() { - expect( - BetaOptInUtil.setBetaOptIn({ - foo: "bar", - service: { - foobar: "baz" - } - }) - ).toEqual({ - foo: "bar", - service: { - "beta-optin": true, - foobar: "baz" - } - }); - }); - }); -}); diff --git a/src/js/utils/__tests__/SchemaUtil-test.js b/src/js/utils/__tests__/SchemaUtil-test.js index 45bcd33434..74af1f8be5 100644 --- a/src/js/utils/__tests__/SchemaUtil-test.js +++ b/src/js/utils/__tests__/SchemaUtil-test.js @@ -48,6 +48,29 @@ describe("SchemaUtil", function() { }); }); + describe("schema with no second level properties", function() { + const $scope = {}; + beforeEach(function() { + var schema = { + properties: { + application: { + description: "This is a description" + } + } + }; + + $scope.subheaderRender = jasmine.createSpy(); + $scope.result = SchemaUtil.schemaToMultipleDefinition({ + schema, + renderSubheader: $scope.subheaderRender + }); + }); + + it("creates the definition", function() { + expect($scope.result.application.definition).toEqual([]); + }); + }); + describe("nested schema", function() { beforeEach(function() { var schema = { diff --git a/system-tests/universe/test-universe.js b/system-tests/universe/test-universe.js index 4d28a5d35a..4c99d7a924 100644 --- a/system-tests/universe/test-universe.js +++ b/system-tests/universe/test-universe.js @@ -22,10 +22,10 @@ describe("Universe", function() { cy.contains("Certified"); // Click the easy deploy - cy.contains("Deploy").click(); + cy.contains("Review & Run").click(); // Wait for the new service to deploy - cy.get(".modal").contains("Success"); + cy.get(".modal").contains("Run Service").click(); cy.get(".modal").contains("Go To Service").click(); // Go to the root services page @@ -50,7 +50,10 @@ describe("Universe", function() { cy.contains("Certified"); // Click the easy deploy - cy.contains("Deploy").click(); + cy.contains("Review & Run").click(); + + // Wait for the new service to deploy + cy.get(".modal").contains("Run Service").click(); // Should give error that package already installed cy @@ -69,9 +72,10 @@ describe("Universe", function() { cy.contains("Community"); // Click the easy deploy - cy.contains("Deploy").click(); + cy.contains("Review & Run").click(); // Wait for the new service to deploy + cy.get(".modal").contains("Run Service").click(); cy.get(".modal").contains("Success"); cy.get(".modal").contains("Go To Service").click(); @@ -97,14 +101,15 @@ describe("Universe", function() { // Check that this package is certified cy.contains("Certified"); - cy.contains("Configure").click(); + cy.contains("Review & Run").click(); + cy.get(".modal").contains("Edit").click(); // Find name input cy.get(".modal input[name=name]").clear().type(serviceName); // Wait for the new service to deploy - cy.get(".modal").contains("Review and Deploy").click(); - cy.get(".modal").contains("Deploy").click(); + cy.get(".modal").contains("Review & Run").click(); + cy.get(".modal").contains("Run Service").click(); cy.get(".modal").contains("Go To Service").click(); // Go to the root services page @@ -129,14 +134,15 @@ describe("Universe", function() { // Check that this package is certified cy.contains("Community"); - cy.contains("Configure").click(); + cy.contains("Review & Run").click(); + cy.get(".modal").contains("Edit").click(); // Find name input cy.get(".modal input[name=name]").clear().type(serviceName); // Wait for the new service to deploy - cy.get(".modal").contains("Review and Deploy").click(); - cy.get(".modal").contains("Deploy").click(); + cy.get(".modal").contains("Review & Run").click(); + cy.get(".modal").contains("Run Service").click(); cy.get(".modal").contains("Go To Service").click(); // Go to the root services page diff --git a/tests/pages/catalog/packages/PackagesTab-cy.js b/tests/pages/catalog/packages/PackagesTab-cy.js index 520d765bff..c84d3d6473 100644 --- a/tests/pages/catalog/packages/PackagesTab-cy.js +++ b/tests/pages/catalog/packages/PackagesTab-cy.js @@ -150,7 +150,7 @@ describe("Packages Tab", function() { it("should open the modal when the panel button is clicked", function() { cy.get(".panel").contains("arangodb").click(); - cy.get(".button.button-primary").contains("Deploy").click(); + cy.get(".button.button-primary").contains("Review & Run").click(); cy.get(".modal").should(function($modal) { expect($modal.length).to.equal(1);