diff --git a/README.md b/README.md index ea6024c3a918fce2eed5ad454bbcabedf002cb50..7803f6c3c3ad5a2eda567505d49ab17387ccbb86 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,12 @@ Create the logs directory and assign ownership to the Apache user (usually www-d mkdir logs sudo chown www-data logs +### Docker + +Database image: + + docker build -f docker/db-Dockerfile --tag rap-ia2/database . + ### Run Unit Tests and build code coverage report (XDebug or another code coverage driver needs to be installed; e.g. `sudo apt install php-xdebug`) diff --git a/classes/datalayer/mysql/MySQLUserDAO.php b/classes/datalayer/mysql/MySQLUserDAO.php index f16ce49582384050e963d9f19c3f404b9f54d6af..37f4fcd68b40e8377c941e8f6dbd5927542bf994 100644 --- a/classes/datalayer/mysql/MySQLUserDAO.php +++ b/classes/datalayer/mysql/MySQLUserDAO.php @@ -251,16 +251,29 @@ class MySQLUserDAO extends BaseMySQLDAO implements UserDAO { try { $dbh->beginTransaction(); - // Moving identities from user2 to user1 - $stmt1 = $dbh->prepare("UPDATE `identity` SET `user_id` = :id1 WHERE `user_id` = :id2"); + // Deleting keep_separated pairs + $stmt1 = $dbh->prepare("DELETE FROM keep_separated WHERE " + . "(user_id1 = :id1 AND user_id2 = :id2) OR" + . "(user_id1 = :id2 AND user_id2 = :id1)"); $stmt1->bindParam(':id1', $userId1); $stmt1->bindParam(':id2', $userId2); $stmt1->execute(); - - // Deleting user2 - $stmt2 = $dbh->prepare("DELETE FROM `user` WHERE `id` = :id2"); + + // Deleting keep_separated records of user that is going to be deleted + $stmt2 = $dbh->prepare("DELETE FROM keep_separated WHERE user_id1 = :id2 OR user_id2 = :id2"); $stmt2->bindParam(':id2', $userId2); $stmt2->execute(); + + // Moving identities from user2 to user1 + $stmt3 = $dbh->prepare("UPDATE `identity` SET `user_id` = :id1 WHERE `user_id` = :id2"); + $stmt3->bindParam(':id1', $userId1); + $stmt3->bindParam(':id2', $userId2); + $stmt3->execute(); + + // Deleting user2 + $stmt4 = $dbh->prepare("DELETE FROM `user` WHERE `id` = :id2"); + $stmt4->bindParam(':id2', $userId2); + $stmt4->execute(); $dbh->commit(); } catch (Exception $ex) { diff --git a/docker/db-Dockerfile b/docker/db-Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..4ac0f9f8b02d55aa6d01115626722b7e714a2a77 --- /dev/null +++ b/docker/db-Dockerfile @@ -0,0 +1,7 @@ +FROM mariadb:10.5 + +ENV MYSQL_ALLOW_EMPTY_PASSWORD yes +ENV MYSQL_DATABASE rap + +COPY sql/setup-database.sql /docker-entrypoint-initdb.d/01-setup-database.sql +COPY sql/delete-user-procedure.sql /docker-entrypoint-initdb.d/02-delete-user-procedure.sql diff --git a/tests/BaseDAOTest.php b/tests/BaseDAOTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2c6e77e8d401ae847ef6edcfee42f6378babeb77 --- /dev/null +++ b/tests/BaseDAOTest.php @@ -0,0 +1,24 @@ +<?php + +abstract class BaseDAOTest extends \PHPUnit\Framework\TestCase { + + protected function getFakeLocator(): \RAP\Locator { + + $config = (object) [ + "databaseConfig" => (object) [ + "dbtype" => 'MySQL', + "hostname" => "127.0.0.1", + "port" => 3307, + "username" => "root", + "password" => "", + "dbname" => "rap" + ] + ]; + + $locatorStub = $this->createMock(\RAP\Locator::class); + $locatorStub->config = $config; + + return $locatorStub; + } + +} diff --git a/tests/MySQLUserDAOTest.php b/tests/MySQLUserDAOTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7ee5b1fde162f92af57c9f8d193345341000deb1 --- /dev/null +++ b/tests/MySQLUserDAOTest.php @@ -0,0 +1,55 @@ +<?php + +class MySQLUserDAOTest extends BaseDAOTest { + + public function setUp(): void { + $this->dao = new \RAP\MySQLUserDAO($this->getFakeLocator()); + } + + public function testJoinUsersAfterKeepSeparated() { + + $user1 = $this->createUser(\RAP\Identity::EDU_GAIN, 'name.surname@inaf.it', '001'); + $user2 = $this->createUser(\RAP\Identity::GOOGLE, 'name.surname@inaf.it', '002'); + $user3 = $this->createUser(\RAP\Identity::LINKEDIN, 'test@inaf.it', '003'); + + $joinable1 = $this->dao->findJoinableUsersByUserId($user1->id); + $this->assertEquals(1, count($joinable1)); + $this->assertEquals($user2->id, $joinable1[0]); + + $joinable2 = $this->dao->findJoinableUsersByUserId($user2->id); + $this->assertEquals(1, count($joinable2)); + $this->assertEquals($user1->id, $joinable2[0]); + + // Add records to keep_separated table to test the two DELETE statements before the join + $this->dao->insertRejectedJoin($user1->id, $user2->id); + $this->dao->insertRejectedJoin($user2->id, $user3->id); + + $joinable = $this->dao->findJoinableUsersByUserId($user1->id); + $this->assertEquals(0, count($joinable)); + + $this->dao->joinUsers($user1->id, $user2->id); + + $joinedUser = $this->dao->findUserById($user1->id); + $this->assertEquals(2, count($joinedUser->identities)); + + $this->assertNull($this->dao->findUserById($user2->id)); + } + + private function createUser(string $identityType, string $email, string $typedId) { + $user = new \RAP\User(); + $user->id = $this->dao->createUser(); + + $identity = new \RAP\Identity($identityType); + $identity->email = $email; + $identity->typedId = $typedId; + + $this->dao->insertIdentity($identity, $user->id); + + $savedUser = $this->dao->findUserById($user->id); + + $this->assertEquals($user->id, $savedUser->id); + + return $savedUser; + } + +} diff --git a/views/confirm-join.php b/views/confirm-join.php index efab33def694af4a06b41c2287868792d1920843..ee4943c42891dea45ed2d533c9d656b112a4144f 100644 --- a/views/confirm-join.php +++ b/views/confirm-join.php @@ -23,7 +23,7 @@ include 'include/header.php'; <div class="row"> <div class="col-xs-12 col-md-6"> - <h4>User id: <?php echo $user->id; ?></h4> + <h4><?php echo $user->id === null ? ' ' : ('User id: ' . $user->id); ?></h4> <div class="panel"> <div class="panel-body"> <?php