Skip to content
This repository was archived by the owner on Apr 3, 2023. It is now read-only.

Commit 081437c

Browse files
author
Teddy Roncin
committed
✨ (Database tests) Added a way to backup the database and check the changes made to it
it is now possible to call the backupDatabase method from the EtuUTTApiTestCase class to make a backup, and then call the assertDatabaseSameExcept method to assert the new database and the old one are the same. Expected differences can be specified in the arguments of the function
1 parent e3506bf commit 081437c

File tree

2 files changed

+95
-23
lines changed

2 files changed

+95
-23
lines changed

tests/EtuUTTApiTestCase.php

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,20 @@
99
use Doctrine\Bundle\FixturesBundle\Fixture;
1010
use Doctrine\Common\DataFixtures\Loader;
1111
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
12+
use Doctrine\DBAL\Schema\Table;
1213
use Doctrine\ORM\EntityManager;
14+
use Symfony\Bridge\Doctrine\Types\UuidType;
15+
use Symfony\Component\Uid\Uuid;
1316

1417
abstract class EtuUTTApiTestCase extends ApiTestCase
1518
{
1619
protected EntityManager $em;
1720
protected User $user;
21+
private array $databaseBackup;
1822

1923
protected function setUp(): void
2024
{
21-
$this->em = static::getContainer()->get('doctrine.orm.entity_manager');//!->getManager();
25+
$this->em = static::getContainer()->get('doctrine.orm.entity_manager'); // !->getManager();
2226
(new ORMPurger($this->em))->purge();
2327
$this->em->clear();
2428
$this->user = $this->createUser('test', 'test', 'test', 'ROLE_ADMIN');
@@ -100,4 +104,54 @@ protected function createUser(string $firstName, string $lastName, string $login
100104
return $user;
101105
}
102106

107+
protected function backupDatabase(): void
108+
{
109+
$this->databaseBackup = [];
110+
$this->_backupDatabase($this->databaseBackup);
111+
}
112+
113+
protected function assertDatabaseSameExcept(array $diff, array $new): void
114+
{
115+
$actualDatabase = [];
116+
$this->_backupDatabase($actualDatabase);
117+
foreach ($diff as $table => ['where' => $where, 'diff' => $delta]) {
118+
foreach ($this->databaseBackup[$table] as $i => $entry) {
119+
if (!array_diff_assoc($where, $entry)) {
120+
foreach ($delta as $key => $value) {
121+
$this->databaseBackup[$table][$i][$key] = $value;
122+
}
123+
}
124+
}
125+
}
126+
foreach ($new as $table => $entries) {
127+
foreach ($entries as $entry) {
128+
$this->databaseBackup[$table][] = $entry;
129+
}
130+
}
131+
static::assertEquals($this->databaseBackup, $actualDatabase);
132+
}
133+
134+
private function _backupDatabase(array &$backup): void
135+
{
136+
$backup = [];
137+
$tables = $this->em->getConnection()->createSchemaManager()->listTables();
138+
foreach ($tables as $table) {
139+
$tableName = $table->getName();
140+
$backup[$tableName] = [];
141+
$rows = $this->em->getConnection()->prepare("SELECT * FROM {$tableName}")->executeQuery()->fetchAllAssociative();
142+
foreach ($rows as $row) {
143+
// Convert all values to printable values
144+
foreach ($row as $column => &$value) {
145+
$value = $this->getPrintableValue($table, $column, $value);
146+
}
147+
// Store the row
148+
$backup[$tableName][] = $row;
149+
}
150+
}
151+
}
152+
153+
private function getPrintableValue(Table $table, string $column, $value): ?string
154+
{
155+
return UuidType::class === $table->getColumn($column)->getType()::class && null !== $value ? Uuid::fromBinary($value)->jsonSerialize() : $value;
156+
}
103157
}

tests/Groups/UpdateGroup.php

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
namespace App\Tests\Groups;
44

55
use App\Entity\Group;
6+
use App\Repository\GroupRepository;
67
use App\Tests\EtuUTTApiTestCase;
7-
use Faker\Provider\Uuid;
8+
use Faker\Provider\Uuid as FakerUuid;
89
use Symfony\Component\HttpFoundation\Response;
910

1011
/**
@@ -18,9 +19,10 @@ public function testNormal(): void
1819
{
1920
$client = static::createClient();
2021
$client->setDefaultOptions(['headers' => ['CAS-LOGIN' => 'test', 'Content-Type' => 'application/merge-patch+json']]);
21-
$group = $this->createGroup('test', false);
22+
$group = $this->createGroup('test', false, flushDb: false);
2223
$user = $this->createUser('foo', 'bar', 'foobar');
2324
$userAdmin = $this->createUser('imthe', 'admin', 'imtheadmin');
25+
$this->backupDatabase();
2426
// Changing the group there doesn't change the group in the database anymore (even if we flush)
2527
$this->em->detach($group);
2628
$group->getDescriptionTranslation()
@@ -55,27 +57,43 @@ public function testNormal(): void
5557
})->toArray(),
5658
])]);
5759
// TODO : do something about the updatedAt field, it doesn't always work depending on the second-subdivisions (ok, i get what i mean) we are executing the test
58-
// $group->setUpdatedAt(new \DateTime());
5960
$this->assertResponseStatusCodeSame(Response::HTTP_OK);
6061
$response = json_decode($crawler->getContent());
6162
static::assertSameGroupReadOne($group, $response);
62-
// TODO : verify that the group has been updated in the database, i just don't get how doctrine works
63-
//$this->em->clear();
64-
//print("l'id c'est ".$group->getId());
65-
/*$dbGroup = $this->em->createQueryBuilder()
66-
->select('g')
67-
->from(Group::class, 'g')
68-
->innerJoin('g.descriptionTranslation', 'd')
69-
// ->where('g.id = :id')
70-
// ->setParameter('id', $group->getId())
71-
->getQuery()
72-
->getArrayResult()
73-
;*/
74-
//echo 'dans la db';
75-
//print_r($dbGroup);
76-
$dbGroup = $this->em->getRepository(Group::class)->findAll()[0];
77-
// echo "dans le truc de merde";
78-
//static::assertEquals($group, $dbGroup);
63+
$this->assertDatabaseSameExcept([
64+
'translations' => [
65+
'where' => ['id' => $group->getDescriptionTranslation()->getId()],
66+
'diff' => [
67+
'french' => $group->getDescriptionTranslation()->getFrench(),
68+
'english' => $group->getDescriptionTranslation()->getEnglish(),
69+
'spanish' => $group->getDescriptionTranslation()->getSpanish(),
70+
'german' => $group->getDescriptionTranslation()->getGerman(),
71+
'chinese' => $group->getDescriptionTranslation()->getChinese(),
72+
],
73+
],
74+
'groups' => [
75+
'where' => ['id' => $group->getId()],
76+
'diff' => [
77+
'avatar' => $group->getAvatar(),
78+
'is_visible' => $group->getIsVisible(),
79+
],
80+
],
81+
'user_timestamps' => [
82+
'where' => ['user_id' => $this->user->getId()],
83+
'diff' => [
84+
'first_login_date' => $group->getUpdatedAt()->format('Y-m-d H:i:s'),
85+
'last_login_date' => $group->getUpdatedAt()->format('Y-m-d H:i:s'),
86+
],
87+
],
88+
], [
89+
'users_groups' => [
90+
['member_id' => $user->getId(), 'group_id' => $group->getId()],
91+
['member_id' => $userAdmin->getId(), 'group_id' => $group->getId()],
92+
],
93+
'users_groups_admins' => [
94+
['admin_id' => $userAdmin->getId(), 'group_id' => $group->getId()],
95+
],
96+
]);
7997
}
8098

8199
public function testNotConnected(): void
@@ -85,15 +103,15 @@ public function testNotConnected(): void
85103
$group = $this->createGroup('group', true);
86104
$client->request('PATCH', '/groups/'.$group->getSlug(), ['body' => []]);
87105
$this->assertResponseStatusCodeSame(Response::HTTP_UNAUTHORIZED);
88-
$client->request('PATCH', '/groups/'.Uuid::uuid(), ['body' => []]);
106+
$client->request('PATCH', '/groups/'.FakerUuid::uuid(), ['body' => []]);
89107
$this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND);
90108
}
91109

92110
public function testNonExistingGroup(): void
93111
{
94112
$client = static::createClient();
95113
$client->setDefaultOptions(['headers' => ['CAS-LOGIN' => 'test', 'Content-Type' => 'application/merge-patch+json']]);
96-
$client->request('PATCH', '/groups/'.Uuid::uuid(), ['body' => []]);
114+
$client->request('PATCH', '/groups/'.FakerUuid::uuid(), ['body' => []]);
97115
$this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND);
98116
}
99117

0 commit comments

Comments
 (0)