]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6801 apply feedback
authorStas Vilchik <vilchiks@gmail.com>
Wed, 30 Sep 2015 13:12:03 +0000 (15:12 +0200)
committerStas Vilchik <vilchiks@gmail.com>
Wed, 30 Sep 2015 13:12:03 +0000 (15:12 +0200)
server/sonar-web/src/main/js/apps/permission-templates/groups-view.js
server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.jsx
server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.jsx
server/sonar-web/src/main/js/apps/permission-templates/permission-template.jsx
server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-groups.hbs
server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-users.hbs
server/sonar-web/src/main/js/apps/permission-templates/users-view.js
server/sonar-web/tests/apps/permission-templates-test.js [new file with mode: 0644]
server/sonar-web/tests/jsdom-setup.js

index 21831f45c3172c9cc8786e30f3b9dc668e42d1ff..c13d978d9d326f54d8b453b23da4c6af8f276f1c 100644 (file)
@@ -1,9 +1,10 @@
+import _ from 'underscore';
 import Modal from '../../components/common/modals';
 import '../../components/common/select-list';
 import './templates';
 
 function getSearchUrl (permission, permissionTemplate) {
-  return baseUrl + '/api/permissions/template_groups?ps=100&permission=' + permission +
+  return baseUrl + '/api/permissions/template_groups?ps=100&permission=' + permission.key +
       '&templateId=' + permissionTemplate.id;
 }
 
