]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5851 add changelog permalink
authorStas Vilchik <vilchiks@gmail.com>
Tue, 14 Apr 2015 13:37:36 +0000 (15:37 +0200)
committerStas Vilchik <vilchiks@gmail.com>
Tue, 14 Apr 2015 13:37:42 +0000 (15:37 +0200)
server/sonar-web/src/main/js/application.js
server/sonar-web/src/main/js/quality-profiles/controller.js
server/sonar-web/src/main/js/quality-profiles/router.js
server/sonar-web/src/main/webapp/WEB-INF/app/controllers/profiles_controller.rb
server/sonar-web/src/test/js/quality-profiles.js

index d71b61294c79d1958af66bb9a6e61b9ad7e5c273..4de2fefb40b426b98e69e536812180183593b45f 100644 (file)
@@ -507,6 +507,23 @@ function closeModalWindow () {
     return SEVERITIES_ORDER.indexOf(severity);
   };
 
+
+  /**
+   * Return a hash of GET parameters
+   * @returns {object}
+   */
+  window.getQueryParams = function () {
+    var qs = window.location.search.split('+').join(' '),
+        params = {},
+        re = /[?&]?([^=]+)=([^&]*)/g,
+        tokens = re.exec(qs);
+    while (tokens) {
+      params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
+      tokens = re.exec(qs);
+    }
+    return params;
+  };
+
 })();
 
 (function () {
index eb8222f8cb06a746f32f3d2686e36d2c3c54ad6d..8219fa96e13efa20409e6cdc95b360a0adf9fdaf 100644 (file)
@@ -41,16 +41,30 @@ define([
       this.fetchProfiles().done(function () {
         var profile = that.options.app.profiles.findWhere({ key: key });
         if (profile != null) {
-          profile.trigger('select', profile);
+          profile.trigger('select', profile, { trigger: false });
         }
       });
     },
 
-    onProfileSelect: function (profile) {
+    changelog: function (key, since, to) {
+      var that = this;
+      this.fetchProfiles().done(function () {
+        var profile = that.options.app.profiles.findWhere({ key: key });
+        if (profile != null) {
+          profile.trigger('select', profile, { trigger: false });
+          profile.fetchChangelog({ since: since, to: to });
+        }
+      });
+    },
+
+    onProfileSelect: function (profile, options) {
       var that = this,
           key = profile.get('key'),
-          route = 'show?key=' + encodeURIComponent(key);
-      this.options.app.router.navigate(route);
+          route = 'show?key=' + encodeURIComponent(key),
+          opts = _.defaults(options || {}, { trigger: true });
+      if (opts.trigger) {
+        this.options.app.router.navigate(route);
+      }
       this.options.app.profilesView.highlight(key);
       this.fetchProfile(profile).done(function () {
         var profileHeaderView = new ProfileHeaderView({ model: profile });
index 521dea6a04afd197d3e3ed06d212f6fefa99ab16..0076462a9f45baefb74f46722072586b7f88a624 100644 (file)
@@ -23,7 +23,8 @@ define(function () {
     routes: {
       '': 'index',
       'index': 'index',
-      'show?key=:key': 'show'
+      'show?key=:key': 'show',
+      'changelog*': 'changelog'
     },
 
     initialize: function (options) {
@@ -36,6 +37,11 @@ define(function () {
 
     show: function (key) {
       this.app.controller.show(key);
+    },
+
+    changelog: function () {
+      var params = window.getQueryParams();
+      this.app.controller.changelog(params.key, params.since, params.to);
     }
   });
 
index 0c815c44eab6c521fbad03f84f93ad8c94a093b9..8ab7cdf9c2819122b502e874e53fa23d22ac10cf 100644 (file)
@@ -28,6 +28,10 @@ class ProfilesController < ApplicationController
     render :action => 'index'
   end
 
+  def changelog
+    render :action => 'index'
+  end
+
   # GET /profiles/export?name=<profile name>&language=<language>&format=<exporter key>
   def export
     language = params[:language]
index fd17be8179815dd43d05a2cc991ae16890ec6536..c330bc6de8000ec91e28a35a2e2d6cbb6f3702c3 100644 (file)
@@ -27,623 +27,623 @@ lib.changeWorkingDirectory('quality-profiles');
 lib.configureCasper();
 
 
-//casper.test.begin(testName('Should Show List'), 9, function (test) {
-//  casper
-//      .start(lib.buildUrl('profiles'), function () {
-//        lib.setDefaultViewport();
-//
-//        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
-//      })
-//
-//      .then(function () {
-//        casper.evaluate(function () {
-//          require(['/js/quality-profiles/app.js']);
-//        });
-//      })
-//
-//      .then(function () {
-//        casper.waitForSelector('.js-list .list-group-item');
-//      })
-//
-//      .then(function () {
-//        test.assertElementCount('.js-list .list-group-item', 5);
-//        test.assertSelectorContains('.js-list .list-group-item', 'Sonar way');
-//        test.assertSelectorContains('.js-list .list-group-item', 'PSR-2');
-//
-//        test.assertElementCount('.js-list-language', 4);
-//        test.assertSelectorContains('.js-list-language', 'Java');
-//        test.assertSelectorContains('.js-list-language', 'JavaScript');
-//        test.assertSelectorContains('.js-list-language', 'PHP');
-//        test.assertSelectorContains('.js-list-language', 'Python');
-//
-//        test.assertElementCount('.js-list .note', 4);
-//      })
-//
-//      .then(function () {
-//        lib.sendCoverage();
-//      })
-//
-//      .run(function () {
-//        test.done();
-//      });
-//});
-//
-//
-//casper.test.begin(testName('Should Show Details'), 9, function (test) {
-//  casper
-//      .start(lib.buildUrl('profiles'), function () {
-//        lib.setDefaultViewport();
-//
-//        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
-//        lib.mockRequestFromFile('/api/rules/search', 'rules.json');
-//        lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.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-sonar-way-67887"]');
-//        casper.waitForSelector('.search-navigator-header-component');
-//      })
-//
-//      .then(function () {
-//        test.assertElementCount('.js-list .list-group-item.active', 1);
-//        test.assertSelectorContains('.js-list .list-group-item.active', 'Sonar way');
-//
-//        test.assertSelectorContains('.search-navigator-workspace-header', 'Sonar way');
-//        test.assertSelectorContains('.search-navigator-workspace-header', 'Java');
-//        test.assertExists('#quality-profile-backup');
-//        test.assertExists('#quality-profile-rename');
-//        test.assertExists('#quality-profile-copy');
-//        test.assertDoesntExist('#quality-profile-delete');
-//        test.assertDoesntExist('#quality-profile-set-as-default');
-//      })
-//
-//      .then(function () {
-//        lib.sendCoverage();
-//      })
-//
-//      .run(function () {
-//        test.done();
-//      });
-//});
-//
-//
-//casper.test.begin(testName('Should Show Inheritance Details'), 10, function (test) {
-//  casper
-//      .start(lib.buildUrl('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('profiles'), function () {
-//        lib.setDefaultViewport();
-//
-//        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 () {
-//        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="php-psr-2-46772"]');
-//        casper.waitForSelector('#quality-profile-projects');
-//      })
-//
-//      .then(function () {
-//        lib.waitForElementCount('#quality-profile-projects .select-list-list li', 2);
-//      })
-//
-//      .then(function () {
-//        test.assertSelectorContains('#quality-profile-projects .select-list-list li', 'CSS');
-//        test.assertSelectorContains('#quality-profile-projects .select-list-list li', 'http-request-parent');
-//      })
-//
-//      .then(function () {
-//        lib.sendCoverage();
-//      })
-//
-//      .run(function () {
-//        test.done();
-//      });
-//});
-//
-//
-//casper.test.begin(testName('Copy Profile'), 5, function (test) {
-//  casper
-//      .start(lib.buildUrl('profiles'), function () {
-//        lib.setDefaultViewport();
-//
-//        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');
-//      })
-//
-//      .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 () {
-//        test.assertElementCount('.js-list .list-group-item', 5);
-//        casper.click('.js-list .list-group-item[data-key="java-sonar-way-67887"]');
-//        casper.waitForSelector('#quality-profile-copy');
-//      })
-//
-//      .then(function () {
-//        casper.click('#quality-profile-copy');
-//        casper.waitForSelector('.modal');
-//      })
-//
-//      .then(function () {
-//        casper.evaluate(function () {
-//          jQuery('#copy-profile-name').val('Copied Profile');
-//        });
-//        casper.click('#copy-profile-submit');
-//        casper.waitForSelectorTextChange('.search-navigator-header-component');
-//      })
-//
-//      .then(function () {
-//        test.assertElementCount('.js-list .list-group-item', 6);
-//        test.assertSelectorContains('.js-list .list-group-item.active', 'Copied Profile');
-//        test.assertSelectorContains('.search-navigator-header-component', 'Copied Profile');
-//        test.assertSelectorContains('.search-navigator-header-component', 'Java');
-//      })
-//
-//      .then(function () {
-//        lib.sendCoverage();
-//      })
-//
-//      .run(function () {
-//        test.done();
-//      });
-//});
-//
-//
-//casper.test.begin(testName('Rename Profile'), 2, function (test) {
-//  casper
-//      .start(lib.buildUrl('profiles'), function () {
-//        lib.setDefaultViewport();
-//
-//        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', '{}');
-//      })
-//
-//      .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-sonar-way-67887"]');
-//        casper.waitForSelector('#quality-profile-rename');
-//      })
-//
-//      .then(function () {
-//        casper.click('#quality-profile-rename');
-//        casper.waitForSelector('.modal');
-//      })
-//
-//      .then(function () {
-//        lib.clearRequestMock(this.searchMock);
-//        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search-renamed.json');
-//
-//        casper.evaluate(function () {
-//          jQuery('#rename-profile-name').val('Renamed Profile');
-//        });
-//        casper.click('#rename-profile-submit');
-//        casper.waitForSelectorTextChange('.search-navigator-header-component');
-//      })
-//
-//      .then(function () {
-//        test.assertSelectorContains('.js-list .list-group-item.active', 'Renamed Profile');
-//        test.assertSelectorContains('.search-navigator-header-component', 'Renamed Profile');
-//      })
-//
-//      .then(function () {
-//        lib.sendCoverage();
-//      })
-//
-//      .run(function () {
-//        test.done();
-//      });
-//});
-//
-//
-//casper.test.begin(testName('Make Profile Default'), 4, function (test) {
-//  casper
-//      .start(lib.buildUrl('profiles'), function () {
-//        lib.setDefaultViewport();
-//
-//        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', '{}');
-//      })
-//
-//      .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 () {
-//        test.assertDoesntExist('.js-list .list-group-item[data-key="php-psr-2-46772"] .note');
-//        test.assertExists('.js-list .list-group-item[data-key="php-sonar-way-10778"] .note');
-//        casper.click('.js-list .list-group-item[data-key="php-psr-2-46772"]');
-//        casper.waitForSelector('#quality-profile-set-as-default');
-//      })
-//
-//      .then(function () {
-//        lib.clearRequestMock(this.searchMock);
-//        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search-another-default.json');
-//
-//        casper.click('#quality-profile-set-as-default');
-//        casper.waitWhileSelector('.js-list .list-group-item[data-key="php-sonar-way-10778"] .note');
-//      })
-//
-//      .then(function () {
-//        test.assertDoesntExist('#quality-profile-set-as-default');
-//        test.assertExists('.js-list .list-group-item[data-key="php-psr-2-46772"] .note');
-//      })
-//
-//      .then(function () {
-//        lib.sendCoverage();
-//      })
-//
-//      .run(function () {
-//        test.done();
-//      });
-//});
-//
-//
-//casper.test.begin(testName('Delete Profile'), 2, function (test) {
-//  casper
-//      .start(lib.buildUrl('profiles'), function () {
-//        lib.setDefaultViewport();
-//
-//        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', '{}');
-//      })
-//
-//      .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 () {
-//        test.assertElementCount('.js-list .list-group-item', 6);
-//        casper.click('.js-list .list-group-item[data-key="java-copied-profile-11711"]');
-//        casper.waitForSelector('#quality-profile-delete');
-//      })
-//
-//      .then(function () {
-//        casper.click('#quality-profile-delete');
-//        casper.waitForSelector('.modal');
-//      })
-//
-//      .then(function () {
-//        lib.clearRequestMock(this.searchMock);
-//        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
-//
-//        casper.click('#delete-profile-submit');
-//        lib.waitForElementCount('.js-list .list-group-item', 5);
-//      })
-//
-//      .then(function () {
-//        test.assertSelectorDoesntContain('.js-list .list-group-item', 'Copied Profile');
-//      })
-//
-//      .then(function () {
-//        lib.sendCoverage();
-//      })
-//
-//      .run(function () {
-//        test.done();
-//      });
-//});
-//
-//
-//casper.test.begin(testName('Create Profile'), 2, function (test) {
-//  casper
-//      .start(lib.buildUrl('profiles'), function () {
-//        lib.setDefaultViewport();
-//
-//        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');
-//      })
-//
-//      .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 () {
-//        test.assertElementCount('.js-list .list-group-item', 5);
-//        casper.click('#quality-profiles-create');
-//        casper.waitForSelector('.modal');
-//      })
-//
-//      .then(function () {
-//        lib.clearRequestMock(this.searchMock);
-//        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search-with-copy.json');
-//
-//        casper.evaluate(function () {
-//          jQuery('#create-profile-name').val('Copied Profile');
-//          jQuery('#create-profile-language').val('java');
-//        });
-//        casper.click('#create-profile-submit');
-//        lib.waitForElementCount('.js-list .list-group-item', 6);
-//      })
-//
-//      .then(function () {
-//        test.assertExists('.js-list .list-group-item.active[data-key="java-copied-profile-11711"]');
-//      })
-//
-//      .then(function () {
-//        lib.sendCoverage();
-//      })
-//
-//      .run(function () {
-//        test.done();
-//      });
-//});
-//
-//
-//casper.test.begin(testName('Restore Built-in Profiles'), 2, function (test) {
-//  casper
-//      .start(lib.buildUrl('profiles'), function () {
-//        lib.setDefaultViewport();
-//
-//        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');
-//      })
-//
-//      .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 () {
-//        test.assertElementCount('.js-list .list-group-item', 1);
-//        casper.click('#quality-profiles-restore-built-in');
-//        casper.waitForSelector('.modal');
-//      })
-//
-//      .then(function () {
-//        lib.clearRequestMock(this.searchMock);
-//        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
-//
-//        casper.evaluate(function () {
-//          jQuery('#restore-built-in-profiles-language').val('java');
-//        });
-//        casper.click('#restore-built-in-profiles-submit');
-//        lib.waitForElementCount('.js-list .list-group-item', 5);
-//      })
-//
-//      .then(function () {
-//        test.assertSelectorContains('.js-list .list-group-item', 'Sonar way');
-//      })
-//
-//      .then(function () {
-//        lib.sendCoverage();
-//      })
-//
-//      .run(function () {
-//        test.done();
-//      });
-//});
-//
-//
-//casper.test.begin(testName('Change Parent'), 1, function (test) {
-//  casper
-//      .start(lib.buildUrl('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();
-//      });
-//});
-//
-//
-//casper.test.begin(testName('Permalink'), 9, function (test) {
-//  casper
-//      .start(lib.buildUrl('profiles#show?key=java-sonar-way-67887'), function () {
-//        lib.setDefaultViewport();
-//
-//        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
-//        lib.mockRequestFromFile('/api/rules/search', 'rules.json');
-//        lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.json');
-//      })
-//
-//      .then(function () {
-//        casper.evaluate(function () {
-//          require(['/js/quality-profiles/app.js']);
-//        });
-//      })
-//
-//      .then(function () {
-//        casper.waitForSelector('#quality-profile-rename');
-//      })
-//
-//      .then(function () {
-//        test.assertElementCount('.js-list .list-group-item.active', 1);
-//        test.assertSelectorContains('.js-list .list-group-item.active', 'Sonar way');
-//
-//        test.assertSelectorContains('.search-navigator-workspace-header', 'Sonar way');
-//        test.assertSelectorContains('.search-navigator-workspace-header', 'Java');
-//        test.assertExists('#quality-profile-backup');
-//        test.assertExists('#quality-profile-rename');
-//        test.assertExists('#quality-profile-copy');
-//        test.assertDoesntExist('#quality-profile-delete');
-//        test.assertDoesntExist('#quality-profile-set-as-default');
-//      })
-//
-//      .then(function () {
-//        lib.sendCoverage();
-//      })
-//
-//      .run(function () {
-//        test.done();
-//      });
-//});
+casper.test.begin(testName('Should Show List'), 9, function (test) {
+  casper
+      .start(lib.buildUrl('profiles'), function () {
+        lib.setDefaultViewport();
+
+        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
+      })
+
+      .then(function () {
+        casper.evaluate(function () {
+          require(['/js/quality-profiles/app.js']);
+        });
+      })
+
+      .then(function () {
+        casper.waitForSelector('.js-list .list-group-item');
+      })
+
+      .then(function () {
+        test.assertElementCount('.js-list .list-group-item', 5);
+        test.assertSelectorContains('.js-list .list-group-item', 'Sonar way');
+        test.assertSelectorContains('.js-list .list-group-item', 'PSR-2');
+
+        test.assertElementCount('.js-list-language', 4);
+        test.assertSelectorContains('.js-list-language', 'Java');
+        test.assertSelectorContains('.js-list-language', 'JavaScript');
+        test.assertSelectorContains('.js-list-language', 'PHP');
+        test.assertSelectorContains('.js-list-language', 'Python');
+
+        test.assertElementCount('.js-list .note', 4);
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Should Show Details'), 9, function (test) {
+  casper
+      .start(lib.buildUrl('profiles'), function () {
+        lib.setDefaultViewport();
+
+        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
+        lib.mockRequestFromFile('/api/rules/search', 'rules.json');
+        lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.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-sonar-way-67887"]');
+        casper.waitForSelector('.search-navigator-header-component');
+      })
+
+      .then(function () {
+        test.assertElementCount('.js-list .list-group-item.active', 1);
+        test.assertSelectorContains('.js-list .list-group-item.active', 'Sonar way');
+
+        test.assertSelectorContains('.search-navigator-workspace-header', 'Sonar way');
+        test.assertSelectorContains('.search-navigator-workspace-header', 'Java');
+        test.assertExists('#quality-profile-backup');
+        test.assertExists('#quality-profile-rename');
+        test.assertExists('#quality-profile-copy');
+        test.assertDoesntExist('#quality-profile-delete');
+        test.assertDoesntExist('#quality-profile-set-as-default');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Should Show Inheritance Details'), 10, function (test) {
+  casper
+      .start(lib.buildUrl('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('profiles'), function () {
+        lib.setDefaultViewport();
+
+        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 () {
+        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="php-psr-2-46772"]');
+        casper.waitForSelector('#quality-profile-projects');
+      })
+
+      .then(function () {
+        lib.waitForElementCount('#quality-profile-projects .select-list-list li', 2);
+      })
+
+      .then(function () {
+        test.assertSelectorContains('#quality-profile-projects .select-list-list li', 'CSS');
+        test.assertSelectorContains('#quality-profile-projects .select-list-list li', 'http-request-parent');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Copy Profile'), 5, function (test) {
+  casper
+      .start(lib.buildUrl('profiles'), function () {
+        lib.setDefaultViewport();
+
+        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');
+      })
+
+      .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 () {
+        test.assertElementCount('.js-list .list-group-item', 5);
+        casper.click('.js-list .list-group-item[data-key="java-sonar-way-67887"]');
+        casper.waitForSelector('#quality-profile-copy');
+      })
+
+      .then(function () {
+        casper.click('#quality-profile-copy');
+        casper.waitForSelector('.modal');
+      })
+
+      .then(function () {
+        casper.evaluate(function () {
+          jQuery('#copy-profile-name').val('Copied Profile');
+        });
+        casper.click('#copy-profile-submit');
+        casper.waitForSelectorTextChange('.search-navigator-header-component');
+      })
+
+      .then(function () {
+        test.assertElementCount('.js-list .list-group-item', 6);
+        test.assertSelectorContains('.js-list .list-group-item.active', 'Copied Profile');
+        test.assertSelectorContains('.search-navigator-header-component', 'Copied Profile');
+        test.assertSelectorContains('.search-navigator-header-component', 'Java');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Rename Profile'), 2, function (test) {
+  casper
+      .start(lib.buildUrl('profiles'), function () {
+        lib.setDefaultViewport();
+
+        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', '{}');
+      })
+
+      .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-sonar-way-67887"]');
+        casper.waitForSelector('#quality-profile-rename');
+      })
+
+      .then(function () {
+        casper.click('#quality-profile-rename');
+        casper.waitForSelector('.modal');
+      })
+
+      .then(function () {
+        lib.clearRequestMock(this.searchMock);
+        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search-renamed.json');
+
+        casper.evaluate(function () {
+          jQuery('#rename-profile-name').val('Renamed Profile');
+        });
+        casper.click('#rename-profile-submit');
+        casper.waitForSelectorTextChange('.search-navigator-header-component');
+      })
+
+      .then(function () {
+        test.assertSelectorContains('.js-list .list-group-item.active', 'Renamed Profile');
+        test.assertSelectorContains('.search-navigator-header-component', 'Renamed Profile');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Make Profile Default'), 4, function (test) {
+  casper
+      .start(lib.buildUrl('profiles'), function () {
+        lib.setDefaultViewport();
+
+        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', '{}');
+      })
+
+      .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 () {
+        test.assertDoesntExist('.js-list .list-group-item[data-key="php-psr-2-46772"] .note');
+        test.assertExists('.js-list .list-group-item[data-key="php-sonar-way-10778"] .note');
+        casper.click('.js-list .list-group-item[data-key="php-psr-2-46772"]');
+        casper.waitForSelector('#quality-profile-set-as-default');
+      })
+
+      .then(function () {
+        lib.clearRequestMock(this.searchMock);
+        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search-another-default.json');
+
+        casper.click('#quality-profile-set-as-default');
+        casper.waitWhileSelector('.js-list .list-group-item[data-key="php-sonar-way-10778"] .note');
+      })
+
+      .then(function () {
+        test.assertDoesntExist('#quality-profile-set-as-default');
+        test.assertExists('.js-list .list-group-item[data-key="php-psr-2-46772"] .note');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Delete Profile'), 2, function (test) {
+  casper
+      .start(lib.buildUrl('profiles'), function () {
+        lib.setDefaultViewport();
+
+        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', '{}');
+      })
+
+      .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 () {
+        test.assertElementCount('.js-list .list-group-item', 6);
+        casper.click('.js-list .list-group-item[data-key="java-copied-profile-11711"]');
+        casper.waitForSelector('#quality-profile-delete');
+      })
+
+      .then(function () {
+        casper.click('#quality-profile-delete');
+        casper.waitForSelector('.modal');
+      })
+
+      .then(function () {
+        lib.clearRequestMock(this.searchMock);
+        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
+
+        casper.click('#delete-profile-submit');
+        lib.waitForElementCount('.js-list .list-group-item', 5);
+      })
+
+      .then(function () {
+        test.assertSelectorDoesntContain('.js-list .list-group-item', 'Copied Profile');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Create Profile'), 2, function (test) {
+  casper
+      .start(lib.buildUrl('profiles'), function () {
+        lib.setDefaultViewport();
+
+        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');
+      })
+
+      .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 () {
+        test.assertElementCount('.js-list .list-group-item', 5);
+        casper.click('#quality-profiles-create');
+        casper.waitForSelector('.modal');
+      })
+
+      .then(function () {
+        lib.clearRequestMock(this.searchMock);
+        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search-with-copy.json');
+
+        casper.evaluate(function () {
+          jQuery('#create-profile-name').val('Copied Profile');
+          jQuery('#create-profile-language').val('java');
+        });
+        casper.click('#create-profile-submit');
+        lib.waitForElementCount('.js-list .list-group-item', 6);
+      })
+
+      .then(function () {
+        test.assertExists('.js-list .list-group-item.active[data-key="java-copied-profile-11711"]');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Restore Built-in Profiles'), 2, function (test) {
+  casper
+      .start(lib.buildUrl('profiles'), function () {
+        lib.setDefaultViewport();
+
+        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');
+      })
+
+      .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 () {
+        test.assertElementCount('.js-list .list-group-item', 1);
+        casper.click('#quality-profiles-restore-built-in');
+        casper.waitForSelector('.modal');
+      })
+
+      .then(function () {
+        lib.clearRequestMock(this.searchMock);
+        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
+
+        casper.evaluate(function () {
+          jQuery('#restore-built-in-profiles-language').val('java');
+        });
+        casper.click('#restore-built-in-profiles-submit');
+        lib.waitForElementCount('.js-list .list-group-item', 5);
+      })
+
+      .then(function () {
+        test.assertSelectorContains('.js-list .list-group-item', 'Sonar way');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
+
+
+casper.test.begin(testName('Change Parent'), 1, function (test) {
+  casper
+      .start(lib.buildUrl('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();
+      });
+});
+
+
+casper.test.begin(testName('Permalink'), 9, function (test) {
+  casper
+      .start(lib.buildUrl('profiles#show?key=java-sonar-way-67887'), function () {
+        lib.setDefaultViewport();
+
+        lib.mockRequestFromFile('/api/qualityprofiles/search', 'search.json');
+        lib.mockRequestFromFile('/api/rules/search', 'rules.json');
+        lib.mockRequestFromFile('/api/qualityprofiles/inheritance', 'inheritance.json');
+      })
+
+      .then(function () {
+        casper.evaluate(function () {
+          require(['/js/quality-profiles/app.js']);
+        });
+      })
+
+      .then(function () {
+        casper.waitForSelector('#quality-profile-rename');
+      })
+
+      .then(function () {
+        test.assertElementCount('.js-list .list-group-item.active', 1);
+        test.assertSelectorContains('.js-list .list-group-item.active', 'Sonar way');
+
+        test.assertSelectorContains('.search-navigator-workspace-header', 'Sonar way');
+        test.assertSelectorContains('.search-navigator-workspace-header', 'Java');
+        test.assertExists('#quality-profile-backup');
+        test.assertExists('#quality-profile-rename');
+        test.assertExists('#quality-profile-copy');
+        test.assertDoesntExist('#quality-profile-delete');
+        test.assertDoesntExist('#quality-profile-set-as-default');
+      })
+
+      .then(function () {
+        lib.sendCoverage();
+      })
+
+      .run(function () {
+        test.done();
+      });
+});
 
 
 casper.test.begin(testName('Changelog'), 21, function (test) {
@@ -715,3 +715,41 @@ casper.test.begin(testName('Changelog'), 21, function (test) {
         test.done();
       });
 });
+
+
+casper.test.begin(testName('Changelog Permalink'), 1, function (test) {
+    casper
+        .start(lib.buildUrl('profiles#changelog?since=2015-03-25&key=java-sonar-way-67887&to=2015-03-26'), function () {
+            lib.setDefaultViewport();
+
+            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/changelog', 'changelog.json', { data: {
+                since: '2015-03-25',
+                to: '2015-03-26'
+            }});
+        })
+
+        .then(function () {
+            casper.evaluate(function () {
+                require(['/js/quality-profiles/app.js']);
+            });
+        })
+
+        .then(function () {
+            casper.waitForSelector('.js-show-more-changelog');
+        })
+
+        .then(function () {
+            test.assertElementCount('#quality-profile-changelog tbody tr', 2);
+        })
+
+        .then(function () {
+            lib.sendCoverage();
+        })
+
+        .run(function () {
+            test.done();
+        });
+});