Easy_solution/tests/Controller/OrganizationControllerTest.php

360 lines
13 KiB
PHP

<?php
namespace App\Tests\Controller;
use App\Entity\Apps;
use App\Entity\Organizations;
use App\Entity\Roles;
use App\Entity\UserOrganizatonApp;
use App\Entity\UsersOrganizations;
use App\Service\AwsService;
use App\Tests\Functional\AbstractFunctionalTest;
use PHPUnit\Framework\Attributes\Test;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class OrganizationControllerTest extends AbstractFunctionalTest
{
//region INDEX tests
#[Test]
public function test_index_super_admin_success(): void
{
// 1. Arrange
$admin = $this->createUser('sAdmin@test.com', ['ROLE_SUPER_ADMIN']);
$this->client->loginUser($admin);
// Create at least one org so 'hasOrganizations' becomes true
$this->createOrganization('Organization 1');
$this->createOrganization('Organization 2');
$this->client->request('GET', '/organization/');
self::assertResponseIsSuccessful();
self::assertSelectorTextNotContains('body', 'Aucune organisation trouvée');
self::assertSelectorExists('#tabulator-org');
}
#[Test]
public function test_index_regular_user_forbidden(): void
{
// 1. Arrange
$user = $this->createUser('user@mail.com');
$this->client->loginUser($user);
// 2. Act
$this->client->request('GET', '/organization/');
// 3. Assert
self::assertResponseStatusCodeSame(403);
}
#[Test]
public function test_index_no_organizations(): void
{
// 1. Arrange
$admin = $this->createUser('user@mail.com', ['ROLE_SUPER_ADMIN']);
$this->client->loginUser($admin);
// 2. Act
$this->client->request('GET', '/organization/');
// 3. Assert
self::assertResponseIsSuccessful();
self::assertSelectorTextContains('body', 'Aucune organisation trouvée');
}
//endregion
//region CREATE tests
#[Test]
public function test_create_super_admin_success(): void
{
// 1. Arrange: Disable reboot to keep our AWS mock alive
$this->client->disableReboot();
$admin = $this->createUser('admin@user.com', ['ROLE_SUPER_ADMIN']);
$this->client->loginUser($admin);
// 2. MOCK AWS Service (Crucial!)
// Your code calls $awsService->PutDocObj, so we must intercept that.
// 2. MOCK AWS Service
$awsMock = $this->createMock(AwsService::class);
$awsMock->expects($this->any())
->method('PutDocObj')
->willReturn(1); // <--- FIXED: Return an integer, not a boolean
// Inject the mock into the test container
static::getContainer()->set(AwsService::class, $awsMock);
// 3. Create a Dummy Image File
$tempFile = tempnam(sys_get_temp_dir(), 'test_logo');
file_put_contents($tempFile, 'fake image content'); // Create a dummy file
$logo = new UploadedFile(
$tempFile,
'logo.png',
'image/png',
null,
true // 'test' mode = true
);
// 4. Act: Request the page
$this->client->request('GET', '/organization/create');
// 5. Submit Form with the FILE object and correct field name 'logoUrl'
$this->client->submitForm('Enregistrer', [
'organization_form[name]' => 'New Organization',
'organization_form[email]' => 'unique-' . uniqid('', true) . '@test.com',
'organization_form[address]' => '123 Test Street',
'organization_form[number]' => '0102030405',
'organization_form[logoUrl]' => $logo, // Pass the OBJECT, not a string
]);
// 6. Assert
// Check for redirect (302)
self::assertResponseRedirects('/organization/');
$this->client->followRedirect();
// Ensure we see the success state
self::assertSelectorTextNotContains('body', 'Aucune organisation trouvée');
self::assertSelectorExists('#tabulator-org');
}
#[Test]
public function test_create_regular_user_forbidden(): void
{
// 1. Arrange
$user = $this->createUser('user@email.com');
$this->client->loginUser($user);
// 2. Act
$this->client->request('GET', '/organization/create');
// 3. Assert
self::assertResponseStatusCodeSame(403);
}
#[Test]
public function test_create_super_admin_invalid_data(): void
{
// 1. Arrange
$admin = $this->createUser('admin@email.com', ['ROLE_SUPER_ADMIN']);
$this->client->loginUser($admin);
// 2. Act
$this->client->request('GET', '/organization/create');
$this->client->submitForm('Enregistrer', [
'organization_form[name]' => '', // Invalid: name is required
'organization_form[email]' => 'not-an-email', // Invalid email format
'organization_form[address]' => '123 Test St',
'organization_form[number]' => '0102030405',
]);
// 3. Assert
self::assertResponseIsSuccessful(); // Form isn't redirected
}
#[Test]
public function test_create_super_admin_duplicate_email(): void
{
// 1. Arrange
$admin = $this->createUser('admin@email.com', ['ROLE_SUPER_ADMIN']);
$this->client->loginUser($admin);
$existingOrg = $this->createOrganization('Existing Org');
// 2. Act
$this->client->request('GET', '/organization/create');
$this->client->submitForm('Enregistrer', [
'organization_form[name]' => 'New Org',
'organization_form[email]' => $existingOrg->getEmail(), // Duplicate email
'organization_form[address]' => '123 Test St',
'organization_form[number]' => '0102030405',
]);
// 3. Assert
self::assertResponseIsSuccessful(); // Form isn't redirected
self::assertSelectorTextContains('body', 'Une organisation avec cet email existe déjà.');
}
//endregion
//region EDIT tests
#[Test]
public function test_edit_super_admin_success(): void
{
// 1. Arrange: Disable reboot to keep our AWS mock alive
$this->client->disableReboot();
$admin = $this->createUser('admin@user.com', ['ROLE_SUPER_ADMIN']);
$this->client->loginUser($admin);
// 2. MOCK AWS Service (Crucial!)
// Your code calls $awsService->PutDocObj, so we must intercept that.
// 2. MOCK AWS Service
$awsMock = $this->createMock(AwsService::class);
$awsMock->expects($this->any())
->method('PutDocObj')
->willReturn(1); // <--- FIXED: Return an integer, not a boolean
// Inject the mock into the test container
static::getContainer()->set(AwsService::class, $awsMock);
// 3. Create a Dummy Image File
$tempFile = tempnam(sys_get_temp_dir(), 'test_logo');
file_put_contents($tempFile, 'fake image content'); // Create a dummy file
$logo = new UploadedFile(
$tempFile,
'logo.png',
'image/png',
null,
true // 'test' mode = true
);
// Create an organization to edit
$organization = $this->createOrganization('Org to Edit');
// 4. Act: Request the edit page
$this->client->request('GET', '/organization/edit/' . $organization->getId());
// 5. Submit Form with the FILE object and correct field name 'logoUrl'
$this->client->submitForm('Enregistrer', [
'organization_form[name]' => 'Edited Organization',
'organization_form[email]' => 'edited-' . uniqid('', true) . '@test.com',
'organization_form[address]' => '456 Edited Street',
'organization_form[number]' => '0504030201',
'organization_form[logoUrl]' => $logo, // Pass the OBJECT, not a
]);
// 6. Assert
// Check for redirect (302)
self::assertResponseRedirects('/organization/');
$this->client->followRedirect();
// Ensure we see the success state
self::assertSelectorTextNotContains('body', 'Aucune organisation trouvée');
self::assertSelectorExists('#tabulator-org');
}
#[Test]
public function test_edit_regular_user_forbidden(): void
{
// 1. Arrange
$user = $this->createUser('user@email.com');
$this->client->loginUser($user);
// Create an organization to edit
$organization = $this->createOrganization('Org to Edit');
// 2. Act
$this->client->request('GET', '/organization/edit/' . $organization->getId());
// 3. Assert
self::assertResponseStatusCodeSame(403);
}
#[Test]
public function test_edit_super_admin_invalid_data(): void
{
// 1. Arrange
$admin = $this->createUser('admin@mail.com', ['ROLE_SUPER_ADMIN']);
$this->client->loginUser($admin);
// Create an organization to edit
$organization = $this->createOrganization('Org to Edit');
// 2. Act
$this->client->request('GET', '/organization/edit/' . $organization->getId());
$this->client->submitForm('Enregistrer', [
'organization_form[name]' => '', // Invalid: name is required
'organization_form[email]' => 'not-an-email', // Invalid email format
'organization_form[address]' => '123 Test St',
'organization_form[number]' => '0102030405',
]);
// 3. Assert
self::assertResponseIsSuccessful(); // Form isn't redirected
}
#[Test]
public function test_edit_nonexistent_organization_not_found(): void
{
// 1. Arrange
$admin = $this->createUser('admin@mail.com', ['ROLE_SUPER_ADMIN']);
$this->client->loginUser($admin);
// 2. Act
$this->client->request('GET', '/organization/edit/99999'); // Assuming
// 3. Assert
self::assertResponseStatusCodeSame(302);
self::assertResponseRedirects('/organization/');
}
//endregion
//region DELETE tests
#[Test]
public function test_delete_super_admin_success(): void
{
// 1. Arrange
$admin = $this->createUser('admin@email.com', ['ROLE_SUPER_ADMIN']);
$this->client->loginUser($admin);
$organization = $this->createOrganization('Org to Delete');
// 2. Act
$this->client->request('POST', '/organization/delete/' . $organization->getId());
// 3. Assert
self::assertResponseRedirects('/organization/');
$this->client->followRedirect();
self::assertSelectorTextNotContains('body', 'Org to Delete');
self::assertTrue($this->entityManager->getRepository(Organizations::class)->find($organization->getId())->isDeleted());
}
#[Test]
public function test_delete_regular_user_forbidden(): void
{
// 1. Arrange
$user = $this->createUser('user@mail.com');
$this->client->loginUser($user);
$organization = $this->createOrganization('Org to Delete');
// 2. Act
$this->client->request('POST', '/organization/delete/' . $organization->getId());
// 3. Assert
self::assertResponseStatusCodeSame(403);
}
#[Test]
public function test_delete_nonexistent_organization_not_found(): void
{
// 1. Arrange
$admin = $this->createUser('admin@user.com', ['ROLE_SUPER_ADMIN']);
$this->client->loginUser($admin);
// 2. Act
$this->client->request('POST', '/organization/delete/99999'); // Assuming
// 3. Assert
self::assertResponseStatusCodeSame(404);
}
#[Test]
public function test_delete_organization_with_dependencies(): void
{
// 1. Arrange
$admin = $this->createUser('user@admin.com', ['ROLE_SUPER_ADMIN']);
$this->client->loginUser($admin);
$organization = $this->createOrganization('Org with Deps');
$app = $this->createApp('Dependent App');
$role = $this->createRole('ROLE_USER');
$uoLink = $this->createUOLink($admin, $organization);
$uoaLink = $this->createUOALink($uoLink, $app, $role);
// 2. Act
$this->client->request('POST', '/organization/delete/' . $organization->getId());
// 3. Assert
self::assertResponseRedirects('/organization/');
$this->client->followRedirect();
self::assertSelectorTextContains('body', 'Aucune organisation trouvée');
//link should be deactivated, not deleted
self::assertCount(1, $this->entityManager->getRepository(Apps::class)->findAll());
self::assertCount(1, $this->entityManager->getRepository(Roles::class)->findAll());
self::assertCount(1, $this->entityManager->getRepository(UsersOrganizations::class)->findAll());
self::assertCount(1, $this->entityManager->getRepository(UserOrganizatonApp::class)->findAll());
self::assertTrue($this->entityManager->getRepository(Organizations::class)->find($organization->getId())->isDeleted());
self::assertFalse($this->entityManager->getRepository(UserOrganizatonApp::class)->find($uoLink->getId())->isActive());
self::assertFalse($this->entityManager->getRepository(UserOrganizatonApp::class)->find($uoaLink->getId())->isActive());
self::assertSelectorNotExists('#tabulator-org');
}
//endregion
}