Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions config/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,26 @@
['controller' => 'Tags', 'action' => 'index'],
['_name' => 'tags:index']
);
$routes->connect(
'/tags/delete/{id}',
['controller' => 'Tags', 'action' => 'delete'],
['pass' => ['id'], '_name' => 'tags:delete']
);
$routes->connect(
'/tags/create',
['controller' => 'Tags', 'action' => 'create'],
['_name' => 'tags:create']
);
$routes->connect(
'/tags/patch/{id}',
['controller' => 'Tags', 'action' => 'patch'],
['pass' => ['id'], '_name' => 'tags:patch']
);
$routes->connect(
'/tags/search',
['controller' => 'Tags', 'action' => 'search'],
['_name' => 'tags:search']
);

// view resource by id / uname
$routes->connect(
Expand Down
10 changes: 5 additions & 5 deletions resources/js/app/components/tag-form/tag-form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export default {
headers,
method: 'GET',
};
const response = await fetch(`${BEDITA.base}/api/model/tags?filter[name]=${this.name}`, options);
const response = await fetch(`${BEDITA.base}/tags/search?filter[name]=${this.name}`, options);
const responseJson = await response.json();

return responseJson?.data?.length > 0;
Expand Down Expand Up @@ -212,11 +212,11 @@ export default {
payload.data.id = this.obj.id;
options.body = JSON.stringify(payload);
options.method = 'PATCH'
response = await fetch(`${BEDITA.base}/api/model/tags/${this.obj.id}`, options);
response = await fetch(`${BEDITA.base}/tags/patch/${this.obj.id}`, options);
} else {
options.body = JSON.stringify(payload);
options.method = 'POST'
response = await fetch(`${BEDITA.base}/api/model/tags`, options);
response = await fetch(`${BEDITA.base}/tags/create`, options);
}
if (response.status === 200) {
if (this.redir) {
Expand Down Expand Up @@ -253,14 +253,14 @@ export default {
const prefix = t`Error on deleting tag`;
try {
const options = {
method: 'DELETE',
method: 'POST',
credentials: 'same-origin',
headers: {
'accept': 'application/json',
'X-CSRF-Token': BEDITA.csrfToken,
},
};
const response = await fetch(`${BEDITA.base}/api/model/tags/${this.obj.id}`, options);
const response = await fetch(`${BEDITA.base}/tags/delete/${this.obj.id}`, options);
if (response.status === 200) {
this.$el.remove(this.$el);
this.dialog?.hide();
Expand Down
2 changes: 1 addition & 1 deletion resources/js/app/components/tag-picker/tag-picker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export default {
return callback(null, []);
}

const res = await fetch(`${BEDITA.base}/api/model/tags?filter[query]=${searchQuery}&filter[enabled]=1&page_size=30`, API_OPTIONS);
const res = await fetch(`${BEDITA.base}/tags/search?filter[query]=${searchQuery}&filter[enabled]=1&page_size=30`, API_OPTIONS);
const json = await res.json();
const tags = [...(json.data || [])];

Expand Down
107 changes: 107 additions & 0 deletions src/Controller/TagsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
namespace App\Controller;

use App\Controller\Model\TagsController as ModelTagsController;
use BEdita\SDK\BEditaClientException;
use Cake\Event\EventInterface;
use Cake\Http\Response;
use Cake\Utility\Hash;

/**
* Tags Controller
Expand All @@ -21,6 +23,7 @@ public function initialize(): void
{
parent::initialize();
$this->loadComponent('ProjectConfiguration');
$this->Security->setConfig('unlockedActions', ['create', 'patch', 'delete']);
}

/**
Expand All @@ -37,6 +40,110 @@ public function index(): ?Response
return null;
}

/**
* Create new tag (ajax).
*
* @return \Cake\Http\Response|null
*/
public function create(): ?Response
{
$this->getRequest()->allowMethod(['post']);
$this->viewBuilder()->setClassName('Json');
$response = $error = null;
try {
$body = (array)$this->getRequest()->getData();
$response = $this->apiClient->post('/model/tags', json_encode($body));
} catch (BEditaClientException $e) {
$error = $e->getMessage();
$this->log($error, 'error');
$this->set('error', $error);
}
$this->set('response', $response);
$this->set('error', $error);
$this->setSerialize(['response', 'error']);

return null;
}

/**
* Delete single tag (ajax).
*
* @param string $id Tag ID.
* @return \Cake\Http\Response|null
*/
public function delete(string $id): ?Response
{
$this->getRequest()->allowMethod(['post']);
$this->viewBuilder()->setClassName('Json');
$response = $error = null;
try {
$this->apiClient->delete(sprintf('/model/tags/%s', $id));
$response = 'ok';
} catch (BEditaClientException $e) {
$error = $e->getMessage();
$this->log($error, 'error');
$this->set('error', $error);
}
$this->set('response', $response);
$this->set('error', $error);
$this->setSerialize(['response', 'error']);

return null;
}

/**
* Save tag (ajax).
*
* @param string $id Tag ID.
* @return \Cake\Http\Response|null
*/
public function patch(string $id): ?Response
{
$this->getRequest()->allowMethod(['patch']);
$this->viewBuilder()->setClassName('Json');
$response = $error = null;
try {
$body = (array)$this->getRequest()->getData();
$this->apiClient->patch(sprintf('/model/tags/%s', $id), json_encode($body));
$response = 'ok';
} catch (BEditaClientException $e) {
$error = $e->getMessage();
$this->log($error, 'error');
$this->set('error', $error);
}
$this->set('response', $response);
$this->set('error', $error);
$this->setSerialize(['response', 'error']);

return null;
}

/**
* Search tags (ajax)
*
* @return \Cake\Http\Response|null
*/
public function search(): ?Response
{
$this->getRequest()->allowMethod(['get']);
$this->viewBuilder()->setClassName('Json');
$data = $error = null;
try {
$query = $this->getRequest()->getQueryParams();
$response = $this->apiClient->get('/model/tags', $query);
$data = (array)Hash::get($response, 'data');
} catch (BEditaClientException $e) {
$error = $e->getMessage();
$this->log($error, 'error');
$this->set('error', $error);
}
$this->set('data', $data);
$this->set('error', $error);
$this->setSerialize(['data', 'error']);

return null;
}

/**
* @inheritDoc
*/
Expand Down
98 changes: 98 additions & 0 deletions tests/TestCase/Controller/TagsControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use BEdita\WebTools\ApiClientProvider;
use Cake\Http\ServerRequest;
use Cake\TestSuite\TestCase;
use Cake\Utility\Hash;

/**
* {@see \App\Controller\TagsController} Test Case
Expand Down Expand Up @@ -110,4 +111,101 @@ public function testBeforeRender(): void
$this->controller->dispatchEvent('Controller.beforeRender');
static::assertSame(['_name' => 'tags:index'], $this->controller->viewBuilder()->getVar('moduleLink'));
}

/**
* Test `create`, `patch`, `delete`, `search` methods
*
* @return void
* @covers ::create()
* @covers ::patch()
* @covers ::delete()
* @covers ::search()
*/
public function testMulti(): void
{
// create with error
$this->setupController(['environment' => ['REQUEST_METHOD' => 'POST']]);
$this->controller->create();
static::assertNotEmpty($this->controller->viewBuilder()->getVar('error'));

// create ok
$data = [
'type' => 'tags',
'attributes' => [
'name' => 'my-dummy-test-tag',
'label' => 'My Dummy Test Tag',
'labels' => [
'default' => 'My Dummy Test Tag',
],
'enabled' => false,
],
];
$request = $this->controller->getRequest()->withData('data', $data);
$this->controller->setRequest($request);
$this->controller->create();
static::assertEmpty($this->controller->viewBuilder()->getVar('error'));
$response = $this->controller->viewBuilder()->getVar('response');
static::assertNotEmpty($response);
$id = $response['data']['id'];

// patch with error
$this->setupController(['environment' => ['REQUEST_METHOD' => 'PATCH']]);
$this->controller->getRequest()->withData('name', 'test');
$this->controller->patch('test');
static::assertNotEmpty($this->controller->viewBuilder()->getVar('error'));
static::assertNotEquals('ok', $this->controller->viewBuilder()->getVar('response'));

// patch ok
$data = [
'id' => $id,
'type' => 'tags',
'attributes' => [
'name' => 'my-dummy-test-tag',
'label' => 'My Dummy Test Tag',
'labels' => [
'default' => 'My Dummy Test Tag',
],
'enabled' => true,
],
];
$request = $this->controller->getRequest()->withData('data', $data);
$this->controller->setRequest($request);
$this->controller->patch($id);
static::assertEquals('ok', $this->controller->viewBuilder()->getVar('response'));
static::assertEmpty($this->controller->viewBuilder()->getVar('error'));

// search with error
$this->setupController(['environment' => ['REQUEST_METHOD' => 'GET']]);
$request = $this->controller->getRequest()->withQueryParams(['filter' => 'wrong']);
$this->controller->setRequest($request);
$this->controller->search();
static::assertNotEmpty($this->controller->viewBuilder()->getVar('error'));

// search ok
$request = $this->controller->getRequest()->withQueryParams(['filter' => ['name' => 'my-dummy-test-tag']]);
$this->controller->setRequest($request);
$this->controller->search();
static::assertEmpty($this->controller->viewBuilder()->getVar('error'));
$response = $this->controller->viewBuilder()->getVar('data');
static::assertNotEmpty($response);
$actual = (array)Hash::get($response, '0');
static::assertNotEmpty($actual);
static::assertEquals('my-dummy-test-tag', $actual['attributes']['name']);
static::assertEquals('My Dummy Test Tag', $actual['attributes']['label']);
static::assertEquals('My Dummy Test Tag', $actual['attributes']['labels']['default']);
static::assertEquals(true, $actual['attributes']['enabled']);
static::assertEquals($id, $actual['id']);

// delete with error
$this->setupController(['environment' => ['REQUEST_METHOD' => 'POST']]);
$this->controller->delete('test');
static::assertNotEmpty($this->controller->viewBuilder()->getVar('error'));
static::assertNotEquals('ok', $this->controller->viewBuilder()->getVar('response'));

// delete ok
$this->setupController(['environment' => ['REQUEST_METHOD' => 'POST']]);
$this->controller->delete($id);
static::assertEquals('ok', $this->controller->viewBuilder()->getVar('response'));
static::assertEmpty($this->controller->viewBuilder()->getVar('error'));
}
}
Loading