Skip to content

Commit 309a671

Browse files
authored
Merge pull request #1 from ByteInternet/ephemeral_apps
Add methods for creating and cancelling ephemeral apps
2 parents 60681c5 + 28a5688 commit 309a671

File tree

8 files changed

+158
-7
lines changed

8 files changed

+158
-7
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@ Here's a list of Hypernode API features implemented in the client.
4949

5050
- Updating one or multiple Hypernode settings at once.
5151
- Querying/polling the logbook for the status of a job.
52+
- Creating and cancelling Ephemeral Hypernode instances.

src/Exception/ResponseException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class ResponseException extends Exception
1313

1414
public function __construct(ResponseInterface $response)
1515
{
16-
parent::__construct();
16+
parent::__construct((string)$response->getBody(), $response->getStatusCode());
1717

1818
$this->response = $response;
1919
}

src/HypernodeClient.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Hypernode\Api\Exception\HypernodeApiClientException;
99
use Hypernode\Api\Exception\HypernodeApiServerException;
1010
use Hypernode\Api\Service\App;
11+
use Hypernode\Api\Service\EphemeralApp;
1112
use Hypernode\Api\Service\Logbook;
1213
use Hypernode\Api\Service\Settings;
1314
use Psr\Http\Message\ResponseInterface;
@@ -18,13 +19,15 @@ class HypernodeClient
1819

1920
public HttpMethodsClientInterface $api;
2021
public App $app;
22+
public EphemeralApp $ephemeralApp;
2123
public Settings $settings;
2224
public Logbook $logbook;
2325

2426
public function __construct(HttpMethodsClientInterface $apiClient)
2527
{
2628
$this->api = $apiClient;
2729
$this->app = new App($this);
30+
$this->ephemeralApp = new EphemeralApp($this);
2831
$this->settings = new Settings($this);
2932
$this->logbook = new Logbook($this);
3033
}

src/Service/App.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,7 @@
77
class App extends AbstractService
88
{
99
public const V2_APP_DETAIL_URL = "/v2/app/%s/";
10+
public const V2_APP_CANCEL_URL = "/v2/app/%s/cancel/";
11+
public const V2_APP_EPHEMERAL_URL = "/v2/app/%s/ephemeral/";
1012
public const V1_APP_FLOWS_URL = "/logbook/v1/logbooks/%s/flows/";
1113
}

src/Service/EphemeralApp.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Hypernode\Api\Service;
6+
7+
use Hypernode\Api\Exception\HypernodeApiClientException;
8+
use Hypernode\Api\Exception\HypernodeApiServerException;
9+
10+
class EphemeralApp extends AbstractService
11+
{
12+
/**
13+
* Create an ephemeral app for given parent app.
14+
*
15+
* @param string $app Name of the parent app
16+
* @return string Name of the ephemeral app
17+
* @throws HypernodeApiClientException
18+
* @throws HypernodeApiServerException
19+
*/
20+
public function create(string $app): string
21+
{
22+
$url = sprintf(App::V2_APP_EPHEMERAL_URL, $app);
23+
24+
$response = $this->client->api->post($url);
25+
26+
$this->client->maybeThrowApiExceptions($response);
27+
28+
$data = $this->client->getJsonFromResponse($response);
29+
30+
return $data['name'];
31+
}
32+
33+
/**
34+
* Cancel an ephemeral app.
35+
*
36+
* @param string $app Name of the ephemeral app
37+
* @return void
38+
* @throws HypernodeApiClientException
39+
* @throws HypernodeApiServerException
40+
*/
41+
public function cancel(string $app): void
42+
{
43+
$url = sprintf(App::V2_APP_CANCEL_URL, $app);
44+
45+
$response = $this->client->api->delete($url);
46+
47+
$this->client->maybeThrowApiExceptions($response);
48+
}
49+
}

tests/unit/Resource/Logbook/JobTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Hypernode\Api\Resource\Logbook;
46

