Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for "entityId", "hierarchyLevel" and "untranslatedName" to the "IssueType" class #208

Merged
merged 1 commit into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Error details from failed API calls were not available back from `Api::api method` call by [@betterphp].
- Warning about `count()` function usage on PHP 7.2, when searching for issues by [@aik099].
- Capitalize `globalId` properly in `createRemotelink` [@glensc].
- The `Api::getIssueTypes` was always returning an error by [@aik099].

## [1.0.0] - 2014-07-27
### Added
Expand Down
151 changes: 50 additions & 101 deletions src/Jira/IssueType.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,151 +25,100 @@
namespace chobie\Jira;


/**
* The issue type.
*
* @method integer getAvatarId() Gets avatar ID.
* @method string getDescription() Gets description.
* @method string getEntityId() Gets Unique ID for next-gen projects.
* @method integer getHierarchyLevel() Gets hierarchy level.
* @method string getIconUrl() Gets icon url.
* @method string getId() Gets ID.
* @method string getName() Gets name.
* @method string getUntranslatedName() Gets untranslated name.
* @method array getScope() Gets details of the next-gen projects the issue type is available in.
* @method string getSelf() Gets the URL of these issue type details.
*/
class IssueType
{

/**
* Self.
*
* @var string
*/
protected $self;

/**
* ID.
*
* @var string
*/
protected $id;

/**
* Description.
*
* @var string
*/
protected $description;

/**
* Icon URL.
* Data.
*
* @var string
*/
protected $iconUrl;

/**
* Name.
*
* @var string
*/
protected $name;

/**
* Sub-task.
*
* @var string
*/
protected $subTask;

/**
* Avatar ID.
*
* @var string
* @var array
*/
protected $avatarId;
private $_data;

/**
* Acceptable keys.
*
* @var array
*/
private $_acceptableKeys = array(
'self',
'id',
'avatarId',
'description',
'entityId',
'hierarchyLevel',
'iconUrl',
'id',
'name',
'subtask',
'avatarId',
'scope',
'self',
'subtask',

'untranslatedName',
);

/**
* Creates issue instance.
*
* @param array $types Types.
* @param array $data Data.
*
* @throws \Exception When unknown type is given.
* @throws \Exception When an unknown data field is given.
*/
public function __construct(array $types)
public function __construct(array $data)
{
foreach ( $types as $key => $value ) {
if ( in_array($key, $this->_acceptableKeys) ) {
$this->$key = $value;
}
else {
throw new \Exception('the key ' . $key . ' does not support');
}
$unknown_fields = array_diff(array_keys($data), $this->_acceptableKeys);

if ( $unknown_fields ) {
throw new \Exception(
'The "' . implode('", "', $unknown_fields) . '" issue type keys are not supported.'
);
}
}

/**
* Gets name.
*
* @return string
*/
public function getName()
{
return $this->name;
$this->_data = $data;
}

/**
* Gets sub-task.
*
* @return string
* @return boolean
*/
public function isSubtask()
{
return $this->subTask;
return $this->_data['subtask'];
}

/**
* Gets ID.
* Allows accessing issue type properties.
*
* @return string
*/
public function getId()
{
return $this->id;
}

/**
* Gets description.
* @param string $method Method name.
* @param array $params Params.
*
* @return string
* @return mixed
* @throws \Exception When requested method wasn't found.
*/
public function getDescription()
public function __call($method, array $params)
{
return $this->description;
}
if ( preg_match('/^get(.+)$/', $method, $regs) ) {
$data_key = lcfirst($regs[1]);

/**
* Gets icon url.
*
* @return string
*/
public function getIconUrl()
{
return $this->iconUrl;
}
if ( in_array($data_key, $this->_acceptableKeys) ) {
return array_key_exists($data_key, $this->_data) ? $this->_data[$data_key] : null;
}
}

/**
* Gets avatar id.
*
* @return string
*/
public function getAvatarId()
{
return $this->avatarId;
throw new \Exception('The "' . __CLASS__ . '::' . $method . '" method does not exist.');
}

}
23 changes: 23 additions & 0 deletions tests/Jira/ApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use chobie\Jira\Api;
use chobie\Jira\Api\Authentication\AuthenticationInterface;
use chobie\Jira\Api\Result;
use chobie\Jira\IssueType;
use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\ObjectProphecy;

Expand Down Expand Up @@ -289,6 +290,28 @@ public function testGetPriorities()
$this->assertEquals($expected, $this->api->getPriorities(), 'Calling twice did not yield the same results');
}

public function testGetIssueTypes()
{
$response = file_get_contents(__DIR__ . '/resources/api_issue_types.json');

$this->expectClientCall(
Api::REQUEST_GET,
'/rest/api/2/issuetype',
array(),
$response
);

$actual = $this->api->getIssueTypes();

$response_decoded = json_decode($response, true);

$expected = array(
new IssueType($response_decoded[0]),
new IssueType($response_decoded[1]),
);
$this->assertEquals($expected, $actual);
}

