Skip to content

feat: #75 get project issue types #76

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

Merged
merged 2 commits into from
Oct 19, 2021
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
25 changes: 25 additions & 0 deletions app/Coding/Project.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Coding;

use Exception;

class Project extends Base
{
public function getIssueTypes($token, $projectName)
{
$response = $this->client->request('POST', 'https://e.coding.net/open-api', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => "token ${token}",
'Content-Type' => 'application/json'
],
'json' => array_merge([
'Action' => 'DescribeProjectIssueTypeList',
'ProjectName' => $projectName,
]),
]);
$result = json_decode($response->getBody(), true);
return $result['Response']['IssueTypes'];
}
}
47 changes: 47 additions & 0 deletions app/Commands/ProjectGetIssueTypesCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace App\Commands;

use App\Coding\Issue;
use App\Coding\Project;
use LaravelZero\Framework\Commands\Command;

class ProjectGetIssueTypesCommand extends Command
{
use WithCoding;

/**
* The signature of the command.
*
* @var string
*/
protected $signature = 'project:get-issue-types
{--coding_token= : CODING 令牌}
{--coding_team_domain= : CODING 团队域名,如 xxx.coding.net 即填写 xxx}
{--coding_project_uri= : CODING 项目标识,如 xxx.coding.net/p/yyy 即填写 yyy}
';

/**
* The description of the command.
*
* @var string
*/
protected $description = '获取项目下的事项类型';

/**
* Execute the console command.
*
*/
public function handle(Project $codingProject): int
{
$this->setCodingApi();

$result = $codingProject->getIssueTypes($this->codingToken, $this->codingProjectUri);

foreach ($result as $item) {
$this->info($item['Id'] . ' ' . $item['Name']);
}

return 0;
}
}
39 changes: 39 additions & 0 deletions tests/Feature/ProjectGetIssueTypesCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Tests\Feature;

use App\Coding\Project;
use Tests\TestCase;

class ProjectGetIssueTypesCommandTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
$codingToken = $this->faker->md5;
config(['coding.token' => $codingToken]);
$codingTeamDomain = $this->faker->domainWord;
config(['coding.team_domain' => $codingTeamDomain]);
$codingProjectUri = $this->faker->slug;
config(['coding.project_uri' => $codingProjectUri]);
}

public function testCreateSuccess()
{
$mock = \Mockery::mock(Project::class, [])->makePartial();
$this->instance(Project::class, $mock);

$mock->shouldReceive('getIssueTypes')->times(1)->andReturn(json_decode(
file_get_contents($this->dataDir . 'coding/' . 'DescribeProjectIssueTypeListResponse.json'),
true
)['Response']['IssueTypes']);

$this->artisan('project:get-issue-types')
->expectsOutput('213217 史诗')
->expectsOutput('213218 用户故事')
->expectsOutput('213220 任务')
->expectsOutput('213221 缺陷')
->expectsOutput('213222 子工作项')
->assertExitCode(0);
}
}
41 changes: 41 additions & 0 deletions tests/Unit/CodingProjectTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Tests\Unit;

use App\Coding\Project;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
use Tests\TestCase;

class CodingProjectTest extends TestCase
{
public function testCreateSuccess()
{
$responseBody = file_get_contents($this->dataDir . 'coding/DescribeProjectIssueTypeListResponse.json');
$codingToken = $this->faker->md5;
$codingProjectUri = $this->faker->slug;

$clientMock = $this->getMockBuilder(Client::class)->getMock();
$clientMock->expects($this->once())
->method('request')
->with(
'POST',
'https://e.coding.net/open-api',
[
'headers' => [
'Accept' => 'application/json',
'Authorization' => "token ${codingToken}",
'Content-Type' => 'application/json'
],
'json' => array_merge([
'Action' => 'DescribeProjectIssueTypeList',
'ProjectName' => $codingProjectUri,
])
]
)
->willReturn(new Response(200, [], $responseBody));
$coding = new Project($clientMock);
$result = $coding->getIssueTypes($codingToken, $codingProjectUri);
$this->assertEquals(json_decode($responseBody, true)['Response']['IssueTypes'], $result);
}
}
52 changes: 52 additions & 0 deletions tests/data/coding/DescribeProjectIssueTypeListResponse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"Response" : {
"IssueTypes" : [
{
"Description" : "史诗是一个较大的功能或特性,可以分解为多个较小的需求或任务。通常其需要分多次迭代才可完成。",
"Id" : 213217,
"IsSystem" : true,
"IssueType" : "EPIC",
"Name" : "史诗",
"SplitTargetIssueTypeId" : [],
"SplitType" : "UNSPLITTABLE"
},
{
"Description" : "用户故事是敏捷框架中最小的工作单元,是从用户角度描述软件如何为其带来特定的价值。",
"Id" : 213218,
"IsSystem" : true,
"IssueType" : "REQUIREMENT",
"Name" : "用户故事",
"SplitTargetIssueTypeId" : [],
"SplitType" : "ALL_REQUIREMENT"
},
{
"Description" : "任务是指为实现某个目标或需求所进行的具体活动。",
"Id" : 213220,
"IsSystem" : true,
"IssueType" : "MISSION",
"Name" : "任务",
"SplitTargetIssueTypeId" : [],
"SplitType" : "UNSPLITTABLE"
},
{
"Description" : "缺陷是指软件不符合最初定义的业务需求的现象,缺陷管理用于跟踪这些问题和错误。",
"Id" : 213221,
"IsSystem" : true,
"IssueType" : "DEFECT",
"Name" : "缺陷",
"SplitTargetIssueTypeId" : [],
"SplitType" : "UNSPLITTABLE"
},
{
"Description" : "在敏捷模式下,将一个事项拆分成更小的块。",
"Id" : 213222,
"IsSystem" : true,
"IssueType" : "SUB_TASK",
"Name" : "子工作项",
"SplitTargetIssueTypeId" : [],
"SplitType" : "UNSPLITTABLE"
}
],
"RequestId" : "9f7e8405-943d-fb02-96bf-3ee3c63e0fe6"
}
}