@@ -25,7 +26,7 @@ export default Modal.extend({
       selectUrl: baseUrl + '/api/permissions/add_group_to_template',
       deselectUrl: baseUrl + '/api/permissions/remove_group_from_template',
       extra: {
-        permission: this.options.permission,
+        permission: this.options.permission.key,
         templateId: this.options.permissionTemplate.id
       },
       selectParameter: 'groupName',
@@ -46,6 +47,7 @@ export default Modal.extend({
 
   serializeData: function () {
     return _.extend(Modal.prototype.serializeData.apply(this, arguments), {
+      permissionName: this.options.permission.name,
       permissionTemplateName: this.options.permissionTemplate.name
     });
   }
index 2cfb51b41236c3628705703d9cdeb088cc932a43..39b9ec520215b18e61fb21f3a3c73a1310f54013 100644 (file)
@@ -4,13 +4,19 @@ import QualifierIcon from '../../components/shared/qualifier-icon';
 
 export default React.createClass({
   propTypes: {
-    permissionTemplate: React.PropTypes.object.isRequired
+    permissionTemplate: React.PropTypes.object.isRequired,
+    topQualifiers: React.PropTypes.array.isRequired
   },
 
-  render() {
-    if (_.size(this.props.permissionTemplate.defaultFor) === 0) {
-      return null;
-    }
+  renderIfSingleTopQualifier() {
+    return (
+        <ul className="list-inline nowrap spacer-bottom">
+          <li>Default</li>
+        </ul>
+    );
+  },
+
+  renderIfMultipleTopQualifiers() {
     let defaults = this.props.permissionTemplate.defaultFor.map(qualifier => {
       return <li key={qualifier}><QualifierIcon qualifier={qualifier}/>&nbsp;{window.t('qualifier', qualifier)}</li>;
     });
@@ -20,5 +26,14 @@ export default React.createClass({
           {defaults}
         </ul>
     );
+  },
+
+  render() {
+    if (_.size(this.props.permissionTemplate.defaultFor) === 0) {
+      return null;
+    }
+    return this.props.topQualifiers.length === 1 ?
+        this.renderIfSingleTopQualifier() :
+        this.renderIfMultipleTopQualifiers();
   }
 });
index 6bda07a46b2777295434d736b08dfcdeec4696ff..87a75de168ba8ae686820a26745ad6838d1c70ed 100644 (file)
@@ -19,12 +19,19 @@ export default React.createClass({
     setDefaultPermissionTemplate(this.props.permissionTemplate.id, qualifier).done(() => this.props.refresh());
   },
 
-  render() {
-    let availableQualifiers = this.getAvailableQualifiers();
-    if (availableQualifiers.length === 0) {
-      return null;
-    }
+  renderIfSingleTopQualifier(availableQualifiers) {
+    let qualifiers = availableQualifiers.map(qualifier => {
+      return (
+          <span key={qualifier} className="text-middle">
+            <a onClick={this.setDefault.bind(this, qualifier)} className="button" href="#">Set Default</a>
+          </span>
+      );
+    });
 
+    return <span className="little-spacer-right">{qualifiers}</span>;
+  },
+
+  renderIfMultipleTopQualifiers(availableQualifiers) {
     let qualifiers = availableQualifiers.map(qualifier => {
       return (
           <li key={qualifier}>
@@ -43,5 +50,16 @@ export default React.createClass({
           <ul className="dropdown-menu">{qualifiers}</ul>
         </span>
     );
+  },
+
+  render() {
+    let availableQualifiers = this.getAvailableQualifiers();
+    if (availableQualifiers.length === 0) {
+      return null;
+    }
+
+    return this.props.topQualifiers.length === 1 ?
+        this.renderIfSingleTopQualifier(availableQualifiers) :
+        this.renderIfMultipleTopQualifiers(availableQualifiers);
   }
 });
index 71645b34d756c07ecf5bc31e372c911cf1653523..ced79afd895a5d0812ef3dd613f53ae59b5788e9 100644 (file)
@@ -72,7 +72,7 @@ export default React.createClass({
                 <td className="spacer-right">Users</td>
                 <td className="spacer-left bordered-left">{p.usersCount}</td>
                 <td className="spacer-left">
-                  <a onClick={this.showUsers.bind(this, p.key)} className="icon-bullet-list" title="Update Users"
+                  <a onClick={this.showUsers.bind(this, p)} className="icon-bullet-list" title="Update Users"
                      data-toggle="tooltip" href="#"></a>
                 </td>
               </tr>
@@ -80,7 +80,7 @@ export default React.createClass({
                 <td className="spacer-right">Groups</td>
                 <td className="spacer-left bordered-left">{p.groupsCount}</td>
                 <td className="spacer-left">
-                  <a onClick={this.showGroups.bind(this, p.key)} className="icon-bullet-list" title="Update Users"
+                  <a onClick={this.showGroups.bind(this, p)} className="icon-bullet-list" title="Update Users"
                      data-toggle="tooltip" href="#"></a>
                 </td>
               </tr>
@@ -97,7 +97,9 @@ export default React.createClass({
           {permissions}
           <td className="thin text-right">
             {this.renderAssociation()}
-            <Defaults permissionTemplate={this.props.permissionTemplate}/>
+            <Defaults
+                permissionTemplate={this.props.permissionTemplate}
+                topQualifiers={this.props.topQualifiers}/>
             <div className="nowrap">
               <SetDefaults
                   permissionTemplate={this.props.permissionTemplate}
index 3301ece4ca5cf5ed26a41b582b1215080f0bb374..d81cb5d5337e09d029665db0bf17ec27e0b0c37f 100644 (file)
@@ -1,5 +1,5 @@
 <div class="modal-head">
-  <h2>Update Groups of "{{permissionTemplateName}}"</h2>
+  <h2>Update Groups for "{{permissionName}}" Permission of "{{permissionTemplateName}}" Template</h2>
 </div>
 <div class="modal-body">
   <div class="js-modal-messages"></div>
index d51f89a5e3417cba64c3701e4830e36a64536a1b..883af51cfec7ffd81c832447fc5acd69ede3be07 100644 (file)
@@ -1,5 +1,5 @@
 <div class="modal-head">
-  <h2>Update Users of "{{permissionTemplateName}}"</h2>
+  <h2>Update Users for "{{permissionName}}" Permission of "{{permissionTemplateName}}" Template</h2>
 </div>
 <div class="modal-body">
   <div class="js-modal-messages"></div>
index 31275f25b6f3001bca5351e5560cb8044021303f..6c6fa5f90e4dccce5ac129e625076cacf34356ce 100644 (file)
@@ -1,3 +1,4 @@
+import _ from 'underscore';
 import Modal from '../../components/common/modals';
 import '../../components/common/select-list';
 import './templates';
@@ -7,7 +8,7 @@ export default Modal.extend({
 
   onRender: function () {
     this._super();
-    var searchUrl = baseUrl + '/api/permissions/template_users?ps=100&permission=' + this.options.permission +
+    var searchUrl = baseUrl + '/api/permissions/template_users?ps=100&permission=' + this.options.permission.key +
         '&templateId=' + this.options.permissionTemplate.id;
     new window.SelectList({
       el: this.$('#permission-templates-users'),
@@ -22,7 +23,7 @@ export default Modal.extend({
       selectUrl: baseUrl + '/api/permissions/add_user_to_template',
       deselectUrl: baseUrl + '/api/permissions/remove_user_from_template',
       extra: {
-        permission: this.options.permission,
+        permission: this.options.permission.key,
         templateId: this.options.permissionTemplate.id
       },
       selectParameter: 'login',
@@ -43,6 +44,7 @@ export default Modal.extend({
 
   serializeData: function () {
     return _.extend(Modal.prototype.serializeData.apply(this, arguments), {
+      permissionName: this.options.permission.name,
       permissionTemplateName: this.options.permissionTemplate.name
     });
   }
diff --git a/server/sonar-web/tests/apps/permission-templates-test.js b/server/sonar-web/tests/apps/permission-templates-test.js
new file mode 100644 (file)
index 0000000..d7cc02f
--- /dev/null
@@ -0,0 +1,85 @@
+/* eslint no-unused-expressions: 0 */
+import React from 'react/addons';
+import Defaults from '../../src/main/js/apps/permission-templates/permission-template-defaults';
+import SetDefaults from '../../src/main/js/apps/permission-templates/permission-template-set-defaults';
+
+let TestUtils = React.addons.TestUtils;
+let chai = require('chai');
+let expect = chai.expect;
+
+describe('Permission Templates', function () {
+  describe('Defaults', () => {
+    it('should display one qualifier', () => {
+      let permissionTemplate = { defaultFor: ['VW'] },
+          topQualifiers = ['TRK', 'VW'];
+      let result = TestUtils.renderIntoDocument(
+          <Defaults permissionTemplate={permissionTemplate} topQualifiers={topQualifiers}/>
+      );
+      expect(TestUtils.scryRenderedDOMComponentsWithClass(result, 'icon-qualifier-trk')).to.be.empty;
+      expect(TestUtils.scryRenderedDOMComponentsWithClass(result, 'icon-qualifier-vw')).to.have.length(1);
+    });
+
+    it('should display two qualifiers', () => {
+      let permissionTemplate = { defaultFor: ['TRK', 'VW'] },
+          topQualifiers = ['TRK', 'VW'];
+      let result = TestUtils.renderIntoDocument(
+          <Defaults permissionTemplate={permissionTemplate} topQualifiers={topQualifiers}/>
+      );
+      expect(TestUtils.scryRenderedDOMComponentsWithClass(result, 'icon-qualifier-trk')).to.have.length(1);
+      expect(TestUtils.scryRenderedDOMComponentsWithClass(result, 'icon-qualifier-vw')).to.have.length(1);
+    });
+
+    it('should omit "project" if there is only one qualifier', () => {
+      let permissionTemplate = { defaultFor: ['TRK'] },
+          topQualifiers = ['TRK'];
+      let result = TestUtils.renderIntoDocument(
+          <Defaults permissionTemplate={permissionTemplate} topQualifiers={topQualifiers}/>
+      );
+      expect(TestUtils.scryRenderedDOMComponentsWithClass(result, 'icon-qualifier-trk')).to.be.empty;
+    });
+  });
+
+  describe('SetDefaults', () => {
+    var refresh = function () {};
+
+    it('should display a dropdown with one option', () => {
+      let permissionTemplate = { defaultFor: ['VW'] },
+          topQualifiers = ['TRK', 'VW'];
+      let result = TestUtils.renderIntoDocument(
+          <SetDefaults permissionTemplate={permissionTemplate} topQualifiers={topQualifiers} refresh={refresh}/>
+      );
+      expect(TestUtils.scryRenderedDOMComponentsWithClass(result, 'dropdown')).to.have.length(1);
+      expect(TestUtils.scryRenderedDOMComponentsWithTag(result, 'a')).to.have.length(1);
+    });
+
+    it('should display a dropdown with two options', () => {
+      let permissionTemplate = { defaultFor: [] },
+          topQualifiers = ['TRK', 'VW'];
+      let result = TestUtils.renderIntoDocument(
+          <SetDefaults permissionTemplate={permissionTemplate} topQualifiers={topQualifiers} refresh={refresh}/>
+      );
+      expect(TestUtils.scryRenderedDOMComponentsWithClass(result, 'dropdown')).to.have.length(1);
+      expect(TestUtils.scryRenderedDOMComponentsWithTag(result, 'a')).to.have.length(2);
+    });
+
+    it('should not display a dropdown', () => {
+      let permissionTemplate = { defaultFor: ['TRK', 'VW'] },
+          topQualifiers = ['TRK', 'VW'];
+      let result = TestUtils.renderIntoDocument(
+          <SetDefaults permissionTemplate={permissionTemplate} topQualifiers={topQualifiers} refresh={refresh}/>
+      );
+      expect(TestUtils.scryRenderedDOMComponentsWithClass(result, 'dropdown')).to.be.empty;
+      expect(TestUtils.scryRenderedDOMComponentsWithTag(result, 'a')).to.be.empty;
+    });
+
+    it('should omit dropdown if there is only one qualifier', () => {
+      let permissionTemplate = { defaultFor: [] },
+          topQualifiers = ['TRK'];
+      let result = TestUtils.renderIntoDocument(
+          <SetDefaults permissionTemplate={permissionTemplate} topQualifiers={topQualifiers} refresh={refresh}/>
+      );
+      expect(TestUtils.scryRenderedDOMComponentsWithClass(result, 'dropdown')).to.be.empty;
+      expect(TestUtils.scryRenderedDOMComponentsWithTag(result, 'a')).to.have.length(1);
+    });
+  });
+});
index ade0fc3aebc172d67d83fd2cd94b3bcc8bc50078..e911cbeb95bdbc5a4763d5483970be5df904421b 100644 (file)
@@ -1,3 +1,5 @@
+/* globals global: false */
+
 var jsdom = require('jsdom');
 
 // A super simple DOM ready for React to render into
@@ -7,3 +9,7 @@ global.window = document.defaultView;
 global.navigator = document.defaultView.navigator;
 
 global.window.baseUrl = '';
+global.window.t = global.window.tp = function () {
+  var args = Array.prototype.slice.call(arguments, 0);
+  return args.join('.');
+};