PageRenderTime 54ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/utils/ConstraintHandlerTest.php

https://bitbucket.org/wildanm/orangehrm
PHP | 359 lines | 231 code | 64 blank | 64 comment | 11 complexity | dcb0a7af41e9536fc0353ce9da0f3bd9 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, AGPL-3.0, BSD-3-Clause, AGPL-1.0, GPL-2.0, LGPL-2.1, LGPL-3.0
  1. <?php
  2. // Call ConstraintHandlerTest::main() if this source file is executed directly.
  3. if (!defined("PHPUnit_MAIN_METHOD")) {
  4. define("PHPUnit_MAIN_METHOD", "ConstraintHandlerTest::main");
  5. }
  6. require_once "PHPUnit/Framework/TestCase.php";
  7. require_once "PHPUnit/Framework/TestSuite.php";
  8. require_once "testConf.php";
  9. require_once ROOT_PATH."/lib/confs/Conf.php";
  10. require_once 'ConstraintHandler.php';
  11. /**
  12. * Test class for ConstraintHandler.
  13. * Generated by PHPUnit_Util_Skeleton on 2007-07-25 at 08:52:16.
  14. */
  15. class ConstraintHandlerTest extends PHPUnit_Framework_TestCase {
  16. /**
  17. * Runs the test methods of this class.
  18. *
  19. * @access public
  20. * @static
  21. */
  22. public static function main() {
  23. require_once "PHPUnit/TextUI/TestRunner.php";
  24. $suite = new PHPUnit_Framework_TestSuite("ConstraintHandlerTest");
  25. $result = PHPUnit_TextUI_TestRunner::run($suite);
  26. }
  27. /**
  28. * Sets up the fixture, for example, open a network connection.
  29. * This method is called before a test is executed.
  30. *
  31. * @access protected
  32. */
  33. protected function setUp() {
  34. $conf = new Conf();
  35. $this->connection = mysql_connect($conf->dbhost.":".$conf->dbport, $conf->dbuser, $conf->dbpass);
  36. $this->assertTrue($this->connection !== false);
  37. $this->assertTrue(mysql_select_db($conf->dbname));
  38. /* Create tables for testing */
  39. $result = mysql_query("DROP TABLE IF EXISTS test_emp_dependents");
  40. $this->assertTrue($result !== false, "Mysql Error: " . mysql_error());
  41. $result = mysql_query("CREATE TABLE test_emp_dependents (" .
  42. "emp_number int(7) not null default 0," .
  43. "ed_seqno decimal(2,0) not null default 0," .
  44. "ed_name varchar(100) default ''," .
  45. "primary key (emp_number, ed_seqno)" .
  46. ") engine=innodb default charset=utf8");
  47. $this->assertTrue($result !== false, "Mysql Error: " . mysql_error());
  48. $result = mysql_query("DROP TABLE IF EXISTS test_users");
  49. $this->assertTrue($result !== false, "Mysql Error: " . mysql_error());
  50. $result = mysql_query("CREATE TABLE test_users (" .
  51. "id varchar(36) not null default ''," .
  52. "emp_number int(7) default null," .
  53. "modified_user_id varchar(36) default null," .
  54. "created_by varchar(36) default null," .
  55. "primary key (id)" .
  56. ") engine=innodb default charset=utf8");
  57. $this->assertTrue($result !== false, "Mysql Error: " . mysql_error());
  58. $result = mysql_query("DROP TABLE IF EXISTS test_employee");
  59. $this->assertTrue($result !== false, "Mysql Error: " . mysql_error());
  60. $result = mysql_query("CREATE TABLE test_employee(" .
  61. "emp_number int(7) not null default 0, " .
  62. "emp_firstname varchar(100) default '' not null," .
  63. "job_title_code varchar(13) default null," .
  64. "work_station int(6) default null," .
  65. "nation_code varchar(13) default null," .
  66. "primary key (emp_number)" .
  67. ") engine=innodb default charset=utf8");
  68. $this->assertTrue($result !== false, "Mysql Error: " . mysql_error());
  69. $result = mysql_query("DROP TABLE IF EXISTS test_job_title");
  70. $this->assertTrue($result !== false, "Mysql Error: " . mysql_error());
  71. $result = mysql_query("CREATE TABLE test_job_title (" .
  72. "jobtit_code varchar(13) not null default ''," .
  73. "jobtit_name varchar(50) default null," .
  74. "jobtit_desc varchar(200) default null," .
  75. "jobtit_comm varchar(400) default null," .
  76. "sal_grd_code varchar(13) default null," .
  77. "primary key(jobtit_code)" .
  78. ") engine=innodb default charset=utf8;");
  79. $this->assertTrue($result !== false, "Mysql Error: " . mysql_error());
  80. $result = mysql_query("DROP TABLE IF EXISTS test_nationality");
  81. $this->assertTrue($result !== false, "Mysql Error: " . mysql_error());
  82. $result = mysql_query("create table `test_nationality` (" .
  83. " `nat_code` varchar(13) not null default ''," .
  84. " `nat_name` varchar(120) default null," .
  85. " primary key (`nat_code`)" .
  86. ") engine=innodb default charset=utf8");
  87. $this->assertTrue($result !== false, "Mysql Error: " . mysql_error());
  88. }
  89. /**
  90. * Tears down the fixture, for example, close a network connection.
  91. * This method is called after a test is executed.
  92. *
  93. * @access protected
  94. */
  95. protected function tearDown() {
  96. $this->assertTrue(mysql_query("DROP TABLE IF EXISTS test_emp_dependents"), "Error: " . mysql_error());
  97. $this->assertTrue($result = mysql_query("DROP TABLE IF EXISTS test_users"), "Error: " . mysql_error());
  98. $this->assertTrue(mysql_query("DROP TABLE IF EXISTS test_employee"), "Error: " . mysql_error());
  99. $this->assertTrue(mysql_query("DROP TABLE IF EXISTS test_job_title"), "Error: " . mysql_error());
  100. $this->assertTrue(mysql_query("DROP TABLE IF EXISTS test_nationality"), "Error: " . mysql_error());
  101. }
  102. /**
  103. * Test method applyConstraints() with simple on delete set null constraint
  104. */
  105. public function testSimpleSetNullConstraint() {
  106. $fkConstraints = array(array("test_employee", array("nation_code"), "test_nationality", array("nat_code"), "null"));
  107. $this->assertTrue(mysql_query("INSERT INTO test_nationality(nat_code, nat_name) VALUES(1, 'Sri Lankan')"));
  108. //$this->assertTrue(mysql_query("INSERT INTO test_nationality(nat_code, nat_name) VALUES(2, 'Indian')"));
  109. $this->assertTrue(mysql_query("INSERT INTO test_employee(emp_number,emp_firstname, nation_code) VALUES(1, 'John', 2), " .
  110. "(2, 'Ruwan', 1), (3, 'Kamal', 2)"));
  111. $constraintHandler = new ConstraintHandler();
  112. $failed = $constraintHandler->applyConstraints($fkConstraints);
  113. $this->assertEquals(0, count($failed));
  114. $this->assertEquals(3, $this->_countRows("test_employee"), "Shouldn't delete employees");
  115. $this->assertEquals(1, $this->_countRows("test_nationality"), "Shouldn't delete nationality");
  116. /* Verify that nation_code is null for two employees */
  117. $this->assertEquals(2, $this->_countRows("test_employee", "nation_code IS NULL"));
  118. $employees = $this->_selectWhere("test_employee", "nation_code IS NULL");
  119. $this->assertEquals(2, count($employees));
  120. /* Test that the correct employees had nation_code set to null */
  121. foreach ($employees as $employee) {
  122. $empNumber = intval($employee['emp_number']);
  123. if (($empNumber != 1) && ($empNumber != 3)) {
  124. $this->fail("nation_code set null for invalid employee: $empNumber");
  125. }
  126. }
  127. /* Check the foreign key constraints have been set */
  128. $this->assertEquals(0, count($constraintHandler->getMissingConstraints($fkConstraints)));
  129. }
  130. /**
  131. * Test method applyConstraints() with simple on delete cascade constraint
  132. */
  133. public function testSimpleCascadeConstraint() {
  134. $this->assertTrue(mysql_query("INSERT INTO test_employee(emp_number,emp_firstname) VALUES(1, 'John'), " .
  135. "(2, 'Ruwan'), (3, 'Kamal')"), "Mysql Error: ". mysql_error());
  136. $this->assertTrue(mysql_query("INSERT INTO test_emp_dependents(emp_number, ed_seqno, ed_name) " .
  137. "VALUES(1, 1, 'Ruwan'), (1, 2, 'Kamani'), (3, 1, 'Sena'), (4, 1, 'Ravi'), (4, 2, 'Janesh'), " .
  138. "(5, 1, 'Wimal')"), "Mysql Error: ". mysql_error());
  139. $fkConstraints = array(array("test_emp_dependents", array("emp_number"), "test_employee", array("emp_number"), "cascade"));
  140. $constraintHandler = new ConstraintHandler();
  141. $failed = $constraintHandler->applyConstraints($fkConstraints);
  142. $this->assertEquals(0, count($failed));
  143. $this->assertEquals(3, $this->_countRows("test_employee"), "Shouldn't delete employees");
  144. $this->assertEquals(3, $this->_countRows("test_emp_dependents"));
  145. $this->assertEquals(0, $this->_countRows("test_emp_dependents", "emp_number = 4"));
  146. $this->assertEquals(0, $this->_countRows("test_emp_dependents", "emp_number = 5"));
  147. $this->assertEquals(2, $this->_countRows("test_emp_dependents", "emp_number = 1"));
  148. $this->assertEquals(1, $this->_countRows("test_emp_dependents", "emp_number = 3"));
  149. /* Check the foreign key constraints have been set */
  150. $this->assertEquals(0, count($constraintHandler->getMissingConstraints($fkConstraints)));
  151. }
  152. /**
  153. * Test method applyConstraints() with simple on delete set null constraint
  154. */
  155. public function testSimpleSetNullWithNoParents() {
  156. $fkConstraints = array(array("test_employee", array("nation_code"), "test_nationality", array("nat_code"), "null"));
  157. $this->assertTrue(mysql_query("INSERT INTO test_employee(emp_number,emp_firstname, nation_code) VALUES(1, 'John', 2), " .
  158. "(2, 'Ruwan', 1), (3, 'Kamal', 2)"));
  159. $constraintHandler = new ConstraintHandler();
  160. $failed = $constraintHandler->applyConstraints($fkConstraints);
  161. $this->assertEquals(0, count($failed));
  162. $this->assertEquals(3, $this->_countRows("test_employee"), "Shouldn't delete employees");
  163. $this->assertEquals(0, $this->_countRows("test_nationality"), "Shouldn't change nationality");
  164. /* Verify that nation_code is null for all employees */
  165. $this->assertEquals(3, $this->_countRows("test_employee", "nation_code IS NULL"));
  166. /* Check the foreign key constraints have been set */
  167. $this->assertEquals(0, count($constraintHandler->getMissingConstraints($fkConstraints)));
  168. }
  169. /**
  170. * Test method applyConstraints() with simple on delete cascade constraint with no entries in
  171. * the parent table.
  172. */
  173. public function testSimpleCascadeConstraintWithNoParents() {
  174. $this->assertTrue(mysql_query("INSERT INTO test_emp_dependents(emp_number, ed_seqno, ed_name) " .
  175. "VALUES(1, 1, 'Ruwan'), (1, 2, 'Kamani'), (3, 1, 'Sena'), (4, 1, 'Ravi'), (4, 2, 'Janesh'), " .
  176. "(5, 1, 'Wimal')"), "Mysql Error: ". mysql_error());
  177. $fkConstraints = array(array("test_emp_dependents", array("emp_number"), "test_employee", array("emp_number"), "cascade"));
  178. $constraintHandler = new ConstraintHandler();
  179. $failed = $constraintHandler->applyConstraints($fkConstraints);
  180. $this->assertEquals(0, count($failed));
  181. $this->assertEquals(0, $this->_countRows("test_employee"), "Shouldn't delete employees");
  182. $this->assertEquals(0, $this->_countRows("test_emp_dependents"));
  183. /* Check the foreign key constraints have been set */
  184. $this->assertEquals(0, count($constraintHandler->getMissingConstraints($fkConstraints)));
  185. }
  186. /**
  187. * Test getConstraintSQL method.
  188. */
  189. public function testGetConstraintSQL() {
  190. $constraintHandler = new ConstraintHandler();
  191. $expected = "ALTER TABLE hs_hr_emp_dependents ADD CONSTRAINT FOREIGN KEY (emp_number) " .
  192. "REFERENCES hs_hr_employee(emp_number) ON DELETE CASCADE";
  193. $constraint = array("hs_hr_emp_dependents", array("emp_number"), "hs_hr_employee", array("emp_number"),
  194. "cascade");
  195. $this->assertEquals($expected, $constraintHandler->getConstraintSQL($constraint));
  196. $expected = "ALTER TABLE hs_hr_leave ADD CONSTRAINT FOREIGN KEY (leave_request_id,leave_type_id,employee_id)" .
  197. " REFERENCES hs_hr_leave_requests(leave_request_id,leave_type_id,employee_id) ON DELETE CASCADE";
  198. $constraint = array("hs_hr_leave", array("leave_request_id","leave_type_id","employee_id"), "hs_hr_leave_requests",
  199. array("leave_request_id","leave_type_id","employee_id"), "cascade");
  200. $constraintHandler = new ConstraintHandler();
  201. $this->assertEquals($expected, $constraintHandler->getConstraintSQL($constraint));
  202. }
  203. /**
  204. * Checks that all constraints in the database are set.
  205. */
  206. public function testAllConstraintsSet() {
  207. $constraintHandler = new ConstraintHandler();
  208. require ROOT_PATH.'/dbscript/constraints.php';
  209. $failed = $constraintHandler->getMissingConstraints($fkConstraints);
  210. $numFailed = count($failed);
  211. if ($numFailed > 0) {
  212. foreach($failed as $constraint) {
  213. $failedList[] = $constraintHandler->getConstraintSQL($constraint);
  214. }
  215. $message = "Following $numFailed constraint(s) were missing: " . implode("\n,",$failedList);
  216. $this->fail($message);
  217. }
  218. }
  219. /**
  220. * Tests the method getMissingConstraints()
  221. */
  222. public function testCheckConstraintsSet() {
  223. $constraintHandler = new ConstraintHandler();
  224. $fkConstraints = array(array("test_emp_dependents", array("emp_number"), "test_employee", array("emp_number"), "cascade"));
  225. $this->assertEquals(1, count($constraintHandler->getMissingConstraints($fkConstraints)));
  226. $this->assertTrue(mysql_query("ALTER TABLE test_emp_dependents add constraint foreign key (emp_number) " .
  227. "references test_employee(emp_number) on delete cascade"));
  228. $this->assertEquals(0, count($constraintHandler->getMissingConstraints($fkConstraints)));
  229. }
  230. /**
  231. * Tests the regexp used in getMissingConstraints().
  232. */
  233. public function testCheckRegExp() {
  234. $string = " CONSTRAINT `test_emp_dependents_ibfk_1` FOREIGN KEY (`emp_number`) REFERENCES `test_employee` (`emp_number`) ON DELETE CASCADE";
  235. $regexp = "/\w*CONSTRAINT\b.*\bFOREIGN\s+KEY[\s(`]+emp_number[\s)`]+REFERENCES[\s`)]+test_employee[\s`(]+emp_number[\s`)]+ON\s+DELETE.*/";
  236. $count = preg_match($regexp, $string);
  237. $this->assertEquals(1, $count);
  238. }
  239. /**
  240. * Convenience method that does a select from a table with given where
  241. * condition.
  242. *
  243. * @param string $table Table name
  244. * @param string $where Where clause
  245. *
  246. * @return array results as an array (MYSQL_BOTH) from the database
  247. */
  248. private function _selectWhere($table, $where) {
  249. $sql = "SELECT * FROM $table WHERE $where";
  250. $result = mysql_query($sql);
  251. $this->assertTrue($result !== false, "Query failed: $sql");
  252. $data = array();
  253. while ($row = mysql_fetch_array($result)) {
  254. $data[] = $row;
  255. }
  256. return $data;
  257. }
  258. /**
  259. * Counts rows in table admins (with optional condition)
  260. *
  261. * @param string $table table name
  262. * @param string $where where clause
  263. * @return int number of rows
  264. */
  265. private function _countRows($table, $where = null) {
  266. $sql = "SELECT COUNT(*) FROM $table";
  267. if (!empty($where)) {
  268. $sql .= " WHERE " . $where;
  269. }
  270. $result = mysql_query($sql);
  271. $this->assertTrue($result !== false, "Query failed: $sql");
  272. $row = mysql_fetch_array($result, MYSQL_NUM);
  273. $this->assertTrue(is_array($row));
  274. $count = $row[0];
  275. return $count;
  276. }
  277. }
  278. // Call ConstraintHandlerTest::main() if this source file is executed directly.
  279. if (PHPUnit_MAIN_METHOD == "ConstraintHandlerTest::main") {
  280. ConstraintHandlerTest::main();
  281. }
  282. ?>