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:
Joas Schilling 2023-04-06 15:27:21 +02:00
Родитель b8d4c4a410
Коммит 495cb5092c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 74434EFE0D2E2205
9 изменённых файлов: 105 добавлений и 7 удалений

Просмотреть файл

@ -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',