Skip to content

Commit fc65e19

Browse files
committed
test releaser
1 parent ea46247 commit fc65e19

File tree

3 files changed

+104
-25
lines changed

3 files changed

+104
-25
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: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
namespace SymfonyDocsBuilder\Release;
44

55
use Symfony\Component\HttpClient\Exception\ClientException;
6-
use Symfony\Component\Process\Exception\ProcessFailedException;
7-
use Symfony\Component\Process\Process;
86
use Symfony\Contracts\HttpClient\HttpClientInterface;
7+
use SymfonyDocsBuilder\Phar\Compiler;
98

109
class Releaser
1110
{
@@ -15,34 +14,27 @@ class Releaser
1514

1615
/** @var HttpClientInterface */
1716
private $client;
17+
private $compiler;
1818

19-
public function __construct(GithubApiHttpClientFactory $githubApiHttpClientFactory)
19+
public function __construct(HttpClientInterface $client, Compiler $compiler)
2020
{
21-
$this->client = $githubApiHttpClientFactory->createHttpClient();
21+
$this->client = $client;
22+
$this->compiler = $compiler;
2223
}
2324

24-
public function doRelease(string $tag, string $name = 'Symfony docs builder %s', string $description = 'Symfony docs builder %s')
25+
public function createRelease(string $tag, string $name = 'Symfony docs builder %s', string $description = 'Symfony docs builder %s')
2526
{
2627
if (!preg_match('/^v\d+\.\d+\.\d+$/', $tag)) {
2728
throw new \RuntimeException(sprintf('"%s" is not a valid tag.', $tag));
2829
}
2930

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

3233
$this->addAssetToRelease($releaseId = $this->createDraftRelease($tag, $name, $description));
3334

3435
$this->publishRelease($releaseId);
3536
}
3637

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

6456
return (int) $response->toArray()['id'];
65-
} catch (ClientException $exception) {
57+
} catch (\RuntimeException $exception) {
6658
if (401 === $exception->getCode()) {
67-
$message = 'Invalid token';
59+
$message = 'Error while trying to create release: Invalid token.';
6860
} else {
69-
$message = 'Maybe the tag name already exists?';
61+
$message = 'Error while trying to create release.';
7062
}
7163

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

@@ -86,10 +79,11 @@ private function addAssetToRelease(int $releaseId): void
8679
),
8780
[
8881
'headers' => ['Content-Type' => 'application/octet-stream'],
82+
// todo: make something for tests
8983
'body' => file_get_contents(__DIR__.'/../../docs.phar'),
9084
]
9185
);
92-
} catch (ClientException $exception) {
86+
} catch (\RuntimeException $exception) {
9387
$this->deleteRelease($releaseId);
9488
throw new \RuntimeException('Error while adding asset to release.', 0, $exception);
9589
}
@@ -107,9 +101,9 @@ private function publishRelease(int $releaseId): void
107101
],
108102
]
109103
);
110-
} catch (ClientException $exception) {
104+
} catch (\RuntimeException $exception) {
111105
$this->deleteRelease($releaseId);
112-
throw new \RuntimeException('Error while publishing release.', 0, $exception);
106+
throw new \RuntimeException('Error while publishing release. Maybe the tag name already exists?', 0, $exception);
113107
}
114108
}
115109

@@ -120,7 +114,7 @@ private function deleteRelease(int $releaseId): void
120114
'DELETE',
121115
sprintf('https://api.github.com/repos/%s/%s/releases/%s', self::GITHUB_USER, self::GITHUB_REPO, $releaseId)
122116
);
123-
} catch (ClientException $exception) {
117+
} catch (\RuntimeException $exception) {
124118
throw new \RuntimeException('Error while deleting release.', 0, $exception);
125119
}
126120
}

tests/Release/ReleaserTest.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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 testCreateReleaseFailsWithInvalidTag()
14+
{
15+
$releaser = new Releaser(new MockHttpClient(), $compiler = $this->createMock(Compiler::class));
16+
17+
$compiler->expects($this->never())->method('compile');
18+
19+
$this->expectException(\RuntimeException::class);
20+
$this->expectExceptionMessage('"invalid tag" is not a valid tag.');
21+
22+
$releaser->createRelease('invalid tag');
23+
}
24+
25+
public function testCreateRelease(): void
26+
{
27+
$callback = static function ($method, $url) {
28+
switch (true) {
29+
case 'POST' === $method
30+
&& 'https://api.github.com/repos/nikophil/test/releases' === $url:
31+
return new MockResponse('{"id":1}');
32+
case 'POST' === $method
33+
&& 'https://uploads.github.com/repos/nikophil/test/releases/1/assets?name=docs.phar' === $url:
34+
case 'PATCH' === $method
35+
&& 'https://api.github.com/repos/nikophil/test/releases/1' === $url:
36+
return new MockResponse();
37+
}
38+
39+
self::fail(sprintf("Unexpected request:\n- method: %s\n- url: %s", $method, $url));
40+
};
41+
42+
$releaser = new Releaser(new MockHttpClient($callback), $compiler = $this->createMock(Compiler::class));
43+
44+
$compiler->expects($this->once())->method('compile');
45+
46+
$releaser->createRelease('v1.0.0');
47+
}
48+
49+
public function testCreateReleaseThrowExceptionIf401IsReturned(): void
50+
{
51+
$releaser = new Releaser(new MockHttpClient([new MockResponse('', ['http_code' => 401])]), $this->createMock(Compiler::class));
52+
53+
$this->expectException(\RuntimeException::class);
54+
$this->expectExceptionMessage('Error while trying to create release: Invalid token.');
55+
56+
$releaser->createRelease('v1.0.0');
57+
}
58+
59+
public function testReleaseIsDeletedIfAddAssetReturnsAnError(): void
60+
{
61+
$callback = static function ($method, $url) {
62+
switch (true) {
63+
case 'POST' === $method
64+
&& 'https://api.github.com/repos/nikophil/test/releases' === $url:
65+
return new MockResponse('{"id":1}');
66+
case 'POST' === $method
67+
&& 'https://uploads.github.com/repos/nikophil/test/releases/1/assets?name=docs.phar' === $url:
68+
return new MockResponse('', ['http_code' => 500]);
69+
case 'DELETE' === $method
70+
&& 'https://api.github.com/repos/nikophil/test/releases/1' === $url:
71+
return new MockResponse();
72+
}
73+
74+
self::fail(sprintf("Unexpected request:\n- method: %s\n- url: %s", $method, $url));
75+
};
76+
77+
$this->expectException(\RuntimeException::class);
78+
$this->expectExceptionMessage('Error while adding asset to release.');
79+
80+
$releaser = new Releaser(new MockHttpClient($callback), $this->createMock(Compiler::class));
81+
82+
$releaser->createRelease('v1.0.0');
83+
}
84+
}

0 commit comments

Comments
 (0)