Skip to content

Commit 622d067

Browse files
[5.1] Add Droplet list filter methods (#362)
* Add Droplet list filters * Use explicit Droplet list filter methods
1 parent dbece58 commit 622d067

3 files changed

Lines changed: 170 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CHANGE LOG
99
* Fixed hydration of object-backed App Platform and project resource fields
1010
* Fixed `LoadBalancer` hydration and update serialization
1111
* Fixed `Volume` hydration when `droplet_ids` is null
12+
* Add support for listing Droplets by name or type
1213

1314

1415
## 5.0.5 (03/05/2025)

src/Api/Droplet.php

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,59 @@ class Droplet extends AbstractApi
3333
*/
3434
public function getAll(?string $tag = null): array
3535
{
36-
$droplets = $this->get('droplets', null === $tag ? [] : ['tag_name' => $tag]);
36+
return $this->getAllWithQuery(null === $tag ? [] : ['tag_name' => $tag]);
37+
}
38+
39+
/**
40+
* @throws ExceptionInterface
41+
*
42+
* @return DropletEntity[]
43+
*/
44+
public function getAllByTag(string $tag): array
45+
{
46+
return $this->getAllWithQuery(['tag_name' => $tag]);
47+
}
48+
49+
/**
50+
* @param 'droplets'|'gpus'|null $type
51+
*
52+
* @throws ExceptionInterface
53+
*
54+
* @return DropletEntity[]
55+
*/
56+
public function getAllByName(string $name, ?string $type = null): array
57+
{
58+
$query = ['name' => $name];
59+
60+
if (null !== $type && \in_array($type, ['droplets', 'gpus'], true)) {
61+
$query['type'] = $type;
62+
}
63+
64+
return $this->getAllWithQuery($query);
65+
}
66+
67+
/**
68+
* @param 'droplets'|'gpus' $type
69+
*
70+
* @throws ExceptionInterface
71+
*
72+
* @return DropletEntity[]
73+
*/
74+
public function getAllByType(string $type): array
75+
{
76+
return $this->getAllWithQuery(\in_array($type, ['droplets', 'gpus'], true) ? ['type' => $type] : []);
77+
}
78+
79+
/**
80+
* @param array<string,string> $query
81+
*
82+
* @throws ExceptionInterface
83+
*
84+
* @return DropletEntity[]
85+
*/
86+
private function getAllWithQuery(array $query): array
87+
{
88+
$droplets = $this->get('droplets', $query);
3789

3890
return \array_map(function ($droplet) {
3991
return new DropletEntity($droplet);

tests/Api/DropletTest.php

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the DigitalOcean API library.
7+
*
8+
* (c) Antoine Kirk <contact@sbin.dk>
9+
* (c) Graham Campbell <hello@gjcampbell.co.uk>
10+
*
11+
* For the full copyright and license information, please view the LICENSE
12+
* file that was distributed with this source code.
13+
*/
14+
15+
namespace DigitalOceanV2\Tests\Api;
16+
17+
use DigitalOceanV2\Api\Droplet;
18+
use DigitalOceanV2\Client;
19+
use DigitalOceanV2\Entity\Droplet as DropletEntity;
20+
use GuzzleHttp\Psr7\Response;
21+
use GuzzleHttp\Psr7\Utils;
22+
use Http\Client\Common\HttpMethodsClientInterface;
23+
use PHPUnit\Framework\TestCase;
24+
25+
/**
26+
* @author Graham Campbell <hello@gjcampbell.co.uk>
27+
*/
28+
class DropletTest extends TestCase
29+
{
30+
public function testItCreatesAnArrayOfDropletEntities(): void
31+
{
32+
$droplets = $this->createApiExpectingGet('/v2/droplets')->getAll();
33+
34+
self::assertInstanceOf(DropletEntity::class, $droplets[0]);
35+
self::assertSame('example.com', $droplets[0]->name);
36+
}
37+
38+
public function testItFiltersDropletsByTagName(): void
39+
{
40+
$droplets = $this->createApiExpectingGet('/v2/droplets?tag_name=awesome')->getAll('awesome');
41+
42+
self::assertInstanceOf(DropletEntity::class, $droplets[0]);
43+
self::assertSame('example.com', $droplets[0]->name);
44+
}
45+
46+
public function testItFiltersDropletsByTagNameMethod(): void
47+
{
48+
$droplets = $this->createApiExpectingGet('/v2/droplets?tag_name=awesome')->getAllByTag('awesome');
49+
50+
self::assertInstanceOf(DropletEntity::class, $droplets[0]);
51+
self::assertSame('example.com', $droplets[0]->name);
52+
}
53+
54+
public function testItFiltersDropletsByName(): void
55+
{
56+
$droplets = $this->createApiExpectingGet('/v2/droplets?name=example.com')->getAllByName('example.com');
57+
58+
self::assertInstanceOf(DropletEntity::class, $droplets[0]);
59+
self::assertSame('example.com', $droplets[0]->name);
60+
}
61+
62+
public function testItFiltersDropletsByType(): void
63+
{
64+
$droplets = $this->createApiExpectingGet('/v2/droplets?type=gpus')->getAllByType('gpus');
65+
66+
self::assertInstanceOf(DropletEntity::class, $droplets[0]);
67+
self::assertSame('example.com', $droplets[0]->name);
68+
}
69+
70+
public function testItFiltersDropletsByStandardType(): void
71+
{
72+
$droplets = $this->createApiExpectingGet('/v2/droplets?type=droplets')->getAllByType('droplets');
73+
74+
self::assertInstanceOf(DropletEntity::class, $droplets[0]);
75+
self::assertSame('example.com', $droplets[0]->name);
76+
}
77+
78+
public function testItFiltersDropletsByNameAndType(): void
79+
{
80+
$droplets = $this->createApiExpectingGet('/v2/droplets?name=example.com&type=gpus')
81+
->getAllByName('example.com', 'gpus');
82+
83+
self::assertInstanceOf(DropletEntity::class, $droplets[0]);
84+
self::assertSame('example.com', $droplets[0]->name);
85+
}
86+
87+
private function createApiExpectingGet(string $uri): Droplet
88+
{
89+
$client = $this->createMock(Client::class);
90+
$client->expects(self::once())
91+
->method('getHttpClient')
92+
->willReturn($httpClient = $this->createMock(HttpMethodsClientInterface::class));
93+
94+
$httpClient->expects(self::once())
95+
->method('get')
96+
->with($uri)
97+
->willReturn(self::createResponse());
98+
99+
return new Droplet($client);
100+
}
101+
102+
private static function createResponse(): Response
103+
{
104+
return new Response(
105+
200,
106+
['Content-Type' => ['application/json']],
107+
Utils::streamFor(\json_encode(['droplets' => [
108+
[
109+
'id' => 3164444,
110+
'name' => 'example.com',
111+
'features' => [],
112+
],
113+
]]))
114+
);
115+
}
116+
}

0 commit comments

Comments
 (0)