client = self::createClient([], [ 'PHP_AUTH_USER' => 'center a_social', 'PHP_AUTH_PW' => 'password', ]); } public function dataGenerateNewAccompanyingCourse() { self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $period = new AccompanyingPeriod(new DateTime('1 week ago')); $user = $em->getRepository(User::class) ->findOneByUsernameCanonical('center a_social'); $period->setCreatedBy($user); //$period->setCreatedAt(new \DateTime('yesterday')); $center = $em->getRepository(Center::class) ->findOneBy(['name' => 'Center A']); $personIds = $em->createQuery('SELECT p.id FROM ' . Person::class . ' p JOIN p.centerCurrent cc' . ' WHERE cc.center = :center') ->setParameter('center', $center) ->setMaxResults(100) ->getScalarResult(); // create a random order shuffle($personIds); for ($i = 0; 2 > $i; ++$i) { $person = $em->getRepository(Person::class)->find(array_pop($personIds)); $period->addPerson($person); } $em->persist($period); $em->flush(); yield [$period]; } public function dataGenerateRandomAccompanyingCourse() { // note about max result for person query, and maxGenerated: // // in the final loop, an id is popped out of the personIds array twice: // // * one for getting the person, which will in turn provide his accompanying period; // * one for getting the personId to populate to the data manager // // Ensure to keep always $maxGenerated to the double of $maxResults. x8 is a good compromize :) $maxGenerated = 3; $maxResults = $maxGenerated * 8; self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $center = $em->getRepository(Center::class) ->findOneBy(['name' => 'Center A']); $qb = $em->createQueryBuilder(); $personIds = $qb ->select('p.id') ->distinct(true) ->from(Person::class, 'p') ->join('p.accompanyingPeriodParticipations', 'participation') ->join('participation.accompanyingPeriod', 'ap') ->join('p.centerCurrent', 'cc') ->where( $qb->expr()->eq( 'cc.center', ':center' ) ) ->andWhere( $qb->expr()->gt( 'SIZE(p.accompanyingPeriodParticipations)', 0 ) ) ->andWhere( $qb->expr()->eq('ap.step', ':step') ) ->setParameter('center', $center) ->setParameter('step', AccompanyingPeriod::STEP_CONFIRMED) ->setMaxResults($maxResults) ->getQuery() ->getScalarResult(); // create a random order shuffle($personIds); $nbGenerated = 0; while ($nbGenerated < $maxGenerated) { $id = array_pop($personIds)['id']; $person = $em->getRepository(Person::class) ->find($id); $periods = $person->getAccompanyingPeriods(); yield [array_pop($personIds)['id'], $periods[array_rand($periods)]->getId()]; ++$nbGenerated; } } public function dataGenerateRandomAccompanyingCourseWithSocialIssue() { // note about max result for person query, and maxGenerated: // // in the final loop, an id is popped out of the personIds array twice: // // * one for getting the person, which will in turn provide his accompanying period; // * one for getting the personId to populate to the data manager // // Ensure to keep always $maxGenerated to the double of $maxResults. x8 is a good compromize :) $maxGenerated = 3; $maxResults = $maxGenerated * 8; self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $center = $em->getRepository(Center::class) ->findOneBy(['name' => 'Center A']); $qb = $em->createQueryBuilder(); $personIds = $qb ->select('p.id') ->distinct(true) ->from(Person::class, 'p') ->join('p.accompanyingPeriodParticipations', 'participation') ->join('participation.accompanyingPeriod', 'ap') ->join('p.centerCurrent', 'cc') ->where( $qb->expr()->eq( 'cc.center', ':center' ) ) ->andWhere( $qb->expr()->gt( 'SIZE(p.accompanyingPeriodParticipations)', 0 ) ) ->andWhere( $qb->expr()->eq('ap.step', ':step') ) ->setParameter('center', $center) ->setParameter('step', AccompanyingPeriod::STEP_CONFIRMED) ->setMaxResults($maxResults) ->getQuery() ->getScalarResult(); // create a random order shuffle($personIds); $socialIssues = $em->createQuery('SELECT s FROM ' . SocialIssue::class . ' s ') ->setMaxResults(10) ->getResult(); $nbGenerated = 0; while ($nbGenerated < $maxGenerated) { $id = array_pop($personIds)['id']; $person = $em->getRepository(Person::class) ->find($id); $periods = $person->getAccompanyingPeriods(); yield [$periods[array_rand($periods)], $socialIssues[array_rand($socialIssues)]]; ++$nbGenerated; } } public function dataGenerateRandomRequestorValidData(): Iterator { $dataLength = 2; $maxResults = 100; self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); $center = $em->getRepository(Center::class) ->findOneBy(['name' => 'Center A']); $qb = $em->createQueryBuilder(); $personIds = $qb ->select('p.id') ->distinct(true) ->from(Person::class, 'p') ->join('p.accompanyingPeriodParticipations', 'participation') ->join('participation.accompanyingPeriod', 'ap') ->join('p.centerCurrent', 'cc') ->where( $qb->expr()->eq( 'cc.center', ':center' ) ) ->andWhere( $qb->expr()->gt( 'SIZE(p.accompanyingPeriodParticipations)', 0 ) ) ->andWhere( $qb->expr()->eq('ap.step', ':step') ) ->setParameter('center', $center) ->setParameter('step', AccompanyingPeriod::STEP_CONFIRMED) ->setMaxResults($maxResults) ->getQuery() ->getScalarResult(); // create a random order shuffle($personIds); $thirdPartyIds = $em->createQuery('SELECT t.id FROM ' . ThirdParty::class . ' t ') ->setMaxResults($maxResults) ->getScalarResult(); // create a random order shuffle($thirdPartyIds); $i = 0; while ($i <= $dataLength) { $person = $em->getRepository(Person::class) ->find(array_pop($personIds)['id']); if (count($person->getAccompanyingPeriods()) === 0) { continue; } $period = $person->getAccompanyingPeriods()[0]; yield [$period, array_pop($personIds)['id'], array_pop($thirdPartyIds)['id']]; ++$i; } } /** * @dataProvider dataGenerateRandomAccompanyingCourse */ public function testAccompanyingCourseAddParticipation(int $personId, int $periodId) { $this->markTestIncomplete('fix test with validation'); $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/participation.json', $periodId), [], // parameters [], // files [], // server parameters json_encode(['type' => 'person', 'id' => $personId], JSON_THROW_ON_ERROR) ); $response = $this->client->getResponse(); $data = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } $this->assertArrayHasKey('id', $data); $this->assertArrayHasKey('startDate', $data); $this->assertNotNull($data['startDate']); // check by deownloading the accompanying cours $this->client->request(Request::METHOD_GET, sprintf('/api/1.0/person/accompanying-course/%d.json', $periodId)); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } $response = $this->client->getResponse(); $data = json_decode((string) $response->getContent(), null, 512, JSON_THROW_ON_ERROR); // check that the person id is contained $participationsPersonsIds = array_map( static fn ($participation) => $participation->person->id, $data->participations ); $this->assertContains($personId, $participationsPersonsIds); // check removing the participation $this->client->request( Request::METHOD_DELETE, sprintf('/api/1.0/person/accompanying-course/%d/participation.json', $periodId), [], // parameters [], // files [], // server parameters json_encode(['type' => 'person', 'id' => $personId], JSON_THROW_ON_ERROR) ); $response = $this->client->getResponse(); $data = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } $this->assertArrayHasKey('id', $data); $this->assertArrayHasKey('startDate', $data); $this->assertNotNull($data['startDate']); $this->assertArrayHasKey('endDate', $data); $this->assertNotNull($data['endDate']); } /** * @dataProvider dataGenerateRandomAccompanyingCourseWithSocialIssue */ public function testAccompanyingCourseAddRemoveSocialIssue(AccompanyingPeriod $period, SocialIssue $si) { $this->markTestIncomplete('fix test with validation'); $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/socialissue.json', $period->getId()), [], [], [], json_encode(['type' => 'social_issue', 'id' => $si->getId()], JSON_THROW_ON_ERROR) ); $this->assertTrue(in_array($this->client->getResponse()->getStatusCode(), [200, 422], true)); if ($this->client->getResponse()->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } $data = json_decode((string) $this->client->getResponse()->getContent(), true, 512, JSON_THROW_ON_ERROR); $this->assertArrayHasKey('id', $data); $this->assertArrayHasKey('type', $data); $this->assertEquals('social_issue', $data['type']); $this->client->request( Request::METHOD_DELETE, sprintf('/api/1.0/person/accompanying-course/%d/socialissue.json', $period->getId()), [], [], [], json_encode(['type' => 'social_issue', 'id' => $si->getId()], JSON_THROW_ON_ERROR) ); $this->assertTrue(in_array($this->client->getResponse()->getStatusCode(), [200, 422], true)); } /** * @dataProvider dataGenerateRandomAccompanyingCourse */ public function testAccompanyingCourseShow(int $personId, int $periodId) { $c = $this->client->request(Request::METHOD_GET, sprintf('/api/1.0/person/accompanying-course/%d.json', $periodId)); $response = $this->client->getResponse(); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } $data = json_decode((string) $response->getContent(), null, 512, JSON_THROW_ON_ERROR); $this->assertEquals( $data->id, $periodId, "test that the response's data contains the id of the period" ); $this->assertGreaterThan(0, $data->participations); } /** * @dataProvider dataGenerateRandomAccompanyingCourse */ public function testAccompanyingPeriodPatch(int $personId, int $periodId) { $this->markTestIncomplete('fix test with validation'); $period = self::$container->get(AccompanyingPeriodRepository::class) ->find($periodId); $initialValueEmergency = $period->isEmergency(); $em = self::$container->get(EntityManagerInterface::class); $this->client->request( Request::METHOD_PATCH, sprintf('/api/1.0/person/accompanying-course/%d.json', $periodId), [], // parameters [], // files [], // server parameters json_encode(['type' => 'accompanying_period', 'emergency' => !$initialValueEmergency], JSON_THROW_ON_ERROR) ); $response = $this->client->getResponse(); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } $period = $em->getRepository(AccompanyingPeriod::class) ->find($periodId); $this->assertEquals(!$initialValueEmergency, $period->isEmergency()); // restore the initial value $period->setEmergency($initialValueEmergency); $em->flush(); } /** * @dataProvider dataGenerateRandomRequestorValidData */ public function testCommentWithValidData(AccompanyingPeriod $period, mixed $personId, mixed $thirdPartyId) { $this->markTestIncomplete('fix test with validation'); $em = self::$container->get(EntityManagerInterface::class); $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/comment.json', $period->getId()), [], // parameters [], // files [], // server parameters json_encode(['type' => 'accompanying_period_comment', 'content' => 'this is a text']) ); $response = $this->client->getResponse(); $data = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } $this->assertArrayHasKey('id', $data); $this->client->request( Request::METHOD_DELETE, sprintf('/api/1.0/person/accompanying-course/%d/comment.json', $period->getId()), [], // parameters [], // files [], // server parameters json_encode(['type' => 'accompanying_period_comment', 'id' => $data['id']], JSON_THROW_ON_ERROR) ); $response = $this->client->getResponse(); $data = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); } /** * @dataProvider dataGenerateNewAccompanyingCourse */ public function testConfirm(AccompanyingPeriod $period) { $this->markTestIncomplete('fix test with validation'); $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/confirm.json', $period->getId()) ); $this->assertTrue(in_array($this->client->getResponse()->getStatusCode(), [200, 422], true)); if ($this->client->getResponse()->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } // add period to remove it in tear down $this->period = $period; } /** * @dataProvider dataGenerateRandomAccompanyingCourse */ public function testReferralAvailable(int $personId, int $periodId) { $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/referrers-suggested.json', $periodId) ); $this->assertTrue(in_array($this->client->getResponse()->getStatusCode(), [200, 422], true)); } /** * @dataProvider dataGenerateRandomRequestorValidData */ public function testRequestorWithValidData(AccompanyingPeriod $period, mixed $personId, mixed $thirdPartyId) { $this->markTestIncomplete('fix test with validation'); $em = self::$container->get(EntityManagerInterface::class); // post a person $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/requestor.json', $period->getId()), [], // parameters [], // files [], // server parameters json_encode(['type' => 'person', 'id' => $personId], JSON_THROW_ON_ERROR) ); $response = $this->client->getResponse(); $data = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } $this->assertArrayHasKey('id', $data); $this->assertEquals($personId, $data['id']); // check into database $period = $em->getRepository(AccompanyingPeriod::class) ->find($period->getId()); $this->assertInstanceOf(Person::class, $period->getRequestor()); $this->assertEquals($personId, $period->getRequestor()->getId()); // post a third party $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/requestor.json', $period->getId()), [], // parameters [], // files [], // server parameters json_encode(['type' => 'thirdparty', 'id' => $thirdPartyId], JSON_THROW_ON_ERROR) ); $response = $this->client->getResponse(); $data = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } $this->assertArrayHasKey('id', $data); $this->assertEquals($thirdPartyId, $data['id']); // check into database $period = $em->getRepository(AccompanyingPeriod::class) ->find($period->getId()); $this->assertInstanceOf(ThirdParty::class, $period->getRequestor()); $this->assertEquals($thirdPartyId, $period->getRequestor()->getId()); // remove the requestor $this->client->request( Request::METHOD_DELETE, sprintf('/api/1.0/person/accompanying-course/%d/requestor.json', $period->getId()) ); $response = $this->client->getResponse(); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } // check into database $period = $em->getRepository(AccompanyingPeriod::class) ->find($period->getId()); $em->refresh($period); $this->assertNull($period->getRequestor()); } /** * @dataProvider dataGenerateRandomRequestorValidData */ public function testResourceWithValidData(AccompanyingPeriod $period, mixed $personId, mixed $thirdPartyId) { $this->markTestIncomplete('fix test with validation'); $em = self::$container->get(EntityManagerInterface::class); // post a person $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/resource.json', $period->getId()), [], // parameters [], // files [], // server parameters json_encode(['type' => 'accompanying_period_resource', 'resource' => ['type' => 'person', 'id' => $personId]]) ); $response = $this->client->getResponse(); $data = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } $this->assertArrayHasKey('id', $data); $this->assertEquals($personId, $data['resource']['id']); // check into database $resource = $em->getRepository(Resource::class) ->find($data['id']); $this->assertInstanceOf(Resource::class, $resource); $this->assertInstanceOf(Person::class, $resource->getResource()); $this->assertEquals($personId, $resource->getResource()->getId()); // remove the resource $this->client->request( Request::METHOD_DELETE, sprintf('/api/1.0/person/accompanying-course/%d/requestor.json', $period->getId()), [], [], [], //server json_encode(['type' => 'accompanying_period_resource', 'id' => $resource->getId()], JSON_THROW_ON_ERROR) ); $response = $this->client->getResponse(); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } // post a third party $this->client->request( Request::METHOD_POST, sprintf('/api/1.0/person/accompanying-course/%d/resource.json', $period->getId()), [], // parameters [], // files [], // server parameters json_encode(['type' => 'accompanying_period_resource', 'resource' => ['type' => 'thirdparty', 'id' => $thirdPartyId]]) ); $response = $this->client->getResponse(); $data = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); if ($response->getStatusCode() === 422) { $this->markTestSkipped('the next tests should appears only on valid accompanying period'); } $this->assertArrayHasKey('id', $data); $this->assertEquals($thirdPartyId, $data['resource']['id']); // check into database $resource = $em->getRepository(Resource::class) ->find($data['id']); $this->assertInstanceOf(Resource::class, $resource); $this->assertInstanceOf(ThirdParty::class, $resource->getResource()); $this->assertEquals($thirdPartyId, $resource->getResource()->getId()); // remove the resource $this->client->request( Request::METHOD_DELETE, sprintf('/api/1.0/person/accompanying-course/%d/requestor.json', $period->getId()), [], [], [], //server json_encode(['type' => 'accompanying_period_resource', 'id' => $resource->getId()], JSON_THROW_ON_ERROR) ); $response = $this->client->getResponse(); $this->assertTrue(in_array($response->getStatusCode(), [200, 422], true)); } public function testShow404() { $this->client->request(Request::METHOD_GET, sprintf('/api/1.0/person/accompanying-course/%d.json', 99999)); $response = $this->client->getResponse(); $this->assertEquals(404, $response->getStatusCode(), "Test that the response of rest api has a status code 'not found' (404)"); } }