From d7315be8b112d68924d25261fcceb5450aafd5c7 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Tue, 31 Mar 2015 16:30:47 +0200 Subject: [PATCH] SONAR-6364 Display CLOSED issues on top of the component viewer --- .../src/main/coffee/issue/models/issue.coffee | 5 + .../issues/component-viewer/main.coffee | 2 +- .../src/main/js/source-viewer/viewer.js | 2 +- .../sonar-web/src/main/less/pages/issues.less | 2 +- .../src/test/js/source-viewer-issues.js | 65 +++++ .../test/json/source-viewer-issues/app.json | 19 ++ .../source-viewer-issues/closed-issues.json | 256 ++++++++++++++++++ .../test/json/source-viewer-issues/lines.json | 22 ++ 8 files changed, 370 insertions(+), 3 deletions(-) create mode 100644 server/sonar-web/src/test/js/source-viewer-issues.js create mode 100644 server/sonar-web/src/test/json/source-viewer-issues/app.json create mode 100644 server/sonar-web/src/test/json/source-viewer-issues/closed-issues.json create mode 100644 server/sonar-web/src/test/json/source-viewer-issues/lines.json diff --git a/server/sonar-web/src/main/coffee/issue/models/issue.coffee b/server/sonar-web/src/main/coffee/issue/models/issue.coffee index e5f99dc2bed..ca21696a82a 100644 --- a/server/sonar-web/src/main/coffee/issue/models/issue.coffee +++ b/server/sonar-web/src/main/coffee/issue/models/issue.coffee @@ -30,3 +30,8 @@ define -> parse: (r) -> if r.issue then r.issue else r + + + getDisplayLine: -> + return 0 if @get('status') == 'CLOSED' + @get('line') || 0 diff --git a/server/sonar-web/src/main/coffee/issues/component-viewer/main.coffee b/server/sonar-web/src/main/coffee/issues/component-viewer/main.coffee index 76288c332d7..335db325971 100644 --- a/server/sonar-web/src/main/coffee/issues/component-viewer/main.coffee +++ b/server/sonar-web/src/main/coffee/issues/component-viewer/main.coffee @@ -52,7 +52,7 @@ define [ super @bindShortcuts() if @baseIssue? - @scrollToLine @baseIssue.get 'line' + @scrollToLine @baseIssue.getDisplayLine() bindShortcuts: -> diff --git a/server/sonar-web/src/main/js/source-viewer/viewer.js b/server/sonar-web/src/main/js/source-viewer/viewer.js index 66600022fa2..b86c28532d3 100644 --- a/server/sonar-web/src/main/js/source-viewer/viewer.js +++ b/server/sonar-web/src/main/js/source-viewer/viewer.js @@ -298,7 +298,7 @@ define([ var that = this, lines = {}; issues.forEach(function (issue) { - var line = issue.get('line') || 0; + var line = issue.getDisplayLine(); if (!_.isArray(lines[line])) { lines[line] = []; } diff --git a/server/sonar-web/src/main/less/pages/issues.less b/server/sonar-web/src/main/less/pages/issues.less index 0cc944a4c37..90998f33aea 100644 --- a/server/sonar-web/src/main/less/pages/issues.less +++ b/server/sonar-web/src/main/less/pages/issues.less @@ -163,7 +163,7 @@ } .issues-workspace-home { - width: ~"calc(100vw - @{sideWidth})"; + width: ~"calc(100vw - @{sideWidth} - 20px)"; max-width: 900px; margin-left: auto; margin-right: auto; diff --git a/server/sonar-web/src/test/js/source-viewer-issues.js b/server/sonar-web/src/test/js/source-viewer-issues.js new file mode 100644 index 00000000000..e1822a1aa72 --- /dev/null +++ b/server/sonar-web/src/test/js/source-viewer-issues.js @@ -0,0 +1,65 @@ +/* + * 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. + */ +/* global casper:false */ + + +var lib = require('../lib'), + testName = lib.testName('Source Viewer', 'Issues'); + +lib.initMessages(); +lib.changeWorkingDirectory('source-viewer-issues'); +lib.configureCasper(); + + +casper.test.begin(testName('Closed Issues on Top'), function (test) { + casper + .start(lib.buildUrl('source-viewer'), function () { + lib.setDefaultViewport(); + + + lib.mockRequestFromFile('/api/components/app', 'app.json'); + lib.mockRequestFromFile('/api/sources/lines', 'lines.json'); + lib.mockRequestFromFile('/api/issues/search', 'closed-issues.json'); + }) + + .then(function () { + casper.evaluate(function () { + require(['/js/source-viewer/app.js']); + }); + }) + + .then(function () { + casper.waitForSelector('.source-line'); + }) + + .then(function () { + casper.click('.source-line-with-issues[data-line-number="0"]'); + lib.capture(); + test.assertElementCount('.source-line-code[data-line-number="0"] .issue', 2); + }) + + .then(function () { + lib.sendCoverage(); + }) + + .run(function () { + test.done(); + }); +}); diff --git a/server/sonar-web/src/test/json/source-viewer-issues/app.json b/server/sonar-web/src/test/json/source-viewer-issues/app.json new file mode 100644 index 00000000000..bfee785a15c --- /dev/null +++ b/server/sonar-web/src/test/json/source-viewer-issues/app.json @@ -0,0 +1,19 @@ +{ + "uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaaa", + "key": "sample:sample", + "path": "sample/path", + "name": "Sample", + "longName": "Sample", + "q": "FIL", + "subProject": "sample:subproject", + "subProjectName": "Sample Sub-Project", + "project": "sample:project", + "projectName": "Sample Project", + "fav": false, + "canMarkAsFavourite": true, + "canCreateManualIssue": true, + "measures": { + "lines": "20", + "duplicationDensity": "25%" + } +} diff --git a/server/sonar-web/src/test/json/source-viewer-issues/closed-issues.json b/server/sonar-web/src/test/json/source-viewer-issues/closed-issues.json new file mode 100644 index 00000000000..338a220b4e4 --- /dev/null +++ b/server/sonar-web/src/test/json/source-viewer-issues/closed-issues.json @@ -0,0 +1,256 @@ +{ + "total": 4, + "p": 1, + "ps": 50, + "paging": { + "pageIndex": 1, + "pageSize": 50, + "total": 4, + "fTotal": "4", + "pages": 1 + }, + "projects": [ + { + "uuid": "69e57151-be0d-4157-adff-c06741d88879", + "key": "org.codehaus.sonar:sonar", + "id": 2865, + "qualifier": "TRK", + "name": "SonarQube", + "longName": "SonarQube" + } + ], + "components": [ + { + "uuid": "69e57151-be0d-4157-adff-c06741d88879", + "key": "org.codehaus.sonar:sonar", + "id": 2865, + "enabled": true, + "qualifier": "TRK", + "name": "SonarQube", + "longName": "SonarQube" + }, + { + "uuid": "cff90ddb-b51f-4dab-808d-2891affa34d9", + "key": "org.codehaus.sonar:sonar-server:src/main/java/org/sonar/server/qualityprofile/RuleActivator.java", + "id": 31223, + "enabled": true, + "qualifier": "FIL", + "name": "RuleActivator.java", + "longName": "src/main/java/org/sonar/server/qualityprofile/RuleActivator.java", + "path": "src/main/java/org/sonar/server/qualityprofile/RuleActivator.java", + "projectId": 2865, + "subProjectId": 2872 + }, + { + "uuid": "e1f6f8bd-6b5f-4e2d-b936-4abffc9e4264", + "key": "org.codehaus.sonar:sonar-server", + "id": 2872, + "enabled": true, + "qualifier": "BRC", + "name": "SonarQube :: Server", + "longName": "SonarQube :: Server", + "path": "sonar-server", + "projectId": 2865, + "subProjectId": 2865 + }, + { + "uuid": "e0071532-a00c-4952-82ac-aed4afb10e5a", + "key": "org.codehaus.sonar:sonar-server:src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java", + "id": 24253, + "enabled": false, + "qualifier": "FIL", + "name": "QProfileOperations.java", + "longName": "src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java", + "path": "src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java", + "projectId": 2865, + "subProjectId": 2872 + } + ], + "issues": [ + { + "key": "5b810e20-4c3b-46cf-8b30-3e613e425001", + "component": "org.codehaus.sonar:sonar-server:src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java", + "componentId": 24253, + "project": "org.codehaus.sonar:sonar", + "rule": "squid:S1143", + "status": "CLOSED", + "resolution": "FIXED", + "severity": "BLOCKER", + "message": "Remove this return statement from this finally block.", + "line": 90, + "debt": "20min", + "assignee": "julien.lancelot", + "author": "julien.lancelot@sonarsource.com", + "actionPlan": "eaf2a3b4-e06f-4e8a-92ec-444f1cf68231", + "creationDate": "2013-12-13T23:55:31+0100", + "updateDate": "2013-12-16T16:42:32+0100", + "fUpdateAge": "about a year", + "closeDate": "2013-12-16T16:42:32+0100", + "tags": [ + "bug" + ], + "actions": [], + "transitions": [], + "assigneeName": "Julien Lancelot", + "actionPlanName": "4.2" + }, + { + "key": "04595b75-2063-43e4-bd61-f83818ee0520", + "component": "org.codehaus.sonar:sonar-server:src/main/java/org/sonar/server/qualityprofile/RuleActivator.java", + "componentId": 31223, + "project": "org.codehaus.sonar:sonar", + "subProject": "org.codehaus.sonar:sonar-server", + "rule": "squid:S2259", + "status": "CLOSED", + "resolution": "FIXED", + "severity": "BLOCKER", + "message": "NullPointerException might be thrown as 'activeRule' is nullable here", + "line": 274, + "debt": "10min", + "assignee": "simon.brandhof", + "author": "simon.brandhof@sonarsource.com", + "creationDate": "2015-03-26T23:08:38+0100", + "updateDate": "2015-03-30T16:41:19+0200", + "fUpdateAge": "24 hours", + "closeDate": "2015-03-30T16:41:19+0200", + "tags": [ + "bug", + "cert", + "cwe", + "owasp-a1", + "owasp-a2", + "owasp-a6", + "security" + ], + "actions": [], + "transitions": [], + "assigneeName": "Simon Brandhof" + }, + { + "key": "5a5f6572-cdaa-4f2d-bd26-4eab8a8eef03", + "component": "org.codehaus.sonar:sonar-server:src/main/java/org/sonar/server/qualityprofile/RuleActivator.java", + "componentId": 31223, + "project": "org.codehaus.sonar:sonar", + "subProject": "org.codehaus.sonar:sonar-server", + "rule": "squid:S2259", + "status": "OPEN", + "severity": "BLOCKER", + "message": "NullPointerException might be thrown as 'activeRuleParamsAsMap' is nullable here", + "line": 4, + "debt": "10min", + "assignee": "simon.brandhof", + "author": "simon.brandhof@sonarsource.com", + "creationDate": "2015-03-26T23:08:38+0100", + "updateDate": "2015-03-26T23:08:38+0100", + "fUpdateAge": "4 days", + "tags": [ + "bug", + "cert", + "cwe", + "owasp-a1", + "owasp-a2", + "owasp-a6", + "security" + ], + "actions": [], + "transitions": [], + "assigneeName": "Simon Brandhof" + }, + { + "key": "2c69b917-a156-4638-a398-969916e29053", + "component": "org.codehaus.sonar:sonar-server:src/main/java/org/sonar/server/qualityprofile/RuleActivator.java", + "componentId": 31223, + "project": "org.codehaus.sonar:sonar", + "subProject": "org.codehaus.sonar:sonar-server", + "rule": "squid:S2259", + "status": "OPEN", + "severity": "BLOCKER", + "message": "NullPointerException might be thrown as 'activeRule' is nullable here", + "line": 5, + "debt": "10min", + "assignee": "simon.brandhof", + "author": "simon.brandhof@sonarsource.com", + "creationDate": "2015-03-26T23:08:38+0100", + "updateDate": "2015-03-26T23:08:38+0100", + "fUpdateAge": "4 days", + "tags": [ + "bug", + "cert", + "cwe", + "owasp-a1", + "owasp-a2", + "owasp-a6", + "security" + ], + "actions": [], + "transitions": [], + "assigneeName": "Simon Brandhof" + } + ], + "rules": [ + { + "key": "squid:S1143", + "name": "Return statements should not occur in finally blocks", + "lang": "java", + "desc": "", + "status": "READY", + "langName": "Java" + }, + { + "key": "squid:S2259", + "name": "Null pointers should not be dereferenced", + "lang": "java", + "desc": "", + "status": "REMOVED", + "langName": "Java" + } + ], + "users": [ + { + "login": "julien.lancelot", + "name": "Julien Lancelot", + "active": true, + "email": "julien.lancelot@sonarsource.com" + }, + { + "login": "simon.brandhof", + "name": "Simon Brandhof", + "active": true, + "email": "simon.brandhof@sonarsource.com" + } + ], + "actionPlans": [ + { + "key": "eaf2a3b4-e06f-4e8a-92ec-444f1cf68231", + "name": "4.2", + "status": "CLOSED", + "project": "org.codehaus.sonar:sonar", + "userLogin": "fabrice.bellingard", + "deadLine": "2014-01-31T00:00:00+0100", + "fDeadLine": "Jan 31, 2014 12:00 AM", + "createdAt": "2013-12-11T08:35:23+0100", + "fCreatedAt": "Dec 11, 2013 8:35 AM", + "updatedAt": "2014-04-14T11:55:03+0200", + "fUpdatedAt": "Apr 14, 2014 11:55 AM" + } + ], + "languages": [ + { + "key": "py", + "name": "Python" + }, + { + "key": "js", + "name": "JavaScript" + }, + { + "key": "php", + "name": "PHP" + }, + { + "key": "java", + "name": "Java" + } + ], + "facets": [] +} diff --git a/server/sonar-web/src/test/json/source-viewer-issues/lines.json b/server/sonar-web/src/test/json/source-viewer-issues/lines.json new file mode 100644 index 00000000000..5fc7b0cb4de --- /dev/null +++ b/server/sonar-web/src/test/json/source-viewer-issues/lines.json @@ -0,0 +1,22 @@ +{"sources": [ + { "line": 1, "code": "line 1" }, + { "line": 2, "code": "line 2" }, + { "line": 3, "code": "line 3" }, + { "line": 4, "code": "line 4" }, + { "line": 5, "code": "line 5" }, + { "line": 6, "code": "line 6" }, + { "line": 7, "code": "line 7" }, + { "line": 8, "code": "line 8" }, + { "line": 9, "code": "line 9" }, + { "line": 10, "code": "line 10" }, + { "line": 11, "code": "line 11", "duplicated": true }, + { "line": 12, "code": "line 12", "duplicated": true }, + { "line": 13, "code": "line 13", "duplicated": true }, + { "line": 14, "code": "line 14", "duplicated": true }, + { "line": 15, "code": "line 15", "duplicated": true }, + { "line": 16, "code": "line 16" }, + { "line": 17, "code": "line 17" }, + { "line": 18, "code": "line 18" }, + { "line": 19, "code": "line 19" }, + { "line": 20, "code": "line 20" } +]} -- 2.39.5