Skip to content

Commit 6182b93

Browse files
authored
Merge pull request #24 from keboola/ondra/AJDA-2680
[AJDA-2680] Add listSubscriptions() and deleteSubscription() to SubscriptionClient
2 parents 1039c14 + fa4bab8 commit 6182b93

3 files changed

Lines changed: 239 additions & 0 deletions

File tree

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,37 @@ $clientFactory = new ClientFactory('https://connection.keboola.com');
4545
$clientFactory->getEventsClient('xxx-xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
4646
```
4747

48+
### Subscription client
49+
50+
```php
51+
use Keboola\NotificationClient\ClientFactory;
52+
use Keboola\NotificationClient\Requests\PostSubscription\EmailRecipient;
53+
use Keboola\NotificationClient\Requests\PostSubscription\Filter;
54+
use Keboola\NotificationClient\Requests\Subscription;
55+
56+
$clientFactory = new ClientFactory('https://connection.keboola.com');
57+
$subscriptionClient = $clientFactory->getSubscriptionClient('xxx-storage-api-token');
58+
59+
// create a subscription
60+
$created = $subscriptionClient->createSubscription(new Subscription(
61+
'job-failed',
62+
new EmailRecipient('you@example.com'),
63+
[new Filter('project.id', '123')],
64+
));
65+
66+
// list all subscriptions for the project (returned by token)
67+
$subscriptions = $subscriptionClient->listSubscriptions();
68+
foreach ($subscriptions as $subscription) {
69+
echo $subscription->getId() . ': ' . $subscription->getEvent() . "\n";
70+
}
71+
72+
// fetch a single subscription by ID
73+
$subscription = $subscriptionClient->getSubscription($created->getId());
74+
75+
// delete a subscription
76+
$subscriptionClient->deleteSubscription($created->getId());
77+
```
78+
4879
## Development
4980
- Create an Azure service principal to download the required images and login:
5081

src/SubscriptionClient.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,39 @@ public function createSubscription(RequestSubscription $requestData): ResponseSu
4141
}
4242
return new ResponseSubscription($this->sendRequest($request));
4343
}
44+
45+
public function deleteSubscription(string $id): void
46+
{
47+
$request = new Request(
48+
'DELETE',
49+
'project-subscriptions/' . rawurlencode($id),
50+
);
51+
$this->sendRequest($request);
52+
}
53+
54+
public function getSubscription(string $id): ResponseSubscription
55+
{
56+
$request = new Request(
57+
'GET',
58+
'project-subscriptions/' . rawurlencode($id),
59+
);
60+
return new ResponseSubscription($this->sendRequest($request));
61+
}
62+
63+
/**
64+
* @return array<ResponseSubscription>
65+
*/
66+
public function listSubscriptions(): array
67+
{
68+
$request = new Request(
69+
'GET',
70+
'project-subscriptions',
71+
);
72+
$response = $this->sendRequest($request);
73+
74+
return array_values(array_map(
75+
fn(array $item): ResponseSubscription => new ResponseSubscription($item),
76+
$response,
77+
));
78+
}
4479
}

tests/SubscriptionClientFunctionalTest.php

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Keboola\NotificationClient\Requests\PostSubscription\EmailRecipient;
1414
use Keboola\NotificationClient\Requests\PostSubscription\Filter;
1515
use Keboola\NotificationClient\Requests\Subscription;
16+
use Keboola\NotificationClient\Responses\Subscription as ResponseSubscription;
1617
use Keboola\NotificationClient\StorageApiIndexClient;
1718
use Keboola\NotificationClient\SubscriptionClient;
1819
use PHPUnit\Framework\TestCase;
@@ -117,4 +118,176 @@ public function testCreateSubscriptionHeaders(): void
117118
);
118119
self::assertSame(['application/json'], $request->getHeaders()['Content-type']);
119120
}
121+
122+
public function testDeleteSubscriptionHeaders(): void
123+
{
124+
$mock = new MockHandler([
125+
new Response(204, [], ''),
126+
]);
127+
$requestHistory = [];
128+
$history = Middleware::history($requestHistory);
129+
$stack = HandlerStack::create($mock);
130+
$stack->push($history);
131+
$client = new SubscriptionClient(
132+
'https://example.com/',
133+
'testToken',
134+
['handler' => $stack, 'backoffMaxTries' => 3, 'userAgent' => 'Test'],
135+
);
136+
137+
$client->deleteSubscription('subscription-123');
138+
139+
/** @var Request $request */
140+
$request = $requestHistory[0]['request'];
141+
self::assertSame('DELETE', $request->getMethod());
142+
self::assertSame('https://example.com/project-subscriptions/subscription-123', (string) $request->getUri());
143+
self::assertSame(
144+
['User-Agent', 'X-StorageApi-Token', 'Host'],
145+
array_keys($request->getHeaders()),
146+
);
147+
}
148+
149+
public function testGetSubscriptionHeaders(): void
150+
{
151+
$mock = new MockHandler([
152+
new Response(
153+
200,
154+
['Content-Type' => 'application/json'],
155+
(string) json_encode([
156+
'id' => 'subscription-123',
157+
'event' => 'job-failed',
158+
'filters' => [
159+
['field' => 'project.id', 'value' => '123'],
160+
],
161+
'recipient' => ['channel' => 'email', 'address' => 'a@example.com'],
162+
]),
163+
),
164+
]);
165+
$requestHistory = [];
166+
$history = Middleware::history($requestHistory);
167+
$stack = HandlerStack::create($mock);
168+
$stack->push($history);
169+
$client = new SubscriptionClient(
170+
'https://example.com/',
171+
'testToken',
172+
['handler' => $stack, 'backoffMaxTries' => 3, 'userAgent' => 'Test'],
173+
);
174+
175+
$result = $client->getSubscription('subscription-123');
176+
177+
/** @var Request $request */
178+
$request = $requestHistory[0]['request'];
179+
self::assertSame('GET', $request->getMethod());
180+
self::assertSame('https://example.com/project-subscriptions/subscription-123', (string) $request->getUri());
181+
self::assertSame(
182+
['User-Agent', 'X-StorageApi-Token', 'Host'],
183+
array_keys($request->getHeaders()),
184+
);
185+
186+
self::assertSame('subscription-123', $result->getId());
187+
self::assertSame('job-failed', $result->getEvent());
188+
self::assertSame('project.id', $result->getFilters()[0]->getField());
189+
self::assertSame('123', $result->getFilters()[0]->getValue());
190+
self::assertSame('email', $result->getRecipientChannel());
191+
self::assertSame('a@example.com', $result->getRecipientAddress());
192+
}
193+
194+
public function testListSubscriptionsHeaders(): void
195+
{
196+
$responseBody = json_encode([
197+
[
198+
'id' => 'sub-1',
199+
'event' => 'job-failed',
200+
'filters' => [
201+
['field' => 'project.id', 'value' => '123'],
202+
],
203+
'recipient' => ['channel' => 'email', 'address' => 'a@example.com'],
204+
],
205+
[
206+
'id' => 'sub-2',
207+
'event' => 'job-succeeded',
208+
'filters' => [],
209+
'recipient' => ['channel' => 'email', 'address' => 'b@example.com'],
210+
],
211+
]);
212+
213+
$mock = new MockHandler([
214+
new Response(200, ['Content-Type' => 'application/json'], (string) $responseBody),
215+
]);
216+
$requestHistory = [];
217+
$history = Middleware::history($requestHistory);
218+
$stack = HandlerStack::create($mock);
219+
$stack->push($history);
220+
$client = new SubscriptionClient(
221+
'https://example.com/',
222+
'testToken',
223+
['handler' => $stack, 'backoffMaxTries' => 3, 'userAgent' => 'Test'],
224+
);
225+
226+
$result = $client->listSubscriptions();
227+
228+
/** @var Request $request */
229+
$request = $requestHistory[0]['request'];
230+
self::assertSame('GET', $request->getMethod());
231+
self::assertSame('https://example.com/project-subscriptions', (string) $request->getUri());
232+
self::assertSame(
233+
['User-Agent', 'X-StorageApi-Token', 'Host'],
234+
array_keys($request->getHeaders()),
235+
);
236+
237+
self::assertCount(2, $result);
238+
self::assertContainsOnlyInstancesOf(
239+
ResponseSubscription::class,
240+
$result,
241+
);
242+
self::assertSame('sub-1', $result[0]->getId());
243+
self::assertSame('job-failed', $result[0]->getEvent());
244+
self::assertSame('project.id', $result[0]->getFilters()[0]->getField());
245+
self::assertSame('123', $result[0]->getFilters()[0]->getValue());
246+
self::assertSame('email', $result[0]->getRecipientChannel());
247+
self::assertSame('a@example.com', $result[0]->getRecipientAddress());
248+
self::assertSame('sub-2', $result[1]->getId());
249+
}
250+
251+
public function testListAndDeleteSubscriptionLifecycle(): void
252+
{
253+
$client = $this->getClient();
254+
255+
// create
256+
$created = $client->createSubscription(new Subscription(
257+
'job-failed',
258+
new EmailRecipient('ajda-2680@example.com'),
259+
[
260+
new Filter('project.id', (string) getenv('TEST_STORAGE_API_PROJECT_ID')),
261+
],
262+
));
263+
self::assertNotEmpty($created->getId());
264+
265+
// get — must return the same subscription
266+
$fetched = $client->getSubscription($created->getId());
267+
self::assertSame($created->getId(), $fetched->getId());
268+
self::assertSame('job-failed', $fetched->getEvent());
269+
270+
// list — must contain the new subscription
271+
$beforeDelete = $client->listSubscriptions();
272+
self::assertContainsOnlyInstancesOf(
273+
ResponseSubscription::class,
274+
$beforeDelete,
275+
);
276+
$ids = array_map(
277+
fn(ResponseSubscription $s): string => $s->getId(),
278+
$beforeDelete,
279+
);
280+
self::assertContains($created->getId(), $ids);
281+
282+
// delete
283+
$client->deleteSubscription($created->getId());
284+
285+
// list — must no longer contain it
286+
$afterDelete = $client->listSubscriptions();
287+
$idsAfter = array_map(
288+
fn(ResponseSubscription $s): string => $s->getId(),
289+
$afterDelete,
290+
);
291+
self::assertNotContains($created->getId(), $idsAfter);
292+
}
120293
}

0 commit comments

Comments
 (0)