Abstract all project test to BaseTest
This commit is contained in:
@@ -5,11 +5,12 @@ namespace App\Tests\Entity\ProjectApi;
|
||||
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
|
||||
use ApiPlatform\Symfony\Bundle\Test\Client;
|
||||
use App\Entity\Project\Category;
|
||||
use App\Entity\Project\Project;
|
||||
use App\Entity\Project\ProjectDeadline;
|
||||
use App\Entity\Project\ProjectStatus;
|
||||
use App\Entity\Project\ProjectTerritory;
|
||||
use App\Entity\User\User;
|
||||
use App\Factory\Project\ProjectFactory;
|
||||
use App\Factory\User\UserFactory;
|
||||
use App\Tests\Traits\TestHelperTrait;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Zenstruck\Foundry\Test\Factories;
|
||||
@@ -19,14 +20,17 @@ abstract class BaseTest extends ApiTestCase
|
||||
{
|
||||
use ResetDatabase;
|
||||
use Factories;
|
||||
use TestHelperTrait;
|
||||
|
||||
protected EntityManagerInterface $entityManager;
|
||||
|
||||
private const USER_EMAIL = 'testuser@example.com';
|
||||
private const USER_PASSWORD = 'projectapitestuserpassword';
|
||||
private const BASE_URI = '/v4/projects';
|
||||
protected const BASE_URI = '/v4/projects';
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
self::bootKernel();
|
||||
|
||||
$this->entityManager = static::getContainer()->get(EntityManagerInterface::class);
|
||||
@@ -49,25 +53,20 @@ abstract class BaseTest extends ApiTestCase
|
||||
return self::BASE_URI.$param;
|
||||
}
|
||||
|
||||
protected function getRequestOptions(Client $client)
|
||||
{
|
||||
return ['headers' => $this->getHeaders($client)];
|
||||
}
|
||||
|
||||
protected function createTestUser(
|
||||
string $handle = 'test_user',
|
||||
string $email = self::USER_EMAIL,
|
||||
): User {
|
||||
$user = new User();
|
||||
$user->setHandle($handle);
|
||||
$user->setEmail($email);
|
||||
$passwordHasher = static::getContainer()->get('security.user_password_hasher');
|
||||
$user->setPassword($passwordHasher->hashPassword($user, self::USER_PASSWORD));
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
protected function prepareTestUser(?User $user = null): void
|
||||
{
|
||||
$user ??= $this->createTestUser();
|
||||
|
||||
$this->entityManager->persist($user);
|
||||
$this->entityManager->flush();
|
||||
) {
|
||||
return UserFactory::createOne([
|
||||
'handle' => $handle,
|
||||
'email' => $email,
|
||||
'password' => self::USER_PASSWORD,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getExampleProjectData(): array
|
||||
@@ -84,60 +83,31 @@ abstract class BaseTest extends ApiTestCase
|
||||
];
|
||||
}
|
||||
|
||||
protected function createTestProject(): Project
|
||||
protected function createTestProjectOptimized(int $count = 1, array $attributes = []): array
|
||||
{
|
||||
$example = $this->getExampleProjectData();
|
||||
$owner = $this->createTestUser();
|
||||
$territory = new ProjectTerritory('ES');
|
||||
|
||||
$project = new Project();
|
||||
$project->setTitle($example['title']);
|
||||
$project->setSubtitle($example['subtitle']);
|
||||
$project->setCategory($example['category']);
|
||||
$project->setTerritory(new ProjectTerritory($example['territory']['country']));
|
||||
$project->setDescription($example['description']);
|
||||
$project->setDeadline($example['deadline']);
|
||||
$project->setOwner($this->createTestUser());
|
||||
$project->setStatus($example['status']);
|
||||
$mergedAttributes = array_merge([
|
||||
'owner' => $owner,
|
||||
'territory' => $territory,
|
||||
], $attributes);
|
||||
|
||||
return $project;
|
||||
}
|
||||
|
||||
protected function prepareTestProject(?Project $project = null): void
|
||||
{
|
||||
$project ??= $this->createTestProject();
|
||||
|
||||
$this->entityManager->persist($project);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
protected function getValidToken(Client $client): string
|
||||
{
|
||||
$client->request(
|
||||
'POST',
|
||||
'/v4/user_tokens',
|
||||
[
|
||||
'json' => [
|
||||
'identifier' => self::USER_EMAIL,
|
||||
'password' => self::USER_PASSWORD,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
return json_decode($client->getResponse()->getContent(), true)['token'];
|
||||
return ProjectFactory::createMany($count, $mergedAttributes);
|
||||
}
|
||||
|
||||
protected function getHeaders(Client $client): array
|
||||
{
|
||||
return [
|
||||
'Authorization' => 'Bearer '.$this->getValidToken($client),
|
||||
'Content-Type' => 'application/json',
|
||||
];
|
||||
$method = $this->getMethod();
|
||||
|
||||
return $this->getAuthHeaders($client, self::USER_EMAIL, self::USER_PASSWORD, $method);
|
||||
}
|
||||
|
||||
// Auxiliary Tests
|
||||
|
||||
protected function testOneNotFound(): void
|
||||
{
|
||||
$this->prepareTestProject();
|
||||
$this->createTestProjectOptimized(1);
|
||||
|
||||
$client = static::createClient();
|
||||
$client->request(
|
||||
@@ -184,15 +154,13 @@ abstract class BaseTest extends ApiTestCase
|
||||
protected function testForbidden(): void
|
||||
{
|
||||
$otherUser = $this->createTestUser('other_user', 'otheruser@example.com');
|
||||
$otherProject = $this->createTestProject()->setOwner($otherUser);
|
||||
$this->entityManager->persist($otherProject);
|
||||
$this->prepareTestUser();
|
||||
$this->createTestProjectOptimized(1, ['owner' => $otherUser]);
|
||||
|
||||
$client = static::createClient();
|
||||
$client->request(
|
||||
$this->getMethod(),
|
||||
$this->getUri(1),
|
||||
['headers' => $this->getHeaders($client)]
|
||||
$this->getRequestOptions($client)
|
||||
);
|
||||
|
||||
$this->assertResponseStatusCodeSame(Response::HTTP_FORBIDDEN);
|
||||
|
||||
@@ -2,13 +2,10 @@
|
||||
|
||||
namespace App\Tests\Entity\ProjectApi;
|
||||
|
||||
use ApiPlatform\Symfony\Bundle\Test\Client;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class CreateTest extends BaseTest
|
||||
{
|
||||
private const URI = '/v4/projects';
|
||||
|
||||
// Auxiliary functions
|
||||
|
||||
protected function getMethod(): string
|
||||
@@ -16,13 +13,6 @@ class CreateTest extends BaseTest
|
||||
return 'POST';
|
||||
}
|
||||
|
||||
protected function getHeaders(Client $client): array
|
||||
{
|
||||
$this->prepareTestUser();
|
||||
|
||||
return parent::getHeaders($client);
|
||||
}
|
||||
|
||||
private function assertProjectData(array $expectedData, array $responseData): void
|
||||
{
|
||||
$this->assertArrayHasKey('id', $responseData);
|
||||
@@ -60,7 +50,8 @@ class CreateTest extends BaseTest
|
||||
|
||||
$requestData = array_merge($requestData, $setData);
|
||||
|
||||
$this->testInsert($requestData, self::URI, $expectedCode);
|
||||
$this->createTestUser();
|
||||
$this->testInsert($requestData, self::BASE_URI, $expectedCode);
|
||||
}
|
||||
|
||||
private function testPostWithInvalidInput(array $invalidData): void
|
||||
@@ -79,6 +70,8 @@ class CreateTest extends BaseTest
|
||||
|
||||
public function testPostWithValidToken(): void
|
||||
{
|
||||
$this->createTestUser();
|
||||
|
||||
$expectedData = [
|
||||
'title' => 'New Education Project',
|
||||
'subtitle' => 'Education for the Future',
|
||||
@@ -90,7 +83,7 @@ class CreateTest extends BaseTest
|
||||
];
|
||||
|
||||
$client = static::createClient();
|
||||
$client->request('POST', self::URI, [
|
||||
$client->request('POST', self::BASE_URI, [
|
||||
'headers' => $this->getHeaders($client),
|
||||
'json' => $expectedData,
|
||||
]);
|
||||
@@ -102,6 +95,8 @@ class CreateTest extends BaseTest
|
||||
|
||||
public function testPostWithoutMandatoryField(): void
|
||||
{
|
||||
$this->createTestUser();
|
||||
|
||||
// Expected data without the 'title' field
|
||||
$requestData = [
|
||||
'subtitle' => 'Education for the Future',
|
||||
@@ -113,7 +108,7 @@ class CreateTest extends BaseTest
|
||||
];
|
||||
|
||||
$client = static::createClient();
|
||||
$client->request('POST', self::URI, [
|
||||
$client->request('POST', self::BASE_URI, [
|
||||
'headers' => $this->getHeaders($client),
|
||||
'json' => $requestData,
|
||||
]);
|
||||
@@ -154,7 +149,7 @@ class CreateTest extends BaseTest
|
||||
|
||||
$client->request(
|
||||
'POST',
|
||||
self::URI,
|
||||
self::BASE_URI,
|
||||
[
|
||||
'json' => [
|
||||
'title' => 'ProjectApiTest Project',
|
||||
|
||||
@@ -15,17 +15,17 @@ class DeleteTest extends BaseTest
|
||||
|
||||
public function testDeleteWithValidToken(): void
|
||||
{
|
||||
$this->prepareTestProject();
|
||||
$this->createTestProjectOptimized();
|
||||
|
||||
$client = static::createClient();
|
||||
$client->request('DELETE', $this->getUri(1), ['headers' => $this->getHeaders($client)]);
|
||||
$client->request('DELETE', $this->getUri(1), $this->getRequestOptions($client));
|
||||
|
||||
$this->assertResponseStatusCodeSame(Response::HTTP_NO_CONTENT);
|
||||
}
|
||||
|
||||
public function testDeleteUnauthorized()
|
||||
{
|
||||
$this->prepareTestProject();
|
||||
$this->createTestProjectOptimized();
|
||||
|
||||
static::createClient()->request('DELETE', $this->getUri(1));
|
||||
|
||||
|
||||
@@ -2,79 +2,29 @@
|
||||
|
||||
namespace App\Tests\Entity\ProjectApi;
|
||||
|
||||
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
|
||||
use ApiPlatform\Symfony\Bundle\Test\Client;
|
||||
use App\Entity\Project\Category;
|
||||
use App\Entity\Project\ProjectStatus;
|
||||
use App\Entity\Project\ProjectTerritory;
|
||||
use App\Factory\Project\ProjectFactory;
|
||||
use App\Factory\User\UserFactory;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Zenstruck\Foundry\Test\Factories;
|
||||
use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
|
||||
class GetAllTest extends ApiTestCase
|
||||
class GetAllTest extends BaseTest
|
||||
{
|
||||
use ResetDatabase;
|
||||
use Factories;
|
||||
protected EntityManagerInterface $entityManager;
|
||||
|
||||
private const USER_EMAIL = 'testuser@example.com';
|
||||
private const USER_PASSWORD = 'projectapitestuserpassword';
|
||||
private const BASE_URI = '/v4/projects';
|
||||
private const METHOD = 'GET';
|
||||
|
||||
private const PAGE_SIZE = 30;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
self::bootKernel();
|
||||
|
||||
$this->entityManager = static::getContainer()->get(EntityManagerInterface::class);
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
// Auxiliary functions
|
||||
|
||||
private function createTestUser()
|
||||
protected function getMethod(): string
|
||||
{
|
||||
return UserFactory::createOne([
|
||||
'email' => self::USER_EMAIL,
|
||||
'password' => self::USER_PASSWORD,
|
||||
]);
|
||||
}
|
||||
|
||||
private function createTestProjectOptimized(int $count, array $attributes = [])
|
||||
{
|
||||
$owner = $this->createTestUser();
|
||||
$territory = new ProjectTerritory('ES');
|
||||
|
||||
$mergedAttributes = array_merge([
|
||||
'owner' => $owner,
|
||||
'territory' => $territory,
|
||||
], $attributes);
|
||||
|
||||
ProjectFactory::createMany($count, $mergedAttributes);
|
||||
}
|
||||
|
||||
private function getHeaders(Client $client)
|
||||
{
|
||||
// Responsability 1: Get Token
|
||||
$client->request(
|
||||
'POST',
|
||||
'/v4/user_tokens',
|
||||
[
|
||||
'json' => [
|
||||
'identifier' => self::USER_EMAIL,
|
||||
'password' => self::USER_PASSWORD,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$token = json_decode($client->getResponse()->getContent(), true)['token'];
|
||||
|
||||
// Responsability 2 : Return headers
|
||||
return ['headers' => ['Authorization' => "Bearer $token"]];
|
||||
return 'GET';
|
||||
}
|
||||
|
||||
private function getMinNumInPage($page = 1, $pageSize = self::PAGE_SIZE)
|
||||
@@ -114,7 +64,7 @@ class GetAllTest extends ApiTestCase
|
||||
|
||||
$uri = self::BASE_URI."?$param=$valueName";
|
||||
$client = static::createClient();
|
||||
$client->request(self::METHOD, $uri, $this->getHeaders($client));
|
||||
$client->request($this->getMethod(), $uri, $this->getRequestOptions($client));
|
||||
|
||||
$this->assertResponseStatusCodeSame($responseCode);
|
||||
|
||||
@@ -145,7 +95,7 @@ class GetAllTest extends ApiTestCase
|
||||
|
||||
$uri = self::BASE_URI.'?'.$queryParams;
|
||||
$client = static::createClient();
|
||||
$client->request(self::METHOD, $uri, $this->getHeaders($client));
|
||||
$client->request($this->getMethod(), $uri, $this->getRequestOptions($client));
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
@@ -162,7 +112,11 @@ class GetAllTest extends ApiTestCase
|
||||
ProjectFactory::createMany($numberOfProjects, ['owner' => $owner]);
|
||||
|
||||
$client = static::createClient();
|
||||
$client->request(self::METHOD, self::BASE_URI, $this->getHeaders($client));
|
||||
$client->request(
|
||||
$$this->getMethod()(),
|
||||
self::BASE_URI,
|
||||
['headers' => $this->getHeaders($client)]
|
||||
);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
@@ -182,9 +136,9 @@ class GetAllTest extends ApiTestCase
|
||||
|
||||
$client = static::createClient();
|
||||
$client->request(
|
||||
self::METHOD,
|
||||
$this->getMethod(),
|
||||
self::BASE_URI."?page=$page&itemsPerPage=$itemsPerPage",
|
||||
$this->getHeaders($client)
|
||||
['headers' => $this->getHeaders($client)]
|
||||
);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
@@ -205,9 +159,9 @@ class GetAllTest extends ApiTestCase
|
||||
|
||||
$client = static::createClient();
|
||||
$client->request(
|
||||
self::METHOD,
|
||||
$this->getMethod(),
|
||||
self::BASE_URI."?itemsPerPage=$itemsPerPage",
|
||||
$this->getHeaders($client)
|
||||
['headers' => $this->getHeaders($client)]
|
||||
);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
@@ -241,7 +195,7 @@ class GetAllTest extends ApiTestCase
|
||||
$category = 'invalid_category';
|
||||
$uri = self::BASE_URI."?category=$category";
|
||||
$client = static::createClient();
|
||||
$client->request(self::METHOD, $uri, $this->getHeaders($client));
|
||||
$client->request($this->getMethod(), $uri, ['headers' => $this->getHeaders($client)]);
|
||||
|
||||
$responseCode = Response::HTTP_OK;
|
||||
$this->assertResponseStatusCodeSame($responseCode);
|
||||
@@ -260,7 +214,7 @@ class GetAllTest extends ApiTestCase
|
||||
|
||||
$uri = self::BASE_URI.'?title=NotFound';
|
||||
$client = static::createClient();
|
||||
$client->request(self::METHOD, $uri, $this->getHeaders($client));
|
||||
$client->request($this->getMethod(), $uri, ['headers' => $this->getHeaders($client)]);
|
||||
|
||||
$this->assertResponseStatusCodeSame(Response::HTTP_OK);
|
||||
|
||||
@@ -311,7 +265,7 @@ class GetAllTest extends ApiTestCase
|
||||
$this->createTestProjectOptimized(1);
|
||||
|
||||
$client = static::createClient();
|
||||
$client->request('GET', self::BASE_URI, $this->getHeaders($client));
|
||||
$client->request('GET', self::BASE_URI, ['headers' => $this->getHeaders($client)]);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
@@ -330,7 +284,7 @@ class GetAllTest extends ApiTestCase
|
||||
|
||||
public function testGetAllUnauthorized(): void
|
||||
{
|
||||
static::createClient()->request(self::METHOD, self::BASE_URI);
|
||||
static::createClient()->request($this->getMethod(), self::BASE_URI);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
}
|
||||
@@ -338,7 +292,7 @@ class GetAllTest extends ApiTestCase
|
||||
public function testGetAllWithInvalidToken(): void
|
||||
{
|
||||
static::createClient()->request(
|
||||
self::METHOD,
|
||||
$this->getMethod(),
|
||||
self::BASE_URI,
|
||||
['headers' => ['Authorization' => 'Bearer 123']]
|
||||
);
|
||||
|
||||
@@ -42,8 +42,6 @@ class GetOneTest extends BaseTest
|
||||
|
||||
private function testSuccessfulGetOneBase(Project $project): void
|
||||
{
|
||||
$this->prepareTestProject($project);
|
||||
|
||||
$client = static::createClient();
|
||||
$client->request('GET', $this->getUri(1), ['headers' => $this->getHeaders($client)]);
|
||||
|
||||
@@ -54,7 +52,7 @@ class GetOneTest extends BaseTest
|
||||
|
||||
private function testGetOneFilteredByStatus(ProjectStatus $status): void
|
||||
{
|
||||
$project = $this->createTestProject()->setStatus($status);
|
||||
$project = $this->createTestProjectOptimized(1, ['status' => $status])[0];
|
||||
|
||||
$this->testSuccessfulGetOneBase($project);
|
||||
}
|
||||
@@ -63,7 +61,7 @@ class GetOneTest extends BaseTest
|
||||
|
||||
public function testGetOneWithValidToken(): void
|
||||
{
|
||||
$project = $this->createTestProject();
|
||||
$project = $this->createTestProjectOptimized(1)[0];
|
||||
|
||||
$this->testSuccessfulGetOneBase($project);
|
||||
}
|
||||
@@ -80,7 +78,7 @@ class GetOneTest extends BaseTest
|
||||
|
||||
public function testGetOneUnauthorized(): void
|
||||
{
|
||||
$this->prepareTestProject();
|
||||
$this->createTestProjectOptimized(1);
|
||||
|
||||
static::createClient()->request('GET', $this->getUri(1));
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Tests\Entity\ProjectApi;
|
||||
|
||||
use ApiPlatform\Symfony\Bundle\Test\Client;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class UpdateTest extends BaseTest
|
||||
@@ -14,19 +13,11 @@ class UpdateTest extends BaseTest
|
||||
return 'PATCH';
|
||||
}
|
||||
|
||||
protected function getHeaders(Client $client): array
|
||||
{
|
||||
return [
|
||||
'Authorization' => 'Bearer '.$this->getValidToken($client),
|
||||
'Content-Type' => 'application/merge-patch+json',
|
||||
];
|
||||
}
|
||||
|
||||
// Runable Tests
|
||||
|
||||
public function testUpdateSuccessful(): void
|
||||
{
|
||||
$this->prepareTestProject();
|
||||
$this->createTestProjectOptimized();
|
||||
|
||||
$dataToModify = [
|
||||
'title' => 'New project title',
|
||||
@@ -38,7 +29,7 @@ class UpdateTest extends BaseTest
|
||||
|
||||
public function testUpdateUnauthorized(): void
|
||||
{
|
||||
$this->prepareTestProject();
|
||||
$this->createTestProjectOptimized();
|
||||
|
||||
static::createClient()->request($this->getMethod(), $this->getUri(1));
|
||||
|
||||
@@ -57,7 +48,7 @@ class UpdateTest extends BaseTest
|
||||
|
||||
public function testUpdateInvalidInput(): void
|
||||
{
|
||||
$this->prepareTestProject();
|
||||
$this->createTestProjectOptimized();
|
||||
$invalidInput = [
|
||||
'title' => 'New project title',
|
||||
'category' => 'invalid-category',
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Traits;
|
||||
|
||||
use ApiPlatform\Symfony\Bundle\Test\Client;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
trait TestHelperTrait
|
||||
{
|
||||
protected function getValidToken(Client $client, string $email, string $password): string
|
||||
{
|
||||
$client->request(
|
||||
'POST',
|
||||
'/v4/user_tokens',
|
||||
[
|
||||
'json' => [
|
||||
'identifier' => $email,
|
||||
'password' => $password,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
return json_decode($client->getResponse()->getContent(), true)['token'];
|
||||
}
|
||||
|
||||
protected function getAuthHeaders(
|
||||
Client $client,
|
||||
string $email,
|
||||
string $password,
|
||||
string $method = 'GET',
|
||||
): array {
|
||||
$contentType = $method == 'PATCH' ? 'application/merge-patch+json' : 'application/json';
|
||||
|
||||
return [
|
||||
'Authorization' => 'Bearer '.$this->getValidToken($client, $email, $password),
|
||||
'Content-Type' => $contentType,
|
||||
];
|
||||
}
|
||||
|
||||
protected function testInvalidToken(
|
||||
string $uri,
|
||||
string $contentType = 'application/json',
|
||||
int $expectedToken = Response::HTTP_UNAUTHORIZED,
|
||||
): void {
|
||||
static::createClient()->request(
|
||||
$this->getMethod(),
|
||||
$uri,
|
||||
['headers' => [
|
||||
'Authorization' => 'Bearer invalid_token',
|
||||
'Content-Type' => $contentType,
|
||||
]]
|
||||
);
|
||||
|
||||
$this->assertResponseStatusCodeSame($expectedToken);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user