aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2015-04-10 16:50:10 +0200
committerStas Vilchik <vilchiks@gmail.com>2015-04-10 16:54:24 +0200
commit75fddb319b1c5de8fea587573bbd2a258235bfe1 (patch)
tree13da917e3d30df69a47c77d23b71157552464c26 /server/sonar-web/src
parentf8c9d04395b645b193926e4fb46fd81a2edc9299 (diff)
downloadsonarqube-75fddb319b1c5de8fea587573bbd2a258235bfe1.tar.gz
sonarqube-75fddb319b1c5de8fea587573bbd2a258235bfe1.zip
SONAR-5851 add inheritance details
Diffstat (limited to 'server/sonar-web/src')
-rw-r--r--server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-change-profile-parent.hbs21
-rw-r--r--server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-profile-details.hbs59
-rw-r--r--server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-profile.hbs4
-rw-r--r--server/sonar-web/src/main/js/quality-profiles/change-profile-parent-view.js80
-rw-r--r--server/sonar-web/src/main/js/quality-profiles/controller.js17
-rw-r--r--server/sonar-web/src/main/js/quality-profiles/delete-profile-view.js1
-rw-r--r--server/sonar-web/src/main/js/quality-profiles/helpers.js26
-rw-r--r--server/sonar-web/src/main/js/quality-profiles/profile-details-view.js33
-rw-r--r--server/sonar-web/src/main/js/quality-profiles/profile-view.js5
-rw-r--r--server/sonar-web/src/main/less/components/alerts.less5
-rw-r--r--server/sonar-web/src/main/less/init/icons.less1
-rw-r--r--server/sonar-web/src/main/less/init/misc.less4
-rw-r--r--server/sonar-web/src/test/js/quality-profiles.js119
-rw-r--r--server/sonar-web/src/test/json/quality-profiles/inheritance-change-parent.json23
-rw-r--r--server/sonar-web/src/test/json/quality-profiles/inheritance-changed-parent.json22
-rw-r--r--server/sonar-web/src/test/json/quality-profiles/inheritance-plus.json23
-rw-r--r--server/sonar-web/src/test/json/quality-profiles/inheritance.json5
-rw-r--r--server/sonar-web/src/test/json/quality-profiles/search-change-parent.json76
-rw-r--r--server/sonar-web/src/test/json/quality-profiles/search-changed-parent.json76
-rw-r--r--server/sonar-web/src/test/json/quality-profiles/search-inheritance.json68
20 files changed, 662 insertions, 6 deletions
diff --git a/server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-change-profile-parent.hbs b/server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-change-profile-parent.hbs
new file mode 100644
index 00000000000..9cbb1778a7f
--- /dev/null
+++ b/server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-change-profile-parent.hbs
@@ -0,0 +1,21 @@
+<form id="change-profile-parent-form">
+ <div class="modal-head">
+ <h2>{{t 'quality_profiles.change_parent'}}</h2>
+ </div>
+ <div class="modal-body">
+ <div class="js-modal-messages"></div>
+ <div class="modal-field">
+ <label for="change-profile-parent">Parent: <em class="mandatory">*</em></label>
+ <select id="change-profile-parent" name="parentKey">
+ <option value="">{{t 'none'}}</option>
+ {{#each profiles}}
+ <option value="{{key}}">{{name}}</option>
+ {{/each}}
+ </select>
+ </div>
+ </div>
+ <div class="modal-foot">
+ <button id="change-profile-parent-submit">{{t 'change_verb'}}</button>
+ <a href="#" class="js-modal-close" id="change-profile-parent-cancel">{{t 'cancel'}}</a>
+ </div>
+</form>
diff --git a/server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-profile-details.hbs b/server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-profile-details.hbs
index 4409201bcd2..ea796d3189b 100644
--- a/server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-profile-details.hbs
+++ b/server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-profile-details.hbs
@@ -27,8 +27,63 @@
<hr class="spacer-top spacer-bottom">
-<h3>{{t 'quality_profiles.profile_inheritance'}}</h3>
-<p class="alert alert-warning">Coming soon...</p>
+<div id="quality-profile-inheritance">
+ <header class="page-header">
+ <h3 class="page-title">{{t 'quality_profiles.profile_inheritance'}}</h3>
+ <div class="page-actions">
+ <div class="button-group">
+ <button id="quality-profile-change-parent">{{t 'quality_profiles.change_parent'}}</button>
+ </div>
+ </div>
+ </header>
+ <div class="text-center">
+ {{#notEmpty ancestors}}
+ <ul id="quality-profile-ancestors">
+ {{#eachReverse ancestors}}
+ <li>
+ <div class="alert alert-inline alert-info">
+ <h6><a class="js-profile" data-key="{{key}}" href="{{profileUrl key}}">{{name}}</a></h6>
+ <p class="note">{{tp 'quality_profile.x_active_rules' activeRuleCount}}</p>
+ {{#if overridingRuleCount}}
+ <p class="note">{{tp 'quality_profiles.x_overridden_rules' overridingRuleCount}}</p>
+ {{/if}}
+ </div>
+ <div class="spacer-top spacer-bottom">
+ <i class="icon-move-down"></i>
+ </div>
+ </li>
+ {{/eachReverse}}
+ </ul>
+ {{/notEmpty}}
+
+ <div id="quality-profile-inheritance-current" class="alert alert-inline alert-success">
+ <h6>{{name}}</h6>
+ <p class="note">{{tp 'quality_profile.x_active_rules' activeRuleCount}}</p>
+ {{#if overridingRuleCount}}
+ <p class="note">{{tp 'quality_profiles.x_overridden_rules' overridingRuleCount}}</p>
+ {{/if}}
+ </div>
+
+ {{#notEmpty children}}
+ <div class="spacer-top spacer-bottom">
+ <i class="icon-move-down"></i>
+ </div>
+ <ul id="quality-profile-children" class="list-inline">
+ {{#eachReverse children}}
+ <li>
+ <div class="alert alert-inline alert-info">
+ <h6><a class="js-profile" data-key="{{key}}" href="{{profileUrl key}}">{{name}}</a></h6>
+ <p class="note">{{tp 'quality_profile.x_active_rules' activeRuleCount}}</p>
+ {{#if overridingRuleCount}}
+ <p class="note">{{tp 'quality_profiles.x_overridden_rules' overridingRuleCount}}</p>
+ {{/if}}
+ </div>
+ </li>
+ {{/eachReverse}}
+ </ul>
+ {{/notEmpty}}
+ </div>
+</div>
<hr class="spacer-top spacer-bottom">
diff --git a/server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-profile.hbs b/server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-profile.hbs
index 0eb92a7ff7c..8c8fbecc3eb 100644
--- a/server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-profile.hbs
+++ b/server/sonar-web/src/main/hbs/quality-profiles/quality-profiles-profile.hbs
@@ -1,3 +1,7 @@
+{{#if isInherited}}
+ <i class="icon-inheritance" title="{{tp 'quality_profiles.inherits' parentName}}"
+ data-toggle="tooltip" data-placement="bottom"></i>
+{{/if}}
{{name}}
{{#if isDefault}}
<span class="note pull-right">{{t 'default'}}</span>
diff --git a/server/sonar-web/src/main/js/quality-profiles/change-profile-parent-view.js b/server/sonar-web/src/main/js/quality-profiles/change-profile-parent-view.js
new file mode 100644
index 00000000000..27a0611248a
--- /dev/null
+++ b/server/sonar-web/src/main/js/quality-profiles/change-profile-parent-view.js
@@ -0,0 +1,80 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+define([
+ 'common/modal-form',
+ 'templates/quality-profiles'
+], function (ModalFormView) {
+
+ var $ = jQuery;
+
+ return ModalFormView.extend({
+ template: Templates['quality-profiles-change-profile-parent'],
+
+ onRender: function () {
+ ModalFormView.prototype.onRender.apply(this, arguments);
+ this.$('select').select2({
+ width: '250px',
+ minimumResultsForSearch: 50
+ });
+ },
+
+ onFormSubmit: function () {
+ ModalFormView.prototype.onFormSubmit.apply(this, arguments);
+ this.sendRequest();
+ },
+
+ sendRequest: function () {
+ var that = this,
+ url = baseUrl + '/api/qualityprofiles/change_parent',
+ parent = this.$('#change-profile-parent').val(),
+ options = {
+ profileKey: this.model.get('key'),
+ parentKey: parent
+ };
+ return $.ajax({
+ type: 'POST',
+ url: url,
+ data: options,
+ statusCode: {
+ // do not show global error
+ 400: null
+ }
+ }).done(function () {
+ that.model.collection.fetch();
+ that.model.trigger('select', that.model);
+ that.close();
+ }).fail(function (jqXHR) {
+ that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings);
+ });
+ },
+
+ serializeData: function () {
+ var that = this,
+ profilesData = this.model.collection.toJSON(),
+ profiles = _.filter(profilesData, function (profile) {
+ return profile.language === that.model.get('language') && profile.key !== that.model.id;
+ });
+ return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
+ profiles: profiles
+ });
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/quality-profiles/controller.js b/server/sonar-web/src/main/js/quality-profiles/controller.js
index ed58081869e..107cfde9815 100644
--- a/server/sonar-web/src/main/js/quality-profiles/controller.js
+++ b/server/sonar-web/src/main/js/quality-profiles/controller.js
@@ -83,7 +83,10 @@ define([
},
fetchProfile: function (profile) {
- return $.when(this.fetchProfileRules(profile));
+ return $.when(
+ this.fetchProfileRules(profile),
+ this.fetchInheritance(profile)
+ );
},
fetchProfileRules: function (profile) {
@@ -101,6 +104,18 @@ define([
profile.set({ rulesSeverities: severityFacet.values });
}
});
+ },
+
+ fetchInheritance: function (profile) {
+ var url = baseUrl + '/api/qualityprofiles/inheritance',
+ options = { profileKey: profile.id };
+ return $.get(url, options).done(function (r) {
+ profile.set({
+ ancestors: r.ancestors,
+ children: r.children
+ });
+ profile.set(r.profile);
+ });
}
});
diff --git a/server/sonar-web/src/main/js/quality-profiles/delete-profile-view.js b/server/sonar-web/src/main/js/quality-profiles/delete-profile-view.js
index 2c23638432d..570b60f00d8 100644
--- a/server/sonar-web/src/main/js/quality-profiles/delete-profile-view.js
+++ b/server/sonar-web/src/main/js/quality-profiles/delete-profile-view.js
@@ -49,6 +49,7 @@ define([
400: null
}
}).done(function () {
+ that.model.collection.fetch();
that.model.trigger('destroy', that.model, that.model.collection);
}).fail(function (jqXHR) {
that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings);
diff --git a/server/sonar-web/src/main/js/quality-profiles/helpers.js b/server/sonar-web/src/main/js/quality-profiles/helpers.js
new file mode 100644
index 00000000000..e1d3cb57e84
--- /dev/null
+++ b/server/sonar-web/src/main/js/quality-profiles/helpers.js
@@ -0,0 +1,26 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+(function () {
+
+ Handlebars.registerHelper('profileUrl', function (key) {
+ return baseUrl + '/quality_profiles/show?key=' + encodeURIComponent(key);
+ });
+
+})();
diff --git a/server/sonar-web/src/main/js/quality-profiles/profile-details-view.js b/server/sonar-web/src/main/js/quality-profiles/profile-details-view.js
index bf4dc4b5c48..9c08fb31ac8 100644
--- a/server/sonar-web/src/main/js/quality-profiles/profile-details-view.js
+++ b/server/sonar-web/src/main/js/quality-profiles/profile-details-view.js
@@ -18,9 +18,13 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
define([
+ 'quality-profiles/change-profile-parent-view',
'common/select-list',
+ 'quality-profiles/helpers',
'templates/quality-profiles'
-], function () {
+], function (ChangeProfileParentView) {
+
+ var $ = jQuery;
return Marionette.ItemView.extend({
template: Templates['quality-profiles-profile-details'],
@@ -29,6 +33,11 @@ define([
'change': 'render'
},
+ events: {
+ 'click .js-profile': 'onProfileClick',
+ 'click #quality-profile-change-parent': 'onChangeParentClick'
+ },
+
onRender: function () {
var key = this.model.get('key');
if (!this.model.get('isDefault')) {
@@ -52,7 +61,7 @@ define([
selected: t('quality_gates.projects.with'),
deselected: t('quality_gates.projects.without'),
all: t('quality_gates.projects.all'),
- noResults: t('quality_gates.projects.noResults'),
+ noResults: t('quality_gates.projects.noResults')
},
tooltips: {
select: t('quality_gates.projects.select_hint'),
@@ -62,6 +71,26 @@ define([
}
},
+ onProfileClick: function (e) {
+ var key = $(e.currentTarget).data('key'),
+ profile = this.model.collection.get(key);
+ if (profile != null) {
+ e.preventDefault();
+ this.model.collection.trigger('select', profile);
+ }
+ },
+
+ onChangeParentClick: function (e) {
+ e.preventDefault();
+ this.changeParent();
+ },
+
+ changeParent: function () {
+ new ChangeProfileParentView({
+ model: this.model
+ }).render();
+ },
+
serializeData: function () {
var key = this.model.get('key'),
rulesSearchUrl = '/coding_rules#qprofile=' + encodeURIComponent(key) + '|activation=true';
diff --git a/server/sonar-web/src/main/js/quality-profiles/profile-view.js b/server/sonar-web/src/main/js/quality-profiles/profile-view.js
index a2983d17729..680cc25d613 100644
--- a/server/sonar-web/src/main/js/quality-profiles/profile-view.js
+++ b/server/sonar-web/src/main/js/quality-profiles/profile-view.js
@@ -37,6 +37,11 @@ define([
onRender: function () {
this.$el.toggleClass('active', this.options.highlighted);
this.$el.attr('data-key', this.model.id);
+ this.$('[data-toggle="tooltip"]').tooltip({ container: 'body' });
+ },
+
+ onClose: function () {
+ this.$('[data-toggle="tooltip"]').tooltip('destroy');
},
onClick: function (e) {
diff --git a/server/sonar-web/src/main/less/components/alerts.less b/server/sonar-web/src/main/less/components/alerts.less
index f3023d48d9a..60b5bf22cda 100644
--- a/server/sonar-web/src/main/less/components/alerts.less
+++ b/server/sonar-web/src/main/less/components/alerts.less
@@ -32,6 +32,11 @@
.alert:empty { display: none; }
+.alert-inline {
+ display: inline-block;
+ vertical-align: middle;
+}
+
// Color
diff --git a/server/sonar-web/src/main/less/init/icons.less b/server/sonar-web/src/main/less/init/icons.less
index ea0a9c63e04..223af1d832b 100644
--- a/server/sonar-web/src/main/less/init/icons.less
+++ b/server/sonar-web/src/main/less/init/icons.less
@@ -444,6 +444,7 @@ a[class^="icon-"], a[class*=" icon-"] {
}
.icon-inheritance:before {
content: "\f126";
+ font-size: @iconSmallFontSize;
}
.icon-plus:before {
content: "\f067";
diff --git a/server/sonar-web/src/main/less/init/misc.less b/server/sonar-web/src/main/less/init/misc.less
index f3000fbb979..a52a57d6e5e 100644
--- a/server/sonar-web/src/main/less/init/misc.less
+++ b/server/sonar-web/src/main/less/init/misc.less
@@ -83,6 +83,10 @@ td.spacer-top { padding-top: 8px; }
pointer-events: none !important;
}
+.display-inline-block {
+ display: inline-block;
+}
+
// Background Color
diff --git a/server/sonar-web/src/test/js/quality-profiles.js b/server/sonar-web/src/test/js/quality-profiles.js
index 51acd6ae1b6..3a1d118178e 100644
--- a/server/sonar-web/src/test/js/quality-profiles.js
+++ b/server/sonar-web/src/test/js/quality-profiles.js
@@ -76,6 +76,7 @@ casper.test.begin(testName('Should Show Details'), 9, function (test) {
lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
lib.mockRequestFromFile('/api/rules/search', 'rules.json');
+ lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.json');
})
.then(function () {
@@ -89,7 +90,7 @@ casper.test.begin(testName('Should Show Details'), 9, function (test) {
})
.then(function () {
- casper.click('.js-list .list-group-item');
+ casper.click('.js-list .list-group-item[data-key="java-sonar-way-67887"]');
casper.waitForSelector('.search-navigator-header-component');
})
@@ -116,6 +117,56 @@ casper.test.begin(testName('Should Show Details'), 9, function (test) {
});
+casper.test.begin(testName('Should Show Inheritance Details'), 10, function (test) {
+ casper
+ .start(lib.buildUrl('quality_profiles'), function () {
+ lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/qualityprofiles/search', 'search-inheritance.json');
+ lib.mockRequestFromFile('/api/rules/search', 'rules.json');
+ lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance-plus.json');
+ })
+
+ .then(function () {
+ casper.evaluate(function () {
+ require(['/js/quality-profiles/app.js']);
+ });
+ })
+
+ .then(function () {
+ casper.waitForSelector('.js-list .list-group-item');
+ })
+
+ .then(function () {
+ casper.click('.js-list .list-group-item[data-key="java-inherited-profile-85155"]');
+ casper.waitForSelector('.search-navigator-header-component');
+ })
+
+ .then(function () {
+ test.assertElementCount('#quality-profile-ancestors li', 1);
+ test.assertSelectorContains('#quality-profile-ancestors', 'Sonar way');
+ test.assertSelectorContains('#quality-profile-ancestors', '161');
+
+ test.assertElementCount('#quality-profile-inheritance-current', 1);
+ test.assertSelectorContains('#quality-profile-inheritance-current', 'Inherited Profile');
+ test.assertSelectorContains('#quality-profile-inheritance-current', '163');
+ test.assertSelectorContains('#quality-profile-inheritance-current', '7');
+
+ test.assertElementCount('#quality-profile-children li', 1);
+ test.assertSelectorContains('#quality-profile-children', 'Second Level Inherited Profile');
+ test.assertSelectorContains('#quality-profile-children', '165');
+ })
+
+ .then(function () {
+ lib.sendCoverage();
+ })
+
+ .run(function () {
+ test.done();
+ });
+});
+
+
casper.test.begin(testName('Should Show Selected Projects'), 2, function (test) {
casper
.start(lib.buildUrl('quality_profiles'), function () {
@@ -124,6 +175,7 @@ casper.test.begin(testName('Should Show Selected Projects'), 2, function (test)
lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
lib.mockRequestFromFile('/api/rules/search', 'rules.json');
lib.mockRequestFromFile('/api/qualityprofiles/projects*', 'projects.json');
+ lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.json');
})
.then(function () {
@@ -167,6 +219,7 @@ casper.test.begin(testName('Copy Profile'), 5, function (test) {
lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
lib.mockRequestFromFile('/api/rules/search', 'rules.json');
+ lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.json');
lib.mockRequestFromFile('/api/qualityprofiles/copy', 'copy.json');
})
@@ -224,6 +277,7 @@ casper.test.begin(testName('Rename Profile'), 2, function (test) {
this.searchMock = lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
lib.mockRequestFromFile('/api/rules/search', 'rules.json');
+ lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.json');
lib.mockRequest('/api/qualityprofiles/rename', '{}');
})
@@ -281,6 +335,7 @@ casper.test.begin(testName('Make Profile Default'), 4, function (test) {
this.searchMock = lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
lib.mockRequestFromFile('/api/rules/search', 'rules.json');
+ lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.json');
lib.mockRequest('/api/qualityprofiles/set_default', '{}');
})
@@ -332,6 +387,7 @@ casper.test.begin(testName('Delete Profile'), 2, function (test) {
this.searchMock = lib.mockRequestFromFile('/api/qualityprofiles/search', 'search-with-copy.json');
lib.mockRequestFromFile('/api/rules/search', 'rules.json');
+ lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.json');
lib.mockRequest('/api/qualityprofiles/delete', '{}');
})
@@ -386,6 +442,7 @@ casper.test.begin(testName('Create Profile'), 2, function (test) {
this.searchMock = lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
lib.mockRequestFromFile('/api/rules/search', 'rules.json');
+ lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.json');
lib.mockRequestFromFile('/api/qualityprofiles/create', 'create.json');
lib.mockRequestFromFile('/api/languages/list', 'languages.json');
})
@@ -440,6 +497,7 @@ casper.test.begin(testName('Restore Built-in Profiles'), 2, function (test) {
this.searchMock = lib.mockRequestFromFile('/api/qualityprofiles/search', 'search-modified.json');
lib.mockRequestFromFile('/api/rules/search', 'rules.json');
+ lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.json');
lib.mockRequest('/api/qualityprofiles/restore_built_in', '{}');
lib.mockRequestFromFile('/api/languages/list', 'languages.json');
})
@@ -484,3 +542,62 @@ casper.test.begin(testName('Restore Built-in Profiles'), 2, function (test) {
test.done();
});
});
+
+
+casper.test.begin(testName('Change Parent'), 1, function (test) {
+ casper
+ .start(lib.buildUrl('quality_profiles'), function () {
+ lib.setDefaultViewport();
+
+ this.searchMock = lib.mockRequestFromFile('/api/qualityprofiles/search', 'search-change-parent.json');
+ lib.mockRequestFromFile('/api/rules/search', 'rules.json');
+ this.inheritanceMock = lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance-change-parent.json');
+ lib.mockRequest('/api/qualityprofiles/change_parent', '{}');
+ })
+
+ .then(function () {
+ casper.evaluate(function () {
+ require(['/js/quality-profiles/app.js']);
+ jQuery.ajaxSetup({ dataType: 'json' });
+ });
+ })
+
+ .then(function () {
+ casper.waitForSelector('.js-list .list-group-item');
+ })
+
+ .then(function () {
+ casper.click('.js-list .list-group-item[data-key="java-inherited-profile-85155"]');
+ casper.waitForSelector('#quality-profile-change-parent');
+ })
+
+ .then(function () {
+ casper.click('#quality-profile-change-parent');
+ casper.waitForSelector('.modal');
+ })
+
+ .then(function () {
+ lib.clearRequestMock(this.searchMock);
+ lib.mockRequestFromFile('/api/qualityprofiles/search', 'search-changed-parent.json');
+ lib.clearRequestMock(this.inheritanceMock);
+ lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance-changed-parent.json');
+
+ casper.evaluate(function () {
+ jQuery('#change-profile-parent').val('java-another-profile-00609');
+ });
+ casper.click('#change-profile-parent-submit');
+ casper.waitForSelectorTextChange('#quality-profile-ancestors');
+ })
+
+ .then(function () {
+ test.assertSelectorContains('#quality-profile-ancestors', 'Another Profile');
+ })
+
+ .then(function () {
+ lib.sendCoverage();
+ })
+
+ .run(function () {
+ test.done();
+ });
+});
diff --git a/server/sonar-web/src/test/json/quality-profiles/inheritance-change-parent.json b/server/sonar-web/src/test/json/quality-profiles/inheritance-change-parent.json
new file mode 100644
index 00000000000..34082a5cfe2
--- /dev/null
+++ b/server/sonar-web/src/test/json/quality-profiles/inheritance-change-parent.json
@@ -0,0 +1,23 @@
+{
+ "profile": {
+ "key": "java-inherited-profile-85155",
+ "name": "Inherited Profile",
+ "parent": "java-sonar-way-67887",
+ "activeRuleCount": 163,
+ "overridingRuleCount": 7
+ },
+ "ancestors": [
+ {
+ "key": "java-sonar-way-67887",
+ "name": "Sonar way",
+ "activeRuleCount": 161
+ }
+ ],
+ "children": [
+ {
+ "key": "java-second-level-inherited-profile-81377",
+ "name": "Second Level Inherited Profile",
+ "activeRuleCount": 165
+ }
+ ]
+}
diff --git a/server/sonar-web/src/test/json/quality-profiles/inheritance-changed-parent.json b/server/sonar-web/src/test/json/quality-profiles/inheritance-changed-parent.json
new file mode 100644
index 00000000000..938d666a250
--- /dev/null
+++ b/server/sonar-web/src/test/json/quality-profiles/inheritance-changed-parent.json
@@ -0,0 +1,22 @@
+{
+ "profile": {
+ "key": "java-inherited-profile-85155",
+ "name": "Inherited Profile",
+ "parent": "java-another-profile-00609",
+ "activeRuleCount": 1
+ },
+ "ancestors": [
+ {
+ "key": "java-another-profile-00609",
+ "name": "Another Profile",
+ "activeRuleCount": 0
+ }
+ ],
+ "children": [
+ {
+ "key": "java-second-level-inherited-profile-81377",
+ "name": "Second Level Inherited Profile",
+ "activeRuleCount": 1
+ }
+ ]
+}
diff --git a/server/sonar-web/src/test/json/quality-profiles/inheritance-plus.json b/server/sonar-web/src/test/json/quality-profiles/inheritance-plus.json
new file mode 100644
index 00000000000..34082a5cfe2
--- /dev/null
+++ b/server/sonar-web/src/test/json/quality-profiles/inheritance-plus.json
@@ -0,0 +1,23 @@
+{
+ "profile": {
+ "key": "java-inherited-profile-85155",
+ "name": "Inherited Profile",
+ "parent": "java-sonar-way-67887",
+ "activeRuleCount": 163,
+ "overridingRuleCount": 7
+ },
+ "ancestors": [
+ {
+ "key": "java-sonar-way-67887",
+ "name": "Sonar way",
+ "activeRuleCount": 161
+ }
+ ],
+ "children": [
+ {
+ "key": "java-second-level-inherited-profile-81377",
+ "name": "Second Level Inherited Profile",
+ "activeRuleCount": 165
+ }
+ ]
+}
diff --git a/server/sonar-web/src/test/json/quality-profiles/inheritance.json b/server/sonar-web/src/test/json/quality-profiles/inheritance.json
new file mode 100644
index 00000000000..62c4717e3bb
--- /dev/null
+++ b/server/sonar-web/src/test/json/quality-profiles/inheritance.json
@@ -0,0 +1,5 @@
+{
+ "profile": {},
+ "ancestors": [],
+ "children": []
+}
diff --git a/server/sonar-web/src/test/json/quality-profiles/search-change-parent.json b/server/sonar-web/src/test/json/quality-profiles/search-change-parent.json
new file mode 100644
index 00000000000..63f22a0bc71
--- /dev/null
+++ b/server/sonar-web/src/test/json/quality-profiles/search-change-parent.json
@@ -0,0 +1,76 @@
+{
+ "profiles": [
+ {
+ "key": "java-another-profile-00609",
+ "name": "Another Profile",
+ "activeRuleCount": 0,
+ "language": "java",
+ "languageName": "Java",
+ "isInherited": false
+ },
+ {
+ "key": "java-inherited-profile-85155",
+ "name": "Inherited Profile",
+ "activeRuleCount": 161,
+ "language": "java",
+ "languageName": "Java",
+ "parentKey": "java-sonar-way-67887",
+ "parentName": "Sonar way",
+ "isInherited": true
+ },
+ {
+ "key": "java-second-level-inherited-profile-81377",
+ "name": "Second Level Inherited Profile",
+ "activeRuleCount": 161,
+ "language": "java",
+ "languageName": "Java",
+ "parentKey": "java-inherited-profile-85155",
+ "parentName": "Inherited Profile",
+ "isInherited": true
+ },
+ {
+ "key": "java-sonar-way-67887",
+ "name": "Sonar way",
+ "activeRuleCount": 161,
+ "language": "java",
+ "languageName": "Java",
+ "isInherited": false,
+ "isDefault": true
+ },
+ {
+ "key": "js-sonar-way-71566",
+ "name": "Sonar way",
+ "activeRuleCount": 63,
+ "language": "js",
+ "languageName": "JavaScript",
+ "isInherited": false,
+ "isDefault": true
+ },
+ {
+ "key": "php-psr-2-46772",
+ "name": "PSR-2",
+ "activeRuleCount": 19,
+ "language": "php",
+ "languageName": "PHP",
+ "isInherited": false,
+ "isDefault": true
+ },
+ {
+ "key": "php-sonar-way-10778",
+ "name": "Sonar way",
+ "activeRuleCount": 59,
+ "language": "php",
+ "languageName": "PHP",
+ "isInherited": false
+ },
+ {
+ "key": "py-sonar-way-78627",
+ "name": "Sonar way",
+ "activeRuleCount": 21,
+ "language": "py",
+ "languageName": "Python",
+ "isInherited": false,
+ "isDefault": true
+ }
+ ]
+}
diff --git a/server/sonar-web/src/test/json/quality-profiles/search-changed-parent.json b/server/sonar-web/src/test/json/quality-profiles/search-changed-parent.json
new file mode 100644
index 00000000000..5ce6a7180aa
--- /dev/null
+++ b/server/sonar-web/src/test/json/quality-profiles/search-changed-parent.json
@@ -0,0 +1,76 @@
+{
+ "profiles": [
+ {
+ "key": "java-another-profile-00609",
+ "name": "Another Profile",
+ "activeRuleCount": 0,
+ "language": "java",
+ "languageName": "Java",
+ "isInherited": false
+ },
+ {
+ "key": "java-inherited-profile-85155",
+ "name": "Inherited Profile",
+ "activeRuleCount": 1,
+ "language": "java",
+ "languageName": "Java",
+ "parentKey": "java-another-profile-00609",
+ "parentName": "Another Profile",
+ "isInherited": true
+ },
+ {
+ "key": "java-second-level-inherited-profile-81377",
+ "name": "Second Level Inherited Profile",
+ "activeRuleCount": 1,
+ "language": "java",
+ "languageName": "Java",
+ "parentKey": "java-inherited-profile-85155",
+ "parentName": "Inherited Profile",
+ "isInherited": true
+ },
+ {
+ "key": "java-sonar-way-67887",
+ "name": "Sonar way",
+ "activeRuleCount": 161,
+ "language": "java",
+ "languageName": "Java",
+ "isInherited": false,
+ "isDefault": true
+ },
+ {
+ "key": "js-sonar-way-71566",
+ "name": "Sonar way",
+ "activeRuleCount": 63,
+ "language": "js",
+ "languageName": "JavaScript",
+ "isInherited": false,
+ "isDefault": true
+ },
+ {
+ "key": "php-psr-2-46772",
+ "name": "PSR-2",
+ "activeRuleCount": 19,
+ "language": "php",
+ "languageName": "PHP",
+ "isInherited": false,
+ "isDefault": true
+ },
+ {
+ "key": "php-sonar-way-10778",
+ "name": "Sonar way",
+ "activeRuleCount": 59,
+ "language": "php",
+ "languageName": "PHP",
+ "isInherited": false
+ },
+ {
+ "key": "py-sonar-way-78627",
+ "name": "Sonar way",
+ "activeRuleCount": 21,
+ "language": "py",
+ "languageName": "Python",
+ "isInherited": false,
+ "isDefault": true
+ }
+ ]
+}
diff --git a/server/sonar-web/src/test/json/quality-profiles/search-inheritance.json b/server/sonar-web/src/test/json/quality-profiles/search-inheritance.json
new file mode 100644
index 00000000000..3d60223a881
--- /dev/null
+++ b/server/sonar-web/src/test/json/quality-profiles/search-inheritance.json
@@ -0,0 +1,68 @@
+{
+ "profiles": [
+ {
+ "key": "java-inherited-profile-85155",
+ "name": "Inherited Profile",
+ "activeRuleCount": 161,
+ "language": "java",
+ "languageName": "Java",
+ "parentKey": "java-sonar-way-67887",
+ "parentName": "Sonar way",
+ "isInherited": true
+ },
+ {
+ "key": "java-second-level-inherited-profile-81377",
+ "name": "Second Level Inherited Profile",
+ "activeRuleCount": 161,
+ "language": "java",
+ "languageName": "Java",
+ "parentKey": "java-inherited-profile-85155",
+ "parentName": "Inherited Profile",
+ "isInherited": true
+ },
+ {
+ "key": "java-sonar-way-67887",
+ "name": "Sonar way",
+ "activeRuleCount": 161,
+ "language": "java",
+ "languageName": "Java",
+ "isInherited": false,
+ "isDefault": true
+ },
+ {
+ "key": "js-sonar-way-71566",
+ "name": "Sonar way",
+ "activeRuleCount": 63,
+ "language": "js",
+ "languageName": "JavaScript",
+ "isInherited": false,
+ "isDefault": true
+ },
+ {
+ "key": "php-psr-2-46772",
+ "name": "PSR-2",
+ "activeRuleCount": 19,
+ "language": "php",
+ "languageName": "PHP",
+ "isInherited": false,
+ "isDefault": true
+ },
+ {
+ "key": "php-sonar-way-10778",
+ "name": "Sonar way",
+ "activeRuleCount": 59,
+ "language": "php",
+ "languageName": "PHP",
+ "isInherited": false
+ },
+ {
+ "key": "py-sonar-way-78627",
+ "name": "Sonar way",
+ "activeRuleCount": 21,
+ "language": "py",
+ "languageName": "Python",
+ "isInherited": false,
+ "isDefault": true
+ }
+ ]
+}