/**
* Expects a particular client call.
*
Expand Down
79 changes: 59 additions & 20 deletions tests/Jira/IssueTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,83 @@

use chobie\Jira\IssueType;
use PHPUnit\Framework\TestCase;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectException;

class IssueTypeTest extends TestCase
{
use ExpectException;

public function testHandlesSingleIssueTypeWithAvatarId()
{
$issueTypeSource = array(
'self' => 'https://hosted.atlassian.net/rest/api/2/issuetype/4',
'id' => '4',
'description' => 'An improvement or enhancement to an existing feature or task.',
'iconUrl' => 'https://hosted.atlassian.net/secure/viewavatar?size=xsmall&avatarId=1&avatarType=issuetype',
'name' => 'Improvement',
'subtask' => false,
'avatarId' => 1,
$issue_type_source = array(
'self' => 'https://hosted.atlassian.net/rest/api/2/issuetype/4',
'id' => '4',
'description' => 'An improvement or enhancement to an existing feature or task.',
'entityId' => '9d7dd6f7-e8b6-4247-954b-7b2c9b2a5ba2',
'iconUrl' => 'https://hosted.atlassian.net/secure/viewavatar?size=xsmall&avatarId=1&avatarType=issuetype',
'name' => 'Improvement',
'scope' => array(
'project' => array('id' => '10000'),
'type' => 'PROJECT',
),
'untranslatedName' => 'Epic',
'subtask' => false,
'hierarchyLevel' => 1,
'avatarId' => 1,
);
$issueType = new IssueType($issueTypeSource);
$this->assertEquals($issueType->getId(), $issueTypeSource['id']);
$this->assertEquals($issueType->getDescription(), $issueTypeSource['description']);
$this->assertEquals($issueType->getIconUrl(), $issueTypeSource['iconUrl']);
$this->assertEquals($issueType->getName(), $issueTypeSource['name']);
$this->assertEquals($issueType->getAvatarId(), $issueTypeSource['avatarId']);
$issue_type = new IssueType($issue_type_source);
$this->assertEquals($issue_type->getSelf(), $issue_type_source['self']);
$this->assertEquals($issue_type->getId(), $issue_type_source['id']);
$this->assertEquals($issue_type->getDescription(), $issue_type_source['description']);
$this->assertEquals($issue_type->getEntityId(), $issue_type_source['entityId']);
$this->assertEquals($issue_type->getIconUrl(), $issue_type_source['iconUrl']);
$this->assertEquals($issue_type->getName(), $issue_type_source['name']);
$this->assertEquals($issue_type->getScope(), $issue_type_source['scope']);
$this->assertEquals($issue_type->isSubtask(), $issue_type_source['subtask']);
$this->assertEquals($issue_type->getUntranslatedName(), $issue_type_source['untranslatedName']);
$this->assertEquals($issue_type->getHierarchyLevel(), $issue_type_source['hierarchyLevel']);
$this->assertEquals($issue_type->getAvatarId(), $issue_type_source['avatarId']);
}

public function testHandlesSingleIssueTypeWithoutAvatarId()
{
$issueTypeSource = array(
$issue_type_source = array(
'self' => 'https://hosted.atlassian.net/rest/api/2/issuetype/4',
'id' => '4',
'description' => 'An improvement or enhancement to an existing feature or task.',
'iconUrl' => 'https://hosted.atlassian.net/secure/viewavatar?size=xsmall&avatarId=1&avatarType=issuetype',
'name' => 'Improvement',
'subtask' => false,
);
$issueType = new IssueType($issueTypeSource);
$this->assertEquals($issueType->getId(), $issueTypeSource['id']);
$this->assertEquals($issueType->getDescription(), $issueTypeSource['description']);
$this->assertEquals($issueType->getIconUrl(), $issueTypeSource['iconUrl']);
$this->assertEquals($issueType->getName(), $issueTypeSource['name']);
$issue_type = new IssueType($issue_type_source);
$this->assertEquals($issue_type->getId(), $issue_type_source['id']);
$this->assertEquals($issue_type->getDescription(), $issue_type_source['description']);
$this->assertEquals($issue_type->getIconUrl(), $issue_type_source['iconUrl']);
$this->assertEquals($issue_type->getName(), $issue_type_source['name']);
}

public function testGettingUnknownProperty()
{
$issue_type_source = array(
'self' => 'https://hosted.atlassian.net/rest/api/2/issuetype/4',
);
$issue_type = new IssueType($issue_type_source);

$this->expectException(\Exception::class);
$this->expectExceptionMessage('The "chobie\Jira\IssueType::getUnknown" method does not exist.');
$issue_type->getUnknown();
}

public function testCreatingWithUnknownField()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('The "unknown" issue type keys are not supported.');

$issue_type_source = array(
'self' => 'https://hosted.atlassian.net/rest/api/2/issuetype/4',
'unknown' => '4',
);
new IssueType($issue_type_source);
}

}
23 changes: 23 additions & 0 deletions tests/Jira/resources/api_issue_types.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[
{
"self": "https://test.atlassian.net/rest/api/2/issuetype/10000",
"id": "10000",
"description": "A big user story that needs to be broken down. Created by Jira Software - do not edit or delete.",
"iconUrl": "https://test.atlassian.net/images/icons/issuetypes/epic.svg",
"name": "Epic",
"untranslatedName": "Epic",
"subtask": false,
"hierarchyLevel": 1
},
{
"self": "https://test.atlassian.net/rest/api/2/issuetype/10034",
"id": "10034",
"description": "A problem which impairs or prevents the functions of the product. (Migrated on 31 Aug 2024 07:01 UTC)",
"iconUrl": "https://test.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10300?size=medium",
"name": "Bug Report",
"untranslatedName": "Bug Report",
"subtask": false,
"avatarId": 10300,
"hierarchyLevel": 0
}
]