|
|
@@ -2,21 +2,42 @@
|
|
|
|
|
|
namespace App\Tests\Application;
|
|
|
|
|
|
-use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
|
|
|
-use ApiPlatform\Symfony\Bundle\Test\Client;
|
|
|
+use DateTime;
|
|
|
+use Zenstruck\Foundry\Proxy;
|
|
|
use App\Entity\Access\Access;
|
|
|
+use App\Enum\Core\TimeZoneEnum;
|
|
|
+use App\Enum\Education\CycleEnum;
|
|
|
+use App\Enum\Booking\VisibilityEnum;
|
|
|
use App\Enum\Organization\LegalEnum;
|
|
|
+use App\Enum\Core\ContactPointTypeEnum;
|
|
|
+use App\Enum\Education\PeriodicityEnum;
|
|
|
+use Doctrine\ORM\EntityManagerInterface;
|
|
|
+use ApiPlatform\Symfony\Bundle\Test\Client;
|
|
|
use App\Enum\Organization\PrincipalTypeEnum;
|
|
|
+use App\Enum\Organization\BulletinOutputEnum;
|
|
|
+use App\Enum\Organization\BulletinPeriodEnum;
|
|
|
+use App\Enum\Organization\SendToBulletinEnum;
|
|
|
+use Symfony\Component\HttpFoundation\Request;
|
|
|
use App\Enum\Organization\SettingsProductEnum;
|
|
|
+use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
|
|
|
+use Doctrine\Common\DataFixtures\Purger\ORMPurger;
|
|
|
use App\Tests\Fixture\Factory\Access\AccessFactory;
|
|
|
-use App\Tests\Fixture\Factory\Organization\OrganizationFactory;
|
|
|
-use App\Tests\Fixture\Factory\Organization\SettingsFactory;
|
|
|
+use App\Tests\Fixture\Factory\Booking\EventFactory;
|
|
|
+use App\Tests\Fixture\Factory\Network\NetworkFactory;
|
|
|
use App\Tests\Fixture\Factory\Person\PersonFactory;
|
|
|
-use Doctrine\Common\DataFixtures\Purger\ORMPurger;
|
|
|
-use Doctrine\ORM\EntityManagerInterface;
|
|
|
-use Symfony\Component\HttpFoundation\Request;
|
|
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
|
|
-use Zenstruck\Foundry\Proxy;
|
|
|
+use App\Tests\Fixture\Factory\Education\CycleFactory;
|
|
|
+use App\Tests\Fixture\Factory\Core\ContactPointFactory;
|
|
|
+use App\Enum\Education\AdvancedEducationNotationTypeEnum;
|
|
|
+use App\Tests\Fixture\Factory\Billing\ResidenceAreaFactory;
|
|
|
+use App\Tests\Fixture\Factory\Mobyt\MobytUserStatusFactory;
|
|
|
+use App\Tests\Fixture\Factory\Organization\SettingsFactory;
|
|
|
+use App\Tests\Fixture\Factory\Billing\BillingSettingFactory;
|
|
|
+use App\Tests\Fixture\Factory\Organization\SubdomainFactory;
|
|
|
+use App\Tests\Fixture\Factory\Organization\ParametersFactory;
|
|
|
+use App\Tests\Fixture\Factory\Education\EducationTimingFactory;
|
|
|
+use App\Tests\Fixture\Factory\Network\NetworkOrganizationFactory;
|
|
|
+use App\Tests\Fixture\Factory\Organization\OrganizationFactory;
|
|
|
|
|
|
/**
|
|
|
* Base class for applicative tests.
|
|
|
@@ -35,6 +56,7 @@ abstract class OtWebTestCase extends ApiTestCase
|
|
|
*/
|
|
|
public function setup(): void
|
|
|
{
|
|
|
+
|
|
|
// Boot le kernel symfony et récupère l'entity manager
|
|
|
// @see https://symfony.com/doc/current/testing.html#retrieving-services-in-the-test
|
|
|
self::bootKernel();
|
|
|
@@ -52,13 +74,14 @@ abstract class OtWebTestCase extends ApiTestCase
|
|
|
$this->client = static::createClient();
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Delete all DB records before populating fixtures.
|
|
|
- *
|
|
|
- * @return void
|
|
|
- *
|
|
|
- * @throws \Doctrine\DBAL\Exception
|
|
|
- */
|
|
|
+ public function loadSchema()
|
|
|
+ {
|
|
|
+ $command = 'bin/console --env=staging doctrine:schema:update --force';
|
|
|
+ $output = shell_exec($command);
|
|
|
+ echo $output;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
private function purgeDb()
|
|
|
{
|
|
|
if (!preg_match('/.*test.*/', $this->em->getConnection()->getDatabase())) {
|
|
|
@@ -69,9 +92,32 @@ abstract class OtWebTestCase extends ApiTestCase
|
|
|
$purger = new ORMPurger($this->em);
|
|
|
$purger->setPurgeMode(ORMPurger::PURGE_MODE_DELETE);
|
|
|
$purger->purge();
|
|
|
+
|
|
|
+ $this->resetAutoIncrement();
|
|
|
+
|
|
|
$this->em->getConnection()->exec('SET FOREIGN_KEY_CHECKS = 1;');
|
|
|
}
|
|
|
|
|
|
+ private function resetAutoIncrement()
|
|
|
+ {
|
|
|
+ $connection = $this->em->getConnection();
|
|
|
+ $schemaManager = $connection->getSchemaManager();
|
|
|
+
|
|
|
+ foreach ($schemaManager->listTableNames() as $tableName) {
|
|
|
+ $connection->executeStatement("ALTER TABLE $tableName AUTO_INCREMENT = 1;");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private function resetAutoIncrement()
|
|
|
+ {
|
|
|
+ $connection = $this->em->getConnection();
|
|
|
+ $schemaManager = $connection->getSchemaManager();
|
|
|
+
|
|
|
+ foreach ($schemaManager->listTableNames() as $tableName) {
|
|
|
+ $connection->executeStatement("ALTER TABLE $tableName AUTO_INCREMENT = 1;");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Create and persist the fixtures (do not flush).
|
|
|
*
|
|
|
@@ -81,27 +127,238 @@ abstract class OtWebTestCase extends ApiTestCase
|
|
|
{
|
|
|
$person = PersonFactory::createOne(
|
|
|
[
|
|
|
- 'username' => 'username',
|
|
|
- 'password' => 'password',
|
|
|
- ]
|
|
|
+ 'username' => 'username',
|
|
|
+ 'password' => 'password'
|
|
|
+ ]
|
|
|
);
|
|
|
|
|
|
+ $personOfOtherOrganization = PersonFactory::createOne(
|
|
|
+ [
|
|
|
+ 'username' => 'intruOfRoot',
|
|
|
+ 'password' => 'password'
|
|
|
+ ]
|
|
|
+ );
|
|
|
+
|
|
|
+ $contactPoint = ContactPointFactory::createOne([
|
|
|
+ 'contactType' => ContactPointTypeEnum::PRINCIPAL
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $parameters = ParametersFactory::createOne([
|
|
|
+ 'educationPeriodicity' => PeriodicityEnum::MONTHLY,
|
|
|
+ 'financialDate' => new DateTime(),
|
|
|
+ 'musicalDate' => new DateTime(),
|
|
|
+ 'startCourseDate' => new DateTime(),
|
|
|
+ 'endCourseDate' => new DateTime(),
|
|
|
+ 'average' => 20,
|
|
|
+ 'editCriteriaNotationByAdminOnly' => true,
|
|
|
+ 'smsSenderName' => 'MySender',
|
|
|
+ 'logoDonorsMove' => false,
|
|
|
+ 'subDomain' => 'subdomain',
|
|
|
+ 'website' => 'https://www.example.com',
|
|
|
+ 'otherWebsite' => 'https://www.otherwebsite.com',
|
|
|
+ 'customDomain' => 'https://www.customdomain.com',
|
|
|
+ 'desactivateOpentalentSiteWeb' => false,
|
|
|
+ 'bulletinPeriod' => BulletinPeriodEnum::YEAR,
|
|
|
+ 'bulletinWithTeacher' => false,
|
|
|
+ 'bulletinPrintAddress' => false,
|
|
|
+ 'bulletinSignatureDirector' => true,
|
|
|
+ 'bulletinDisplayLevelAcquired' => true,
|
|
|
+ 'bulletinShowEducationWithoutEvaluation' => false,
|
|
|
+ 'bulletinViewTestResults' => false,
|
|
|
+ 'bulletinShowAbsences' => false,
|
|
|
+ 'bulletinShowAverages' => true,
|
|
|
+ 'bulletinOutput' => BulletinOutputEnum::SEND_BY_EMAIL,
|
|
|
+ 'bulletinEditWithoutEvaluation' => true,
|
|
|
+ 'bulletinReceiver' => SendToBulletinEnum::STUDENTS_AND_THEIR_GUARDIANS,
|
|
|
+ 'usernameSMS' => '2iosinterne',
|
|
|
+ 'passwordSMS' => '2iosot74',
|
|
|
+ 'showAdherentList' => true,
|
|
|
+ 'studentsAreAdherents' => false,
|
|
|
+ 'timezone' => TimeZoneEnum::EUROPE_PARIS,
|
|
|
+ 'advancedEducationNotationType' => AdvancedEducationNotationTypeEnum::BY_EDUCATION,
|
|
|
+ 'sendAttendanceEmail' => true,
|
|
|
+ 'sendAttendanceSms' => true,
|
|
|
+ 'generateAttendanceReport' => true,
|
|
|
+ 'consultPedagogicResult' => true,
|
|
|
+ 'consultTeacherListing' => true,
|
|
|
+ 'periodValidation' => true,
|
|
|
+
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $parameters2 = ParametersFactory::createOne([
|
|
|
+ 'educationPeriodicity' => PeriodicityEnum::MONTHLY,
|
|
|
+ 'financialDate' => new DateTime(),
|
|
|
+ 'musicalDate' => new DateTime(),
|
|
|
+ 'startCourseDate' => new DateTime(),
|
|
|
+ 'endCourseDate' => new DateTime(),
|
|
|
+ 'average' => 20,
|
|
|
+ 'editCriteriaNotationByAdminOnly' => true,
|
|
|
+ 'smsSenderName' => 'toto',
|
|
|
+ 'logoDonorsMove' => false,
|
|
|
+ 'subDomain' => 'subdomain',
|
|
|
+ 'website' => 'https://www.toto.com',
|
|
|
+ 'otherWebsite' => 'https://www.toto.com',
|
|
|
+ 'customDomain' => 'https://www.toto.com',
|
|
|
+ 'desactivateOpentalentSiteWeb' => false,
|
|
|
+ 'bulletinPeriod' => BulletinPeriodEnum::YEAR,
|
|
|
+ 'bulletinWithTeacher' => false,
|
|
|
+ 'bulletinPrintAddress' => false,
|
|
|
+ 'bulletinSignatureDirector' => true,
|
|
|
+ 'bulletinDisplayLevelAcquired' => true,
|
|
|
+ 'bulletinShowEducationWithoutEvaluation' => false,
|
|
|
+ 'bulletinViewTestResults' => false,
|
|
|
+ 'bulletinShowAbsences' => false,
|
|
|
+ 'bulletinShowAverages' => true,
|
|
|
+ 'bulletinOutput' => BulletinOutputEnum::SEND_BY_EMAIL,
|
|
|
+ 'bulletinEditWithoutEvaluation' => true,
|
|
|
+ 'bulletinReceiver' => SendToBulletinEnum::STUDENTS_AND_THEIR_GUARDIANS,
|
|
|
+ 'usernameSMS' => 'toto',
|
|
|
+ 'passwordSMS' => 'toto',
|
|
|
+ 'showAdherentList' => true,
|
|
|
+ 'studentsAreAdherents' => false,
|
|
|
+ 'timezone' => TimeZoneEnum::EUROPE_PARIS,
|
|
|
+ 'advancedEducationNotationType' => AdvancedEducationNotationTypeEnum::BY_EDUCATION,
|
|
|
+ 'sendAttendanceEmail' => true,
|
|
|
+ 'sendAttendanceSms' => true,
|
|
|
+ 'generateAttendanceReport' => true,
|
|
|
+ 'consultPedagogicResult' => true,
|
|
|
+ 'consultTeacherListing' => true,
|
|
|
+ 'periodValidation' => true,
|
|
|
+
|
|
|
+ ]);
|
|
|
+
|
|
|
+
|
|
|
$organization = OrganizationFactory::createOne([
|
|
|
- 'legalStatus' => LegalEnum::ASSOCIATION_LAW_1901()->getValue(),
|
|
|
- 'principalType' => PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY()->getValue(),
|
|
|
- 'name' => 'My Organization',
|
|
|
+ 'legalStatus' => LegalEnum::ASSOCIATION_LAW_1901,
|
|
|
+ 'principalType' => PrincipalTypeEnum::NATIONAL_FEDERATION,
|
|
|
+ 'name' => 'Root',
|
|
|
+ 'parameters' => $parameters,
|
|
|
+ 'siretNumber' => '34919841600035',
|
|
|
+ 'identifier' => 'FR042100000050',
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $network1 = NetworkFactory::createOne([
|
|
|
+ 'name' => 'Network 1',
|
|
|
+ 'logo' => 'logo',
|
|
|
+ 'url' => 'https://www.network1.com',
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $network2 = NetworkFactory::createOne([
|
|
|
+ 'name' => 'Network 2',
|
|
|
+ 'logo' => 'logo',
|
|
|
+ 'url' => 'https://www.network2.com',
|
|
|
+ ]);
|
|
|
+
|
|
|
+
|
|
|
+ $cmfNetwork = NetworkFactory::createOne([
|
|
|
+ 'name' => 'CMF',
|
|
|
+ 'logo' => 'logo',
|
|
|
+ 'url' => 'https://www.cmf.com',
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $networkOrganization = NetworkOrganizationFactory::createOne([
|
|
|
+ 'network' => $cmfNetwork,
|
|
|
+ 'organization' => $organization,
|
|
|
+ 'startDate' => new DateTime('2001-01-01'),
|
|
|
+ 'endDate' => new DateTime('2031-12-31'),
|
|
|
+ 'leadingCause' => 'leadingCause'
|
|
|
+ ]);
|
|
|
+
|
|
|
+
|
|
|
+ $billingSetting = BillingSettingFactory::createOne([
|
|
|
+ 'organization' => $organization,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $residenceArea = ResidenceAreaFactory::createOne([
|
|
|
+ 'label' => 'Résidence 1',
|
|
|
+ 'billingSetting' => $billingSetting,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $organization2 = OrganizationFactory::createOne([
|
|
|
+ 'legalStatus' => LegalEnum::ASSOCIATION_LAW_1901,
|
|
|
+ 'principalType' => PrincipalTypeEnum::NATIONAL_FEDERATION,
|
|
|
+ 'name' => 'Other Organization',
|
|
|
+ 'parameters' => $parameters2,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $settings2 = SettingsFactory::createOne([
|
|
|
+ 'product' => SettingsProductEnum::SCHOOL_PREMIUM,
|
|
|
+ 'organization' => $organization2,
|
|
|
+ 'modules' => ['BillingAdministration']
|
|
|
+ ]);
|
|
|
+ $mobyteUserStatus = MobytUserStatusFactory::createOne([
|
|
|
+ 'organizationId' => $organization->getId(),
|
|
|
+ 'active' => true,
|
|
|
+ 'amount' => 100,
|
|
|
+ 'money' => 100
|
|
|
]);
|
|
|
|
|
|
- SettingsFactory::createOne([
|
|
|
- 'product' => SettingsProductEnum::ARTIST(),
|
|
|
- 'organization' => $organization,
|
|
|
+ $cycle = CycleFactory::createOne([
|
|
|
+ 'organization' => $organization,
|
|
|
+ 'label' => 'Cycle 1',
|
|
|
+ 'cycleEnum' => CycleEnum::CYCLE_1
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $settings = SettingsFactory::createOne([
|
|
|
+ 'product' => SettingsProductEnum::SCHOOL_PREMIUM,
|
|
|
+ 'organization' => $organization,
|
|
|
+ 'modules' => [
|
|
|
+ 'Sms' => true,
|
|
|
+ // 'BillingAdministration' => true,
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $educationTimings = EducationTimingFactory::createOne([
|
|
|
+ 'organization' => $organization,
|
|
|
+ 'timing' => 45
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $educationTimings2 = EducationTimingFactory::createOne([
|
|
|
+ 'organization' => $organization2,
|
|
|
+ 'timing' => 60
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $subdomain = SubdomainFactory::createOne([
|
|
|
+ 'organization' => $organization,
|
|
|
+ 'subdomain' => 'subdomain',
|
|
|
+ 'active' => true
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $event = EventFactory::createOne([
|
|
|
+ 'organization' => $organization,
|
|
|
+ 'name' => 'My event',
|
|
|
+ 'datetimeStart' => new \DateTime(),
|
|
|
+ 'datetimeEnd' => new \DateTime(),
|
|
|
+ 'visibility' => VisibilityEnum::PUBLIC_VISIBILITY
|
|
|
]);
|
|
|
|
|
|
$this->user = AccessFactory::createOne([
|
|
|
- 'person' => $person,
|
|
|
- 'organization' => $organization,
|
|
|
- 'roles' => ['ROLE_USERS_VIEW'],
|
|
|
+ 'person' => $person,
|
|
|
+ 'organization' => $organization,
|
|
|
+ 'roles' => ["ROLE_ADMIN","ROLE_ADMIN_CORE","ROLE_SUPER_ADMIN", "ROLE_ORGANIZATION_VIEW","ROLE_ORGANIZATION" ],
|
|
|
+ 'adminAccess' => true,
|
|
|
+ 'activityYear' => 2021
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $student = PersonFactory::createOne([
|
|
|
+ 'username' => 'student',
|
|
|
+ 'password' => 'password'
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $accessWithNoRole = AccessFactory::createOne([
|
|
|
+ 'person' => $student,
|
|
|
+ 'organization' => $organization,
|
|
|
+ 'roles' => ["ROLE_STUDENT"],
|
|
|
+ 'adminAccess' => false
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $acccesFromOtherOrganization = AccessFactory::createOne([
|
|
|
+ 'person' => $personOfOtherOrganization,
|
|
|
+ 'organization' => $organization2,
|
|
|
+ 'roles' => ["ROLE_ADMIN","ROLE_ADMIN_CORE","ROLE_SUPER_ADMIN", "ROLE_ORGANIZATION_VIEW","ROLE_ORGANIZATION" ],
|
|
|
+ 'adminAccess' => true,
|
|
|
]);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -110,7 +367,7 @@ abstract class OtWebTestCase extends ApiTestCase
|
|
|
* @param array<mixed> $data
|
|
|
* @param array<mixed> $headers
|
|
|
*/
|
|
|
- protected function request(string $method, string $route, ?array $data = null, array $headers = []): ResponseInterface
|
|
|
+ protected function request(string $method, string $route, array | null $data = null, array $headers = []): ResponseInterface
|
|
|
{
|
|
|
if ($this->user) {
|
|
|
$headers = array_merge(
|
|
|
@@ -201,14 +458,50 @@ abstract class OtWebTestCase extends ApiTestCase
|
|
|
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
|
|
|
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
|
|
|
*/
|
|
|
- protected function loginAs(Proxy|Access $access): void
|
|
|
+ public function loginAs()
|
|
|
{
|
|
|
- $person = $access->getPerson();
|
|
|
+ $access = $this->em->getRepository(Access::class)->find(1);
|
|
|
+ $person = $access->getPerson();
|
|
|
|
|
|
$response = $this->post(
|
|
|
'/login_check',
|
|
|
['username' => $person->getUsername(), 'password' => $person->getPassword()]
|
|
|
);
|
|
|
+
|
|
|
+ $content = $response->getContent();
|
|
|
+
|
|
|
+ $decodedContent = json_decode($content);
|
|
|
+
|
|
|
+ // Vérifier que le token est présent
|
|
|
+ if (!isset($decodedContent->token)) {
|
|
|
+ throw new \Exception("Token not found in response");
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->securityToken = $decodedContent->token;
|
|
|
+ $this->user = $access;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Login as the given Access user
|
|
|
+ *
|
|
|
+ * @param Proxy|Access $access
|
|
|
+ * @return void
|
|
|
+ * @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
|
|
|
+ * @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
|
|
|
+ * @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
|
|
|
+ * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
|
|
|
+ */
|
|
|
+ public function loginAsStudent()
|
|
|
+ {
|
|
|
+ // on récupère l'access qui a l'id 641003 dans l'entity manager
|
|
|
+ $access = $this->em->getRepository(Access::class)->find(2);
|
|
|
+ $person = $access->getPerson();
|
|
|
+
|
|
|
+ $response = $this->post(
|
|
|
+ '/login_check',
|
|
|
+ ['username' => $person->getUsername(), 'password' => $person->getPassword()]
|
|
|
+ );
|
|
|
+
|
|
|
$content = $response->getContent();
|
|
|
|
|
|
$this->securityToken = json_decode($content)->token;
|
|
|
@@ -216,7 +509,38 @@ abstract class OtWebTestCase extends ApiTestCase
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Assert that the response has the expected status code and is well formated.
|
|
|
+ * Login as the given Access user
|
|
|
+ *
|
|
|
+ * @param Proxy|Access $access
|
|
|
+ * @return void
|
|
|
+ * @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
|
|
|
+ * @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
|
|
|
+ * @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
|
|
|
+ * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
|
|
|
+ */
|
|
|
+ public function loginAsintruOfRoot()
|
|
|
+ {
|
|
|
+ $access = $this->em->getRepository(Access::class)->find(3);
|
|
|
+ $person = $access->getPerson();
|
|
|
+
|
|
|
+ $response = $this->post(
|
|
|
+ '/login_check',
|
|
|
+ ['username' => $person->getUsername(), 'password' => $person->getPassword()]
|
|
|
+ );
|
|
|
+
|
|
|
+ $content = $response->getContent();
|
|
|
+
|
|
|
+ $this->securityToken = json_decode($content)->token;
|
|
|
+ $this->user = $access;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Assert that the response has the expected status code and is well formated
|
|
|
+ *
|
|
|
+ * @param string $resourceClass
|
|
|
+ * @param int $expectedStatus
|
|
|
+ * @return void
|
|
|
*/
|
|
|
protected function validateCollectionSchema(string $resourceClass, int $expectedStatus = 200): void
|
|
|
{
|