Skip to content

Commit b832e62

Browse files
committed
test releaser
1 parent ea46247 commit b832e62

File tree

3 files changed

+116
-26
lines changed

3 files changed

+116
-26
lines changed

bin/create_release

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,23 @@
33

44
require __DIR__.'/../vendor/autoload.php';
55

6+
use SymfonyDocsBuilder\Phar\Compiler;
67
use SymfonyDocsBuilder\Release\GithubApiHttpClientFactory;
78
use SymfonyDocsBuilder\Release\Releaser;
89

910
error_reporting(-1);
1011
ini_set('display_errors', 1);
1112

1213
try {
13-
$releaser = new Releaser(new GithubApiHttpClientFactory());
14+
$releaser = new Releaser((new GithubApiHttpClientFactory())->createHttpClient(), new Compiler());
1415

1516
if ($argc === 1) {
1617
throw new RuntimeException('Not enough arguments. usage: "./bin/release tag [release_name [release_description]]"');
1718
}
1819

1920
array_shift($argv);
2021

21-
$releaser->doRelease(...$argv);
22+
$releaser->createRelease(...$argv);
2223
} catch (Exception $e) {
2324
echo 'Failed to create a new release: ['.get_class($e).'] '.$e->getMessage().' at '.$e->getFile().':'.$e->getLine()."\n";
2425
exit(1);

src/Release/Releaser.php

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22

33
namespace SymfonyDocsBuilder\Release;
44

5-
use Symfony\Component\HttpClient\Exception\ClientException;
6-
use Symfony\Component\Process\Exception\ProcessFailedException;
7-
use Symfony\Component\Process\Process;
85
use Symfony\Contracts\HttpClient\HttpClientInterface;
6+
use SymfonyDocsBuilder\Phar\Compiler;
97

108
class Releaser
119
{
@@ -15,34 +13,27 @@ class Releaser
1513

1614
/** @var HttpClientInterface */
1715
private $client;
16+
private $compiler;
1817

19-
public function __construct(GithubApiHttpClientFactory $githubApiHttpClientFactory)
18+
public function __construct(HttpClientInterface $client, Compiler $compiler)
2019
{
21-
$this->client = $githubApiHttpClientFactory->createHttpClient();
20+
$this->client = $client;
21+
$this->compiler = $compiler;
2222
}
2323

24-
public function doRelease(string $tag, string $name = 'Symfony docs builder %s', string $description = 'Symfony docs builder %s')
24+
public function createRelease(string $tag, string $name = 'Symfony docs builder %s', string $description = 'Symfony docs builder %s')
2525
{
2626
if (!preg_match('/^v\d+\.\d+\.\d+$/', $tag)) {
2727
throw new \RuntimeException(sprintf('"%s" is not a valid tag.', $tag));
2828
}
2929

30-
$this->compilePhar();
30+
$this->compiler->compile();
3131

3232
$this->addAssetToRelease($releaseId = $this->createDraftRelease($tag, $name, $description));
3333

3434
$this->publishRelease($releaseId);
3535
}
3636

37-
/**
38-
* @throws ProcessFailedException
39-
*/
40-
private function compilePhar(): void
41-
{
42-
$process = Process::fromShellCommandline('./bin/compile', __DIR__.'/../..');
43-
$process->mustRun();
44-
}
45-
4637
private function createDraftRelease(string $tag, string $name, string $description): int
4738
{
4839
try {
@@ -62,14 +53,15 @@ private function createDraftRelease(string $tag, string $name, string $descripti
6253
);
6354

6455
return (int) $response->toArray()['id'];
65-
} catch (ClientException $exception) {
56+
} catch (\RuntimeException $exception) {
6657
if (401 === $exception->getCode()) {
67-
$message = 'Invalid token';
58+
$message = 'Error while trying to create release: Invalid token.';
6859
} else {
69-
$message = 'Maybe the tag name already exists?';
60+
$message = 'Error while trying to create release.';
7061
}
7162

72-
throw new \RuntimeException(sprintf('Error while trying to create release: %s.', $message), 0, $exception);
63+
// todo: create new exception which can be exploited in ./bin/create_release
64+
throw new \RuntimeException($message, 0, $exception);
7365
}
7466
}
7567

@@ -89,7 +81,7 @@ private function addAssetToRelease(int $releaseId): void
8981
'body' => file_get_contents(__DIR__.'/../../docs.phar'),
9082
]
9183
);
92-
} catch (ClientException $exception) {
84+
} catch (\RuntimeException $exception) {
9385
$this->deleteRelease($releaseId);
9486
throw new \RuntimeException('Error while adding asset to release.', 0, $exception);
9587
}
@@ -107,9 +99,9 @@ private function publishRelease(int $releaseId): void
10799
],
108100
]
109101
);
110-
} catch (ClientException $exception) {
102+
} catch (\RuntimeException $exception) {
111103
$this->deleteRelease($releaseId);
112-
throw new \RuntimeException('Error while publishing release.', 0, $exception);
104+
throw new \RuntimeException('Error while publishing release. Maybe the tag name already exists?', 0, $exception);
113105
}
114106
}
115107

