Skip to content

Commit 38a4ca4

Browse files
committed
feat: #78 cli create iteration
1 parent 240f90b commit 38a4ca4

File tree

6 files changed

+145
-9
lines changed

6 files changed

+145
-9
lines changed

app/Coding/Iteration.php

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace App\Coding;
44

5+
use Carbon\Carbon;
6+
57
class Iteration extends Base
68
{
79
public function create($token, $projectName, $data)
@@ -20,4 +22,10 @@ public function create($token, $projectName, $data)
2022
$result = json_decode($response->getBody(), true);
2123
return $result['Response']['Iteration'];
2224
}
25+
26+
public static function generateName(Carbon $startAt, Carbon $endAt): string
27+
{
28+
$endFormat = $startAt->year == $endAt->year ? 'm/d' : 'Y/m/d';
29+
return $startAt->format('Y/m/d') . '-' . $endAt->format($endFormat) . ' 迭代';
30+
}
2331
}
+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace App\Commands;
4+
5+
use App\Coding\Iteration;
6+
use Carbon\Carbon;
7+
use LaravelZero\Framework\Commands\Command;
8+
9+
class IterationCreateCommand extends Command
10+
{
11+
use WithCoding;
12+
13+
/**
14+
* The signature of the command.
15+
*
16+
* @var string
17+
*/
18+
protected $signature = 'iteration:create
19+
{--start_at= : 开始时间,格式:2021-10-20}
20+
{--end_at= : 结束时间,格式:2021-10-30}
21+
{--name= : 标题}
22+
{--goal= : 目标}
23+
{--assignee= : 处理人 ID}
24+
{--coding_token= : CODING 令牌}
25+
{--coding_team_domain= : CODING 团队域名,如 xxx.coding.net 即填写 xxx}
26+
{--coding_project_uri= : CODING 项目标识,如 xxx.coding.net/p/yyy 即填写 yyy}
27+
';
28+
29+
/**
30+
* The description of the command.
31+
*
32+
* @var string
33+
*/
34+
protected $description = '创建迭代';
35+
36+
/**
37+
* Execute the console command.
38+
*
39+
*/
40+
public function handle(Iteration $iteration): int
41+
{
42+
$this->setCodingApi();
43+
44+
$data = [];
45+
$startAt = Carbon::parse($this->option('start_at') ?? $this->ask('开始时间:', Carbon::today()->toDateString()));
46+
$data['StartAt'] = $startAt->toDateString();
47+
$endAt = Carbon::parse($this->option('end_at') ?? $this->ask(
48+
'结束时间:',
49+
Carbon::today()->addDays(14)->toDateString()
50+
));
51+
$data['EndAt'] = $endAt->toDateString();
52+
$data['Name'] = $this->option('name') ?? $this->ask('标题:', Iteration::generateName($startAt, $endAt));
53+
$data['Goal'] = $this->option('goal');
54+
$data['Assignee'] = $this->option('assignee');
55+
56+
$result = $iteration->create($this->codingToken, $this->codingProjectUri, $data);
57+
58+
$this->info('创建成功');
59+
$this->info("https://{$this->codingTeamDomain}.coding.net/p/{$this->codingProjectUri}" .
60+
"/iterations/${result['Code']}/issues");
61+
62+
return 0;
63+
}
64+
}

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"laravel-fans/confluence": "^0.1.1",
2727
"laravel-zero/framework": "^8.8",
2828
"league/html-to-markdown": "^5.0",
29+
"nesbot/carbon": "^2.53",
2930
"sinkcup/laravel-filesystem-cos-updated": "^4.0"
3031
},
3132
"require-dev": {

composer.lock

+10-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace Tests\Feature;
4+
5+
use App\Coding\Iteration;
6+
use Carbon\Carbon;
7+
use Tests\TestCase;
8+
9+
class IterationCreateCommandTest extends TestCase
10+
{
11+
private string $teamDomain;
12+
private string $projectUri;
13+
14+
protected function setUp(): void
15+
{
16+
parent::setUp();
17+
$codingToken = $this->faker->md5;
18+
config(['coding.token' => $codingToken]);
19+
$this->teamDomain = $this->faker->domainWord;
20+
config(['coding.team_domain' => $this->teamDomain]);
21+
$this->projectUri = $this->faker->slug;
22+
config(['coding.project_uri' => $this->projectUri]);
23+
}
24+
25+
public function testCreateSuccess()
26+
{
27+
$mock = \Mockery::mock(Iteration::class, [])->makePartial();
28+
$this->instance(Iteration::class, $mock);
29+
30+
$mock->shouldReceive('create')->times(1)->andReturn(json_decode(
31+
file_get_contents($this->dataDir . 'coding/' . 'CreateIterationResponse.json'),
32+
true
33+
)['Response']['Iteration']);
34+
35+
$startAt = $this->faker->date();
36+
$endAt = Carbon::parse($startAt)->addDays($this->faker->randomNumber())->toDateString();
37+
$this->artisan('iteration:create', [
38+
'--goal' => $this->faker->text(),
39+
'--assignee' => $this->faker->randomNumber(),
40+
])
41+
->expectsQuestion('开始时间:', $startAt)
42+
->expectsQuestion('结束时间:', $endAt)
43+
->expectsQuestion('标题:', $startAt . '~' . $endAt . ' 迭代')
44+
->expectsOutput('创建成功')
45+
->expectsOutput("https://$this->teamDomain.coding.net/p/$this->projectUri/iterations/2746/issues")
46+
->assertExitCode(0);
47+
}
48+
}

tests/Unit/CodingIterationTest.php

+14
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use App\Coding\Issue;
66
use App\Coding\Iteration;
7+
use Carbon\Carbon;
78
use GuzzleHttp\Client;
89
use GuzzleHttp\Psr7\Response;
910
use Tests\TestCase;
@@ -42,4 +43,17 @@ public function testCreateSuccess()
4243
$result = $coding->create($codingToken, $codingProjectUri, $data);
4344
$this->assertEquals(json_decode($responseBody, true)['Response']['Iteration'], $result);
4445
}
46+
47+
public function testGenerateName()
48+
{
49+
$startAt = Carbon::parse('2021-10-20');
50+
$endAt = Carbon::parse('2021-10-30');
51+
$result = Iteration::generateName($startAt, $endAt);
52+
$this->assertEquals("2021/10/20-10/30 迭代", $result);
53+
54+
$startAt = Carbon::parse('2021-12-27');
55+
$endAt = Carbon::parse('2022-01-07');
56+
$result = Iteration::generateName($startAt, $endAt);
57+
$this->assertEquals("2021/12/27-2022/01/07 迭代", $result);
58+
}
4559
}

0 commit comments

Comments
 (0)