diff --git a/docs/api/administration-service.yaml b/docs/api/administration-service.yaml index 892423282c..891a3ffdc4 100644 --- a/docs/api/administration-service.yaml +++ b/docs/api/administration-service.yaml @@ -4257,6 +4257,38 @@ paths: description: Internal Server Error '401': description: The User is unauthorized + '/api/administration/registration/application/{applicationId}/retrigger-set-cx-membership': + post: + tags: + - Registration + summary: 'Retriggers the last failed step (Authorization required - Roles: approve_new_partner)' + parameters: + - name: applicationId + in: path + description: Id of the application that should be triggered + required: true + schema: + type: string + format: uuid + responses: + '204': + description: Empty response on success. + '400': + description: Either the CompanyApplication is not in status SUBMITTED or the next step can't automatically retriggered. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: No application found for the applicationId. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal Server Error + '401': + description: The User is unauthorized /api/administration/RegistrationStatus/callback: get: tags: @@ -7529,6 +7561,8 @@ components: - RETRIGGER_REMOVE_REGISTRATION_ROLES - RETRIGGER_SET_THEME - RETRIGGER_SET_MEMBERSHIP + - SET_CX_MEMBERSHIP_IN_BPDM + - RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM - TRIGGER_PROVIDER - AWAIT_START_AUTOSETUP - OFFERSUBSCRIPTION_CLIENT_CREATION diff --git a/docs/api/apps-service.yaml b/docs/api/apps-service.yaml index 648af38be3..160ca530dc 100644 --- a/docs/api/apps-service.yaml +++ b/docs/api/apps-service.yaml @@ -3563,6 +3563,8 @@ components: - RETRIGGER_REMOVE_REGISTRATION_ROLES - RETRIGGER_SET_THEME - RETRIGGER_SET_MEMBERSHIP + - SET_CX_MEMBERSHIP_IN_BPDM + - RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM - TRIGGER_PROVIDER - AWAIT_START_AUTOSETUP - OFFERSUBSCRIPTION_CLIENT_CREATION diff --git a/docs/api/services-service.yaml b/docs/api/services-service.yaml index c585977aed..9a9a4ab529 100644 --- a/docs/api/services-service.yaml +++ b/docs/api/services-service.yaml @@ -2143,6 +2143,8 @@ components: - RETRIGGER_REMOVE_REGISTRATION_ROLES - RETRIGGER_SET_THEME - RETRIGGER_SET_MEMBERSHIP + - SET_CX_MEMBERSHIP_IN_BPDM + - RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM - TRIGGER_PROVIDER - AWAIT_START_AUTOSETUP - OFFERSUBSCRIPTION_CLIENT_CREATION diff --git a/src/administration/Administration.Service/Controllers/RegistrationController.cs b/src/administration/Administration.Service/Controllers/RegistrationController.cs index b317ec3044..9e73a0e09f 100644 --- a/src/administration/Administration.Service/Controllers/RegistrationController.cs +++ b/src/administration/Administration.Service/Controllers/RegistrationController.cs @@ -726,5 +726,27 @@ public async Task RetriggerSetMembership([FromRoute] Guid appli await logic.TriggerChecklistAsync(applicationId, ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ProcessStepTypeId.RETRIGGER_SET_MEMBERSHIP).ConfigureAwait(ConfigureAwaitOptions.None); return NoContent(); } + + /// + /// Retriggers the last failed step + /// + /// Id of the application that should be triggered + /// NoContent + /// Example: POST: api/administration/registration/application/{applicationId}/retrigger-set-cx-membership + /// Empty response on success. + /// Either the CompanyApplication is not in status SUBMITTED or the next step can't automatically retriggered. + /// No application found for the applicationId. + [HttpPost] + [Authorize(Roles = "approve_new_partner")] + [Authorize(Policy = PolicyTypes.CompanyUser)] + [Route("application/{applicationId}/retrigger-set-cx-membership")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)] + public async Task RetriggerSetCxMembership([FromRoute] Guid applicationId) + { + await logic.TriggerChecklistAsync(applicationId, ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ProcessStepTypeId.RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM).ConfigureAwait(ConfigureAwaitOptions.None); + return NoContent(); + } } diff --git a/src/externalsystems/Bpdm.Library/BpdmService.cs b/src/externalsystems/Bpdm.Library/BpdmService.cs index 25ebb38997..e74657cc47 100644 --- a/src/externalsystems/Bpdm.Library/BpdmService.cs +++ b/src/externalsystems/Bpdm.Library/BpdmService.cs @@ -23,6 +23,7 @@ using Org.Eclipse.TractusX.Portal.Backend.Framework.HttpClientExtensions; using Org.Eclipse.TractusX.Portal.Backend.Framework.Token; using System.Net.Http.Json; +using System.Text; using System.Text.Json; using System.Text.Json.Serialization; @@ -176,4 +177,23 @@ public async Task GetSharingState(Guid applicationId, Cancella throw new ServiceException($"Access to sharing state did not return a valid json response: {je.Message}"); } } + + /// + public async Task SetCxMembership(string businessPartnerNumber, CancellationToken cancellationToken) + { + using var httpClient = await _tokenService.GetAuthorizedClient(_settings, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + + var requestData = new BpdmCxMembership( + new BpdmCxMembershipDto[]{ + new(businessPartnerNumber, true) + }.AsEnumerable() + ); + + async ValueTask<(bool, string?)> CreateErrorMessage(HttpResponseMessage errorResponse) => + (false, (await errorResponse.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None))); + + await httpClient.PutAsJsonAsync("v6/cx-memberships", requestData, Options, cancellationToken) + .CatchingIntoServiceExceptionFor("bpdm-put-cx-membership", HttpAsyncResponseMessageExtension.RecoverOptions.INFRASTRUCTURE, CreateErrorMessage).ConfigureAwait(false); + return true; + } } diff --git a/src/externalsystems/Bpdm.Library/IBpdmService.cs b/src/externalsystems/Bpdm.Library/IBpdmService.cs index ed3673aaf2..d080f4d8c7 100644 --- a/src/externalsystems/Bpdm.Library/IBpdmService.cs +++ b/src/externalsystems/Bpdm.Library/IBpdmService.cs @@ -44,4 +44,12 @@ public interface IBpdmService Task SetSharingStateToReady(string externalId, CancellationToken cancellationToken); Task FetchInputLegalEntity(string externalId, CancellationToken cancellationToken); Task GetSharingState(Guid applicationId, CancellationToken cancellationToken); + + /// + /// Send membership information to the BPDM Pool + /// + /// The BPN to set Cx Membership + /// Cancellation Token + /// Returns true if the service call was successful, otherwise false + Task SetCxMembership(string businessPartnerNumber, CancellationToken cancellationToken); } diff --git a/src/externalsystems/Bpdm.Library/Models/BpdmCxMembershipDto.cs b/src/externalsystems/Bpdm.Library/Models/BpdmCxMembershipDto.cs new file mode 100644 index 0000000000..0424824458 --- /dev/null +++ b/src/externalsystems/Bpdm.Library/Models/BpdmCxMembershipDto.cs @@ -0,0 +1,40 @@ +/******************************************************************************** + * Copyright (c) 2022 BMW Group AG + * Copyright (c) 2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +using System.Text.Json.Serialization; +namespace Org.Eclipse.TractusX.Portal.Backend.Bpdm.Library.Models; + +/// +/// Modal to send multiple data to BPDM. +/// +/// List of memberships +public record BpdmCxMembership( + [property: JsonPropertyName("memberships")] IEnumerable Memberships +); + +/// +/// Modal to send single data to BPDM. +/// +/// Business Partner Number +/// True, if BPN has added for Catena-X mambership +public record BpdmCxMembershipDto( + [property: JsonPropertyName("bpnL")] string Bpn, + [property: JsonPropertyName("isCatenaXMember")] bool IsCatenaXMember +); diff --git a/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepTypeId.cs b/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepTypeId.cs index 35c002c0f3..e799abbbe1 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepTypeId.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Enums/ProcessStepTypeId.cs @@ -64,6 +64,8 @@ public enum ProcessStepTypeId RETRIGGER_REMOVE_REGISTRATION_ROLES = 41, RETRIGGER_SET_THEME = 42, RETRIGGER_SET_MEMBERSHIP = 43, + SET_CX_MEMBERSHIP_IN_BPDM = 44, + RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM = 45, // OfferSubscriptionProcess TRIGGER_PROVIDER = 100, diff --git a/src/processes/ApplicationChecklist.Executor/ApplicationChecklistHandlerService.cs b/src/processes/ApplicationChecklist.Executor/ApplicationChecklistHandlerService.cs index 48ae16f1db..b8e6a3167f 100644 --- a/src/processes/ApplicationChecklist.Executor/ApplicationChecklistHandlerService.cs +++ b/src/processes/ApplicationChecklist.Executor/ApplicationChecklistHandlerService.cs @@ -62,6 +62,7 @@ public class ApplicationChecklistHandlerService( new(ProcessStepTypeId.REMOVE_REGISTRATION_ROLES, new(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, true, applicationActivationService.RemoveRegistrationRoles, (ex, _, _) => checklistService.HandleServiceErrorAsync(ex, ProcessStepTypeId.RETRIGGER_REMOVE_REGISTRATION_ROLES))), new(ProcessStepTypeId.SET_THEME, new(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, true, applicationActivationService.SetTheme, (ex, _, _) => checklistService.HandleServiceErrorAsync(ex, ProcessStepTypeId.RETRIGGER_SET_THEME))), new(ProcessStepTypeId.SET_MEMBERSHIP, new(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, true, applicationActivationService.SetMembership, (ex, _, _) => checklistService.HandleServiceErrorAsync(ex, ProcessStepTypeId.RETRIGGER_SET_MEMBERSHIP))), + new(ProcessStepTypeId.SET_CX_MEMBERSHIP_IN_BPDM, new(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, true, applicationActivationService.SetCxMembership, (ex, _, _) => checklistService.HandleServiceErrorAsync(ex, ProcessStepTypeId.RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM))), new(ProcessStepTypeId.FINISH_APPLICATION_ACTIVATION, new(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, true, applicationActivationService.SaveApplicationActivationToDatabase, null)) ]); diff --git a/src/processes/ApplicationChecklist.Library/ApplicationChecklistEntryTypeIdExtensions.cs b/src/processes/ApplicationChecklist.Library/ApplicationChecklistEntryTypeIdExtensions.cs index f5ffb38ea7..375444d84b 100644 --- a/src/processes/ApplicationChecklist.Library/ApplicationChecklistEntryTypeIdExtensions.cs +++ b/src/processes/ApplicationChecklist.Library/ApplicationChecklistEntryTypeIdExtensions.cs @@ -29,7 +29,7 @@ public static class ApplicationChecklistEntryTypeIdExtensions new(ApplicationChecklistEntryTypeId.IDENTITY_WALLET, [ProcessStepTypeId.RETRIGGER_IDENTITY_WALLET, ProcessStepTypeId.RETRIGGER_CREATE_DIM_WALLET, ProcessStepTypeId.RETRIGGER_VALIDATE_DID_DOCUMENT]), new(ApplicationChecklistEntryTypeId.SELF_DESCRIPTION_LP, [ProcessStepTypeId.RETRIGGER_SELF_DESCRIPTION_LP]), new(ApplicationChecklistEntryTypeId.BUSINESS_PARTNER_NUMBER, [ProcessStepTypeId.RETRIGGER_BUSINESS_PARTNER_NUMBER_PUSH, ProcessStepTypeId.RETRIGGER_BUSINESS_PARTNER_NUMBER_PULL]), - new(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, [ProcessStepTypeId.RETRIGGER_ASSIGN_INITIAL_ROLES, ProcessStepTypeId.RETRIGGER_ASSIGN_BPN_TO_USERS, ProcessStepTypeId.RETRIGGER_REMOVE_REGISTRATION_ROLES, ProcessStepTypeId.RETRIGGER_SET_THEME, ProcessStepTypeId.RETRIGGER_SET_MEMBERSHIP]) + new(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, [ProcessStepTypeId.RETRIGGER_ASSIGN_INITIAL_ROLES, ProcessStepTypeId.RETRIGGER_ASSIGN_BPN_TO_USERS, ProcessStepTypeId.RETRIGGER_REMOVE_REGISTRATION_ROLES, ProcessStepTypeId.RETRIGGER_SET_THEME, ProcessStepTypeId.RETRIGGER_SET_MEMBERSHIP, ProcessStepTypeId.RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM]) ]); public static IEnumerable GetManualTriggerProcessStepIds(this ApplicationChecklistEntryTypeId entryTypeId) => @@ -56,6 +56,7 @@ public static (ProcessStepTypeId ProcessStepTypeId, ApplicationChecklistEntrySta ProcessStepTypeId.RETRIGGER_REMOVE_REGISTRATION_ROLES => (ProcessStepTypeId.REMOVE_REGISTRATION_ROLES, ApplicationChecklistEntryStatusId.IN_PROGRESS), ProcessStepTypeId.RETRIGGER_SET_THEME => (ProcessStepTypeId.SET_THEME, ApplicationChecklistEntryStatusId.IN_PROGRESS), ProcessStepTypeId.RETRIGGER_SET_MEMBERSHIP => (ProcessStepTypeId.SET_MEMBERSHIP, ApplicationChecklistEntryStatusId.IN_PROGRESS), + ProcessStepTypeId.RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM => (ProcessStepTypeId.SET_CX_MEMBERSHIP_IN_BPDM, ApplicationChecklistEntryStatusId.IN_PROGRESS), _ => default, }; } diff --git a/src/registration/ApplicationActivation.Library/ApplicationActivation.Library.csproj b/src/registration/ApplicationActivation.Library/ApplicationActivation.Library.csproj index 721b5a1ef5..3fc62150b4 100644 --- a/src/registration/ApplicationActivation.Library/ApplicationActivation.Library.csproj +++ b/src/registration/ApplicationActivation.Library/ApplicationActivation.Library.csproj @@ -35,6 +35,7 @@ + diff --git a/src/registration/ApplicationActivation.Library/ApplicationActivationService.cs b/src/registration/ApplicationActivation.Library/ApplicationActivationService.cs index 12eb85fd3a..9ab5342b1b 100644 --- a/src/registration/ApplicationActivation.Library/ApplicationActivationService.cs +++ b/src/registration/ApplicationActivation.Library/ApplicationActivationService.cs @@ -19,6 +19,7 @@ using Microsoft.Extensions.Options; using Org.Eclipse.TractusX.Portal.Backend.ApplicationActivation.Library.DependencyInjection; +using Org.Eclipse.TractusX.Portal.Backend.Bpdm.Library; using Org.Eclipse.TractusX.Portal.Backend.Custodian.Library; using Org.Eclipse.TractusX.Portal.Backend.Framework.Async; using Org.Eclipse.TractusX.Portal.Backend.Framework.DateTimeProvider; @@ -43,6 +44,7 @@ public class ApplicationActivationService( IProvisioningManager provisioningManager, IDateTimeProvider dateTime, ICustodianService custodianService, + IBpdmService bpdmService, IMailingProcessCreation mailingProcessCreation, IOptions options) : IApplicationActivationService @@ -288,6 +290,26 @@ await provisioningManager.DeleteClientRolesFromCentralUserAsync(iamUserId, roleN { entry.Comment = resultMessage; }, + Enumerable.Repeat(ProcessStepTypeId.SET_CX_MEMBERSHIP_IN_BPDM, 1), + null, + true, + null); + } + + public async Task SetCxMembership(IApplicationChecklistService.WorkerChecklistProcessStepData context, CancellationToken cancellationToken) + { + var businessPartnerNumber = await portalRepositories.GetInstance() + .GetBpnForApplicationIdAsync(context.ApplicationId) + .ConfigureAwait(ConfigureAwaitOptions.None); + if (businessPartnerNumber is null) + { + throw new ConflictException("BusinessPartnerNumber must be set"); + } + + var resultMessage = await bpdmService.SetCxMembership(businessPartnerNumber, cancellationToken).ConfigureAwait(ConfigureAwaitOptions.None); + return new IApplicationChecklistService.WorkerChecklistProcessStepExecutionResult( + ProcessStepStatusId.DONE, + null, Enumerable.Repeat(ProcessStepTypeId.FINISH_APPLICATION_ACTIVATION, 1), null, true, diff --git a/src/registration/ApplicationActivation.Library/IApplicationActivationService.cs b/src/registration/ApplicationActivation.Library/IApplicationActivationService.cs index be995b33d5..666127b700 100644 --- a/src/registration/ApplicationActivation.Library/IApplicationActivationService.cs +++ b/src/registration/ApplicationActivation.Library/IApplicationActivationService.cs @@ -35,5 +35,6 @@ public interface IApplicationActivationService Task RemoveRegistrationRoles(IApplicationChecklistService.WorkerChecklistProcessStepData context, CancellationToken cancellationToken); Task SetTheme(IApplicationChecklistService.WorkerChecklistProcessStepData context, CancellationToken cancellationToken); Task SetMembership(IApplicationChecklistService.WorkerChecklistProcessStepData context, CancellationToken cancellationToken); + Task SetCxMembership(IApplicationChecklistService.WorkerChecklistProcessStepData context, CancellationToken cancellationToken); Task SaveApplicationActivationToDatabase(IApplicationChecklistService.WorkerChecklistProcessStepData context, CancellationToken cancellationToken); } diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs index 86bcf45791..88a512a531 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs @@ -693,6 +693,7 @@ public async Task TriggerChecklistAsync_WithFailingChecklistServiceCall_ReturnsE [InlineData(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ProcessStepTypeId.RETRIGGER_REMOVE_REGISTRATION_ROLES, ProcessStepTypeId.REMOVE_REGISTRATION_ROLES, ApplicationChecklistEntryStatusId.IN_PROGRESS)] [InlineData(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ProcessStepTypeId.RETRIGGER_SET_THEME, ProcessStepTypeId.SET_THEME, ApplicationChecklistEntryStatusId.IN_PROGRESS)] [InlineData(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ProcessStepTypeId.RETRIGGER_SET_MEMBERSHIP, ProcessStepTypeId.SET_MEMBERSHIP, ApplicationChecklistEntryStatusId.IN_PROGRESS)] + [InlineData(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ProcessStepTypeId.RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM, ProcessStepTypeId.SET_CX_MEMBERSHIP_IN_BPDM, ApplicationChecklistEntryStatusId.IN_PROGRESS)] public async Task TriggerChecklistAsync_WithValidData_ReturnsExpected(ApplicationChecklistEntryTypeId typeId, ProcessStepTypeId stepId, ProcessStepTypeId nextStepId, ApplicationChecklistEntryStatusId statusId) { // Arrange @@ -790,6 +791,7 @@ public async Task TriggerChecklistAsync_WithWrongProcessStepForChecklist_ThrowsC [InlineData(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ProcessStepTypeId.RETRIGGER_REMOVE_REGISTRATION_ROLES)] [InlineData(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ProcessStepTypeId.RETRIGGER_SET_THEME)] [InlineData(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ProcessStepTypeId.RETRIGGER_SET_MEMBERSHIP)] + [InlineData(ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ProcessStepTypeId.RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM)] public async Task TriggerChecklistAsync_Success(ApplicationChecklistEntryTypeId typeId, ProcessStepTypeId stepId) { // Arrange diff --git a/tests/administration/Administration.Service.Tests/Controllers/RegistrationControllerTest.cs b/tests/administration/Administration.Service.Tests/Controllers/RegistrationControllerTest.cs index 856d684475..d046733623 100644 --- a/tests/administration/Administration.Service.Tests/Controllers/RegistrationControllerTest.cs +++ b/tests/administration/Administration.Service.Tests/Controllers/RegistrationControllerTest.cs @@ -359,4 +359,18 @@ public async Task RetriggerDeleteCentralUser_ReturnsExpectedResult() A.CallTo(() => _logic.RetriggerDeleteCentralUser(processId)).MustHaveHappenedOnceExactly(); result.Should().BeOfType(); } + + [Fact] + public async Task RetriggerSetCxMembership_ReturnsExpectedResult() + { + // Arrange + var applicationId = _fixture.Create(); + + // Act + var result = await _controller.RetriggerSetCxMembership(applicationId); + + // Assert + A.CallTo(() => _logic.TriggerChecklistAsync(applicationId, ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ProcessStepTypeId.RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM)).MustHaveHappenedOnceExactly(); + result.Should().BeOfType(); + } } diff --git a/tests/externalsystems/Bpdm.Library/BpdmServiceTests.cs b/tests/externalsystems/Bpdm.Library/BpdmServiceTests.cs index 785550475c..78b426e284 100644 --- a/tests/externalsystems/Bpdm.Library/BpdmServiceTests.cs +++ b/tests/externalsystems/Bpdm.Library/BpdmServiceTests.cs @@ -662,4 +662,50 @@ public async Task GetSharingState_WithInvalidData_ThrowsServiceException() } #endregion + + #region SetCxMembership + + [Fact] + public async Task SetCxMembership_WithValidData_DoesNotThrowException() + { + // Arrange + const string bpn = "123"; + var httpMessageHandlerMock = new HttpMessageHandlerMock(HttpStatusCode.OK); + using var httpClient = new HttpClient(httpMessageHandlerMock) + { + BaseAddress = new Uri("https://base.address.com") + }; + A.CallTo(() => _tokenService.GetAuthorizedClient(_options.Value, A._)) + .Returns(httpClient); + var sut = new BpdmService(_tokenService, _options); + + // Act + var result = await sut.SetCxMembership(bpn, CancellationToken.None); + + // Assert + result.Should().BeTrue(); + } + + [Fact] + public async Task SetCxMembership_WithInvalidData_ThrowsServiceException() + { + // Arrange + const string bpn = "123"; + var httpMessageHandlerMock = new HttpMessageHandlerMock(HttpStatusCode.BadRequest); + using var httpClient = new HttpClient(httpMessageHandlerMock) + { + BaseAddress = new Uri("https://base.address.com") + }; + A.CallTo(() => _tokenService.GetAuthorizedClient(_options.Value, A._)).Returns(httpClient); + var sut = new BpdmService(_tokenService, _options); + + // Act + async Task Act() => await sut.SetCxMembership(bpn, CancellationToken.None); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Contain("bpdm-put-cx-membership"); + } + + #endregion } diff --git a/tests/processes/ApplicationChecklist.Executor.Tests/ApplicationChecklistHandlerServiceTests.cs b/tests/processes/ApplicationChecklist.Executor.Tests/ApplicationChecklistHandlerServiceTests.cs index 7911bcc6ba..8def33cbb9 100644 --- a/tests/processes/ApplicationChecklist.Executor.Tests/ApplicationChecklistHandlerServiceTests.cs +++ b/tests/processes/ApplicationChecklist.Executor.Tests/ApplicationChecklistHandlerServiceTests.cs @@ -155,6 +155,9 @@ public void GetProcessStepExecution_ExecutableStep_Success(ProcessStepTypeId ste case ProcessStepTypeId.SET_MEMBERSHIP: A.CallTo(() => _applicationActivationService.SetMembership(context, A._)).MustHaveHappenedOnceExactly(); break; + case ProcessStepTypeId.SET_CX_MEMBERSHIP_IN_BPDM: + A.CallTo(() => _applicationActivationService.SetCxMembership(context, A._)).MustHaveHappenedOnceExactly(); + break; case ProcessStepTypeId.FINISH_APPLICATION_ACTIVATION: A.CallTo(() => _applicationActivationService.SaveApplicationActivationToDatabase(context, A._)).MustHaveHappenedOnceExactly(); break; @@ -229,6 +232,10 @@ public void GetProcessStepExecution_ExecutableStep_Success(ProcessStepTypeId ste execution.ErrorFunc?.Should().NotBeNull(); A.CallTo(() => _checklistService.HandleServiceErrorAsync(error, ProcessStepTypeId.RETRIGGER_SET_MEMBERSHIP)).MustHaveHappenedOnceExactly(); break; + case ProcessStepTypeId.SET_CX_MEMBERSHIP_IN_BPDM: + execution.ErrorFunc?.Should().NotBeNull(); + A.CallTo(() => _checklistService.HandleServiceErrorAsync(error, ProcessStepTypeId.RETRIGGER_SET_CX_MEMBERSHIP_IN_BPDM)).MustHaveHappenedOnceExactly(); + break; case ProcessStepTypeId.FINISH_APPLICATION_ACTIVATION: execution.ErrorFunc?.Should().BeNull(); A.CallTo(() => _checklistService.HandleServiceErrorAsync(A._, A._)).MustNotHaveHappened(); diff --git a/tests/registration/ApplicationActivation.Library.Tests/ApplicationActivationTests.cs b/tests/registration/ApplicationActivation.Library.Tests/ApplicationActivationTests.cs index 933dc8a9f1..0f1599cfbf 100644 --- a/tests/registration/ApplicationActivation.Library.Tests/ApplicationActivationTests.cs +++ b/tests/registration/ApplicationActivation.Library.Tests/ApplicationActivationTests.cs @@ -19,6 +19,7 @@ using Microsoft.Extensions.Options; using Org.Eclipse.TractusX.Portal.Backend.ApplicationActivation.Library.DependencyInjection; +using Org.Eclipse.TractusX.Portal.Backend.Bpdm.Library; using Org.Eclipse.TractusX.Portal.Backend.Custodian.Library; using Org.Eclipse.TractusX.Portal.Backend.Framework.DateTimeProvider; using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling; @@ -83,6 +84,7 @@ public class ApplicationActivationTests private readonly ApplicationActivationService _sut; private readonly IDateTimeProvider _dateTimeProvider; private readonly ICustodianService _custodianService; + private readonly IBpdmService _bpdmService; public ApplicationActivationTests() { @@ -99,6 +101,7 @@ public ApplicationActivationTests() _notificationService = A.Fake(); _dateTimeProvider = A.Fake(); _custodianService = A.Fake(); + _bpdmService = A.Fake(); _settings = A.Fake(); _processStepRepository = A.Fake(); @@ -124,7 +127,7 @@ public ApplicationActivationTests() A.CallTo(() => portalRepositories.GetInstance()).Returns(_processStepRepository); A.CallTo(() => options.Value).Returns(_settings); - _sut = new ApplicationActivationService(portalRepositories, _notificationService, _provisioningManager, _dateTimeProvider, _custodianService, _mailingProcessCreation, options); + _sut = new ApplicationActivationService(portalRepositories, _notificationService, _provisioningManager, _dateTimeProvider, _custodianService, _bpdmService, _mailingProcessCreation, options); } #endregion @@ -599,7 +602,7 @@ public async Task SetMembership_WithValid_ReturnsExpected() //Assert result.StepStatusId.Should().Be(ProcessStepStatusId.DONE); result.ScheduleStepTypeIds.Should().ContainSingle() - .And.Satisfy(x => x == ProcessStepTypeId.FINISH_APPLICATION_ACTIVATION); + .And.Satisfy(x => x == ProcessStepTypeId.SET_CX_MEMBERSHIP_IN_BPDM); result.ModifyChecklistEntry?.Should().NotBeNull(); result.ModifyChecklistEntry?.Invoke(applicationChecklistEntry); applicationChecklistEntry.Comment.Should() @@ -611,6 +614,39 @@ public async Task SetMembership_WithValid_ReturnsExpected() #endregion + #region SET_CX_MEMBERSHIP_IN_BPDM + + [Fact] + public async Task SetCxMembership_WithValid_ReturnsExpected() + { + //Arrange + var context = new IApplicationChecklistService.WorkerChecklistProcessStepData( + Id, + default, + Checklist, + Enumerable.Empty()); + var applicationChecklistEntry = new ApplicationChecklistEntry(Id, ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION, ApplicationChecklistEntryStatusId.TO_DO, DateTimeOffset.UtcNow); + A.CallTo(() => _applicationRepository.GetBpnForApplicationIdAsync(Id)) + .Returns(BusinessPartnerNumber); + A.CallTo(() => _bpdmService.SetCxMembership(BusinessPartnerNumber, A._)) + .Returns(true); + + //Act + var result = await _sut.SetCxMembership(context, CancellationToken.None); + + //Assert + result.StepStatusId.Should().Be(ProcessStepStatusId.DONE); + result.ScheduleStepTypeIds.Should().ContainSingle() + .And.Satisfy(x => x == ProcessStepTypeId.FINISH_APPLICATION_ACTIVATION); + result.ModifyChecklistEntry?.Should().NotBeNull(); + result.ModifyChecklistEntry?.Invoke(applicationChecklistEntry); + result.SkipStepTypeIds.Should().BeNull(); + result.Modified.Should().BeTrue(); + result.ProcessMessage.Should().BeNull(); + } + + #endregion + #region FINISH_APPLICATION_ACTIVATION [Fact]