]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6661 add update center web tests
authorStas Vilchik <vilchiks@gmail.com>
Fri, 26 Jun 2015 08:25:53 +0000 (10:25 +0200)
committerStas Vilchik <vilchiks@gmail.com>
Fri, 26 Jun 2015 08:26:01 +0000 (10:26 +0200)
12 files changed:
server/sonar-web/Gruntfile.coffee
server/sonar-web/src/main/js/apps/update-center/list-item-view.js
server/sonar-web/src/main/js/apps/update-center/templates/update-center-header.hbs
server/sonar-web/src/main/js/apps/update-center/templates/update-center-plugin-changelog.hbs
server/sonar-web/src/main/js/apps/update-center/templates/update-center-plugin.hbs
server/sonar-web/src/main/js/apps/update-center/templates/update-center-system-update.hbs
server/sonar-web/src/test/js/update-center-spec.js [new file with mode: 0644]
server/sonar-web/src/test/json/update-center-spec/available.json [new file with mode: 0644]
server/sonar-web/src/test/json/update-center-spec/installed.json [new file with mode: 0644]
server/sonar-web/src/test/json/update-center-spec/pending.json [new file with mode: 0644]
server/sonar-web/src/test/json/update-center-spec/system-updates.json [new file with mode: 0644]
server/sonar-web/src/test/json/update-center-spec/updates.json [new file with mode: 0644]

index ee08f9f5033365c94b90240df65976da07b24670..53d3419a035da4ab05966f4c5dfb2a79dafac6a0 100644 (file)
@@ -166,6 +166,7 @@ module.exports = (grunt) ->
           'casper:computation'
           'casper:metrics'
           'casper:maintenance'
+          'casper:updateCenter'
         ]
 
 
@@ -348,6 +349,8 @@ module.exports = (grunt) ->
         src: ['src/test/js/metrics-spec.js']
       maintenance:
         src: ['src/test/js/maintenance-spec.js']
+      updateCenter:
+        src: ['src/test/js/update-center-spec.js']
 
     uglify:
       build:
