feat(API): Add an endpoint to check for existance of notification ids
Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Родитель
b8d4c4a410
Коммит
495cb5092c
|
@ -3,9 +3,11 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023, Joas Schilling <coding@schilljs.com>
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
|
@ -26,6 +28,7 @@ return [
|
|||
'ocs' => [
|
||||
['name' => 'Endpoint#listNotifications', 'url' => '/api/{apiVersion}/notifications', 'verb' => 'GET', 'requirements' => ['apiVersion' => 'v(1|2)']],
|
||||
['name' => 'Endpoint#getNotification', 'url' => '/api/{apiVersion}/notifications/{id}', 'verb' => 'GET', 'requirements' => ['apiVersion' => 'v(1|2)', 'id' => '\d+']],
|
||||
['name' => 'Endpoint#confirmIdsForUser', 'url' => '/api/{apiVersion}/notifications/exists', 'verb' => 'POST', 'requirements' => ['apiVersion' => 'v(1|2)']],
|
||||
['name' => 'Endpoint#deleteNotification', 'url' => '/api/{apiVersion}/notifications/{id}', 'verb' => 'DELETE', 'requirements' => ['apiVersion' => 'v(1|2)', 'id' => '\d+']],
|
||||
['name' => 'Endpoint#deleteAllNotifications', 'url' => '/api/{apiVersion}/notifications', 'verb' => 'DELETE', 'requirements' => ['apiVersion' => 'v(1|2)']],
|
||||
['name' => 'Push#registerDevice', 'url' => '/api/{apiVersion}/push', 'verb' => 'POST', 'requirements' => ['apiVersion' => 'v2']],
|
||||
|
|
|
@ -168,3 +168,12 @@ In order to delete a notification, you can send a DELETE request against `/ocs/v
|
|||
In order to delete all notifications, you can send a DELETE request against `/ocs/v2.php/apps/notifications/api/v2/notifications`
|
||||
|
||||
**Note:** This endpoint was added for Nextcloud 14, so check for the `delete-all` capability first.
|
||||
|
||||
|
||||
## Check existance of notifications for a user
|
||||
|
||||
In order to check whether a set of notification ids (max. 200 items per request) still exist for a user,
|
||||
a client can send a POST request against `/ocs/v2.php/apps/notifications/api/v2/notifications/exists` with
|
||||
the integer list provided as `ids` field on the POST body.
|
||||
|
||||
**Note:** This endpoint was added for Nextcloud 27, so check for the `exists` capability first.
|
||||
|
|
|
@ -49,6 +49,7 @@ class Capabilities implements ICapability {
|
|||
'rich-strings',
|
||||
'action-web',
|
||||
'user-status',
|
||||
'exists',
|
||||
],
|
||||
'push' => [
|
||||
'devices',
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023, Joas Schilling <coding@schilljs.com>
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
|
@ -169,6 +171,30 @@ class EndpointController extends OCSController {
|
|||
return new DataResponse($this->notificationToArray($id, $notification, $apiVersion, $hasActiveTalkDesktop));
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*
|
||||
* @param string $apiVersion
|
||||
* @param int[] $ids
|
||||
* @return DataResponse
|
||||
*/
|
||||
public function confirmIdsForUser(string $apiVersion, array $ids): DataResponse {
|
||||
if (!$this->manager->hasNotifiers()) {
|
||||
return new DataResponse([], Http::STATUS_OK);
|
||||
}
|
||||
|
||||
if (empty($ids)) {
|
||||
return new DataResponse([], Http::STATUS_OK);
|
||||
}
|
||||
|
||||
if (count($ids) > 200) {
|
||||
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$existingIds = $this->handler->confirmIdsForUser($this->getCurrentUser(), $ids);
|
||||
return new DataResponse($existingIds, Http::STATUS_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023, Joas Schilling <coding@schilljs.com>
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
|
@ -217,6 +219,30 @@ class Handler {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that the notification ids still exist for the user
|
||||
*
|
||||
* @param string $user
|
||||
* @param int[] $ids
|
||||
* @return int[]
|
||||
*/
|
||||
public function confirmIdsForUser(string $user, array $ids): array {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->select('*')
|
||||
->from('notifications')
|
||||
->where($query->expr()->in('notification_id', $query->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
|
||||
->andWhere($query->expr()->eq('user', $query->createNamedParameter($user)));
|
||||
$result = $query->executeQuery();
|
||||
|
||||
$existing = [];
|
||||
while ($row = $result->fetch()) {
|
||||
$existing[] = (int) $row['notification_id'];
|
||||
}
|
||||
$result->closeCursor();
|
||||
|
||||
return $existing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notifications after (and excluding) the given id
|
||||
*
|
||||
|
|
|
@ -148,11 +148,34 @@ class FeatureContext implements Context, SnippetAcceptingContext {
|
|||
}
|
||||
|
||||
/**
|
||||
* Parses the xml answer to get the array of users returned.
|
||||
* @param ResponseInterface $response
|
||||
* @return array
|
||||
* @Then /^confirms previously fetched notification ids exist on (v\d+)$/
|
||||
*/
|
||||
public function checkNotificationsExists(string $api) {
|
||||
$notificationIds = end($this->notificationIds);
|
||||
|
||||
$sendingWithGarbage = $notificationIds;
|
||||
// An array instead of int
|
||||
$sendingWithGarbage[] = $notificationIds;
|
||||
// A string instead of int
|
||||
$sendingWithGarbage[] = '$notificationIds';
|
||||
// A duplicate
|
||||
$sendingWithGarbage[] = reset($notificationIds);
|
||||
|
||||
$this->sendingToWith('POST', '/apps/notifications/api/' . $api . '/notifications/exists?format=json', [
|
||||
'ids' => $sendingWithGarbage,
|
||||
]);
|
||||
|
||||
$this->assertStatusCode($this->response, 200);
|
||||
$actualIds = $this->getDataFromOCSResponse($this->response);
|
||||
|
||||
Assert::assertSame($notificationIds, $actualIds);
|
||||
}
|
||||
|
||||
protected function getArrayOfNotificationsResponded(ResponseInterface $response): array {
|
||||
return $this->getDataFromOCSResponse($response);
|
||||
}
|
||||
|
||||
protected function getDataFromOCSResponse(ResponseInterface $response): array {
|
||||
$jsonBody = json_decode($response->getBody()->getContents(), true);
|
||||
return $jsonBody['ocs']['data'];
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
Feature: exists-notifications-v2
|
||||
Background:
|
||||
Given user "test1" exists
|
||||
Given as user "test1"
|
||||
|
||||
Scenario: Delete first notification
|
||||
Given user "test1" has notifications
|
||||
And user "test1" has 1 notifications on v2
|
||||
Then confirms previously fetched notification ids exist on v2
|
|
@ -37,6 +37,6 @@ class RoutesTest extends TestCase {
|
|||
$this->assertCount(1, $routes);
|
||||
$this->assertArrayHasKey('ocs', $routes);
|
||||
$this->assertIsArray($routes['ocs']);
|
||||
$this->assertCount(9, $routes['ocs']);
|
||||
$this->assertCount(10, $routes['ocs']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ class CapabilitiesTest extends TestCase {
|
|||
'rich-strings',
|
||||
'action-web',
|
||||
'user-status',
|
||||
'exists',
|
||||
],
|
||||
'push' => [
|
||||
'devices',
|
||||
|
|
Загрузка…
Ссылка в новой задаче