From 4306b184c4471825f916d895b047ed03fdf58985 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Mon, 16 Jan 2017 12:31:08 +0100 Subject: History mechanism Use case: rest API service * saved by default in data/history * same format as datastore.php * traced events: * save/edit/delete link * change settings or plugins settings * rename tag --- tests/HistoryTest.php | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 tests/HistoryTest.php (limited to 'tests/HistoryTest.php') diff --git a/tests/HistoryTest.php b/tests/HistoryTest.php new file mode 100644 index 00000000..79322249 --- /dev/null +++ b/tests/HistoryTest.php @@ -0,0 +1,195 @@ +assertFileExists(self::$historyFilePath); + } + + /** + * Not writable history file: raise an exception. + * + * @expectedException Exception + * @expectedExceptionMessage History file isn't readable or writable + */ + public function testConstructNotWritable() + { + touch(self::$historyFilePath); + chmod(self::$historyFilePath, 0440); + new History(self::$historyFilePath); + } + + /** + * Not parsable history file: raise an exception. + * + * @expectedException Exception + * @expectedExceptionMessageRegExp /Could not parse history file/ + */ + public function testConstructNotParsable() + { + file_put_contents(self::$historyFilePath, 'not parsable'); + // gzinflate generates a warning + @new History(self::$historyFilePath); + } + + /** + * Test add link event + */ + public function testAddLink() + { + $history = new History(self::$historyFilePath); + $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->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->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->assertEquals('str', $actual['id']); + } + + /** + * Test updated link event + */ + public function testUpdateLink() + { + $history = new History(self::$historyFilePath); + $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->assertEquals(1, $actual['id']); + } + + /** + * Test delete link event + */ + public function testDeleteLink() + { + $history = new History(self::$historyFilePath); + $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->assertEquals(1, $actual['id']); + } + + /** + * Test updated settings event + */ + public function testUpdateSettings() + { + $history = new History(self::$historyFilePath); + $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->assertEmpty($actual['id']); + } + + /** + * Make sure that new items are stored at the beginning + */ + public function testHistoryOrder() + { + $history = new History(self::$historyFilePath); + $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->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->assertEquals(1, $actual['id']); + } + + /** + * Re-read history from file after writing an event + */ + public function testHistoryRead() + { + $history = new History(self::$historyFilePath); + $history->updateLink(['id' => 1]); + $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->assertEquals(1, $actual['id']); + } + + /** + * Re-read history from file after writing an event and make sure that the order is correct + */ + public function testHistoryOrderRead() + { + $history = new History(self::$historyFilePath); + $history->updateLink(['id' => 1]); + $history->addLink(['id' => 1]); + + $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->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->assertEquals(1, $actual['id']); + } + + /** + * Test retention time: delete old entries. + */ + public function testHistoryRententionTime() + { + $history = new History(self::$historyFilePath, 5); + $history->updateLink(['id' => 1]); + $this->assertEquals(1, count($history->getHistory())); + $arr = $history->getHistory(); + $arr[0]['datetime'] = (new DateTime('-1 hour'))->format(DateTime::ATOM); + FileUtils::writeFlatDB(self::$historyFilePath, $arr); + + $history = new History(self::$historyFilePath, 60); + $this->assertEquals(1, count($history->getHistory())); + $this->assertEquals(1, $history->getHistory()[0]['id']); + $history->updateLink(['id' => 2]); + $this->assertEquals(1, count($history->getHistory())); + $this->assertEquals(2, $history->getHistory()[0]['id']); + } +} -- cgit v1.2.3 From d16ca2e22f3d7325fc9593fccd8523eebe226567 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Mon, 16 Jan 2017 12:50:36 +0100 Subject: History: lazy loading for the history file Only read it when it's necessary --- tests/HistoryTest.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'tests/HistoryTest.php') diff --git a/tests/HistoryTest.php b/tests/HistoryTest.php index 79322249..91525845 100644 --- a/tests/HistoryTest.php +++ b/tests/HistoryTest.php @@ -21,9 +21,19 @@ class HistoryTest extends PHPUnit_Framework_TestCase /** * Test that the history file is created if it doesn't exist. */ - public function testConstructFileCreated() + public function testConstructLazyLoading() { new History(self::$historyFilePath); + $this->assertFileNotExists(self::$historyFilePath); + } + + /** + * Test that the history file is created if it doesn't exist. + */ + public function testAddEventCreateFile() + { + $history = new History(self::$historyFilePath); + $history->updateSettings(); $this->assertFileExists(self::$historyFilePath); } @@ -37,7 +47,8 @@ class HistoryTest extends PHPUnit_Framework_TestCase { touch(self::$historyFilePath); chmod(self::$historyFilePath, 0440); - new History(self::$historyFilePath); + $history = new History(self::$historyFilePath); + $history->updateSettings(); } /** @@ -49,8 +60,9 @@ class HistoryTest extends PHPUnit_Framework_TestCase public function testConstructNotParsable() { file_put_contents(self::$historyFilePath, 'not parsable'); + $history = new History(self::$historyFilePath); // gzinflate generates a warning - @new History(self::$historyFilePath); + @$history->updateSettings(); } /** -- cgit v1.2.3