API: filter notes by category (introduce v1.1)

This commit is contained in:
korelstar 2020-05-22 11:35:59 +02:00 committed by GitHub
parent 79ae40eee1
commit e2f4e30d3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 13 deletions

View File

@ -6,7 +6,7 @@
"guzzlehttp/guzzle": "^6.5",
"staabm/annotate-pull-request-from-checkstyle": "^1.1.0"
},
"autoload": {
"autoload-dev": {
"psr-4": {
"OCA\\Notes\\Tests\\API\\": "tests/api/"
}

View File

@ -8,6 +8,7 @@ In this document, the Notes API major version 1 and all its minor versions are d
| API version | Introduced with app version | Remarkable Changes |
|:-----------:|:----------------------------|:-------------------|
| **1.0** | Notes 3.3 (May 2020) | Separate title, no auto rename based on content |
| **1.1** | Notes 3.4 (May 2020) | Filter "Get all notes" by category |
@ -41,11 +42,12 @@ All defined routes in the specification are appended to this url. To access all
<details><summary>Details</summary>
#### Request parameters
| Parameter | Type | Description |
|:------|:-----|:-----|
| `exclude` | string, optional | Fields which should be excluded from response, seperated with a comma e.g.: `?exclude=content,title`. You can use this in order to reduce transferred data size if you are interested in specific attributes, only. |
| `purgeBefore` | integer, optional | All notes without change before of this Unix timestamp are purged from the response, i.e. only the attribute `id` is included. You should use the Unix timestamp value from the last request's HTTP response header `Last-Modified` in order to reduce transferred data size. |
| `If-None-Match` | HTTP header, optional | Use this in order to reduce transferred data size (see [HTTP ETag](https://en.wikipedia.org/wiki/HTTP_ETag)). You should use the value from the last request's HTTP response header `ETag`. |
| Parameter | Type | Description | since API version |
|:------|:-----|:-----|:-----|
| `category` | string, optional | Filter the result by category name, e.g. `?category=recipes`. Notes with another category are not included in the result. *Compatibility note:* in API v1.0, this parameter is ignored; i.e., the result contains all notes regardless of this parameter. | 1.1 |
| `exclude` | string, optional | Fields which should be excluded from response, seperated with a comma e.g.: `?exclude=content,title`. You can use this in order to reduce transferred data size if you are interested in specific attributes, only. | 1.0 |
| `purgeBefore` | integer, optional | All notes without change before of this Unix timestamp are purged from the response, i.e. only the attribute `id` is included. You should use the Unix timestamp value from the last request's HTTP response header `Last-Modified` in order to reduce transferred data size. | 1.0 |
| `If-None-Match` | HTTP header, optional | Use this in order to reduce transferred data size (see [HTTP ETag](https://en.wikipedia.org/wiki/HTTP_ETag)). You should use the value from the last request's HTTP response header `ETag`. | 1.0 |
#### Response
##### 200 OK

View File

@ -6,7 +6,7 @@ use OCP\AppFramework\App;
class Application extends App {
public static $API_VERSIONS = [ '0.2', '1.0' ];
public static $API_VERSIONS = [ '0.2', '1.1' ];
public function __construct(array $urlParams = []) {
parent::__construct('notes', $urlParams);

View File

@ -47,11 +47,16 @@ class NotesApiController extends ApiController {
* @CORS
* @NoCSRFRequired
*/
public function index(string $exclude = '', int $pruneBefore = 0) : JSONResponse {
return $this->helper->handleErrorResponse(function () use ($exclude, $pruneBefore) {
public function index(?string $category = null, string $exclude = '', int $pruneBefore = 0) : JSONResponse {
return $this->helper->handleErrorResponse(function () use ($category, $exclude, $pruneBefore) {
$exclude = explode(',', $exclude);
$now = new \DateTime(); // this must be before loading notes if there are concurrent changes possible
$notes = $this->service->getAll($this->getUID())['notes'];
if ($category !== null) {
$notes = array_values(array_filter($notes, function ($note) use ($category) {
return $note->getCategory() === $category;
}));
}
$metas = $this->metaService->updateAll($this->getUID(), $notes);
$notesData = array_map(function ($note) use ($metas, $pruneBefore, $exclude) {
$lastUpdate = $metas[$note->getId()]->getLastUpdate();

View File

@ -5,6 +5,6 @@ namespace OCA\Notes\Tests\API;
class APIv1Test extends CommonAPITest {
public function __construct() {
parent::__construct('1.0', false);
parent::__construct('1.1', false);
}
}

View File

@ -13,12 +13,16 @@ abstract class AbstractAPITest extends TestCase {
$this->apiVersion = $apiVersion;
}
protected function setUp() : void {
protected function getAPIMajorVersion() {
if ($this->apiVersion === '0.2') {
$v = $this->apiVersion;
return $this->apiVersion;
} else {
$v = intval($this->apiVersion);
return intval($this->apiVersion);
}
}
protected function setUp() : void {
$v = $this->getAPIMajorVersion();
$this->http = new \GuzzleHttp\Client([
'base_uri' => 'http://localhost:8080/index.php/apps/notes/api/v'.$v.'/',
'auth' => ['test', 'test'],

View File

@ -144,6 +144,31 @@ abstract class CommonAPITest extends AbstractAPITest {
$this->assertEquals(404, $response->getStatusCode());
}
/**
* @depends testCheckForReferenceNotes
* @depends testCreateNotes
*/
public function testGetNotesWithCategory(array $refNotes, array $testNotes) : void {
if ($this->getAPIMajorVersion() < 1) {
$this->markTestSkipped('Get Notes with Category requires API v1');
}
$allNotes = array_merge($refNotes, $testNotes);
$this->checkGetReferenceNotes($allNotes, 'Pre-condition');
$note = $testNotes[0];
$category = $note->category;
$filteredNotes = array_filter(
$allNotes,
function ($note) use ($category) {
return $category === $note->category;
}
);
$this->assertNotEmpty($filteredNotes, 'Filtered notes');
$this->checkGetReferenceNotes(
$filteredNotes,
'Get notes with category '.$category,
'?category='.urlencode($category)
);
}
/**
* @depends testCheckForReferenceNotes