From ec6840ed293586e92b83f03d12343725d56a5ffb Mon Sep 17 00:00:00 2001 From: nttdata-rtorsoli Date: Wed, 24 Jan 2024 13:12:28 +0100 Subject: [PATCH 1/2] BKE - It is possible to delete document only on Draft descriptor --- .../resources/interface-specification.yml | 16 ++- .../api/impl/ProcessApiServiceImpl.scala | 2 + .../api/impl/ResponseHandlers.scala | 2 + .../catalogprocess/CatalogProcessSpec.scala | 135 +++++++++++++++++- 4 files changed, 144 insertions(+), 11 deletions(-) diff --git a/src/main/resources/interface-specification.yml b/src/main/resources/interface-specification.yml index f501710f..ff5e4f2a 100644 --- a/src/main/resources/interface-specification.yml +++ b/src/main/resources/interface-specification.yml @@ -786,14 +786,20 @@ paths: responses: '204': description: Document deleted. - '404': - description: E-Service descriptor document not found + '400': + description: Bad request content: application/problem+json: schema: - $ref: '#/components/schemas/Problem' - '400': - description: Bad request + $ref: '#/components/schemas/Problem' + '403': + description: Forbidden + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + '404': + description: E-Service descriptor document not found content: application/problem+json: schema: diff --git a/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ProcessApiServiceImpl.scala b/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ProcessApiServiceImpl.scala index 839dead9..c68319ad 100644 --- a/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ProcessApiServiceImpl.scala +++ b/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ProcessApiServiceImpl.scala @@ -519,6 +519,8 @@ final case class ProcessApiServiceImpl( documentUuid <- documentId.toFutureUUID catalogItem <- catalogManagementService.getEServiceById(eServiceUuid) _ <- assertRequesterAllowed(catalogItem.producerId)(organizationId) + descriptor <- assertDescriptorExists(catalogItem, descriptorUuid) + _ <- isDraftDescriptor(descriptor) result <- catalogManagementService.deleteEServiceDocument( eServiceUuid.toString, descriptorUuid.toString, diff --git a/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ResponseHandlers.scala b/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ResponseHandlers.scala index cd1144b5..f22a8b72 100644 --- a/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ResponseHandlers.scala +++ b/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ResponseHandlers.scala @@ -210,8 +210,10 @@ object ResponseHandlers extends AkkaResponses { )(result: Try[T])(implicit contexts: Seq[(String, String)], logger: LoggerTakingImplicit[ContextFieldsToLog]): Route = result match { case Success(s) => success(s) + case Failure(ex: NotValidDescriptor) => badRequest(ex, logMessage) case Failure(ex: OperationForbidden.type) => forbidden(ex, logMessage) case Failure(ex: EServiceNotFound) => notFound(ex, logMessage) + case Failure(ex: EServiceDescriptorNotFound) => notFound(ex, logMessage) case Failure(ex: DescriptorDocumentNotFound) => notFound(ex, logMessage) case Failure(ex) => internalServerError(ex, logMessage) } diff --git a/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala b/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala index 3cc5fe01..8514ec04 100644 --- a/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala +++ b/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala @@ -782,26 +782,39 @@ class CatalogProcessSpec extends SpecHelper with AnyWordSpecLike with ScalatestR } "EService document deletion" should { "succeed" in { - val requesterId = UUID.randomUUID() + val requesterId = UUID.randomUUID() + val descriptorId = UUID.randomUUID() implicit val context: Seq[(String, String)] = Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> requesterId.toString) val eServiceDoc = SpecData.eServiceDoc - val descriptor = + val eServiceDescriptor = SpecData.eServiceDescriptor.copy( - state = CatalogManagementDependency.EServiceDescriptorState.PUBLISHED, + id = descriptorId, + state = CatalogManagementDependency.EServiceDescriptorState.DRAFT, docs = Seq(eServiceDoc) ) - val eService = SpecData.eService.copy(descriptors = Seq(descriptor), producerId = requesterId) + val eService = SpecData.eService.copy(descriptors = Seq(eServiceDescriptor), producerId = requesterId) + + val descriptor = + SpecData.catalogDescriptor.copy( + id = descriptorId, + docs = Seq(SpecData.catalogDocument.copy(id = eServiceDoc.id)), + state = Draft + ) (mockCatalogManagementService .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) .expects(eService.id, *, *) .once() - .returns(Future.successful(SpecData.catalogItem.copy(id = eService.id, producerId = requesterId))) + .returns( + Future.successful( + SpecData.catalogItem.copy(id = eService.id, producerId = requesterId, descriptors = Seq(descriptor)) + ) + ) (mockCatalogManagementService .deleteEServiceDocument(_: String, _: String, _: String)(_: Seq[(String, String)])) @@ -855,6 +868,82 @@ class CatalogProcessSpec extends SpecHelper with AnyWordSpecLike with ScalatestR status shouldEqual StatusCodes.NotFound } } + "fail if descriptor does not exists" in { + val requesterId = UUID.randomUUID() + + implicit val context: Seq[(String, String)] = + Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> requesterId.toString) + + val eService = SpecData.eService.copy(descriptors = Seq.empty, producerId = requesterId) + + val descriptor = + SpecData.catalogDescriptor.copy( + id = UUID.randomUUID(), + docs = Seq(SpecData.catalogDocument.copy(id = SpecData.eServiceDoc.id)), + state = Draft + ) + + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(eService.id, *, *) + .once() + .returns( + Future.successful( + SpecData.catalogItem.copy(id = eService.id, producerId = requesterId, descriptors = Seq(descriptor)) + ) + ) + + Delete() ~> service.deleteEServiceDocumentById( + eService.id.toString, + UUID.randomUUID().toString, + SpecData.eServiceDoc.id.toString + ) ~> check { + status shouldEqual StatusCodes.NotFound + } + } + "fail if Descriptor is not Draft" in { + val requesterId = UUID.randomUUID() + val descriptorId = UUID.randomUUID() + + implicit val context: Seq[(String, String)] = + Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> requesterId.toString) + + val eServiceDoc = SpecData.eServiceDoc + + val eServiceDescriptor = + SpecData.eServiceDescriptor.copy( + id = descriptorId, + state = CatalogManagementDependency.EServiceDescriptorState.PUBLISHED, + docs = Seq(eServiceDoc) + ) + + val eService = SpecData.eService.copy(descriptors = Seq(eServiceDescriptor), producerId = requesterId) + + val descriptor = + SpecData.catalogDescriptor.copy( + id = descriptorId, + docs = Seq(SpecData.catalogDocument.copy(id = eServiceDoc.id)), + state = Published + ) + + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(eService.id, *, *) + .once() + .returns( + Future.successful( + SpecData.catalogItem.copy(id = eService.id, producerId = requesterId, descriptors = Seq(descriptor)) + ) + ) + + Delete() ~> service.deleteEServiceDocumentById( + eService.id.toString, + descriptor.id.toString, + eServiceDoc.id.toString + ) ~> check { + status shouldEqual StatusCodes.BadRequest + } + } } "Descriptor creation" should { "succeed" in { @@ -2481,7 +2570,11 @@ class CatalogProcessSpec extends SpecHelper with AnyWordSpecLike with ScalatestR Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> requesterId.toString) val descriptor = - SpecData.catalogDescriptor.copy(id = descriptorId, docs = Seq(SpecData.catalogDocument.copy(id = documentId))) + SpecData.catalogDescriptor.copy( + id = descriptorId, + docs = Seq(SpecData.catalogDocument.copy(id = documentId)), + state = Draft + ) val eService = SpecData.catalogItem.copy(descriptors = Seq(descriptor), producerId = requesterId) @@ -2543,6 +2636,36 @@ class CatalogProcessSpec extends SpecHelper with AnyWordSpecLike with ScalatestR status shouldEqual StatusCodes.Forbidden } } + "fail if descriptor does not exists" in { + val requesterId = UUID.randomUUID() + val descriptorId = UUID.randomUUID() + val documentId = UUID.randomUUID() + + implicit val context: Seq[(String, String)] = + Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> requesterId.toString) + + val descriptor = + SpecData.catalogDescriptor.copy( + id = UUID.randomUUID(), + docs = Seq(SpecData.catalogDocument.copy(id = documentId)) + ) + + val eService = SpecData.catalogItem.copy(descriptors = Seq(descriptor), producerId = requesterId) + + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(SpecData.catalogItem.id, *, *) + .once() + .returns(Future.successful(eService)) + + Delete() ~> service.deleteEServiceDocumentById( + SpecData.catalogItem.id.toString, + descriptorId.toString, + documentId.toString + ) ~> check { + status shouldEqual StatusCodes.NotFound + } + } } "Risk Analysis creation" should { "succeed" in { From 565c8bf51a58e711bf640834bb047e50ae628cce Mon Sep 17 00:00:00 2001 From: nttdata-rtorsoli Date: Wed, 24 Jan 2024 13:16:08 +0100 Subject: [PATCH 2/2] PIN-4464 Added test --- .../catalogprocess/CatalogProcessSpec.scala | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala b/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala index 8514ec04..ecbcc5b8 100644 --- a/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala +++ b/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala @@ -781,7 +781,7 @@ class CatalogProcessSpec extends SpecHelper with AnyWordSpecLike with ScalatestR } } "EService document deletion" should { - "succeed" in { + "succeed only on Draft descriptor" in { val requesterId = UUID.randomUUID() val descriptorId = UUID.randomUUID() @@ -2561,7 +2561,7 @@ class CatalogProcessSpec extends SpecHelper with AnyWordSpecLike with ScalatestR } } "Document deletion" should { - "succeed" in { + "succeed only on Draft Descriptor" in { val requesterId = UUID.randomUUID() val descriptorId = UUID.randomUUID() val documentId = UUID.randomUUID() @@ -2666,6 +2666,37 @@ class CatalogProcessSpec extends SpecHelper with AnyWordSpecLike with ScalatestR status shouldEqual StatusCodes.NotFound } } + "fail if descriptor is not Draft" in { + val requesterId = UUID.randomUUID() + val descriptorId = UUID.randomUUID() + val documentId = UUID.randomUUID() + + implicit val context: Seq[(String, String)] = + Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> requesterId.toString) + + val descriptor = + SpecData.catalogDescriptor.copy( + id = descriptorId, + docs = Seq(SpecData.catalogDocument.copy(id = documentId)), + state = Published + ) + + val eService = SpecData.catalogItem.copy(descriptors = Seq(descriptor), producerId = requesterId) + + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(SpecData.catalogItem.id, *, *) + .once() + .returns(Future.successful(eService)) + + Delete() ~> service.deleteEServiceDocumentById( + SpecData.catalogItem.id.toString, + descriptorId.toString, + documentId.toString + ) ~> check { + status shouldEqual StatusCodes.BadRequest + } + } } "Risk Analysis creation" should { "succeed" in {