Skip to content
Snippets Groups Projects
Commit 4cec8221 authored by Patrick Barroca's avatar Patrick Barroca
Browse files

rel #33379: show redmine history

parent 9e957f5b
Branches
Tags
7 merge requests!1553Master,!1502Master,!1501Stable,!1472Stable,!1409Stable,!1403Dev#33379 redmine create and edit ticket,!1387Dev#33379 redmine create and edit ticket
......@@ -6,4 +6,6 @@ echo $this->tag('h2', $this->_('Description'));
echo $this->tag('pre', $this->issue->getdescription());
echo $this->renderForm($this->form);
?>
echo $this->tag('h2', $this->_('Historique'));
echo $this->redmine_IssueJournal($this->issue);
......@@ -164,8 +164,11 @@ class Class_WebService_Redmine extends Class_WebService_Abstract {
if (!$this->isValid() || !$ticket)
return new Class_WebService_Redmine_Issue();
$data = $this->getIssueApi()->show($ticket);
return Class_WebService_Redmine_Issue::newWith(isset($data['issue']) ? $data['issue'] : []);
$data = $this->getIssueApi()->show($ticket, ['include' => 'journals']);
$issue = Class_WebService_Redmine_Issue::newWith(isset($data['issue']) ? $data['issue'] : []);
$issue->setService($this);
return $issue;
}
......@@ -187,6 +190,18 @@ class Class_WebService_Redmine extends Class_WebService_Abstract {
}
public function getIssueStatusFor($id) {
if (!$this->isValid())
return $id;
$statuses = $this->getIssueStatus();
foreach($statuses as $k => $v)
if ($k == $id)
return $v;
return $id;
}
public function getIssuePriorities() {
return $this->getCustomOptions(static::CUSTOM_PRIORITY_ID);
......@@ -212,7 +227,7 @@ class Class_WebService_Redmine extends Class_WebService_Abstract {
if ($id != $field['id'])
continue;
if (!$field['is_required'])
if (!isset($field['is_required']) || !$field['is_required'])
$options[''] = '';
foreach ($field['possible_values'] as $possible) {
......
<?php
/**
* Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
* the Free Software Foundation.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH 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 AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
* along with BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class ZendAfi_View_Helper_Redmine_IssueJournal extends ZendAfi_View_Helper_BaseHelper {
protected $_issue;
public function Redmine_IssueJournal($issue) {
if (!$issue || (!$events = $issue->getjournals()))
return $this->_('Aucun historique');
$this->_issue = $issue;
$html = '';
foreach($events as $event)
$html .= $this->_tag('div', $this->render($event));
return $html;
}
protected function render($event) {
return $this->renderTitle($event)
. $this->renderDetails($event['details'])
. $this->renderNote($event['notes']);
}
protected function renderTitle($event) {
$user = $event['user']['name'];
$date = strftime($this->_('%x à %X'), strtotime($event['created_on']));
return $this->_tag('h3', $this->_('Mis à jour par %s le %s', $user, $date));
}
protected function renderDetails($details) {
$html = '';
foreach($details as $detail)
$html .= $this->renderDetail($detail);
return $this->_tag('ul', $html);
}
protected function renderNote($note) {
if (!$note)
return '';
return $this->_tag('pre', $note);
}
protected function renderDetail($detail) {
$label = '';
if ('relation' == $detail['property'])
$label = $this->labelFromCode($detail['name'], $detail['new_value']);
if ('attr' == $detail['property'])
$label = $this->labelFromCode($detail['name'], $detail['old_value'], $detail['new_value']);
return $this->_tag('li', $label);
}
protected function labelFromCode($code, $value, $other=null) {
$mapping =
['copied_from' => function() use ($value) { return $this->_('Copié depuis #%s', $value); },
'status_id' => function() use ($value, $other) {
return $this->_('Statut changé de %s à %s',
$this->statusFrom($value), $this->statusFrom($other));
},
'done_ratio' => function() use ($value, $other) { return $this->_('%% réalisé changé de %s à %s', $value, $other); }];
$default = $other
? $this->_('%s changé de %s à %s', $code, $value, $other)
: ($code . ' ' . $value);
return array_key_exists($code, $mapping)
? $mapping[$code]()
: $default;
}
protected function statusFrom($id) {
if (!$service = $this->_issue->getService())
return $id;
return $service->getIssueStatusFor($id);
}
}
......@@ -380,7 +380,7 @@ class Admin_RedmineControllerEditIssue34247Test extends Admin_RedmineControllerW
$redmine_api = $this->mock()
->whenCalled('show')
->with('34247')
->with('34247', ['include' => 'journals'])
->answers(RedmineFixtures::fieldIndexation());
$redmine_api_status = $this->mock()
......@@ -400,14 +400,19 @@ class Admin_RedmineControllerEditIssue34247Test extends Admin_RedmineControllerW
->with('issue_status')
->answers($redmine_api_status)
->whenCalled('api')
->with('issue_priority')
->answers($redmine_api_priority)
->beStrict();
Class_WebService_Redmine::setClient($redmine_client);
$custom_fields_api = $this->mock()
->whenCalled('all')
->answers(RedmineFixtures::customFields());
Class_WebService_Redmine::setAdminClient($this->mock()
->whenCalled('api')
->with('custom_fields')
->answers($custom_fields_api));
$this->dispatch('admin/redmine/edit-issue/id_lib/1/id/34247', true);
}
......@@ -428,6 +433,56 @@ class Admin_RedmineControllerEditIssue34247Test extends Admin_RedmineControllerW
public function subjectShouldBePresent() {
$this->assertXPathContentContains('//div', 'reindexation des champs');
}
/** @test */
public function statusShouldBePresent() {
$this->assertXPathContentContains('//select[@name="status_id"]//option', 'A qualifier');
}
/** @test */
public function priorityShouldBePresent() {
$this->assertXPathContentContains('//select[@name="priority"]//option', 'Normale');
}
/** @test */
public function moduleShouldBePresent() {
$this->assertXPathContentContains('//select[@name="module"]//option', 'Articles');
}
/** @test */
public function historyShouldBePresent() {
$this->assertXPathContentContains('//h2', 'Historique');
}
/** @test */
public function nameAndCreationDateForNoteShouldBeDisplayed() {
$this->assertXPathContentContains('//h3','Mis à jour par test-support le 07/01/2016 à 09:30:26',$this->_response->getBody());
}
/** @test */
public function detailsShouldContainsCopiedInformation() {
$this->assertXPathContentContains('//ul//li','Copié depuis #35800');
}
/** @test */
public function detailsShouldContainsStatusChanged() {
$this->assertXPathContentContains('//ul//li','Statut changé de A qualifier à Affecté au dév.');
}
/** @test */
public function detailsShouldContainsRatio() {
$this->assertXPathContentContains('//ul//li','% réalisé changé de 0 à 20');
}
/** @test */
public function noteShouldBeDisplayed() {
$this->assertXPathContentContains('//pre', 'Pris en charge par le developpement');
}
}
......@@ -437,7 +492,9 @@ class Admin_RedmineControllerPostEditIssue34247Test extends Admin_RedmineControl
parent::setUp();
$redmine_api = $this->mock()
->whenCalled('show')->with('34247')->answers(RedmineFixtures::fieldIndexation())
->whenCalled('show')->with('34247', ['include' => 'journals'])
->answers(RedmineFixtures::fieldIndexation())
->whenCalled('update')->answers('hfg')
->whenCalled('all')->answers(RedmineFixtures::supportStatus());
......
......@@ -130,7 +130,7 @@ class RedmineFixtures {
public static function fieldIndexation() {
return json_decode('{"issue":{"id":34247,"project":{"id":214,"name":"Support Bokeh AFI-OPAC 2.0"},"tracker":{"id":12,"name":"Demande d\'assistance"},"status":{"id":2,"name":"Affect\u00e9 au d\u00e9v."},"priority":{"id":5,"name":"Haut"},"author":{"id":207,"name":"gloas"},"assigned_to":{"id":207,"name":"gloas"},"subject":"reindexation des champs personnalis\u00e9s ","description":"Url de l\'anomalie : http:\/\/web.afi-sa.net\/miop-test.net\/admin\/custom-fields\/edit\/id\/1\r\n\r\n\u00c9tapes pour parvenir au bug :\r\n* indexer un champs personnalis\u00e9\r\n* les facettes des notices des articles qui ont une valeur de param\u00e9tr\u00e9e pour ce champ personnalis\u00e9 ne sont pas mises \u00e0 jour.\r\n","done_ratio":20,"spent_hours":0,"custom_fields":[{"id":43,"name":"Personne \u00e0 contacter","value":"Nom \/ pr\u00e9nom \/ email \/ t\u00e9l\u00e9phone"},{"id":42,"name":"Pris en charge par","value":""},{"id":37,"name":"Module Portail","value":"Recherche"},{"id":5,"name":"Priorit\u00e9 client","value":"Normale"},{"id":1,"name":"Client","value":""},{"id":38,"name":"Qualification","value":"Bug logiciel"},{"id":46,"name":"Relanc\u00e9 le","value":""}],"created_on":"2015-09-29T10:01:49Z","updated_on":"2015-12-02T13:37:49Z"}}', true);
return json_decode('{"issue":{"id":34247,"project":{"id":214,"name":"Support Bokeh AFI-OPAC 2.0"},"tracker":{"id":12,"name":"Demande d\'assistance"},"status":{"id":2,"name":"Affect\u00e9 au d\u00e9v."},"priority":{"id":5,"name":"Haut"},"author":{"id":207,"name":"gloas"},"assigned_to":{"id":207,"name":"gloas"},"subject":"reindexation des champs personnalis\u00e9s ","description":"Url de l\'anomalie : http:\/\/web.afi-sa.net\/miop-test.net\/admin\/custom-fields\/edit\/id\/1\r\n\r\n\u00c9tapes pour parvenir au bug :\r\n* indexer un champs personnalis\u00e9\r\n* les facettes des notices des articles qui ont une valeur de param\u00e9tr\u00e9e pour ce champ personnalis\u00e9 ne sont pas mises \u00e0 jour.\r\n","done_ratio":20,"spent_hours":0,"custom_fields":[{"id":43,"name":"Personne \u00e0 contacter","value":"Nom \/ pr\u00e9nom \/ email \/ t\u00e9l\u00e9phone"},{"id":42,"name":"Pris en charge par","value":""},{"id":37,"name":"Module Portail","value":"Recherche"},{"id":5,"name":"Priorit\u00e9 client","value":"Normale"},{"id":1,"name":"Client","value":""},{"id":38,"name":"Qualification","value":"Bug logiciel"},{"id":46,"name":"Relanc\u00e9 le","value":""}],"created_on":"2015-09-29T10:01:49Z","updated_on":"2015-12-02T13:37:49Z","journals":[{"id":149465,"user":{"id":1198,"name":"test-support"},"notes":"","created_on":"2016-01-07T08:30:26Z","details":[{"property":"relation","name":"copied_from","new_value":"35800"}]},{"id":149517,"user":{"id":92,"name":"other"},"notes":"Pris en charge par le developpement","created_on":"2016-01-07T09:38:13Z","details":[{"property":"attr","name":"status_id","old_value":"1","new_value":"2"},{"property":"attr","name":"done_ratio","old_value":"0","new_value":"20"}]}]}}', true);
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment