Skip to content

Commit

Permalink
When using Jira as source for the 'ready user story points' metric, c…
Browse files Browse the repository at this point in the history
…hanging the status of a user story in the details tab didn't work. Fixes #1230.
  • Loading branch information
fniessink committed Jun 17, 2020
1 parent ffbea0f commit 20d9294
Show file tree
Hide file tree
Showing 10 changed files with 22 additions and 17 deletions.
4 changes: 2 additions & 2 deletions components/collector/src/collector_utilities/type.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""Quality-time specific types."""

from typing import Any, Dict, List, NewType, Optional, Union
from typing import Any, Dict, List, NewType, Optional

import aiohttp


Entity = Dict[str, Union[int, float, str]] # pylint: disable=invalid-name
Entity = Dict[str, str] # pylint: disable=invalid-name
Entities = List[Entity]
ErrorMessage = Optional[str]
Job = Dict[str, Any]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ async def _parse_source_responses(self, responses: Responses) -> Tuple[Value, Va

def _create_entity(self, issue: Dict, url: URL) -> Entity:
entity = super()._create_entity(issue, url)
entity[self.entity_key] = cast(float, self.__value_of_field_to_sum(issue))
entity[self.entity_key] = str(cast(float, self.__value_of_field_to_sum(issue)))
return entity

def _include_issue(self, issue: Dict) -> bool:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ async def _parse_source_responses(self, responses: Responses) -> Tuple[Value, Va
priority = warning["priority"].lower()
file_path = warning["fileName"]
if file_path in entities:
entities[file_path]["nr_vulnerabilities"] = int(entities[file_path]["nr_vulnerabilities"]) + 1
entities[file_path]["nr_vulnerabilities"] = str(int(entities[file_path]["nr_vulnerabilities"]) + 1)
entities[file_path]["highest_severity"] = \
self.__highest_severity(str(entities[file_path]["highest_severity"]).lower(), priority).capitalize()
else:
entities[file_path] = dict(
key=file_path, file_path=file_path, highest_severity=priority.capitalize(), nr_vulnerabilities=1)
key=file_path, file_path=file_path, highest_severity=priority.capitalize(), nr_vulnerabilities="1")
return str(len(entities)), "100", list(entities.values())

def __highest_severity(self, severity1: str, severity2: str) -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def __parse_entity(
highest_severity = severity
break
return dict(key=key, file_path=file_path, highest_severity=highest_severity.capitalize(),
url=entity_landing_url, nr_vulnerabilities=len(vulnerabilities))
url=entity_landing_url, nr_vulnerabilities=str(len(vulnerabilities)))

def __vulnerabilities(self, element: Element, namespaces: Namespaces) -> List[Element]:
"""Return the vulnerabilities that have one of the severities specified in the parameters."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ async def test_nr_story_points(self):
self.assert_measurement(
response, value="42",
entities=[
dict(key="1", summary="user story 1", url="https://jira/browse/1", points=10.0),
dict(key="2", summary="user story 2", url="https://jira/browse/2", points=32.0)])
dict(key="1", summary="user story 1", url="https://jira/browse/1", points="10.0"),
dict(key="2", summary="user story 2", url="https://jira/browse/2", points="32.0")])


class JiraManualTestDurationTest(JiraTestCase):
Expand All @@ -135,5 +135,5 @@ async def test_duration(self):
self.assert_measurement(
response, value="25",
entities=[
dict(duration=10.0, key="1", summary="test 1", url="https://jira/browse/1"),
dict(duration=15.0, key="2", summary="test 2", url="https://jira/browse/2")])
dict(duration="10.0", key="1", summary="test 1", url="https://jira/browse/1"),
dict(duration="15.0", key="2", summary="test 2", url="https://jira/browse/2")])
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ async def test_warnings(self):
dict(fileName="/f3", priority="LOW"),
dict(fileName="/f4", priority="CRITICAL")]))
expected_entities = [
dict(key="/f1", file_path="/f1", highest_severity="High", nr_vulnerabilities=2),
dict(key="/f2", file_path="/f2", highest_severity="Normal", nr_vulnerabilities=1),
dict(key="/f4", file_path="/f4", highest_severity="Critical", nr_vulnerabilities=1)]
dict(key="/f1", file_path="/f1", highest_severity="High", nr_vulnerabilities="2"),
dict(key="/f2", file_path="/f2", highest_severity="Normal", nr_vulnerabilities="1"),
dict(key="/f4", file_path="/f4", highest_severity="Critical", nr_vulnerabilities="1")]
self.assert_measurement(response, value="3", entities=expected_entities)

async def test_up_to_dateness(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async def test_warnings(self):
response = await self.collect(metric, get_request_text=xml)
expected_entities = [
dict(key="12345", url="https://owasp_dependency_check.html#l1_12345",
highest_severity="Medium", nr_vulnerabilities=2,
highest_severity="Medium", nr_vulnerabilities="2",
file_path="/home/jenkins/workspace/hackazon-owaspdep/hackazon/js/jquery.min.js")]
self.assert_measurement(response, value="1", entities=expected_entities)

Expand All @@ -65,7 +65,7 @@ async def test_low_warnings(self):
response = await self.collect(metric, get_request_text=xml)
expected_entities = [
dict(key="12345", url="https://owasp_dependency_check.html#l1_12345",
highest_severity="Low", nr_vulnerabilities=1,
highest_severity="Low", nr_vulnerabilities="1",
file_path="/home/jenkins/workspace/hackazon-owaspdep/hackazon/js/jquery.min.js")]
self.assert_measurement(response, value="1", entities=expected_entities)

Expand Down
6 changes: 5 additions & 1 deletion components/frontend/src/source/SourceEntities.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ export function SourceEntities(props) {
</Table.Row>
let entities = Array.from(props.source.entities);
if (sortColumn !== null) {
const parse = columnType === "integer" ? (value) => parseInt(value, 10) : (value) => value;
const parse = {
"integer": (value) => parseInt(value, 10),
"float": (value) => parseFloat(value),
"text": (value) => value
}[columnType];
entities.sort((a, b) => parse(a[sortColumn]) < parse(b[sortColumn]) ? -1 : 1)
if (sortDirection === 'descending') {
entities.reverse()
Expand Down
2 changes: 1 addition & 1 deletion components/server/src/data/datamodel.json
Original file line number Diff line number Diff line change
Expand Up @@ -2424,7 +2424,7 @@
{
"name": "Points",
"key": "points",
"type": "integer"
"type": "float"
}
]
}
Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Reordering items or changing the type of a metric would sometimes fail because Quality-time would also try to save the layout of the dashboard. Fixed by only saving the dashboard layout when the user deliberately changes the layout by dragging a card. Fixes [#1160](https://github.com/ICTU/quality-time/issues/1160).
- Columns with numbers in the source entity views were incorrectly sorted as text. Fixes [#1196](https://github.com/ICTU/quality-time/issues/1196).
- Collecting unmerged branches using Azure DevOps as source would fail if the project name contained spaces and the user did not specify a repository. Quality-time would fail to find the default repository because it would use the URL-quoted project name to look for it, instead of the unquoted project name. Fixes [#1224](https://github.com/ICTU/quality-time/issues/1224).
- When using Jira as source for the 'ready user story points' metric, changing the status of a user story in the details tab didn't work. Fixes [#1230](https://github.com/ICTU/quality-time/issues/1230).

## [2.3.2] - [2020-06-10]

Expand Down

0 comments on commit 20d9294

Please sign in to comment.