PageRenderTime 64ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/tine20/Tinebase/Timemachine/ModificationLogTest.php

https://gitlab.com/rsilveira1987/Expresso
PHP | 335 lines | 219 code | 32 blank | 84 comment | 7 complexity | 95232d2caced0ff8f4e7400455737c21 MD5 | raw file
  1. <?php
  2. /**
  3. * Tine 2.0 - http://www.tine20.org
  4. *
  5. * @package Tinebase
  6. * @subpackage Record
  7. * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
  8. * @copyright Copyright (c) 2008-2012 Metaways Infosystems GmbH (http://www.metaways.de)
  9. * @author Cornelius Weiss <c.weiss@metaways.de>
  10. */
  11. /**
  12. * Test helper
  13. */
  14. require_once dirname(dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR . 'TestHelper.php';
  15. /**
  16. * Test class for Tinebase_Group
  17. */
  18. class Tinebase_Timemachine_ModificationLogTest extends PHPUnit_Framework_TestCase
  19. {
  20. /**
  21. * @var Tinebase_Timemachine_ModificationLog
  22. */
  23. protected $_modLogClass;
  24. /**
  25. * @var Tinebase_Record_RecordSet
  26. */
  27. protected $_logEntries;
  28. /**
  29. * @var Tinebase_Record_RecordSet
  30. * Persistant Records we need to cleanup at tearDown()
  31. */
  32. protected $_persistantLogEntries;
  33. /**
  34. * @var array holds recordId's we create log entries for
  35. */
  36. protected $_recordIds = array();
  37. /**
  38. * Runs the test methods of this class.
  39. *
  40. * @access public
  41. * @static
  42. */
  43. public static function main()
  44. {
  45. $suite = new PHPUnit_Framework_TestSuite('Tinebase_Timemachine_ModificationLogTest');
  46. PHPUnit_TextUI_TestRunner::run($suite);
  47. }
  48. /**
  49. * Lets update a record tree times
  50. *
  51. * @access protected
  52. */
  53. protected function setUp()
  54. {
  55. Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
  56. $now = new Tinebase_DateTime();
  57. $this->_modLogClass = Tinebase_Timemachine_ModificationLog::getInstance();
  58. $this->_persistantLogEntries = new Tinebase_Record_RecordSet('Tinebase_Model_ModificationLog');
  59. $this->_recordIds = array('5dea69be9c72ea3d263613277c3b02d529fbd8bc');
  60. $tinebaseApp = Tinebase_Application::getInstance()->getApplicationByName('Tinebase');
  61. $this->_logEntries = new Tinebase_Record_RecordSet('Tinebase_Model_ModificationLog', array(
  62. array(
  63. 'application_id' => $tinebaseApp,
  64. 'record_id' => $this->_recordIds[0],
  65. 'record_type' => 'TestType',
  66. 'record_backend' => 'TestBackend',
  67. 'modification_time' => $this->_cloner($now)->addDay(-2),
  68. 'modification_account' => 7,
  69. 'modified_attribute' => 'FirstTestAttribute',
  70. 'old_value' => 'Hamburg',
  71. 'new_value' => 'Bremen'
  72. ),
  73. array(
  74. 'application_id' => $tinebaseApp,
  75. 'record_id' => $this->_recordIds[0],
  76. 'record_type' => 'TestType',
  77. 'record_backend' => 'TestBackend',
  78. 'modification_time' => $this->_cloner($now)->addDay(-1),
  79. 'modification_account' => 7,
  80. 'modified_attribute' => 'FirstTestAttribute',
  81. 'old_value' => 'Bremen',
  82. 'new_value' => 'Frankfurt'
  83. ),
  84. array(
  85. 'application_id' => $tinebaseApp,
  86. 'record_id' => $this->_recordIds[0],
  87. 'record_type' => 'TestType',
  88. 'record_backend' => 'TestBackend',
  89. 'modification_time' => $this->_cloner($now),
  90. 'modification_account' => 7,
  91. 'modified_attribute' => 'FirstTestAttribute',
  92. 'old_value' => 'Frankfurt',
  93. 'new_value' => 'Stuttgart'
  94. ),
  95. array(
  96. 'application_id' => $tinebaseApp,
  97. 'record_id' => $this->_recordIds[0],
  98. 'record_type' => 'TestType',
  99. 'record_backend' => 'TestBackend',
  100. 'modification_time' => $this->_cloner($now)->addDay(-2),
  101. 'modification_account' => 7,
  102. 'modified_attribute' => 'SecondTestAttribute',
  103. 'old_value' => 'Deutschland',
  104. 'new_value' => 'Östereich'
  105. ),
  106. array(
  107. 'application_id' => $tinebaseApp,
  108. 'record_id' => $this->_recordIds[0],
  109. 'record_type' => 'TestType',
  110. 'record_backend' => 'TestBackend',
  111. 'modification_time' => $this->_cloner($now)->addDay(-1)->addSecond(1),
  112. 'modification_account' => 7,
  113. 'modified_attribute' => 'SecondTestAttribute',
  114. 'old_value' => 'Östereich',
  115. 'new_value' => 'Schweitz'
  116. ),
  117. array(
  118. 'application_id' => $tinebaseApp->getId(),
  119. 'record_id' => $this->_recordIds[0],
  120. 'record_type' => 'TestType',
  121. 'record_backend' => 'TestBackend',
  122. 'modification_time' => $this->_cloner($now),
  123. 'modification_account' => 7,
  124. 'modified_attribute' => 'SecondTestAttribute',
  125. 'old_value' => 'Schweitz',
  126. 'new_value' => 'Italien'
  127. )), true, false);
  128. foreach ($this->_logEntries as $logEntry) {
  129. $id = $this->_modLogClass->setModification($logEntry);
  130. $this->_persistantLogEntries->addRecord($this->_modLogClass->getModification($id));
  131. }
  132. }
  133. /**
  134. * cleanup database
  135. * @access protected
  136. */
  137. protected function tearDown()
  138. {
  139. Tinebase_TransactionManager::getInstance()->rollBack();
  140. }
  141. /**
  142. * tests that the returned mod logs equal the initial ones we defined
  143. * in this test setup.
  144. * If this works, also the setting of logs works!
  145. *
  146. */
  147. public function testGetModification()
  148. {
  149. foreach ($this->_logEntries as $num => $logEntry) {
  150. $rawLogEntry = $logEntry->toArray();
  151. $rawPersistantLogEntry = $this->_persistantLogEntries[$num]->toArray();
  152. foreach ($rawLogEntry as $field => $value) {
  153. $persistantValue = $rawPersistantLogEntry[$field];
  154. if ($value != $persistantValue) {
  155. $this->fail("Failed asserting that contents of saved LogEntry #$num in field $field equals initial datas. \n" .
  156. "Expected '$value', got '$persistantValue'");
  157. }
  158. }
  159. }
  160. $this->assertTrue(true);
  161. }
  162. /**
  163. * tests computation of a records differences described by a set of modification logs
  164. */
  165. public function testComputeDiff()
  166. {
  167. $diffs = $this->_modLogClass->computeDiff($this->_persistantLogEntries)->toArray();
  168. $this->assertEquals(2, count($diffs)); // we changed two attributes
  169. foreach ($diffs as $diff) {
  170. switch ($diff['modified_attribute']) {
  171. case 'FirstTestAttribute':
  172. $this->assertEquals('Hamburg', $diff['old_value']);
  173. $this->assertEquals('Stuttgart', $diff['new_value']);
  174. break;
  175. case 'SecondTestAttribute':
  176. $this->assertEquals('Deutschland', $diff['old_value']);
  177. $this->assertEquals('Italien', $diff['new_value']);
  178. }
  179. }
  180. }
  181. /**
  182. * get modifications test
  183. */
  184. public function testGetModifications()
  185. {
  186. $testBase = array(
  187. 'record_id' => '5dea69be9c72ea3d263613277c3b02d529fbd8bc',
  188. 'type' => 'TestType',
  189. 'backend' => 'TestBackend'
  190. );
  191. $firstModificationTime = $this->_persistantLogEntries[0]->modification_time;
  192. $lastModificationTime = $this->_persistantLogEntries[count($this->_persistantLogEntries)-1]->modification_time;
  193. $toTest[] = $testBase + array(
  194. 'from_add' => 'addDay,-3',
  195. 'until_add' => 'addDay,1',
  196. 'nums' => 6
  197. );
  198. $toTest[] = $testBase + array(
  199. 'nums' => 4
  200. );
  201. $toTest[] = $testBase + array(
  202. 'account' => Tinebase_Record_Abstract::generateUID(),
  203. 'nums' => 0
  204. );
  205. foreach ($toTest as $params) {
  206. $from = clone $firstModificationTime;
  207. $until = clone $lastModificationTime;
  208. if (isset($params['from_add'])) {
  209. list($fn,$p) = explode(',', $params['from_add']);
  210. $from->$fn($p);
  211. }
  212. if (isset($params['until_add'])) {
  213. list($fn,$p) = explode(',', $params['until_add']);
  214. $until->$fn($p);
  215. }
  216. $account = isset($params['account']) ? $params['account'] : NULL;
  217. $diffs = $this->_modLogClass->getModifications('Tinebase', $params['record_id'], $params['type'], $params['backend'], $from, $until, $account);
  218. $count = 0;
  219. foreach ($diffs as $diff) {
  220. if ($diff->record_id == $params['record_id']) {
  221. $count++;
  222. }
  223. }
  224. $this->assertEquals($params['nums'], $count);
  225. }
  226. }
  227. /**
  228. * test modlog undo
  229. *
  230. * @see 0006252: allow to undo history items (modlog)
  231. * @see 0000554: modlog: records can't be updated in less than 1 second intervals
  232. */
  233. public function testUndo()
  234. {
  235. // create a record
  236. $contact = Addressbook_Controller_Contact::getInstance()->create(new Addressbook_Model_Contact(array(
  237. 'n_family' => 'tester',
  238. 'tel_cell' => '+491234',
  239. )));
  240. // change something using the record controller
  241. $contact->tel_cell = NULL;
  242. $contact = Addressbook_Controller_Contact::getInstance()->update($contact);
  243. // fetch modlog and test seq
  244. $modlog = $this->_modLogClass->getModifications('Addressbook', $contact->getId(), NULL, 'Sql',
  245. Tinebase_DateTime::now()->subSecond(5), Tinebase_DateTime::now())->getFirstRecord();
  246. $this->assertTrue($modlog !== NULL);
  247. $this->assertEquals(2, $modlog->seq);
  248. $this->assertEquals('+491234', $modlog->old_value);
  249. $filter = new Tinebase_Model_ModificationLogFilter(array(
  250. array('field' => 'record_type', 'operator' => 'equals', 'value' => 'Addressbook_Model_Contact'),
  251. array('field' => 'record_id', 'operator' => 'equals', 'value' => $contact->getId()),
  252. array('field' => 'modification_time', 'operator' => 'within', 'value' => 'weekThis'),
  253. ));
  254. $result = $this->_modLogClass->undo($filter);
  255. $this->assertEquals(1, $result['totalcount'], 'did not get 1 undone modlog: ' . print_r($result, TRUE));
  256. $this->assertEquals('+491234', $result['undoneModlogs']->getFirstRecord()->old_value);
  257. // check record after undo
  258. $contact = Addressbook_Controller_Contact::getInstance()->get($contact);
  259. $this->assertEquals('+491234', $contact->tel_cell);
  260. }
  261. /**
  262. * purges mod log entries of given recordIds
  263. *
  264. * @param mixed [string|array|Tinebase_Record_RecordSet] $_recordIds
  265. *
  266. * @todo should be removed when other tests do not need this anymore
  267. */
  268. public static function purgeLogs($_recordIds)
  269. {
  270. $table = new Tinebase_Db_Table(array('name' => SQL_TABLE_PREFIX . 'timemachine_modlog'));
  271. foreach ((array) $_recordIds as $recordId) {
  272. $table->delete($table->getAdapter()->quoteInto('record_id = ?', $recordId));
  273. }
  274. }
  275. /**
  276. * Workaround as the php clone operator does not return cloned
  277. * objects right hand sided
  278. *
  279. * @param object $_object
  280. * @return object
  281. */
  282. protected function _cloner($_object)
  283. {
  284. return clone $_object;
  285. }
  286. /**
  287. * testDateTimeModlog
  288. *
  289. * @see 0000996: add changes in relations/linked objects to modlog/history
  290. */
  291. public function testDateTimeModlog()
  292. {
  293. $task = Tasks_Controller_Task::getInstance()->create(new Tasks_Model_Task(array(
  294. 'summary' => 'test task',
  295. )));
  296. $task->due = Tinebase_DateTime::now();
  297. $updatedTask = Tasks_Controller_Task::getInstance()->update($task);
  298. $task->seq = 1;
  299. $modlog = $this->_modLogClass->getModificationsBySeq($task, 2);
  300. $this->assertEquals(1, count($modlog));
  301. $this->assertEquals((string) $task->due, (string) $modlog->getFirstRecord()->new_value, 'new value mismatch: ' . print_r($modlog->toArray(), TRUE));
  302. }
  303. }