index 456d83b9597fb768bd139421a6989c0558ccbe0a..578ae82589ae23f601b1dc4c9cc61be4221201b9 100644 (file)
@@ -30,6 +30,9 @@ define([
 
     onRender: function () {
       this.$el.attr('data-id', this.model.id);
+      if (this.model.get('_system')) {
+        this.$el.attr('data-system', '');
+      }
       this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' });
     },
 
index d358d3dfdd7b375893b68e046097b5cf12b109a3..0bcfd3cd7343b85d889c05d087b006ca063e307b 100644 (file)
@@ -4,7 +4,7 @@
 </header>
 
 {{#any installing uninstalling}}
-  <div class="panel panel-warning big-spacer-bottom">
+  <div class="js-pending panel panel-warning big-spacer-bottom">
     <div class="display-inline-block">
       <p>
         SonarQube needs to be restarted in order to
index 6a59095f2b5c256d342266da04c3d360add05838..ebfb458f314e5db0175115dc1dd5bd09257380bc 100644 (file)
@@ -1,38 +1,38 @@
 <div class="bubble-popup-container">
   <div class="bubble-popup-title">Changelog</div>
 
-  <ul>
+  <ul class="js-plugin-changelog-list">
     {{#each previousUpdates}}
       <li class="spacer-bottom">
         <div class="pull-left spacer-right">
-          <span class="badge badge-success little-spacer-bottom">{{release.version}}</span>
+          <span class="js-plugin-changelog-version badge badge-success little-spacer-bottom">{{release.version}}</span>
         </div>
         <div class="pull-left spacer-right">
-          <p class="note">{{d release.date}}</p>
+          <p class="js-plugin-changelog-date note">{{d release.date}}</p>
         </div>
         {{#if release.changeLogUrl}}
           <div class="pull-right spacer-left">
-            <a href="{{release.changeLogUrl}}">Release Notes</a>
+            <a class="js-plugin-changelog-link" href="{{release.changeLogUrl}}">Release Notes</a>
           </div>
         {{/if}}
-        <div class="overflow-hidden">
+        <div class="js-plugin-changelog-description overflow-hidden">
           {{{release.description}}}
         </div>
       </li>
     {{/each}}
     <li class="spacer-bottom">
       <div class="pull-left spacer-right">
-        <span class="badge badge-success little-spacer-bottom">{{release.version}}</span>
+        <span class="js-plugin-changelog-version badge badge-success little-spacer-bottom">{{release.version}}</span>
       </div>
       <div class="pull-left spacer-right">
-        <p class="note">{{d release.date}}</p>
+        <p class="js-plugin-changelog-date note">{{d release.date}}</p>
       </div>
       {{#if release.changeLogUrl}}
         <div class="pull-right spacer-left">
-          <a href="{{release.changeLogUrl}}">Release Notes</a>
+          <a class="js-plugin-changelog-link" href="{{release.changeLogUrl}}">Release Notes</a>
         </div>
       {{/if}}
-      <div class="overflow-hidden">
+      <div class="js-plugin-changelog-description overflow-hidden">
         {{{release.description}}}
       </div>
     </li>
index aebd742b21d5df1d9aebc76f9ce03211de42a828..34fba6afb363fe22b12224dcb5a6145942f64757 100644 (file)
@@ -2,7 +2,7 @@
   <div>
     <strong class="js-plugin-name">{{name}}</strong>
     {{#if category}}
-      <span class="badge spacer-left">{{category}}</span>
+      <span class="js-plugin-category badge spacer-left">{{category}}</span>
     {{/if}}
   </div>
   <div class="js-plugin-description little-spacer-top">{{{description}}}</div>
@@ -15,7 +15,7 @@
   <ul class="overflow-hidden bordered-left">
     {{#if version}}
       <li class="spacer-left little-spacer-bottom">
-        <strong>{{version}}</strong>&nbsp;installed
+        <strong class="js-plugin-installed-version">{{version}}</strong>&nbsp;installed
       </li>
     {{/if}}
     {{#notEmpty updates}}
         <li class="spacer-left little-spacer-bottom">
           <div class="pull-left spacer-right">
             {{#notEq status 'COMPATIBLE'}}
-              <span class="badge badge-warning" data-toggle="tooltip" title="{{t 'update_center.status' status}}">
-                {{release.version}}
-              </span>
+              <span class="js-update-version badge badge-warning" data-toggle="tooltip"
+                    title="{{t 'update_center.status' status}}">{{release.version}}</span>
             {{else}}
-              <span class="badge badge-success">{{release.version}}</span>
+              <span class="js-update-version badge badge-success">{{release.version}}</span>
             {{/notEq}}
           </div>
           <div class="overflow-hidden">
       <li class="little-spacer-bottom">
         <ul class="list-inline">
           {{#if homepageUrl}}
-            <li><a href="{{homepageUrl}}">Homepage</a></li>
+            <li><a class="js-plugin-homepage" href="{{homepageUrl}}">Homepage</a></li>
           {{/if}}
           {{#if issueTrackerUrl}}
-            <li><a href="{{issueTrackerUrl}}">Issue Tracker</a></li>
+            <li><a class="js-plugin-issues" href="{{issueTrackerUrl}}">Issue Tracker</a></li>
           {{/if}}
           {{#if termsAndConditionsUrl}}
-            <li><a href="{{termsAndConditionsUrl}}">Terms and Conditions</a></li>
+            <li><a class="js-plugin-terms" href="{{termsAndConditionsUrl}}">Terms and Conditions</a></li>
           {{/if}}
         </ul>
       </li>
     {{/any}}
 
     {{#if license}}
-      <li class="little-spacer-bottom">Licensed under {{license}}</li>
+      <li class="little-spacer-bottom">Licensed under <span class="js-plugin-license">{{license}}</span></li>
     {{/if}}
 
     {{#if organizationName}}
       <li class="little-spacer-bottom">
         Developed by
         {{#if organizationUrl}}
-          <a href="{{organizationUrl}}">{{organizationName}}</a>
+          <a class="js-plugin-organization" href="{{organizationUrl}}">{{organizationName}}</a>
         {{else}}
-          {{organizationName}}
+          <span class="js-plugin-organization">{{organizationName}}</span>
         {{/if}}
       </li>
     {{/if}}
index adc28664f786cb05dcea847e6efe4804859bd7db..7ecc1b25fb4a5d028ffc722beff2e95ae2df4a80 100644 (file)
 <div class="display-inline-block text-top width-20">
   <div>
     <strong class="js-plugin-name">SonarQube {{version}}</strong>
-    <span class="badge badge-success spacer-left">System Update</span>
+    <span class="js-plugin-category badge badge-success spacer-left">System Update</span>
   </div>
   <div class="js-plugin-description little-spacer-top">{{{description}}}</div>
 
   <ul class="big-spacer-top">
     {{#if changeLogUrl}}
       <li class="little-spacer-bottom">
-        <a href="{{changeLogUrl}}">Release Notes</a>
+        <a class="js-plugin-release-notes" href="{{changeLogUrl}}">Release Notes</a>
       </li>
     {{/if}}
     {{#if releaseDate}}
-      <li class="little-spacer-bottom">Released: {{d releaseDate}}</li>
+      <li class="little-spacer-bottom">Released: <span class="js-plugin-date">{{d releaseDate}}</span></li>
     {{/if}}
   </ul>
 </div>
@@ -31,7 +31,7 @@
   <div class="pull-left spacer-right">
     <strong>How to upgrade</strong>
   </div>
-  <ul class="list-styled overflow-hidden bordered-left">
+  <ul class="js-plugin-update-steps list-styled overflow-hidden bordered-left">
     <li class="little-spacer-bottom">Stop SonarQube</li>
     <li class="little-spacer-bottom"><a href="{{downloadUrl}}">Download</a> and install
       SonarQube {{version}} after having carefully read the
diff --git a/server/sonar-web/src/test/js/update-center-spec.js b/server/sonar-web/src/test/js/update-center-spec.js
new file mode 100644 (file)
index 0000000..fcf8be2
--- /dev/null
@@ -0,0 +1,430 @@
+/* global describe:false, it:false */
+var lib = require('../lib');
+
+describe('Update Center App', function () {
+
+  it('should show plugin card', 16, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base#installed'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/installed', 'installed.json');
+          lib.fmock('/api/plugins/updates', 'updates.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 5);
+          test.assertSelectorContains('li[data-id="scmgit"] .js-plugin-name', 'Git');
+          test.assertSelectorContains('li[data-id="scmgit"] .js-plugin-category', 'Integration');
+          test.assertSelectorContains('li[data-id="scmgit"] .js-plugin-description', 'Git SCM Provider.');
+          test.assertSelectorContains('li[data-id="scmgit"] .js-plugin-installed-version', '1.0');
+          test.assertElementCount('li[data-id="scmgit"] .js-update-version', 1);
+          test.assertSelectorContains('li[data-id="scmgit"] .js-update-version', '1.1');
+          test.assertElementCount('li[data-id="scmgit"] .js-changelog', 1);
+          test.assertElementCount('li[data-id="scmgit"] .js-plugin-homepage', 1);
+          test.assertElementCount('li[data-id="scmgit"] .js-plugin-issues', 1);
+          test.assertDoesntExist('li[data-id="scmgit"] .js-plugin-terms');
+          test.assertSelectorContains('li[data-id="scmgit"] .js-plugin-license', 'GNU LGPL 3');
+          test.assertSelectorContains('li[data-id="scmgit"] .js-plugin-organization', 'SonarSource');
+          test.assertElementCount('li[data-id="scmgit"] .js-update', 1);
+          test.assertElementCount('li[data-id="scmgit"] .js-uninstall', 1);
+          test.assertDoesntExist('li[data-id="scmgit"] .js-install');
+        });
+  });
+
+  it('should show system update', 8, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base#updates'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/installed', 'installed.json');
+          lib.fmock('/api/plugins/updates', 'updates.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+          lib.fmock('/api/system/upgrades', 'system-updates.json');
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-system]', 1);
+          test.assertSelectorContains('li[data-system] .js-plugin-name', 'SonarQube 5.3');
+          test.assertSelectorContains('li[data-system] .js-plugin-category', 'System Update');
+          test.assertSelectorContains('li[data-system] .js-plugin-description', 'New!');
+          test.assertElementCount('li[data-system] .js-plugin-release-notes', 1);
+          test.assertElementCount('li[data-system] .js-plugin-date', 1);
+          test.assertElementCount('li[data-system] .js-plugin-update-steps', 1);
+          test.assertElementCount('li[data-system] .js-plugin-update-steps > li', 4);
+        });
+  });
+
+  it('should show installed', 3, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base#installed'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/installed', 'installed.json');
+          lib.fmock('/api/plugins/updates', 'updates.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 5);
+          test.assertExists('li[data-id="scmgit"]');
+          test.assertExists('li[data-id="javascript"]');
+        });
+  });
+
+  it('should show updates', 3, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base#updates'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/installed', 'installed.json');
+          lib.fmock('/api/plugins/updates', 'updates.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+          lib.fmock('/api/system/upgrades', 'system-updates.json');
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 4);
+          test.assertExists('li[data-id="scmgit"]');
+          test.assertDoesntExist('li[data-id="javascript"]');
+        });
+  });
+
+  it('should show available', 3, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base#available'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/available', 'available.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 3);
+          test.assertDoesntExist('li[data-id="scmgit"]');
+          test.assertExists('li[data-id="abap"]');
+        });
+  });
+
+  it('should switch between views', 18, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base#installed'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/installed', 'installed.json');
+          lib.fmock('/api/plugins/updates', 'updates.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+          lib.fmock('/api/plugins/available', 'available.json');
+          lib.fmock('/api/system/upgrades', 'system-updates.json');
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 5);
+          test.assertExists('li[data-id="javascript"]');
+          test.assertExists('#update-center-filter-installed:checked');
+          casper.click('#update-center-filter-available');
+          casper.waitForSelector('li[data-id="abap"]');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 3);
+          test.assertExists('li[data-id="abap"]');
+          test.assertExists('#update-center-filter-available:checked');
+          casper.click('#update-center-filter-updates');
+          casper.waitForSelector('li[data-id="scmgit"]');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 4);
+          test.assertExists('li[data-id="scmgit"]');
+          test.assertExists('#update-center-filter-updates:checked');
+          casper.click('#update-center-filter-installed');
+          casper.waitForSelector('li[data-id="javascript"]');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 5);
+          test.assertExists('li[data-id="javascript"]');
+          test.assertExists('#update-center-filter-installed:checked');
+          casper.click('#update-center-filter-available');
+          casper.waitForSelector('li[data-id="abap"]');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 3);
+          test.assertExists('li[data-id="abap"]');
+          test.assertExists('#update-center-filter-available:checked');
+          casper.click('#update-center-filter-updates');
+          casper.waitForSelector('li[data-id="scmgit"]');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 4);
+          test.assertExists('li[data-id="scmgit"]');
+          test.assertExists('#update-center-filter-updates:checked');
+        });
+  });
+
+  it('should search', 5, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base#installed'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/installed', 'installed.json');
+          lib.fmock('/api/plugins/updates', 'updates.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 5);
+          test.assertDoesntExist('li.hidden[data-id]');
+          casper.evaluate(function () {
+            jQuery('#update-center-search-query').val('jA');
+          });
+          casper.click('#update-center-search-submit');
+          casper.waitForSelector('li.hidden[data-id]');
+        })
+
+        .then(function () {
+          test.assertElementCount('li[data-id]', 5);
+          test.assertElementCount('li.hidden[data-id]', 3);
+          test.assertSelectorContains('li:not(.hidden)[data-id] .js-plugin-name', 'JavaScript');
+        });
+  });
+
+  it('should show plugin changelog', 4, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base#installed'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/installed', 'installed.json');
+          lib.fmock('/api/plugins/updates', 'updates.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          casper.click('li[data-id="python"] .js-changelog');
+          casper.waitForSelector('.bubble-popup');
+        })
+
+        .then(function () {
+          test.assertElementCount('.bubble-popup .js-plugin-changelog-version', 2);
+          test.assertElementCount('.bubble-popup .js-plugin-changelog-date', 2);
+          test.assertElementCount('.bubble-popup .js-plugin-changelog-link', 2);
+          test.assertElementCount('.bubble-popup .js-plugin-changelog-description', 2);
+        });
+  });
+
+  it('should update plugin', 1, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/installed', 'installed.json');
+          lib.fmock('/api/plugins/updates', 'updates.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+          lib.smock('/api/plugins/update', '{}', { data: { key: 'scmgit' } });
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          casper.click('li[data-id="scmgit"] .js-update');
+          casper.waitUntilVisible('li[data-id="scmgit"] .js-spinner');
+        })
+
+        .then(function () {
+          test.assertSelectorContains('li[data-id="scmgit"]', 'To Be Installed');
+        });
+  });
+
+  it('should uninstall plugin', 1, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/installed', 'installed.json');
+          lib.fmock('/api/plugins/updates', 'updates.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+          lib.smock('/api/plugins/uninstall', '{}', { data: { key: 'scmgit' } });
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          casper.click('li[data-id="scmgit"] .js-uninstall');
+          casper.waitUntilVisible('li[data-id="scmgit"] .js-spinner');
+        })
+
+        .then(function () {
+          test.assertSelectorContains('li[data-id="scmgit"]', 'To Be Uninstalled');
+        });
+  });
+
+  it('should install plugin', 1, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base#available'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/available', 'available.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+          lib.smock('/api/plugins/install', '{}', { data: { key: 'abap' } });
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          casper.click('li[data-id="abap"] .js-install');
+          casper.waitUntilVisible('li[data-id="abap"] .js-spinner');
+        })
+
+        .then(function () {
+          test.assertSelectorContains('li[data-id="abap"]', 'To Be Installed');
+        });
+  });
+
+  it('should cancel all pending', 1, function (casper, test) {
+    return casper
+        .start(lib.buildUrl('base#available'), function () {
+          lib.setDefaultViewport();
+          lib.fmock('/api/plugins/available', 'available.json');
+          lib.fmock('/api/plugins/pending', 'pending.json');
+          lib.smock('/api/plugins/cancel_all', '{}');
+        })
+
+        .then(function () {
+          casper.evaluate(function () {
+            require(['apps/update-center/app'], function (App) {
+              App.start({ el: '#content', urlRoot: '/pages/base' });
+            });
+          });
+        })
+
+        .then(function () {
+          casper.waitForSelector('.js-plugin-name');
+        })
+
+        .then(function () {
+          test.assertExists('.js-pending');
+          casper.click('.js-cancel-all');
+          casper.waitUntilVisible('.js-pending');
+        });
+  });
+
+});
diff --git a/server/sonar-web/src/test/json/update-center-spec/available.json b/server/sonar-web/src/test/json/update-center-spec/available.json
new file mode 100644 (file)
index 0000000..9565863
--- /dev/null
@@ -0,0 +1,68 @@
+{
+  "plugins": [
+    {
+      "key": "abap",
+      "name": "ABAP",
+      "category": "Languages",
+      "description": "Enable analysis and reporting on ABAP projects",
+      "license": "Commercial",
+      "termsAndConditionsUrl": "http://dist.sonarsource.com/SonarSource_Terms_And_Conditions.pdf",
+      "organizationName": "SonarSource",
+      "organizationUrl": "http://www.sonarsource.com",
+      "release": {
+        "version": "3.2",
+        "date": "2015-03-10",
+        "description": "14 new rules, most of them designed to detect potential performance hotspots.",
+        "changeLogUrl": "http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10054&version=10575"
+      },
+      "update": {
+        "status": "COMPATIBLE",
+        "requires": []
+      }
+    },
+    {
+      "key": "visualstudio",
+      "name": "Analysis Bootstrapper for Visual Studio Projects",
+      "category": "Languages",
+      "description": "Bootstraps the analysis from Visual Studio solution and project files.",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource",
+      "organizationUrl": "http://www.sonarsource.com",
+      "release": {
+        "version": "1.2",
+        "date": "2014-10-23",
+        "description": "Support multi-language (JavaScript, CSS) and SonarQube 4.5"
+      },
+      "update": {
+        "status": "COMPATIBLE",
+        "requires": []
+      }
+    },
+    {
+      "key": "android",
+      "name": "Android",
+      "category": "Languages",
+      "description": "Import Android Lint reports.",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource and Jerome Van Der Linden, Stephane Nicolas, Florian Roncari, Thomas Bores",
+      "organizationUrl": "http://www.sonarsource.com",
+      "release": {
+        "version": "1.1",
+        "date": "2015-04-23",
+        "description": "This plugin has been renamed \"Android Lint\" to prevent any misunderstanding about its purpose: an Android project can be analysed with the standard SonarQube Java plugin and this plugin just allows to import Android Lint reports if needed. This new version provides a default sqale mapping for the Android Lint rules and the ability to automatically execute lint has been dropped.",
+        "changeLogUrl": "http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10944&version=11729"
+      },
+      "update": {
+        "status": "COMPATIBLE",
+        "requires": [
+          {
+            "key": "java",
+            "name": "Java",
+            "description": "SonarQube rule engine."
+          }
+        ]
+      }
+    }
+  ],
+  "updateCenterRefresh": "2015-06-26T09:24:39+0200"
+}
diff --git a/server/sonar-web/src/test/json/update-center-spec/installed.json b/server/sonar-web/src/test/json/update-center-spec/installed.json
new file mode 100644 (file)
index 0000000..b1ef6f7
--- /dev/null
@@ -0,0 +1,63 @@
+{
+  "plugins": [
+    {
+      "key": "scmgit",
+      "name": "Git",
+      "description": "Git SCM Provider.",
+      "version": "1.0",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource",
+      "organizationUrl": "http://www.sonarsource.com",
+      "homepageUrl": "http://redirect.sonarsource.com/plugins/scmgit.html",
+      "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARSCGIT",
+      "implementationBuild": "9ce9d330c313c296fab051317cc5ad4b26319e07"
+    },
+    {
+      "key": "java",
+      "name": "Java",
+      "description": "SonarQube rule engine.",
+      "version": "3.2-SNAPSHOT",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource",
+      "organizationUrl": "http://www.sonarsource.com",
+      "homepageUrl": "http://redirect.sonarsource.com/plugins/java.html",
+      "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARJAVA",
+      "implementationBuild": "c5c58e015c8d44b4f46dea7eea353e42ea7059a2"
+    },
+    {
+      "key": "javascript",
+      "name": "JavaScript",
+      "description": "Enables analysis of JavaScript projects.",
+      "version": "2.6",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource and Eriks Nukis",
+      "organizationUrl": "http://www.sonarsource.com",
+      "homepageUrl": "http://redirect.sonarsource.com/plugins/javascript.html",
+      "issueTrackerUrl": "https://jira.codehaus.org/browse/SONARJS",
+      "implementationBuild": "6bd2bfe2eb0d5db6760d8f566ca399bcbcf80a5d"
+    },
+    {
+      "key": "php",
+      "name": "PHP",
+      "description": "Enables analysis of PHP projects.",
+      "version": "2.4",
+      "license": "GNU LGPL v3",
+      "organizationName": "SonarSource and Akram Ben Aissi",
+      "organizationUrl": "http://www.sonarsource.com/",
+      "homepageUrl": "http://docs.codehaus.org/display/SONAR/PHP+Plugin",
+      "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARPHP",
+      "implementationBuild": "1b445c1b06da39330051cf943f24e361ee9001f6"
+    },
+    {
+      "key": "python",
+      "name": "Python",
+      "description": "Enable analysis and reporting on python projects.",
+      "version": "1.3",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource and Waleri Enns",
+      "homepageUrl": "http://docs.codehaus.org/display/SONAR/Python+Plugin",
+      "issueTrackerUrl": "https://jira.codehaus.org/browse/SONARPY",
+      "implementationBuild": "2683ee7b41164f809454470c08d3764c53903722"
+    }
+  ]
+}
diff --git a/server/sonar-web/src/test/json/update-center-spec/pending.json b/server/sonar-web/src/test/json/update-center-spec/pending.json
new file mode 100644 (file)
index 0000000..5aab8a7
--- /dev/null
@@ -0,0 +1,54 @@
+{
+  "installing": [
+    {
+      "key": "visualstudio",
+      "name": "Analysis Bootstrapper for Visual Studio Projects",
+      "description": "Bootstraps the analysis from Visual Studio solution and project files.",
+      "version": "1.2",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource",
+      "organizationUrl": "http://www.sonarsource.com",
+      "homepageUrl": "http://docs.codehaus.org/x/TAA1Dg",
+      "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARVS",
+      "implementationBuild": "debe8e3820709cb34658d23f4de77d65577d42b1"
+    },
+    {
+      "key": "java",
+      "name": "Java",
+      "description": "SonarQube rule engine.",
+      "version": "3.3",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource",
+      "organizationUrl": "http://www.sonarsource.com",
+      "homepageUrl": "http://redirect.sonarsource.com/plugins/java.html",
+      "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARJAVA",
+      "implementationBuild": "8edb61630d99c752a252842633254374c0a3e70d"
+    },
+    {
+      "key": "php",
+      "name": "PHP",
+      "description": "Enables analysis of PHP projects.",
+      "version": "2.6",
+      "license": "GNU LGPL v3",
+      "organizationName": "SonarSource and Akram Ben Aissi",
+      "organizationUrl": "http://www.sonarsource.com/",
+      "homepageUrl": "http://redirect.sonarsource.com/plugins/php.html",
+      "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARPHP",
+      "implementationBuild": "153f397dc6cac76c93eca5df541278447ed85ea4"
+    }
+  ],
+  "removing": [
+    {
+      "key": "javascript",
+      "name": "JavaScript",
+      "description": "Enables analysis of JavaScript projects.",
+      "version": "2.6",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource and Eriks Nukis",
+      "organizationUrl": "http://www.sonarsource.com",
+      "homepageUrl": "http://redirect.sonarsource.com/plugins/javascript.html",
+      "issueTrackerUrl": "https://jira.codehaus.org/browse/SONARJS",
+      "implementationBuild": "6bd2bfe2eb0d5db6760d8f566ca399bcbcf80a5d"
+    }
+  ]
+}
diff --git a/server/sonar-web/src/test/json/update-center-spec/system-updates.json b/server/sonar-web/src/test/json/update-center-spec/system-updates.json
new file mode 100644 (file)
index 0000000..290ff56
--- /dev/null
@@ -0,0 +1,26 @@
+{
+  "upgrades": [
+    {
+      "version": "5.3",
+      "description": "New!",
+      "releaseDate": "2015-06-19",
+      "changeLogUrl": "http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10930&version=11625",
+      "downloadUrl": "https://downloads.sonarsource.com/sonarqube/sonarqube-5.0.zip",
+      "plugins": {
+        "requireUpdate": [
+          {
+            "key": "python",
+            "name": "Python",
+            "category": "Languages",
+            "description": "Enable analysis and reporting on python projects.",
+            "license": "GNU LGPL 3",
+            "organizationName": "SonarSource and Waleri Enns",
+            "version": "1.5"
+          }
+        ],
+        "incompatible": []
+      }
+    }
+  ],
+  "updateCenterRefresh": "2015-06-26T09:59:51+0200"
+}
diff --git a/server/sonar-web/src/test/json/update-center-spec/updates.json b/server/sonar-web/src/test/json/update-center-spec/updates.json
new file mode 100644 (file)
index 0000000..dc040f6
--- /dev/null
@@ -0,0 +1,118 @@
+{
+  "plugins": [
+    {
+      "key": "scmgit",
+      "name": "Git",
+      "category": "Integration",
+      "description": "Git SCM Provider.",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource",
+      "organizationUrl": "http://www.sonarsource.com",
+      "updates": [
+        {
+          "release": {
+            "version": "1.1",
+            "date": "2015-06-01",
+            "description": "Use Git commit date instead of author date",
+            "changeLogUrl": "http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10964&version=11856"
+          },
+          "status": "COMPATIBLE",
+          "requires": []
+        }
+      ]
+    },
+    {
+      "key": "java",
+      "name": "Java",
+      "category": "Languages",
+      "description": "SonarQube rule engine.",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource",
+      "organizationUrl": "http://www.sonarsource.com",
+      "updates": [
+        {
+          "release": {
+            "version": "3.3",
+            "date": "2015-05-19",
+            "description": "Detection of locks left locked and new rules",
+            "changeLogUrl": "http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10973&version=11898"
+          },
+          "status": "COMPATIBLE",
+          "requires": []
+        }
+      ]
+    },
+    {
+      "key": "php",
+      "name": "PHP",
+      "category": "Languages",
+      "description": "Enables analysis of PHP projects.",
+      "license": "GNU LGPL v3",
+      "organizationName": "SonarSource and Akram Ben Aissi",
+      "organizationUrl": "http://www.sonarsource.com/",
+      "updates": [
+        {
+          "release": {
+            "version": "2.4.1",
+            "date": "2015-02-24",
+            "description": "Bug fix release",
+            "changeLogUrl": "http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10956&version=11824"
+          },
+          "status": "COMPATIBLE",
+          "requires": []
+        },
+        {
+          "release": {
+            "version": "2.5",
+            "date": "2015-05-19",
+            "description": "5 bug detection rules, removal of all known parsing limitations and import of PHPUnit IT coverage report",
+            "changeLogUrl": "http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10956&version=11825"
+          },
+          "status": "COMPATIBLE",
+          "requires": []
+        },
+        {
+          "release": {
+            "version": "2.6",
+            "date": "2015-06-05",
+            "description": "5 new rules & improvement of existing ones",
+            "changeLogUrl": "http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10956&version=11826"
+          },
+          "status": "COMPATIBLE",
+          "requires": []
+        }
+      ]
+    },
+    {
+      "key": "python",
+      "name": "Python",
+      "category": "Languages",
+      "description": "Enable analysis and reporting on python projects.",
+      "license": "GNU LGPL 3",
+      "organizationName": "SonarSource and Waleri Enns",
+      "updates": [
+        {
+          "release": {
+            "version": "1.4",
+            "date": "2015-03-24",
+            "description": "Provides a SQALE definition to PyLint rules, allows the import of Pylint reports and adds tags to rules.",
+            "changeLogUrl": "http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10958&version=11835"
+          },
+          "status": "INCOMPATIBLE",
+          "requires": []
+        },
+        {
+          "release": {
+            "version": "1.5",
+            "date": "2015-04-02",
+            "description": "Provides 20 new rules and fixes some parsing issues.",
+            "changeLogUrl": "http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=10958&version=11836"
+          },
+          "status": "COMPATIBLE",
+          "requires": []
+        }
+      ]
+    }
+  ],
+  "updateCenterRefresh": "2015-06-26T09:27:08+0200"
+}