57
use GuzzleHttp\Psr7\Response;
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Hypernode\Api\Service;
6+
7+
use GuzzleHttp\Psr7\Response;
8+
use Hypernode\Api\Exception\HypernodeApiClientException;
9+
use Hypernode\Api\Exception\HypernodeApiServerException;
10+
use Hypernode\Api\HypernodeClientTestCase;
11+
12+
class EphemeralAppTest extends HypernodeClientTestCase
13+
{
14+
public function testCreateEphemeralApp()
15+
{
16+
$this->responses->append(
17+
new Response(200, [], json_encode([
18+
'name' => 'johndoe-eph123456',
19+
'parent' => 'johndoe',
20+
'type' => 'ephemeral',
21+
])),
22+
);
23+
24+
$ephemeralAppName = $this->client->ephemeralApp->create('johndoe');
25+
26+
$request = $this->responses->getLastRequest();
27+
$this->assertEquals('POST', $request->getMethod());
28+
$this->assertEquals('/v2/app/johndoe/ephemeral/', $request->getUri());
29+
$this->assertEquals('johndoe-eph123456', $ephemeralAppName);
30+
}
31+
32+
public function testCreateEphemeralAppRaisesClientExceptions()
33+
{
34+
$badRequestResponse = new Response(400, [], json_encode([
35+
'non_field_errors' => ['Your request was invalid.']
36+
]));
37+
$this->responses->append($badRequestResponse);
38+
39+
$this->expectExceptionObject(new HypernodeApiClientException($badRequestResponse));
40+
41+
$this->client->ephemeralApp->create('johndoe');
42+
}
43+
44+
public function testCreateEphemeralAppRaisesServerExceptions()
45+
{
46+
$badRequestResponse = new Response(500, [], json_encode([
47+
'non_field_errors' => ['Something went wrong processing your request.']
48+
]));
49+
$this->responses->append($badRequestResponse);
50+
51+
$this->expectExceptionObject(new HypernodeApiServerException($badRequestResponse));
52+
53+
$this->client->ephemeralApp->create('johndoe');
54+
}
55+
56+
public function testCancelEphemeralApp()
57+
{
58+
$this->responses->append(
59+
new Response(204, [], null),
60+
);
61+
62+
$this->client->ephemeralApp->cancel('johndoe-eph123456');
63+
64+
$request = $this->responses->getLastRequest();
65+
$this->assertEquals('DELETE', $request->getMethod());
66+
$this->assertEquals('/v2/app/johndoe-eph123456/cancel/', $request->getUri());
67+
}
68+
69+
public function testCancelEphemeralAppRaisesClientExceptions()
70+
{
71+
$badRequestResponse = new Response(400, [], json_encode([
72+
'non_field_errors' => ['Your request was invalid.']
73+
]));
74+
$this->responses->append($badRequestResponse);
75+
76+
$this->expectExceptionObject(new HypernodeApiClientException($badRequestResponse));
77+
78+
$this->client->ephemeralApp->cancel('johndoe');
79+
}
80+
81+
public function testCancelEphemeralAppRaisesServerExceptions()
82+
{
83+
$badRequestResponse = new Response(500, [], json_encode([
84+
'non_field_errors' => ['Something went wrong processing your request.']
85+
]));
86+
$this->responses->append($badRequestResponse);
87+
88+
$this->expectExceptionObject(new HypernodeApiServerException($badRequestResponse));
89+
90+
$this->client->ephemeralApp->cancel('johndoe');
91+
}
92+
}

tests/unit/Service/SettingsTest.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Hypernode\Api\Service;
46

57
use GuzzleHttp\Psr7\Response;
@@ -20,10 +22,10 @@ public function testSetSingleSettingToSameValue()
2022
$this->assertNull($job);
2123
$this->assertEquals('PATCH', $request->getMethod());
2224
$this->assertEquals('/v2/app/johndoe/', $request->getUri());
23-
$this->assertJson($request->getBody());
25+
$this->assertJson((string)$request->getBody());
2426
$this->assertEquals(
2527
['php_version' => '8.1'],
26-
json_decode($request->getBody(), true)
28+
json_decode((string)$request->getBody(), true)
2729
);
2830
}
2931

@@ -41,10 +43,10 @@ public function testSetSingleSettingToDifferentValue()
4143
$this->assertNotNull($job);
4244
$this->assertEquals('PATCH', $request->getMethod());
4345
$this->assertEquals('/v2/app/johndoe/', $request->getUri());
44-
$this->assertJson($request->getBody());
46+
$this->assertJson((string)$request->getBody());
4547
$this->assertEquals(
4648
['php_version' => '8.1'],
47-
json_decode($request->getBody(), true)
49+
json_decode((string)$request->getBody(), true)
4850
);
4951
}
5052

@@ -68,13 +70,13 @@ public function testSetMultipleSettings()
6870
$this->assertNotNull($job);
6971
$this->assertEquals('PATCH', $request->getMethod());
7072
$this->assertEquals('/v2/app/johndoe/', $request->getUri());
71-
$this->assertJson($request->getBody());
73+
$this->assertJson((string)$request->getBody());
7274
$this->assertEquals(
7375
[
7476
'php_version' => '8.1',
7577
'nodejs_version' => '18'
7678
],
77-
json_decode($request->getBody(), true)
79+
json_decode((string)$request->getBody(), true)
7880
);
7981
}
8082
}

0 commit comments

Comments
 (0)