diff --git a/config/routes/api.yaml b/config/routes/api.yaml index d9ef2aa4..1a40d1fe 100644 --- a/config/routes/api.yaml +++ b/config/routes/api.yaml @@ -3,6 +3,12 @@ api_example: prefix: /api name_prefix: api_example_ +api_activity_area: + resource: 'api/activity-area.yaml' + prefix: /api/activity-areas + name_prefix: api_activity_area_ + trailing_slash_on_root: false + api_agents: resource: 'api/agent.yaml' prefix: /api/agents diff --git a/config/routes/api/activity-area.yaml b/config/routes/api/activity-area.yaml new file mode 100644 index 00000000..90fe6773 --- /dev/null +++ b/config/routes/api/activity-area.yaml @@ -0,0 +1,14 @@ +get: + path: /{id} + controller: App\Controller\Api\ActivityAreaApiController::get + methods: ['GET'] + +list: + path: / + controller: App\Controller\Api\ActivityAreaApiController::list + methods: ['GET'] + +remove: + path: /{id} + controller: App\Controller\Api\ActivityAreaApiController::remove + methods: ['DELETE'] diff --git a/public/docs/components/paths/activity-area/Collection.yaml b/public/docs/components/paths/activity-area/Collection.yaml new file mode 100644 index 00000000..e97cc494 --- /dev/null +++ b/public/docs/components/paths/activity-area/Collection.yaml @@ -0,0 +1,14 @@ +get: + tags: + - Áreas de Atividade + summary: Recupera uma lista de áreas de atividade + responses: + '200': + description: Lista de áreas de atividade + content: + application/json: + schema: + type: array + items: + allOf: + - $ref: '../../responses/activity-area/ActivityAreaGetCollectionResponse.yaml' diff --git a/public/docs/components/paths/activity-area/Item.yaml b/public/docs/components/paths/activity-area/Item.yaml new file mode 100644 index 00000000..2bce068a --- /dev/null +++ b/public/docs/components/paths/activity-area/Item.yaml @@ -0,0 +1,37 @@ +get: + parameters: + - $ref: '../../parameters/path/id.yaml' + tags: + - Áreas de Atividade + summary: Recupera uma única área de atividade + responses: + '200': + description: Área de atividade encontrada + content: + application/json: + schema: + $ref: '../../responses/activity-area/ActivityAreaGetItemResponse.yaml' + '404': + description: Área de atividade não encontrada + content: + application/json: + schema: + $ref: '../../responses/activity-area/ActivityAreaNotFound.yaml' + +delete: + parameters: + - $ref: '../../parameters/path/id.yaml' + tags: + - Áreas de Atividade + summary: Remove uma única área de atividade + responses: + '204': + description: Não possui conteúdo de resposta + content: + application/json: {} + '404': + description: Área de atividade não encontrada + content: + application/json: + schema: + $ref: '../../responses/activity-area/ActivityAreaNotFound.yaml' diff --git a/public/docs/components/responses/activity-area/ActivityAreaGetCollectionResponse.yaml b/public/docs/components/responses/activity-area/ActivityAreaGetCollectionResponse.yaml new file mode 100644 index 00000000..43c9f4ce --- /dev/null +++ b/public/docs/components/responses/activity-area/ActivityAreaGetCollectionResponse.yaml @@ -0,0 +1,3 @@ +type: object +allOf: + - $ref: './CommonDefinitions.yaml#/ActivityAreaBase' diff --git a/public/docs/components/responses/activity-area/ActivityAreaGetItemResponse.yaml b/public/docs/components/responses/activity-area/ActivityAreaGetItemResponse.yaml new file mode 100644 index 00000000..43c9f4ce --- /dev/null +++ b/public/docs/components/responses/activity-area/ActivityAreaGetItemResponse.yaml @@ -0,0 +1,3 @@ +type: object +allOf: + - $ref: './CommonDefinitions.yaml#/ActivityAreaBase' diff --git a/public/docs/components/responses/activity-area/ActivityAreaNotFound.yaml b/public/docs/components/responses/activity-area/ActivityAreaNotFound.yaml new file mode 100644 index 00000000..4c5dc621 --- /dev/null +++ b/public/docs/components/responses/activity-area/ActivityAreaNotFound.yaml @@ -0,0 +1,11 @@ +type: object +properties: + error_message: + type: string + default: "not_found" + error_details: + type: object + properties: + description: + type: string + default: "The requested ActivityArea was not found." diff --git a/public/docs/components/responses/activity-area/CommonDefinitions.yaml b/public/docs/components/responses/activity-area/CommonDefinitions.yaml new file mode 100644 index 00000000..4b0dfc9b --- /dev/null +++ b/public/docs/components/responses/activity-area/CommonDefinitions.yaml @@ -0,0 +1,13 @@ +ActivityAreaBase: + type: object + properties: + id: + type: string + format: uuid + description: "Identificador único da área de atividade." + example: "123e4567-e89b-12d3-a456-426614174000" + name: + type: string + maxLength: 20 + description: "Nome da área de atividade." + example: "Teatro" diff --git a/public/docs/components/schemas/activity-area.yaml b/public/docs/components/schemas/activity-area.yaml new file mode 100644 index 00000000..cbcc45d2 --- /dev/null +++ b/public/docs/components/schemas/activity-area.yaml @@ -0,0 +1,12 @@ +type: object +properties: + id: + type: string + format: uuid + description: "Identificador único da área de atividade." + example: "123e4567-e89b-12d3-a456-426614174000" + name: + type: string + maxLength: 20 + description: "Nome da área de atividade." + example: "Teatro" diff --git a/public/docs/openapi.yaml b/public/docs/openapi.yaml index b221beae..b20e86dd 100644 --- a/public/docs/openapi.yaml +++ b/public/docs/openapi.yaml @@ -4,6 +4,7 @@ info: description: |- API responsável por praticamente todas as funcionalidades de gerenciamento: - Agentes + - Áreas de atividade - Espaços - Eventos - Faqs @@ -30,6 +31,8 @@ tags: description: Endpoints relacionados a autorização - name: Agentes description: Endpoints relacionados aos agentes + - name: Áreas de Atividade + description: Endpoints relacionados às áreas de atividade - name: Espaços description: Endpoints relacionados aos espaços - name: Eventos @@ -53,6 +56,10 @@ tags: - name: Usuários description: Endpoints relacionados aos usuários paths: + /activity-areas: + $ref: './components/paths/activity-area/Collection.yaml' + /activity-areas/{id}: + $ref: './components/paths/activity-area/Item.yaml' /agents: $ref: './components/paths/agent/Collection.yaml' /agents/{id}: @@ -117,6 +124,8 @@ paths: $ref: './components/paths/user/Item.yaml' components: schemas: + ActivityArea: + $ref: './components/schemas/activity-area.yaml' Agent: $ref: './components/schemas/agent.yaml' Event: diff --git a/src/Controller/Api/ActivityAreaApiController.php b/src/Controller/Api/ActivityAreaApiController.php new file mode 100644 index 00000000..a39e002f --- /dev/null +++ b/src/Controller/Api/ActivityAreaApiController.php @@ -0,0 +1,44 @@ +service->get($id); + + return $this->json($activityArea, context: ['groups' => ['activity-area.get', 'activity-area.get.item']]); + } + + public function list(): JsonResponse + { + return $this->json($this->service->list(), context: [ + 'groups' => 'activity-area.get', + AbstractNormalizer::CALLBACKS => [ + 'parent' => [EntityIdNormalizerHelper::class, 'normalizeEntityId'], + ], + ]); + } + + public function remove(?Uuid $id): JsonResponse + { + $this->service->remove($id); + + return $this->json(data: [], status: Response::HTTP_NO_CONTENT); + } +} diff --git a/src/DataFixtures/Entity/ActivityAreaFixtures.php b/src/DataFixtures/Entity/ActivityAreaFixtures.php index 5de7c8f8..362d173e 100644 --- a/src/DataFixtures/Entity/ActivityAreaFixtures.php +++ b/src/DataFixtures/Entity/ActivityAreaFixtures.php @@ -85,7 +85,9 @@ private function createActivityAreas(ObjectManager $manager): void { foreach (self::ACTIVITY_AREAS as $activityAreaData) { $activityArea = $this->serializer->denormalize($activityAreaData, ActivityArea::class); - $this->setReference(self::ACTIVITY_AREA_ID_PREFIX.$activityAreaData['id'], $activityArea); + + $this->setReference(sprintf('%s-%s', self::ACTIVITY_AREA_ID_PREFIX, $activityAreaData['id']), $activityArea); + $manager->persist($activityArea); } diff --git a/src/Entity/ActivityArea.php b/src/Entity/ActivityArea.php index 0712cc84..faa409ae 100644 --- a/src/Entity/ActivityArea.php +++ b/src/Entity/ActivityArea.php @@ -15,11 +15,11 @@ class ActivityArea { #[ORM\Id] #[ORM\Column(type: UuidType::NAME)] - #[Groups(['space.get', 'space.get.item', 'activity_area.get'])] + #[Groups(['space.get', 'space.get.item', 'activity-area.get', 'activity-area.get.item'])] private ?Uuid $id = null; #[ORM\Column(length: 20)] - #[Groups(['space.get', 'space.get.item', 'activity_area.get'])] + #[Groups(['space.get', 'space.get.item', 'activity-area.get', 'activity-area.get.item'])] private ?string $name = null; public function getId(): ?Uuid diff --git a/src/Entity/Space.php b/src/Entity/Space.php index 80515a10..0e215266 100644 --- a/src/Entity/Space.php +++ b/src/Entity/Space.php @@ -22,7 +22,7 @@ class Space extends AbstractEntity { #[ORM\Id] #[ORM\Column(type: UuidType::NAME)] - #[Groups(['event.get', 'initiative.get', 'opportunity.get', 'space.get', 'activity_area.get'])] + #[Groups(['event.get', 'initiative.get', 'opportunity.get', 'space.get', 'activity-area.get'])] private ?Uuid $id = null; #[ORM\Column(length: 100)] diff --git a/src/Exception/ActivityArea/ActivityAreaResourceNotFoundException.php b/src/Exception/ActivityArea/ActivityAreaResourceNotFoundException.php new file mode 100644 index 00000000..4687fcb0 --- /dev/null +++ b/src/Exception/ActivityArea/ActivityAreaResourceNotFoundException.php @@ -0,0 +1,12 @@ +getEntityManager()->remove($activityArea); + $this->getEntityManager()->flush(); + } } diff --git a/src/Repository/Interface/ActivityAreaRepositoryInterface.php b/src/Repository/Interface/ActivityAreaRepositoryInterface.php index cfa196fd..57c92964 100644 --- a/src/Repository/Interface/ActivityAreaRepositoryInterface.php +++ b/src/Repository/Interface/ActivityAreaRepositoryInterface.php @@ -9,4 +9,6 @@ interface ActivityAreaRepositoryInterface { public function save(ActivityArea $activityArea): ActivityArea; + + public function remove(ActivityArea $activityArea); } diff --git a/src/Service/ActivityAreaService.php b/src/Service/ActivityAreaService.php new file mode 100644 index 00000000..288b3455 --- /dev/null +++ b/src/Service/ActivityAreaService.php @@ -0,0 +1,58 @@ +security); + } + + public function get(Uuid $id): ActivityArea + { + $activityArea = $this->findOneBy(['id' => $id]); + + if (null === $activityArea) { + throw new ActivityAreaResourceNotFoundException(); + } + + return $activityArea; + } + + public function list(int $limit = 50, array $params = []): array + { + return $this->repository->findBy( + $params, + ['name' => 'ASC'], + $limit + ); + } + + public function remove(Uuid $id): void + { + $activityArea = $this->findOneBy(['id' => $id]); + + if (null === $activityArea) { + throw new ActivityAreaResourceNotFoundException(); + } + + $this->repository->remove($activityArea); + } + + private function findOneBy(array $array): ?ActivityArea + { + return $this->repository->findOneBy($array); + } +} diff --git a/src/Service/Interface/ActivityAreaServiceInterface.php b/src/Service/Interface/ActivityAreaServiceInterface.php new file mode 100644 index 00000000..d6fbce7c --- /dev/null +++ b/src/Service/Interface/ActivityAreaServiceInterface.php @@ -0,0 +1,17 @@ +request(Request::METHOD_GET, self::BASE_URL); + + $this->assertResponseIsSuccessful(); + $this->assertResponseStatusCodeSame(Response::HTTP_OK); + + $response = json_decode($client->getResponse()->getContent(), true); + $this->assertIsArray($response); + $this->assertNotEmpty($response); + } + + public function testGetOneActivityAreaItemWithSuccess(): void + { + $client = static::apiClient(); + + $url = sprintf('%s/%s', self::BASE_URL, ActivityAreaFixtures::ACTIVITY_AREA_ID_1); + $client->request(Request::METHOD_GET, $url); + + $this->assertResponseIsSuccessful(); + $this->assertResponseStatusCodeSame(Response::HTTP_OK); + + $activityArea = $client->getContainer()->get(EntityManagerInterface::class) + ->find(ActivityArea::class, ActivityAreaFixtures::ACTIVITY_AREA_ID_1); + + $this->assertResponseBodySame([ + 'id' => ActivityAreaFixtures::ACTIVITY_AREA_ID_1, + 'name' => $activityArea->getName(), + ]); + } + + public function testGetAnActivityAreaWhenNotFound(): void + { + $client = static::apiClient(); + + $client->request(Request::METHOD_GET, sprintf('%s/%s', self::BASE_URL, Uuid::v4()->toRfc4122())); + + $this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND); + $this->assertResponseBodySame([ + 'error_message' => 'not_found', + 'error_details' => [ + 'description' => 'The requested ActivityArea was not found.', + ], + ]); + } + + public function testDeleteAResourceWhenNotFound(): void + { + $client = static::apiClient(); + + $client->request(Request::METHOD_DELETE, sprintf('%s/%s', self::BASE_URL, Uuid::v4()->toRfc4122())); + + $this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND); + $this->assertResponseBodySame([ + 'error_message' => 'not_found', + 'error_details' => [ + 'description' => 'The requested ActivityArea was not found.', + ], + ]); + } + + public function testDeleteAActivityAreaItemWithSuccess(): void + { + $client = static::apiClient(); + + $url = sprintf('%s/%s', self::BASE_URL, ActivityAreaFixtures::ACTIVITY_AREA_ID_2); + + $client->request(Request::METHOD_DELETE, $url); + $this->assertResponseIsSuccessful(); + $this->assertResponseStatusCodeSame(Response::HTTP_NO_CONTENT); + + $client->request(Request::METHOD_GET, $url); + $this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND); + } + + public function testDeleteAnActivityAreaWhenNotFound(): void + { + $client = static::apiClient(); + + $client->request(Request::METHOD_DELETE, sprintf('%s/%s', self::BASE_URL, Uuid::v4()->toRfc4122())); + + $this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND); + $this->assertResponseBodySame([ + 'error_message' => 'not_found', + 'error_details' => [ + 'description' => 'The requested ActivityArea was not found.', + ], + ]); + } +}