Skip to content

Commit b8b7cfa

Browse files
committed
Set a status on a commit
1 parent fd206b6 commit b8b7cfa

File tree

6 files changed

+308
-5
lines changed

6 files changed

+308
-5
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php declare(strict_types=1);
2+
use ApiClients\Client\Github\AsyncClient;
3+
use ApiClients\Client\Github\Resource\Async\Repository;
4+
use ApiClients\Client\Github\Resource\Async\User;
5+
use React\EventLoop\Factory;
6+
use Rx\Observable;
7+
use function ApiClients\Foundation\resource_pretty_print;
8+
9+
require dirname(__DIR__) . DIRECTORY_SEPARATOR . 'vendor/autoload.php';
10+
11+
$loop = Factory::create();
12+
13+
$client = AsyncClient::create($loop, require 'resolve_token.php');
14+
15+
$client->user($argv[1] ?? 'php-api-clients')->then(function (User $user) use ($argv) {
16+
resource_pretty_print($user);
17+
18+
return $user->repository($argv[2] ?? 'github');
19+
})->then(function (Repository $repository) {
20+
resource_pretty_print($repository, 1, true);
21+
$repository->commits()->take(1)->flatMap(function (Repository\Commit $commit) {
22+
resource_pretty_print($commit, 2, true);
23+
24+
return Observable::fromPromise($commit->createStatus('success', 'https://php-api-clients.org/', 'Status Message', 'PHP-API-Clients/Github'));
25+
})->subscribe(function ($status) {
26+
resource_pretty_print($status, 3, true);
27+
}, 'display_throwable');
28+
})->done(null, 'display_throwable');
29+
30+
$loop->run();
31+
32+
displayState($client->getRateLimitState());
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Client\Github\CommandBus\Command\Repository\Commit;
4+
5+
use ApiClients\Client\Github\Resource\Repository\CommitInterface;
6+
use WyriHaximus\Tactician\CommandHandler\Annotations\Handler;
7+
8+
/**
9+
* @Handler("ApiClients\Client\Github\CommandBus\Handler\Repository\Commit\CreateStatusHandler")
10+
*/
11+
final class CreateStatusCommand
12+
{
13+
/** @var CommitInterface */
14+
private $commit;
15+
16+
/** @var string */
17+
private $state;
18+
19+
/** @var null|string */
20+
private $targetUrl;
21+
22+
/** @var null|string */
23+
private $description;
24+
25+
/** @var null|string */
26+
private $context;
27+
28+
/**
29+
* @param CommitInterface $commit
30+
* @param string $state
31+
* @param string|null $targetUrl
32+
* @param string|null $description
33+
* @param string|null $context
34+
*/
35+
public function __construct(CommitInterface $commit, string $state, ?string $targetUrl = null, ?string $description = null, ?string $context = null)
36+
{
37+
$this->commit = $commit;
38+
$this->state = $state;
39+
$this->targetUrl = $targetUrl;
40+
$this->description = $description;
41+
$this->context = $context;
42+
}
43+
44+
/**
45+
* @return CommitInterface
46+
*/
47+
public function getCommit(): CommitInterface
48+
{
49+
return $this->commit;
50+
}
51+
52+
/**
53+
* @return string
54+
*/
55+
public function getState(): string
56+
{
57+
return $this->state;
58+
}
59+
60+
/**
61+
* @return string|null
62+
*/
63+
public function getTargetUrl(): ?string
64+
{
65+
return $this->targetUrl;
66+
}
67+
68+
/**
69+
* @return string|null
70+
*/
71+
public function getDescription(): ?string
72+
{
73+
return $this->description;
74+
}
75+
76+
/**
77+
* @return string|null
78+
*/
79+
public function getContext(): ?string
80+
{
81+
return $this->context;
82+
}
83+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Client\Github\CommandBus\Handler\Repository\Commit;
4+
5+
use ApiClients\Client\Github\CommandBus\Command\Repository\Commit\CreateStatusCommand;
6+
use ApiClients\Client\Github\Resource\Repository\Commit\StatusInterface;
7+
use ApiClients\Foundation\Hydrator\Hydrator;
8+
use ApiClients\Foundation\Transport\Service\RequestService;
9+
use ApiClients\Middleware\Json\JsonStream;
10+
use React\Promise\PromiseInterface;
11+
use RingCentral\Psr7\Request;
12+
13+
final class CreateStatusHandler
14+
{
15+
/**
16+
* @var RequestService
17+
*/
18+
private $requestService;
19+
20+
/**
21+
* @var Hydrator
22+
*/
23+
private $hydrator;
24+
25+
/**
26+
* @param RequestService $requestService
27+
* @param Hydrator $hydrator
28+
*/
29+
public function __construct(RequestService $requestService, Hydrator $hydrator)
30+
{
31+
$this->requestService = $requestService;
32+
$this->hydrator = $hydrator;
33+
}
34+
35+
/**
36+
* @param CreateStatusCommand $command
37+
* @return PromiseInterface
38+
*/
39+
public function handle(CreateStatusCommand $command): PromiseInterface
40+
{
41+
$json = [
42+
'state' => $command->getState(),
43+
];
44+
45+
$targetUrl = $command->getTargetUrl();
46+
if ($targetUrl !== null) {
47+
$json['target_url'] = $targetUrl;
48+
}
49+
$description = $command->getDescription();
50+
if ($description !== null) {
51+
$json['description'] = $description;
52+
}
53+
$context = $command->getContext();
54+
if ($context !== null) {
55+
$json['context'] = $context;
56+
}
57+
unset($targetUrl, $description, $context);
58+
59+
return $this->requestService->request(
60+
new Request(
61+
'POST',
62+
\str_replace('/commits/', '/statuses/', $command->getCommit()->url()),
63+
[],
64+
new JsonStream($json)
65+
)
66+
)->then(function ($status) {
67+
return $this->hydrator->hydrate(StatusInterface::HYDRATE_CLASS, $status->getBody()->getParsedContents());
68+
});
69+
}
70+
}

src/Middleware/ErrorMiddleware.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,17 @@ final class ErrorMiddleware implements MiddlewareInterface
2020
use PostTrait;
2121

2222
/**
23-
* @param Throwable $throwable
24-
* @param string $transactionId
25-
* @param array $options
23+
* @param Throwable $throwable
24+
* @param string $transactionId
25+
* @param array $options
2626
* @return CancellablePromiseInterface
2727
* @SecondLast()
2828
*/
2929
public function error(
3030
Throwable $throwable,
3131
string $transactionId,
3232
array $options = []
33-
): CancellablePromiseInterface
34-
{
33+
): CancellablePromiseInterface {
3534
if ($throwable instanceof UnprocessableEntityException ||
3635
$throwable instanceof BadRequestException
3736
) {

src/Resource/Async/Repository/Commit.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace ApiClients\Client\Github\Resource\Async\Repository;
44

55
use ApiClients\Client\Github\CommandBus\Command\RefreshCommand;
6+
use ApiClients\Client\Github\CommandBus\Command\Repository\Commit\CreateStatusCommand;
67
use ApiClients\Client\Github\CommandBus\Command\Repository\Commit\StatusCommand;
78
use ApiClients\Client\Github\CommandBus\Command\Repository\Commit\StatusesCommand;
89
use ApiClients\Client\Github\Resource\Repository\Commit as BaseCommit;
@@ -32,4 +33,11 @@ public function statuses(): ObservableInterface
3233
new StatusesCommand($this)
3334
));
3435
}
36+
37+
public function createStatus(string $state, ?string $targetUrl = null, ?string $description = null, ?string $context = null): PromiseInterface
38+
{
39+
return $this->handleCommand(
40+
new CreateStatusCommand($this, $state, $targetUrl, $description, $context)
41+
);
42+
}
3543
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace ApiClients\Tests\Github\CommandBus\Handler\Repository\Commit;
4+
5+
use ApiClients\Client\Github\CommandBus\Command\Repository\Commit\CreateStatusCommand;
6+
use ApiClients\Client\Github\CommandBus\Handler\Repository\Commit\CreateStatusHandler;
7+
use ApiClients\Client\Github\Resource\Repository\Commit\StatusInterface;
8+
use ApiClients\Client\Github\Resource\Repository\CommitInterface;
9+
use ApiClients\Foundation\Hydrator\Hydrator;
10+
use ApiClients\Foundation\Transport\Service\RequestService;
11+
use ApiClients\Middleware\Json\JsonStream;
12+
use ApiClients\Tools\TestUtilities\TestCase;
13+
use RingCentral\Psr7\Request;
14+
use RingCentral\Psr7\Response;
15+
use function React\Promise\resolve;
16+
17+
final class CreateStatusHandlerTest extends TestCase
18+
{
19+
public function provideCommandsAndJsonCombinations()
20+
{
21+
$commit = $this->prophesize(CommitInterface::class);
22+
$commit->url()->shouldBeCalled()->willReturn('repos/login/repository/commits/0123456789abcdef');
23+
24+
yield [
25+
new CreateStatusCommand(
26+
$commit->reveal(),
27+
'error'
28+
),
29+
[
30+
'state' => 'error',
31+
],
32+
];
33+
34+
yield [
35+
new CreateStatusCommand(
36+
$commit->reveal(),
37+
'error',
38+
'https://php-api-clients.org/'
39+
),
40+
[
41+
'state' => 'error',
42+
'target_url' => 'https://php-api-clients.org/',
43+
],
44+
];
45+
46+
yield [
47+
new CreateStatusCommand(
48+
$commit->reveal(),
49+
'error',
50+
'https://php-api-clients.org/',
51+
'Floki and Deathwing sitting in the garden watching Gandalf play'
52+
),
53+
[
54+
'state' => 'error',
55+
'target_url' => 'https://php-api-clients.org/',
56+
'description' => 'Floki and Deathwing sitting in the garden watching Gandalf play',
57+
],
58+
];
59+
60+
yield [
61+
new CreateStatusCommand(
62+
$commit->reveal(),
63+
'error',
64+
'https://php-api-clients.org/',
65+
'Floki and Deathwing sitting in the garden watching Gandalf play',
66+
'PHP-API-Clients/Github'
67+
),
68+
[
69+
'state' => 'error',
70+
'target_url' => 'https://php-api-clients.org/',
71+
'description' => 'Floki and Deathwing sitting in the garden watching Gandalf play',
72+
'context' => 'PHP-API-Clients/Github',
73+
],
74+
];
75+
}
76+
77+
/**
78+
* @param CreateStatusCommand $command
79+
* @param array $json
80+
*
81+
* @dataProvider provideCommandsAndJsonCombinations
82+
*/
83+
public function testCommand(CreateStatusCommand $command, array $json)
84+
{
85+
$resource = $this->prophesize(StatusInterface::class)->reveal();
86+
$status = [
87+
'state' => 'success',
88+
];
89+
90+
$request = new Request(
91+
'POST',
92+
'repos/login/repository/statuses/0123456789abcdef',
93+
[],
94+
new JsonStream($json)
95+
);
96+
$response = new Response(
97+
200,
98+
[],
99+
new JsonStream($status)
100+
);
101+
102+
$service = $this->prophesize(RequestService::class);
103+
$service->request($request)->shouldBeCalled()->willReturn(resolve($response));
104+
105+
$hydrator = $this->prophesize(Hydrator::class);
106+
$hydrator->hydrate(StatusInterface::HYDRATE_CLASS, $status)->shouldBeCalled()->willReturn($resource);
107+
108+
$handler = new CreateStatusHandler($service->reveal(), $hydrator->reveal());
109+
$handler->handle($command);
110+
}
111+
}

0 commit comments

Comments
 (0)