From 813849e5216cb87121e0f778a734575be6a36052 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sun, 7 May 2017 16:50:20 +0200 Subject: [PATCH] Add history entries for API endpoint CHANGED: datetime is now store as an object in history store file --- application/FileUtils.php | 2 +- application/History.php | 4 ++-- application/api/ApiMiddleware.php | 5 ++-- application/api/controllers/ApiController.php | 9 ++++++- application/api/controllers/History.php | 2 +- application/api/controllers/Links.php | 5 +++- index.php | 17 ++++++------- tests/HistoryTest.php | 24 +++++++++---------- .../BookmarkImportTest.php | 4 ++-- tests/api/controllers/DeleteLinkTest.php | 22 +++++++++++++++++ tests/api/controllers/GetLinkIdTest.php | 1 + tests/api/controllers/GetLinksTest.php | 1 + tests/api/controllers/HistoryTest.php | 7 +----- tests/api/controllers/InfoTest.php | 1 + tests/api/controllers/PostLinkTest.php | 23 ++++++++++++++++++ tests/api/controllers/PutLinkTest.php | 23 ++++++++++++++++++ 16 files changed, 114 insertions(+), 36 deletions(-) diff --git a/application/FileUtils.php b/application/FileUtils.php index b8ad8970..a167f642 100644 --- a/application/FileUtils.php +++ b/application/FileUtils.php @@ -26,7 +26,7 @@ class FileUtils * The file will be created if it doesn't exist. * * @param string $file File path. - * @param string $content Content to write. + * @param mixed $content Content to write. * * @return int|bool Number of bytes written or false if it fails. * diff --git a/application/History.php b/application/History.php index f93b0356..116b9264 100644 --- a/application/History.php +++ b/application/History.php @@ -135,7 +135,7 @@ protected function addEvent($status, $id = null) $item = [ 'event' => $status, - 'datetime' => (new DateTime())->format(DateTime::ATOM), + 'datetime' => new DateTime(), 'id' => $id !== null ? $id : '', ]; $this->history = array_merge([$item], $this->history); @@ -177,7 +177,7 @@ protected function write() { $comparaison = new DateTime('-'. $this->retentionTime . ' seconds'); foreach ($this->history as $key => $value) { - if (DateTime::createFromFormat(DateTime::ATOM, $value['datetime']) < $comparaison) { + if ($value['datetime'] < $comparaison) { unset($this->history[$key]); } } diff --git a/application/api/ApiMiddleware.php b/application/api/ApiMiddleware.php index 4120f7a9..ff209393 100644 --- a/application/api/ApiMiddleware.php +++ b/application/api/ApiMiddleware.php @@ -4,6 +4,7 @@ use Shaarli\Api\Exceptions\ApiException; use Shaarli\Api\Exceptions\ApiAuthorizationException; +use Shaarli\Config\ConfigManager; use Slim\Container; use Slim\Http\Request; use Slim\Http\Response; @@ -31,7 +32,7 @@ class ApiMiddleware protected $container; /** - * @var \ConfigManager instance. + * @var ConfigManager instance. */ protected $conf; @@ -121,7 +122,7 @@ protected function checkToken($request) { * * FIXME! LinkDB could use a refactoring to avoid this trick. * - * @param \ConfigManager $conf instance. + * @param ConfigManager $conf instance. */ protected function setLinkDb($conf) { diff --git a/application/api/controllers/ApiController.php b/application/api/controllers/ApiController.php index f35b923a..3be85b98 100644 --- a/application/api/controllers/ApiController.php +++ b/application/api/controllers/ApiController.php @@ -2,6 +2,7 @@ namespace Shaarli\Api\Controllers; +use Shaarli\Config\ConfigManager; use \Slim\Container; /** @@ -19,7 +20,7 @@ abstract class ApiController protected $ci; /** - * @var \ConfigManager + * @var ConfigManager */ protected $conf; @@ -28,6 +29,11 @@ abstract class ApiController */ protected $linkDb; + /** + * @var \History + */ + protected $history; + /** * @var int|null JSON style option. */ @@ -45,6 +51,7 @@ public function __construct(Container $ci) $this->ci = $ci; $this->conf = $ci->get('conf'); $this->linkDb = $ci->get('db'); + $this->history = $ci->get('history'); if ($this->conf->get('dev.debug', false)) { $this->jsonStyle = JSON_PRETTY_PRINT; } else { diff --git a/application/api/controllers/History.php b/application/api/controllers/History.php index c4ff3e5d..da034eb2 100644 --- a/application/api/controllers/History.php +++ b/application/api/controllers/History.php @@ -28,7 +28,7 @@ class History extends ApiController */ public function getHistory($request, $response) { - $history = (new \History($this->conf->get('resource.history')))->getHistory(); + $history = $this->history->getHistory(); $history = array_reverse($history); // Return history operations from the {offset}th, starting from {since}. diff --git a/application/api/controllers/Links.php b/application/api/controllers/Links.php index a40e974d..eb78dd26 100644 --- a/application/api/controllers/Links.php +++ b/application/api/controllers/Links.php @@ -141,6 +141,7 @@ public function postLink($request, $response) $this->linkDb[$link['id']] = $link; $this->linkDb->save($this->conf->get('resource.page_cache')); + $this->history->addLink($link); $out = ApiUtils::formatLink($link, index_url($this->ci['environment'])); $redirect = $this->ci->router->relativePathFor('getLink', ['id' => $link['id']]); return $response->withAddedHeader('Location', $redirect) @@ -184,6 +185,7 @@ public function putLink($request, $response, $args) $responseLink = ApiUtils::updateLink($responseLink, $requestLink); $this->linkDb[$responseLink['id']] = $responseLink; $this->linkDb->save($this->conf->get('resource.page_cache')); + $this->history->updateLink($responseLink); $out = ApiUtils::formatLink($responseLink, $index); return $response->withJson($out, 200, $this->jsonStyle); @@ -205,9 +207,10 @@ public function deleteLink($request, $response, $args) if (! isset($this->linkDb[$args['id']])) { throw new ApiLinkNotFoundException(); } - + $link = $this->linkDb[$args['id']]; unset($this->linkDb[(int) $args['id']]); $this->linkDb->save($this->conf->get('resource.page_cache')); + $this->history->deleteLink($link); return $response->withStatus(204); } diff --git a/index.php b/index.php index cddc9eeb..fb7318d9 100644 --- a/index.php +++ b/index.php @@ -707,7 +707,7 @@ function showLinkList($PAGE, $LINKSDB, $conf, $pluginManager) { * @param PluginManager $pluginManager Plugin Manager instance, * @param LinkDB $LINKSDB */ -function renderPage($conf, $pluginManager, $LINKSDB) +function renderPage($conf, $pluginManager, $LINKSDB, $history) { $updater = new Updater( read_updates_file($conf->get('resource.updates')), @@ -728,12 +728,6 @@ function renderPage($conf, $pluginManager, $LINKSDB) die($e->getMessage()); } - try { - $history = new History($conf->get('resource.history')); - } catch(Exception $e) { - die($e->getMessage()); - } - $PAGE = new PageBuilder($conf); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('privateLinkcount', count_private($LINKSDB)); @@ -2240,9 +2234,16 @@ function resizeImage($filepath) $conf->get('redirector.encode_url') ); +try { + $history = new History($conf->get('resource.history')); +} catch(Exception $e) { + die($e->getMessage()); +} + $container = new \Slim\Container(); $container['conf'] = $conf; $container['plugins'] = $pluginManager; +$container['history'] = $history; $app = new \Slim\App($container); // REST API routes @@ -2262,7 +2263,7 @@ function resizeImage($filepath) if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], '/api/v1') === false) { // We use UTF-8 for proper international characters handling. header('Content-Type: text/html; charset=utf-8'); - renderPage($conf, $pluginManager, $linkDb); + renderPage($conf, $pluginManager, $linkDb, $history); } else { $app->respond($response); } diff --git a/tests/HistoryTest.php b/tests/HistoryTest.php index 91525845..d3bef5a3 100644 --- a/tests/HistoryTest.php +++ b/tests/HistoryTest.php @@ -74,21 +74,21 @@ public function testAddLink() $history->addLink(['id' => 0]); $actual = $history->getHistory()[0]; $this->assertEquals(History::CREATED, $actual['event']); - $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); + $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']); $this->assertEquals(0, $actual['id']); $history = new History(self::$historyFilePath); $history->addLink(['id' => 1]); $actual = $history->getHistory()[0]; $this->assertEquals(History::CREATED, $actual['event']); - $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); + $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']); $this->assertEquals(1, $actual['id']); $history = new History(self::$historyFilePath); $history->addLink(['id' => 'str']); $actual = $history->getHistory()[0]; $this->assertEquals(History::CREATED, $actual['event']); - $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); + $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']); $this->assertEquals('str', $actual['id']); } @@ -101,7 +101,7 @@ public function testUpdateLink() $history->updateLink(['id' => 1]); $actual = $history->getHistory()[0]; $this->assertEquals(History::UPDATED, $actual['event']); - $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); + $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']); $this->assertEquals(1, $actual['id']); } @@ -114,7 +114,7 @@ public function testDeleteLink() $history->deleteLink(['id' => 1]); $actual = $history->getHistory()[0]; $this->assertEquals(History::DELETED, $actual['event']); - $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); + $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']); $this->assertEquals(1, $actual['id']); } @@ -127,7 +127,7 @@ public function testUpdateSettings() $history->updateSettings(); $actual = $history->getHistory()[0]; $this->assertEquals(History::SETTINGS, $actual['event']); - $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); + $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']); $this->assertEmpty($actual['id']); } @@ -140,13 +140,13 @@ public function testHistoryOrder() $history->updateLink(['id' => 1]); $actual = $history->getHistory()[0]; $this->assertEquals(History::UPDATED, $actual['event']); - $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); + $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']); $this->assertEquals(1, $actual['id']); $history->addLink(['id' => 1]); $actual = $history->getHistory()[0]; $this->assertEquals(History::CREATED, $actual['event']); - $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); + $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']); $this->assertEquals(1, $actual['id']); } @@ -160,7 +160,7 @@ public function testHistoryRead() $history = new History(self::$historyFilePath); $actual = $history->getHistory()[0]; $this->assertEquals(History::UPDATED, $actual['event']); - $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); + $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']); $this->assertEquals(1, $actual['id']); } @@ -176,12 +176,12 @@ public function testHistoryOrderRead() $history = new History(self::$historyFilePath); $actual = $history->getHistory()[0]; $this->assertEquals(History::CREATED, $actual['event']); - $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); + $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']); $this->assertEquals(1, $actual['id']); $actual = $history->getHistory()[1]; $this->assertEquals(History::UPDATED, $actual['event']); - $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); + $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']); $this->assertEquals(1, $actual['id']); } @@ -194,7 +194,7 @@ public function testHistoryRententionTime() $history->updateLink(['id' => 1]); $this->assertEquals(1, count($history->getHistory())); $arr = $history->getHistory(); - $arr[0]['datetime'] = (new DateTime('-1 hour'))->format(DateTime::ATOM); + $arr[0]['datetime'] = new DateTime('-1 hour'); FileUtils::writeFlatDB(self::$historyFilePath, $arr); $history = new History(self::$historyFilePath, 60); diff --git a/tests/NetscapeBookmarkUtils/BookmarkImportTest.php b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php index f838f259..5fc1d1e8 100644 --- a/tests/NetscapeBookmarkUtils/BookmarkImportTest.php +++ b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php @@ -628,7 +628,7 @@ public function testImportCreateUpdateHistory() $this->assertEquals($nbLinks, count($history)); foreach ($history as $value) { $this->assertEquals(History::CREATED, $value['event']); - $this->assertTrue(new DateTime('-5 seconds') < DateTime::createFromFormat(DateTime::ATOM, $value['datetime'])); + $this->assertTrue(new DateTime('-5 seconds') < $value['datetime']); $this->assertTrue(is_int($value['id'])); } @@ -638,7 +638,7 @@ public function testImportCreateUpdateHistory() $this->assertEquals($nbLinks * 2, count($history)); for ($i = 0 ; $i < $nbLinks ; $i++) { $this->assertEquals(History::UPDATED, $history[$i]['event']); - $this->assertTrue(new DateTime('-5 seconds') < DateTime::createFromFormat(DateTime::ATOM, $history[$i]['datetime'])); + $this->assertTrue(new DateTime('-5 seconds') < $history[$i]['datetime']); $this->assertTrue(is_int($history[$i]['id'])); } } diff --git a/tests/api/controllers/DeleteLinkTest.php b/tests/api/controllers/DeleteLinkTest.php index 6894e8a2..7d797137 100644 --- a/tests/api/controllers/DeleteLinkTest.php +++ b/tests/api/controllers/DeleteLinkTest.php @@ -16,6 +16,11 @@ class DeleteLinkTest extends \PHPUnit_Framework_TestCase */ protected static $testDatastore = 'sandbox/datastore.php'; + /** + * @var string datastore to test write operations + */ + protected static $testHistory = 'sandbox/history.php'; + /** * @var ConfigManager instance */ @@ -31,6 +36,11 @@ class DeleteLinkTest extends \PHPUnit_Framework_TestCase */ protected $linkDB; + /** + * @var \History instance. + */ + protected $history; + /** * @var Container instance. */ @@ -50,9 +60,13 @@ public function setUp() $this->refDB = new \ReferenceLinkDB(); $this->refDB->write(self::$testDatastore); $this->linkDB = new \LinkDB(self::$testDatastore, true, false); + $refHistory = new \ReferenceHistory(); + $refHistory->write(self::$testHistory); + $this->history = new \History(self::$testHistory); $this->container = new Container(); $this->container['conf'] = $this->conf; $this->container['db'] = $this->linkDB; + $this->container['history'] = $this->history; $this->controller = new Links($this->container); } @@ -63,6 +77,7 @@ public function setUp() public function tearDown() { @unlink(self::$testDatastore); + @unlink(self::$testHistory); } /** @@ -83,6 +98,13 @@ public function testDeleteLinkValid() $this->linkDB = new \LinkDB(self::$testDatastore, true, false); $this->assertFalse(isset($this->linkDB[$id])); + + $historyEntry = $this->history->getHistory()[0]; + $this->assertEquals(\History::DELETED, $historyEntry['event']); + $this->assertTrue( + (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] + ); + $this->assertEquals($id, $historyEntry['id']); } /** diff --git a/tests/api/controllers/GetLinkIdTest.php b/tests/api/controllers/GetLinkIdTest.php index 45b18e6a..57528d5a 100644 --- a/tests/api/controllers/GetLinkIdTest.php +++ b/tests/api/controllers/GetLinkIdTest.php @@ -62,6 +62,7 @@ public function setUp() $this->container = new Container(); $this->container['conf'] = $this->conf; $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); + $this->container['history'] = null; $this->controller = new Links($this->container); } diff --git a/tests/api/controllers/GetLinksTest.php b/tests/api/controllers/GetLinksTest.php index 10330cd9..84ae7f7a 100644 --- a/tests/api/controllers/GetLinksTest.php +++ b/tests/api/controllers/GetLinksTest.php @@ -61,6 +61,7 @@ public function setUp() $this->container = new Container(); $this->container['conf'] = $this->conf; $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); + $this->container['history'] = null; $this->controller = new Links($this->container); } diff --git a/tests/api/controllers/HistoryTest.php b/tests/api/controllers/HistoryTest.php index 21e9c0ba..61046d97 100644 --- a/tests/api/controllers/HistoryTest.php +++ b/tests/api/controllers/HistoryTest.php @@ -29,11 +29,6 @@ class HistoryTest extends \PHPUnit_Framework_TestCase */ protected $refHistory = null; - /** - * @var \History instance. - */ - protected $history; - /** * @var Container instance. */ @@ -52,10 +47,10 @@ public function setUp() $this->conf = new ConfigManager('tests/utils/config/configJson.json.php'); $this->refHistory = new \ReferenceHistory(); $this->refHistory->write(self::$testHistory); - $this->conf->set('resource.history', self::$testHistory); $this->container = new Container(); $this->container['conf'] = $this->conf; $this->container['db'] = true; + $this->container['history'] = new \History(self::$testHistory); $this->controller = new History($this->container); } diff --git a/tests/api/controllers/InfoTest.php b/tests/api/controllers/InfoTest.php index 4beef3f7..e85eb281 100644 --- a/tests/api/controllers/InfoTest.php +++ b/tests/api/controllers/InfoTest.php @@ -54,6 +54,7 @@ public function setUp() $this->container = new Container(); $this->container['conf'] = $this->conf; $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); + $this->container['history'] = null; $this->controller = new Info($this->container); } diff --git a/tests/api/controllers/PostLinkTest.php b/tests/api/controllers/PostLinkTest.php index 3ed7bcb0..31954e39 100644 --- a/tests/api/controllers/PostLinkTest.php +++ b/tests/api/controllers/PostLinkTest.php @@ -23,6 +23,11 @@ class PostLinkTest extends \PHPUnit_Framework_TestCase */ protected static $testDatastore = 'sandbox/datastore.php'; + /** + * @var string datastore to test write operations + */ + protected static $testHistory = 'sandbox/history.php'; + /** * @var ConfigManager instance */ @@ -33,6 +38,11 @@ class PostLinkTest extends \PHPUnit_Framework_TestCase */ protected $refDB = null; + /** + * @var \History instance. + */ + protected $history; + /** * @var Container instance. */ @@ -57,9 +67,14 @@ public function setUp() $this->refDB = new \ReferenceLinkDB(); $this->refDB->write(self::$testDatastore); + $refHistory = new \ReferenceHistory(); + $refHistory->write(self::$testHistory); + $this->history = new \History(self::$testHistory); + $this->container = new Container(); $this->container['conf'] = $this->conf; $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); + $this->container['history'] = new \History(self::$testHistory); $this->controller = new Links($this->container); @@ -85,6 +100,7 @@ public function setUp() public function tearDown() { @unlink(self::$testDatastore); + @unlink(self::$testHistory); } /** @@ -112,6 +128,13 @@ public function testPostLinkMinimal() $this->assertEquals(false, $data['private']); $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])); $this->assertEquals('', $data['updated']); + + $historyEntry = $this->history->getHistory()[0]; + $this->assertEquals(\History::CREATED, $historyEntry['event']); + $this->assertTrue( + (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] + ); + $this->assertEquals(43, $historyEntry['id']); } /** diff --git a/tests/api/controllers/PutLinkTest.php b/tests/api/controllers/PutLinkTest.php index 4096c1a7..8a562571 100644 --- a/tests/api/controllers/PutLinkTest.php +++ b/tests/api/controllers/PutLinkTest.php @@ -17,6 +17,11 @@ class PutLinkTest extends \PHPUnit_Framework_TestCase */ protected static $testDatastore = 'sandbox/datastore.php'; + /** + * @var string datastore to test write operations + */ + protected static $testHistory = 'sandbox/history.php'; + /** * @var ConfigManager instance */ @@ -27,6 +32,11 @@ class PutLinkTest extends \PHPUnit_Framework_TestCase */ protected $refDB = null; + /** + * @var \History instance. + */ + protected $history; + /** * @var Container instance. */ @@ -51,9 +61,14 @@ public function setUp() $this->refDB = new \ReferenceLinkDB(); $this->refDB->write(self::$testDatastore); + $refHistory = new \ReferenceHistory(); + $refHistory->write(self::$testHistory); + $this->history = new \History(self::$testHistory); + $this->container = new Container(); $this->container['conf'] = $this->conf; $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); + $this->container['history'] = new \History(self::$testHistory); $this->controller = new Links($this->container); @@ -71,6 +86,7 @@ public function setUp() public function tearDown() { @unlink(self::$testDatastore); + @unlink(self::$testHistory); } /** @@ -100,6 +116,13 @@ public function testPutLinkMinimal() \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) ); $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])); + + $historyEntry = $this->history->getHistory()[0]; + $this->assertEquals(\History::UPDATED, $historyEntry['event']); + $this->assertTrue( + (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] + ); + $this->assertEquals($id, $historyEntry['id']); } /**