@@ -120,7 +112,7 @@ private function deleteRelease(int $releaseId): void
120112
'DELETE',
121113
sprintf('https://api.github.com/repos/%s/%s/releases/%s', self::GITHUB_USER, self::GITHUB_REPO, $releaseId)
122114
);
123-
} catch (ClientException $exception) {
115+
} catch (\RuntimeException $exception) {
124116
throw new \RuntimeException('Error while deleting release.', 0, $exception);
125117
}
126118
}

tests/Release/ReleaserTest.php

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
3+
namespace SymfonyDocsBuilder\Tests\Release;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Symfony\Component\HttpClient\MockHttpClient;
7+
use Symfony\Component\HttpClient\Response\MockResponse;
8+
use SymfonyDocsBuilder\Phar\Compiler;
9+
use SymfonyDocsBuilder\Release\Releaser;
10+
11+
class ReleaserTest extends TestCase
12+
{
13+
public function setUp(): void
14+
{
15+
if (file_exists($pharFile = __DIR__.'/../../docs.phar')) {
16+
unlink($pharFile);
17+
}
18+
touch($pharFile);
19+
}
20+
21+
public function tearDown(): void
22+
{
23+
unlink( __DIR__.'/../../docs.phar');
24+
}
25+
26+
public function testCreateReleaseFailsWithInvalidTag(): void
27+
{
28+
$releaser = new Releaser(new MockHttpClient(), $compiler = $this->createMock(Compiler::class));
29+
30+
$compiler->expects($this->never())->method('compile');
31+
32+
$this->expectException(\RuntimeException::class);
33+
$this->expectExceptionMessage('"invalid tag" is not a valid tag.');
34+
35+
$releaser->createRelease('invalid tag');
36+
}
37+
38+
public function testCreateRelease(): void
39+
{
40+
$callback = static function ($method, $url) {
41+
switch (true) {
42+
case 'POST' === $method
43+
&& 'https://api.github.com/repos/nikophil/test/releases' === $url:
44+
return new MockResponse('{"id":1}');
45+
case 'POST' === $method
46+
&& 'https://uploads.github.com/repos/nikophil/test/releases/1/assets?name=docs.phar' === $url:
47+
case 'PATCH' === $method
48+
&& 'https://api.github.com/repos/nikophil/test/releases/1' === $url:
49+
return new MockResponse();
50+
}
51+
52+
self::fail(sprintf("Unexpected request:\n- method: %s\n- url: %s", $method, $url));
53+
};
54+
55+
$releaser = new Releaser(new MockHttpClient($callback), $compiler = $this->createMock(Compiler::class));
56+
57+
$compiler->expects($this->once())->method('compile');
58+
59+
$releaser->createRelease('v1.0.0');
60+
}
61+
62+
public function testCreateReleaseThrowExceptionIf401IsReturned(): void
63+
{
64+
$releaser = new Releaser(new MockHttpClient([new MockResponse('', ['http_code' => 401])]), $this->createMock(Compiler::class));
65+
66+
$this->expectException(\RuntimeException::class);
67+
$this->expectExceptionMessage('Error while trying to create release: Invalid token.');
68+
69+
$releaser->createRelease('v1.0.0');
70+
}
71+
72+
public function testReleaseIsDeletedIfAddAssetReturnsAnError(): void
73+
{
74+
$callback = static function ($method, $url) {
75+
switch (true) {
76+
case 'POST' === $method
77+
&& 'https://api.github.com/repos/nikophil/test/releases' === $url:
78+
return new MockResponse('{"id":1}');
79+
case 'POST' === $method
80+
&& 'https://uploads.github.com/repos/nikophil/test/releases/1/assets?name=docs.phar' === $url:
81+
return new MockResponse('', ['http_code' => 500]);
82+
case 'DELETE' === $method
83+
&& 'https://api.github.com/repos/nikophil/test/releases/1' === $url:
84+
return new MockResponse();
85+
}
86+
87+
self::fail(sprintf("Unexpected request:\n- method: %s\n- url: %s", $method, $url));
88+
};
89+
90+
$this->expectException(\RuntimeException::class);
91+
$this->expectExceptionMessage('Error while adding asset to release.');
92+
93+
$releaser = new Releaser(new MockHttpClient($callback), $this->createMock(Compiler::class));
94+
95+
$releaser->createRelease('v1.0.0');
96+
}
97+
}

0 commit comments

Comments
 (0)