diff --git a/src/internal-packages/validation/lib/components/common/bson-type-selector.jsx b/src/internal-packages/validation/lib/components/common/bson-type-selector.jsx index 717deb0df7e..27a6273b30d 100644 --- a/src/internal-packages/validation/lib/components/common/bson-type-selector.jsx +++ b/src/internal-packages/validation/lib/components/common/bson-type-selector.jsx @@ -1,8 +1,9 @@ const React = require('react'); const _ = require('lodash'); const OptionSelector = require('./option-selector'); +const semver = require('semver'); -// const debug = require('debug')('mongodb-compass:validation'); +// const debug = require('debug')('mongodb-compass:bson-type-selector'); const BSON_TYPES = [ {name: 'Double', number: 1, alias: 'double'}, @@ -28,11 +29,23 @@ const BSON_TYPES = [ {name: 'Max key', number: 127, alias: 'maxKey'} ]; - class BSONTypeSelector extends React.Component { constructor(props) { super(props); + // try catch block in case semver typeerrors while remove decimal128 + // if server is < 3.4.x + let canRemoveDecimal = false; + try { + canRemoveDecimal = semver.gt('3.4.0-rc0', this.props.serverVersion); + } catch (e) { + canRemoveDecimal = true; + } + + if (canRemoveDecimal) { + _.remove(BSON_TYPES, (type) => type.number === 19); + } + this.state = { type: null }; @@ -81,13 +94,7 @@ class BSONTypeSelector extends React.Component { */ render() { const selectedTypeName = _.get(this.state.type, 'alias', ''); - // TODO: make recentServer true if server is 3.4 < - const recentServer = true; - // remove the decimal version if not recentServer - const typeOptions = _.zipObject(_.map(_.filter(BSON_TYPES, (t) => { - // filter out decimal if server < 3.4 - return !(t.alias === 'decimal128' && !recentServer); - }), (type) => { + const typeOptions = _.zipObject(_.map(BSON_TYPES, (type) => { return [type.alias, type.name]; })); @@ -107,7 +114,8 @@ BSONTypeSelector.propTypes = { typeNumber: React.PropTypes.number, typeAlias: React.PropTypes.string, typeName: React.PropTypes.string, - onTypeClicked: React.PropTypes.func.isRequired + onTypeClicked: React.PropTypes.func, + serverVersion: React.PropTypes.string }; BSONTypeSelector.displayName = 'BSONTypeSelector'; diff --git a/src/internal-packages/validation/lib/components/rule-builder.jsx b/src/internal-packages/validation/lib/components/rule-builder.jsx index 7a398beac10..dee64bb4ec2 100644 --- a/src/internal-packages/validation/lib/components/rule-builder.jsx +++ b/src/internal-packages/validation/lib/components/rule-builder.jsx @@ -91,7 +91,7 @@ class RuleBuilder extends React.Component { renderRules() { return _.map(this.props.validationRules, (rule) => { - return ; + return ; }); } /** @@ -174,7 +174,8 @@ RuleBuilder.propTypes = { editState: React.PropTypes.oneOf(['unmodified', 'modified', 'updating', 'error', 'success']).isRequired, validationAction: React.PropTypes.oneOf(['warn', 'error']).isRequired, validationLevel: React.PropTypes.oneOf(['off', 'moderate', 'strict']).isRequired, - validationRules: React.PropTypes.array.isRequired + validationRules: React.PropTypes.array.isRequired, + serverVersion: React.PropTypes.string }; RuleBuilder.displayName = 'RuleBuilder'; diff --git a/src/internal-packages/validation/lib/components/rule-categories/type.jsx b/src/internal-packages/validation/lib/components/rule-categories/type.jsx index 7c1ddbf255e..b797afc9282 100644 --- a/src/internal-packages/validation/lib/components/rule-categories/type.jsx +++ b/src/internal-packages/validation/lib/components/rule-categories/type.jsx @@ -80,14 +80,15 @@ class RuleCategoryType extends React.Component { const typeNumber = this.props.parameters.type; return ( - + ); } } RuleCategoryType.propTypes = { id: React.PropTypes.string.isRequired, - parameters: React.PropTypes.object.isRequired + parameters: React.PropTypes.object.isRequired, + serverVersion: React.PropTypes.string }; RuleCategoryType.displayName = 'RuleCategoryType'; diff --git a/src/internal-packages/validation/lib/components/rule.jsx b/src/internal-packages/validation/lib/components/rule.jsx index 4ad1289e6d1..0c5c97a52cf 100644 --- a/src/internal-packages/validation/lib/components/rule.jsx +++ b/src/internal-packages/validation/lib/components/rule.jsx @@ -59,6 +59,7 @@ class Rule extends React.Component { : null; @@ -106,7 +107,8 @@ Rule.propTypes = { field: React.PropTypes.string.isRequired, category: React.PropTypes.string.isRequired, parameters: React.PropTypes.object.isRequired, - nullable: React.PropTypes.bool.isRequired + nullable: React.PropTypes.bool.isRequired, + serverVersion: React.PropTypes.string }; Rule.displayName = 'Rule'; diff --git a/src/internal-packages/validation/lib/components/validation.jsx b/src/internal-packages/validation/lib/components/validation.jsx index 3bfa7d00dc3..c240eae6d65 100644 --- a/src/internal-packages/validation/lib/components/validation.jsx +++ b/src/internal-packages/validation/lib/components/validation.jsx @@ -46,6 +46,7 @@ class Validation extends React.Component { validationAction={this.props.validationAction} validationLevel={this.props.validationLevel} editState={this.props.editState} + serverVersion={this.props.serverVersion} /> ) : ( @@ -86,7 +87,8 @@ Validation.propTypes = { validationAction: React.PropTypes.oneOf(['warn', 'error']).isRequired, validatorDoc: React.PropTypes.object.isRequired, validationLevel: React.PropTypes.oneOf(['off', 'moderate', 'strict']).isRequired, - validationRules: React.PropTypes.array.isRequired + validationRules: React.PropTypes.array.isRequired, + serverVersion: React.PropTypes.string }; Validation.defaultProps = { diff --git a/src/internal-packages/validation/lib/stores/index.js b/src/internal-packages/validation/lib/stores/index.js index 98a4df45dcf..3d5ce1eb4c4 100644 --- a/src/internal-packages/validation/lib/stores/index.js +++ b/src/internal-packages/validation/lib/stores/index.js @@ -54,7 +54,8 @@ const ValidationStore = Reflux.createStore({ validationAction: 'warn', // one of `warn`, `error` fetchState: 'initial', // one of `initial`, `fetching`, `success`, `error` editState: 'unmodified', // one of `unmodified`, `modified`, `updating`, `success`, `error` - isExpressibleByRules: true // boolean + isExpressibleByRules: true, // boolean + serverVersion: '' }; }, @@ -223,6 +224,11 @@ const ValidationStore = Reflux.createStore({ */ _fetchFromServer(callback) { const ns = toNS(NamespaceStore.ns); + + if (this.state.serverVersion === '') { + const serverVersion = app.instance.build.version; + this.setState({serverVersion: serverVersion}); + } app.dataService.listCollections(ns.database, {name: ns.collection}, function(err, res) { if (err) { return callback(err); diff --git a/test/validation.store.test.js b/test/validation.store.test.js index 0f1334bcf3e..b5dd1cd4178 100644 --- a/test/validation.store.test.js +++ b/test/validation.store.test.js @@ -5,7 +5,7 @@ const ValidationStore = require('../src/internal-packages/validation/lib/stores' const sinon = require('sinon'); const _ = require('lodash'); -function mockFetchFromServer(err, res, delay) { +function mockFetchFromServer(err, res, delay, serverVersion) { if (delay === undefined) { delay = 0; } @@ -14,6 +14,10 @@ function mockFetchFromServer(err, res, delay) { return callback(err, res); }, delay); }; + // the above fetchFromServer makes a call for app.instance.build.version + // which will be undefined at the time of this test so setting serverVersion + // manually here, which would otherwise be overwritten + ValidationStore.setState({serverVersion: serverVersion}); } const mockValidatorDoc = { @@ -47,6 +51,11 @@ describe('ValidationStore', function() { unsubscribe = function() {}; }); + it('check a pre 3.4 server version', function(done) { + mockFetchFromServer(null, mockValidatorDoc, 0, '3.1.9'); + expect(ValidationStore.state.serverVersion).to.be.equal('3.1.9'); + done(); + }); it('goes into {fetchState: "fetching"} when starting to fetch from server', function(done) { mockFetchFromServer(null, mockValidatorDoc);