mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
tags
This commit is contained in:
parent
e2012ed833
commit
0d9e52956c
11
run_tests.sh
11
run_tests.sh
@ -3,5 +3,14 @@
|
||||
# Example to test just one method of a test unit:
|
||||
# php phpunit-5.7.20.phar --filter testConflict ChangeTest tests/Model/ChangeTest.php --bootstrap vendor/autoload.php tests/Model/
|
||||
|
||||
# php5.6 phpunit-5.7.20.phar --bootstrap vendor/autoload.php tests/Controller/
|
||||
echo '============================================================================================='
|
||||
echo 'Testing controllers....'
|
||||
echo '============================================================================================='
|
||||
php5.6 phpunit-5.7.20.phar --bootstrap vendor/autoload.php tests/Controller/
|
||||
|
||||
echo ""
|
||||
|
||||
echo '============================================================================================='
|
||||
echo 'Testing models....'
|
||||
echo '============================================================================================='
|
||||
php5.6 phpunit-5.7.20.phar --bootstrap vendor/autoload.php tests/Model/
|
103
src/AppBundle/Controller/TagsController.php
Normal file
103
src/AppBundle/Controller/TagsController.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace AppBundle\Controller;
|
||||
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use AppBundle\Controller\ApiController;
|
||||
use AppBundle\Model\Tag;
|
||||
use AppBundle\Model\BaseItem;
|
||||
use AppBundle\Exception\ValidationException;
|
||||
|
||||
class TagsController extends ApiController {
|
||||
|
||||
/**
|
||||
* @Route("/tags")
|
||||
*/
|
||||
public function allAction(Request $request) {
|
||||
if ($request->isMethod('POST')) {
|
||||
$tag = new Tag();
|
||||
$tag->fromPublicArray($request->request->all());
|
||||
$tag->owner_id = $this->user()->id;
|
||||
$tag->save();
|
||||
return static::successResponse($tag->toPublicArray());
|
||||
}
|
||||
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/tags/{id}")
|
||||
*/
|
||||
public function oneAction($id, Request $request) {
|
||||
$tag = Tag::find(Tag::unhex($id));
|
||||
if (!$tag && !$request->isMethod('PUT')) throw new NotFoundException();
|
||||
|
||||
if ($request->isMethod('GET')) {
|
||||
return static::successResponse($tag);
|
||||
}
|
||||
|
||||
$query = $request->query->all();
|
||||
if ($tag && isset($query['rev_id'])) $tag->revId = $query['rev_id'];
|
||||
|
||||
if ($request->isMethod('PUT')) {
|
||||
$isNew = !$tag;
|
||||
if ($isNew) $tag = new Tag();
|
||||
$data = Tag::filter($this->putParameters());
|
||||
$tag->fromPublicArray($data);
|
||||
$tag->id = Tag::unhex($id);
|
||||
$tag->owner_id = $this->user()->id;
|
||||
$tag->setIsNew($isNew);
|
||||
$tag->save();
|
||||
return static::successResponse($tag);
|
||||
}
|
||||
|
||||
if ($request->isMethod('PATCH')) {
|
||||
$tag->fromPublicArray($this->patchParameters());
|
||||
$tag->save();
|
||||
return static::successResponse($tag);
|
||||
}
|
||||
|
||||
if ($request->isMethod('DELETE')) {
|
||||
$tag->delete();
|
||||
return static::successResponse();
|
||||
}
|
||||
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/tags/{id}/items/{itemId}")
|
||||
*/
|
||||
public function linkedItemAction($id, $itemId = null, Request $request = null) {
|
||||
$tag = Tag::byId(Tag::unhex($id));
|
||||
if (!$tag) throw new NotFoundException();
|
||||
|
||||
if ($request->isMethod('GET')) {
|
||||
return static::successResponse($tag->items());
|
||||
}
|
||||
|
||||
if ($request->isMethod('POST')) {
|
||||
$item = $request->request->all();
|
||||
if (!isset($item['id'])) throw new ValidationException('Item "id" parameter is missing');
|
||||
$itemId = $item['id'];
|
||||
$item = BaseItem::anyById(BaseItem::unhex($itemId));
|
||||
|
||||
if (!$item) throw new ValidationException('Item not found: ' . $itemId);
|
||||
|
||||
$tag->add($item);
|
||||
|
||||
return static::successResponse($tag);
|
||||
}
|
||||
|
||||
if ($request->isMethod('DELETE')) {
|
||||
$tag->remove(BaseItem::unhex($itemId));
|
||||
return static::successResponse($tag);
|
||||
}
|
||||
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -41,5 +41,12 @@ class BaseItem extends BaseModel {
|
||||
|
||||
throw new \Exception('Unsupported item type: ' . $itemTypeId);
|
||||
}
|
||||
|
||||
// Use only if type of item is unknown
|
||||
static public function anyById($itemId) {
|
||||
$folder = Folder::find($itemId);
|
||||
if ($folder) return $folder;
|
||||
return Note::find($itemId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -185,6 +185,7 @@ class BaseModel extends \Illuminate\Database\Eloquent\Model {
|
||||
if (!empty($output['client_id'])) $output['client_id'] = self::hex($output['client_id']);
|
||||
if (!empty($output['item_id'])) $output['item_id'] = self::hex($output['item_id']);
|
||||
if (!empty($output['user_id'])) $output['user_id'] = self::hex($output['user_id']);
|
||||
if (!empty($output['tag_id'])) $output['tag_id'] = self::hex($output['tag_id']);
|
||||
|
||||
foreach ($output as $k => $v) {
|
||||
if (isset(static::$enums[$k])) {
|
||||
|
@ -2,48 +2,22 @@
|
||||
|
||||
namespace AppBundle\Model;
|
||||
|
||||
use AppBundle\Exception\ForbiddenException;
|
||||
|
||||
class Tag extends BaseItem {
|
||||
|
||||
// A star has the exact same behaviour as a tag, except
|
||||
// it might be diplayed differently.
|
||||
static private $starTag_ = null;
|
||||
|
||||
static public function starTag($ownerId) {
|
||||
if (self::$starTag_) return self::$starTag_;
|
||||
$t = Tag::where('internal', '=', 1)
|
||||
->where('title', '=', 'star')
|
||||
->first();
|
||||
|
||||
if (!$t) {
|
||||
$t = new Tag();
|
||||
$t->title = 'star';
|
||||
$t->internal = 1;
|
||||
$t->owner_id = $ownerId;
|
||||
$t->save();
|
||||
}
|
||||
|
||||
self::$starTag_ = $t;
|
||||
return self::$starTag_;
|
||||
}
|
||||
|
||||
static public function star($item) {
|
||||
self::starTag($item->owner_id)->add($item);
|
||||
}
|
||||
|
||||
static public function unstar($item) {
|
||||
self::starTag($item->owner_id)->remove($item);
|
||||
}
|
||||
|
||||
static public function isStarred($item) {
|
||||
return self::starTag($item->owner_id)->includes($item);
|
||||
}
|
||||
|
||||
static public function starredItems($ownerId) {
|
||||
return self::starTag($ownerId)->items();
|
||||
}
|
||||
static protected $fields = array(
|
||||
'id' => null,
|
||||
'title' => null,
|
||||
'owner_id' => null,
|
||||
'created_time' => null,
|
||||
'updated_time' => null,
|
||||
);
|
||||
|
||||
public function add($item) {
|
||||
if ($this->includes($item)) return;
|
||||
if ($this->includes($item->id)) return;
|
||||
|
||||
if ($item->owner_id != $this->owner_id) throw new ForbiddenException();
|
||||
|
||||
$t = new Tagged_item();
|
||||
$t->tag_id = $this->id;
|
||||
@ -52,27 +26,19 @@ class Tag extends BaseItem {
|
||||
$t->save();
|
||||
}
|
||||
|
||||
public function includes($item) {
|
||||
return !!Tagged_item::where('item_type', '=', $item->itemTypeId())
|
||||
->where('item_id', '=', $item->id)
|
||||
public function includes($itemId) {
|
||||
return !!Tagged_item::where('item_id', '=', $itemId)
|
||||
->where('tag_id', '=', $this->id)
|
||||
->first();
|
||||
}
|
||||
|
||||
public function remove($item) {
|
||||
Tagged_item::where('item_type', '=', $item->itemTypeId())
|
||||
->where('item_id', '=', $item->id)
|
||||
->delete();
|
||||
public function remove($itemId) {
|
||||
return Tagged_item::where('tag_id', '=', $this->id)->where('item_id', '=', $itemId)->delete();
|
||||
}
|
||||
|
||||
// TODO: retrieve items in one SQL query
|
||||
public function items() {
|
||||
$output = array();
|
||||
$taggedItems = Tagged_item::where('tag_id', '=', $this->id)->get();
|
||||
foreach ($taggedItems as $taggedItem) {
|
||||
$item = BaseItem::byTypeAndId($taggedItem->item_type, $taggedItem->item_id);
|
||||
$output[] = $item;
|
||||
}
|
||||
return $output;
|
||||
return Tagged_item::where('tag_id', '=', $this->id)->get();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,4 +4,13 @@ namespace AppBundle\Model;
|
||||
|
||||
class Tagged_item extends BaseModel {
|
||||
|
||||
static protected $fields = array(
|
||||
'id' => null,
|
||||
'tag_id' => null,
|
||||
'item_id' => null,
|
||||
'item_type' => null,
|
||||
'created_time' => null,
|
||||
'updated_time' => null,
|
||||
);
|
||||
|
||||
}
|
||||
|
@ -38,11 +38,8 @@ CREATE TABLE `tags` (
|
||||
`id` binary(16) NOT NULL,
|
||||
`title` varchar(1024) NOT NULL default '',
|
||||
`owner_id` binary(16) NOT NULL,
|
||||
`internal` tinyint(1) NOT NULL default '0',
|
||||
`created_time` int(11) NOT NULL default '0',
|
||||
`updated_time` int(11) NOT NULL default '0',
|
||||
`is_encrypted` tinyint(1) NOT NULL default '0',
|
||||
`encryption_method` int(11) NOT NULL default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) CHARACTER SET=utf8;
|
||||
|
||||
|
@ -45,6 +45,7 @@ class BaseControllerTestCase extends WebTestCase {
|
||||
'error' => $e->getMessage(),
|
||||
'code' => $e->getCode(),
|
||||
'type' => get_class($e),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
);
|
||||
}
|
||||
return $output;
|
||||
|
54
tests/Controller/TagsControllerTest.php
Normal file
54
tests/Controller/TagsControllerTest.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
require_once dirname(dirname(__FILE__)) . '/setup.php';
|
||||
|
||||
use AppBundle\Model\Tag;
|
||||
use AppBundle\Model\Folder;
|
||||
use AppBundle\Model\Note;
|
||||
|
||||
class TagsControllerTest extends BaseControllerTestCase {
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
Tag::truncate();
|
||||
Note::truncate();
|
||||
Folder::truncate();
|
||||
}
|
||||
|
||||
public function testCreate() {
|
||||
$this->loadSession(1, 1);
|
||||
|
||||
$t = $this->request('POST', '/tags', null, array('title' => 'my tag'));
|
||||
|
||||
$this->assertEquals('my tag', $t['title']);
|
||||
}
|
||||
|
||||
public function testTagNote() {
|
||||
$this->loadSession(1, 1);
|
||||
|
||||
$tag = $this->request('POST', '/tags', null, array('title' => 'my tag'));
|
||||
|
||||
$note = $this->request('POST', '/notes', null, array('title' => 'my note'));
|
||||
$this->request('POST', '/tags/' . $tag['id'] . '/items', null, array('id' => $note['id']));
|
||||
$items = $this->request('GET', '/tags/' . $tag['id'] . '/items');
|
||||
$this->assertEquals(1, count($items));
|
||||
$this->assertEquals('note', $items[0]['item_type']);
|
||||
$this->assertEquals($note['id'], $items[0]['item_id']);
|
||||
$this->assertEquals($tag['id'], $items[0]['tag_id']);
|
||||
|
||||
$folder = $this->request('POST', '/folders', null, array('title' => 'my folder'));
|
||||
$this->request('POST', '/tags/' . $tag['id'] . '/items', null, array('id' => $folder['id']));
|
||||
$items = $this->request('GET', '/tags/' . $tag['id'] . '/items');
|
||||
$this->assertEquals(2, count($items));
|
||||
$this->assertEquals('folder', $items[1]['item_type']);
|
||||
$this->assertEquals($folder['id'], $items[1]['item_id']);
|
||||
$this->assertEquals($tag['id'], $items[1]['tag_id']);
|
||||
|
||||
$this->request('DELETE', '/tags/' . $tag['id'] . '/items/' . $note['id']);
|
||||
$items = $this->request('GET', '/tags/' . $tag['id'] . '/items');
|
||||
$this->assertEquals(1, count($items));
|
||||
$this->assertEquals('folder', $items[0]['item_type']);
|
||||
}
|
||||
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once dirname(dirname(__FILE__)) . '/setup.php';
|
||||
|
||||
use AppBundle\Model\Note;
|
||||
use AppBundle\Model\Tag;
|
||||
|
||||
class TagTest extends BaseTestCase {
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testTagging() {
|
||||
$note = new Note();
|
||||
$note->save();
|
||||
|
||||
$tag = new Tag();
|
||||
$tag->owner_id = $this->userId();
|
||||
$tag->save();
|
||||
|
||||
$this->assertFalse($tag->includes($note));
|
||||
|
||||
$tag->add($note);
|
||||
$items = $tag->items();
|
||||
$this->assertEquals(1, count($items));
|
||||
|
||||
$tag->add($note);
|
||||
$items = $tag->items();
|
||||
$this->assertEquals(1, count($items));
|
||||
|
||||
$note2 = new Note();
|
||||
$note2->save();
|
||||
|
||||
$tag->add($note2);
|
||||
$items = $tag->items();
|
||||
$this->assertEquals(2, count($items));
|
||||
|
||||
$this->assertEquals($note->id, $items[0]->id);
|
||||
$this->assertEquals($note2->id, $items[1]->id);
|
||||
$this->assertTrue($tag->includes($note));
|
||||
$this->assertTrue($tag->includes($note2));
|
||||
|
||||
$tag->remove($note);
|
||||
$items = $tag->items();
|
||||
$this->assertEquals(1, count($items));
|
||||
|
||||
$tag->remove($note2);
|
||||
$items = $tag->items();
|
||||
$this->assertEquals(0, count($items));
|
||||
}
|
||||
|
||||
public function testStarring() {
|
||||
$note = new Note();
|
||||
$note->owner_id = $this->userId();
|
||||
$note->save();
|
||||
|
||||
$this->assertFalse(Tag::isStarred($note));
|
||||
|
||||
Tag::star($note);
|
||||
$this->assertTrue(Tag::isStarred($note));
|
||||
$this->assertEquals(1, count(Tag::starredItems($this->userId())));
|
||||
|
||||
Tag::star($note);
|
||||
$this->assertEquals(1, count(Tag::starredItems($this->userId())));
|
||||
|
||||
Tag::unstar($note);
|
||||
$this->assertFalse(Tag::isStarred($note));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user