diff --git a/docs/api/apps-service.yaml b/docs/api/apps-service.yaml index 4d2f050fec..feddd4e1c2 100644 --- a/docs/api/apps-service.yaml +++ b/docs/api/apps-service.yaml @@ -2168,7 +2168,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/AppProviderSubscriptionDetailData' + $ref: '#/components/schemas/OfferProviderSubscriptionDetailData' '403': description: User's company does not provide the app. content: @@ -2828,44 +2828,6 @@ components: description: the technicalUser Profile additionalProperties: false description: Response for the app creation - AppProviderSubscriptionDetailData: - type: object - properties: - id: - type: string - format: uuid - offerSubscriptionStatus: - $ref: '#/components/schemas/OfferSubscriptionStatusId' - name: - type: string - nullable: true - customer: - type: string - bpn: - type: string - nullable: true - contact: - type: array - items: - type: string - technicalUserData: - type: array - items: - $ref: '#/components/schemas/SubscriptionTechnicalUserData' - connectorData: - type: array - items: - $ref: '#/components/schemas/SubscriptionAssignedConnectorData' - tenantUrl: - type: string - nullable: true - appInstanceId: - type: string - processStepTypeId: - $ref: '#/components/schemas/ProcessStepTypeId' - externalService: - $ref: '#/components/schemas/SubscriptionExternalServiceData' - additionalProperties: false AppRequestModel: type: object properties: @@ -3435,6 +3397,45 @@ components: message: type: string additionalProperties: false + OfferProviderSubscriptionDetailData: + type: object + properties: + id: + type: string + format: uuid + offerSubscriptionStatus: + $ref: '#/components/schemas/OfferSubscriptionStatusId' + name: + type: string + nullable: true + customer: + type: string + bpn: + type: string + nullable: true + contact: + type: array + items: + type: string + technicalUserData: + type: array + items: + $ref: '#/components/schemas/SubscriptionTechnicalUserData' + connectorData: + type: array + items: + $ref: '#/components/schemas/SubscriptionAssignedConnectorData' + tenantUrl: + type: string + nullable: true + appInstanceId: + type: string + nullable: true + processStepTypeId: + $ref: '#/components/schemas/ProcessStepTypeId' + externalService: + $ref: '#/components/schemas/SubscriptionExternalServiceData' + additionalProperties: false OfferSorting: enum: - DateAsc diff --git a/docs/api/services-service.yaml b/docs/api/services-service.yaml index 25a8d05269..38bd9055e4 100644 --- a/docs/api/services-service.yaml +++ b/docs/api/services-service.yaml @@ -2216,26 +2216,42 @@ components: properties: id: type: string + description: Id of the Offer format: uuid offerSubscriptionStatus: $ref: '#/components/schemas/OfferSubscriptionStatusId' name: type: string + description: Name of the Offer nullable: true customer: type: string + description: Name of the company subscribing the offer bpn: type: string + description: 'When called from /provider bpn of the company subscribing the offer, otherwise the provider company''s bpn' nullable: true contact: type: array items: type: string + description: 'When called from /provider the company admins of the subscribing company, otherwise the salesmanagers of the offer provider' technicalUserData: type: array items: $ref: '#/components/schemas/SubscriptionTechnicalUserData' + description: Information about the technical user + connectorData: + type: array + items: + $ref: '#/components/schemas/SubscriptionAssignedConnectorData' + description: '' + processStepTypeId: + $ref: '#/components/schemas/ProcessStepTypeId' + externalService: + $ref: '#/components/schemas/SubscriptionExternalServiceData' additionalProperties: false + description: Detail data for a offer subscription ServiceData: type: object properties: @@ -2766,6 +2782,25 @@ components: status: $ref: '#/components/schemas/OfferSubscriptionStatusId' additionalProperties: false + SubscriptionExternalServiceData: + type: object + properties: + trusted_issuer: + type: string + participant_id: + type: string + nullable: true + iatp_id: + type: string + nullable: true + did_resolver: + type: string + decentralIdentityManagementAuthUrl: + type: string + decentralIdentityManagementServiceUrl: + type: string + nullable: true + additionalProperties: false SubscriptionStatusSorting: enum: - CompanyNameAsc diff --git a/src/marketplace/Apps.Service/BusinessLogic/AppsBusinessLogic.cs b/src/marketplace/Apps.Service/BusinessLogic/AppsBusinessLogic.cs index 557a2ee413..79d4f41d5e 100644 --- a/src/marketplace/Apps.Service/BusinessLogic/AppsBusinessLogic.cs +++ b/src/marketplace/Apps.Service/BusinessLogic/AppsBusinessLogic.cs @@ -227,8 +227,8 @@ public IAsyncEnumerable GetAppAgreement(Guid appId) => _offerService.GetOfferDocumentContentAsync(appId, documentId, _settings.AppImageDocumentTypeIds, OfferTypeId.APP, cancellationToken); /// - public Task GetSubscriptionDetailForProvider(Guid appId, Guid subscriptionId) => - _offerService.GetAppSubscriptionDetailsForProviderAsync(appId, subscriptionId, OfferTypeId.APP, _settings.CompanyAdminRoles, new WalletConfigData(_settings.IssuerDid, _settings.BpnDidResolverUrl, _settings.DecentralIdentityManagementAuthUrl)); + public Task GetSubscriptionDetailForProvider(Guid appId, Guid subscriptionId) => + _offerService.GetOfferSubscriptionDetailsForProviderAsync(appId, subscriptionId, OfferTypeId.APP, _settings.CompanyAdminRoles, new WalletConfigData(_settings.IssuerDid, _settings.BpnDidResolverUrl, _settings.DecentralIdentityManagementAuthUrl)); /// public Task GetSubscriptionDetailForSubscriber(Guid appId, Guid subscriptionId) => diff --git a/src/marketplace/Apps.Service/BusinessLogic/IAppsBusinessLogic.cs b/src/marketplace/Apps.Service/BusinessLogic/IAppsBusinessLogic.cs index ec3739ed97..763b523e67 100644 --- a/src/marketplace/Apps.Service/BusinessLogic/IAppsBusinessLogic.cs +++ b/src/marketplace/Apps.Service/BusinessLogic/IAppsBusinessLogic.cs @@ -162,7 +162,7 @@ public interface IAppsBusinessLogic /// Id of the app /// Id of the subscription /// Returns the details of the subscription - Task GetSubscriptionDetailForProvider(Guid appId, Guid subscriptionId); + Task GetSubscriptionDetailForProvider(Guid appId, Guid subscriptionId); /// /// Gets the information for the subscription diff --git a/src/marketplace/Apps.Service/Controllers/AppsController.cs b/src/marketplace/Apps.Service/Controllers/AppsController.cs index ca4f0388ae..7cbaed274f 100644 --- a/src/marketplace/Apps.Service/Controllers/AppsController.cs +++ b/src/marketplace/Apps.Service/Controllers/AppsController.cs @@ -381,11 +381,11 @@ public async Task GetAppDocumentContentAsync([FromRoute] Guid appId, [Authorize(Roles = "app_management")] [Authorize(Policy = PolicyTypes.ValidCompany)] [Route("{appId}/subscription/{subscriptionId}/provider")] - [ProducesResponseType(typeof(AppProviderSubscriptionDetailData), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(OfferProviderSubscriptionDetailData), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status403Forbidden)] [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)] [PublicUrl(CompanyRoleId.APP_PROVIDER)] - public Task GetSubscriptionDetailForProvider([FromRoute] Guid appId, [FromRoute] Guid subscriptionId) => + public Task GetSubscriptionDetailForProvider([FromRoute] Guid appId, [FromRoute] Guid subscriptionId) => _appsBusinessLogic.GetSubscriptionDetailForProvider(appId, subscriptionId); /// diff --git a/src/marketplace/Offers.Library/Models/OfferProviderSubscriptionDetailData.cs b/src/marketplace/Offers.Library/Models/OfferProviderSubscriptionDetailData.cs new file mode 100644 index 0000000000..90aab1bada --- /dev/null +++ b/src/marketplace/Offers.Library/Models/OfferProviderSubscriptionDetailData.cs @@ -0,0 +1,59 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; +using System.Text.Json.Serialization; + +namespace Org.Eclipse.TractusX.Portal.Backend.Offers.Library.Models; + +/// +/// Detail data for a offer subscription +/// +/// Id of the Offer +/// Status of the offer subscription +/// Name of the Offer +/// Name of the company subscribing the offer +/// When called from /provider bpn of the company subscribing the offer, otherwise the provider company's bpn +/// When called from /provider the company admins of the subscribing company, otherwise the salesmanagers of the offer provider +/// Information about the technical user +/// Url of Tenant +/// Id of the app instance +public record OfferProviderSubscriptionDetailData( + Guid Id, + OfferSubscriptionStatusId OfferSubscriptionStatus, + string? Name, + string Customer, + string? Bpn, + IEnumerable Contact, + IEnumerable TechnicalUserData, + IEnumerable ConnectorData, + string? TenantUrl, + string? AppInstanceId, + ProcessStepTypeId? ProcessStepTypeId, + SubscriptionExternalServiceData ExternalService +); +public record SubscriptionExternalServiceData( + [property: JsonPropertyName("trusted_issuer")] string TrustedIssuer, + [property: JsonPropertyName("participant_id")] string? ParticipantId, + [property: JsonPropertyName("iatp_id")] string? IatpId, + [property: JsonPropertyName("did_resolver")] string DidResolver, + [property: JsonPropertyName("decentralIdentityManagementAuthUrl")] string DecentralIdentityManagementAuthUrl, + [property: JsonPropertyName("decentralIdentityManagementServiceUrl")] string? DecentralIdentityManagementServiceUrl +); diff --git a/src/marketplace/Offers.Library/Service/IOfferService.cs b/src/marketplace/Offers.Library/Service/IOfferService.cs index 15697e083f..169193d4c5 100644 --- a/src/marketplace/Offers.Library/Service/IOfferService.cs +++ b/src/marketplace/Offers.Library/Service/IOfferService.cs @@ -213,16 +213,6 @@ Task CreateOrUpdateOfferSubscriptionAgreementConsentAsync(Guid subscriptionId, /// Client to get the technicalUserProfiles Task UpdateTechnicalUserProfiles(Guid offerId, OfferTypeId offerTypeId, IEnumerable data, string technicalUserProfileClient); - /// - /// Gets the information for the subscription for the provider - /// - /// Id of the offer - /// Id of the subscription - /// Offer type - /// The roles of the users that will be listed as contact - /// Returns the details of the subscription - Task GetSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, OfferTypeId offerTypeId, IEnumerable contactUserRoles); - /// /// Gets the information for the subscription for the subscriber /// @@ -254,7 +244,7 @@ Task CreateOrUpdateOfferSubscriptionAgreementConsentAsync(Guid subscriptionId, /// The roles of the users that will be listed as contact /// The information for the external service data /// Returns the details of the subscription - Task GetAppSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, OfferTypeId offerTypeId, IEnumerable contactUserRoles, WalletConfigData walletData); + Task GetOfferSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, OfferTypeId offerTypeId, IEnumerable contactUserRoles, WalletConfigData walletData); /// /// Unsubscribe the Offer subscription by subscriptionId diff --git a/src/marketplace/Offers.Library/Service/OfferService.cs b/src/marketplace/Offers.Library/Service/OfferService.cs index d6bd98a8d0..436fb6441a 100644 --- a/src/marketplace/Offers.Library/Service/OfferService.cs +++ b/src/marketplace/Offers.Library/Service/OfferService.cs @@ -788,16 +788,12 @@ public async Task UpdateTechnicalUserProfiles(Guid offerId, OfferTypeId offerTyp } /// - public Task GetSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, OfferTypeId offerTypeId, IEnumerable contactUserRoles) => - GetOfferSubscriptionDetailsInternal(offerId, subscriptionId, offerTypeId, contactUserRoles, OfferCompanyRole.Provider, portalRepositories.GetInstance().GetSubscriptionDetailsForProviderAsync); - - /// - public async Task GetAppSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, OfferTypeId offerTypeId, IEnumerable contactUserRoles, WalletConfigData walletData) + public async Task GetOfferSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, OfferTypeId offerTypeId, IEnumerable contactUserRoles, WalletConfigData walletData) { - var data = await GetOfferSubscriptionDetailsInternal(offerId, subscriptionId, offerTypeId, contactUserRoles, OfferCompanyRole.Provider, portalRepositories.GetInstance().GetAppSubscriptionDetailsForProviderAsync) + var data = await GetOfferSubscriptionDetailsInternal(offerId, subscriptionId, offerTypeId, contactUserRoles, OfferCompanyRole.Provider, portalRepositories.GetInstance().GetOfferSubscriptionDetailsForProviderAsync) .ConfigureAwait(ConfigureAwaitOptions.None); - return new AppProviderSubscriptionDetailData( + return new OfferProviderSubscriptionDetailData( data.Id, data.OfferSubscriptionStatus, data.Name, diff --git a/src/marketplace/Services.Service/BusinessLogic/ServiceBusinessLogic.cs b/src/marketplace/Services.Service/BusinessLogic/ServiceBusinessLogic.cs index fdb1cfabd1..3d21cb8ea3 100644 --- a/src/marketplace/Services.Service/BusinessLogic/ServiceBusinessLogic.cs +++ b/src/marketplace/Services.Service/BusinessLogic/ServiceBusinessLogic.cs @@ -210,8 +210,22 @@ private static IEnumerable GetOfferStatusIds(ServiceStatusIdFilte } /// - public Task GetSubscriptionDetailForProvider(Guid serviceId, Guid subscriptionId) => - _offerService.GetSubscriptionDetailsForProviderAsync(serviceId, subscriptionId, OfferTypeId.SERVICE, _settings.CompanyAdminRoles); + public async Task GetSubscriptionDetailForProvider(Guid serviceId, Guid subscriptionId) + { + var offerSubscriptionDetails = await _offerService.GetOfferSubscriptionDetailsForProviderAsync(serviceId, subscriptionId, OfferTypeId.SERVICE, _settings.CompanyAdminRoles, new WalletConfigData(_settings.IssuerDid, _settings.BpnDidResolverUrl, _settings.DecentralIdentityManagementAuthUrl)).ConfigureAwait(ConfigureAwaitOptions.None); + return new( + offerSubscriptionDetails.Id, + offerSubscriptionDetails.OfferSubscriptionStatus, + offerSubscriptionDetails.Name, + offerSubscriptionDetails.Customer, + offerSubscriptionDetails.Bpn, + offerSubscriptionDetails.Contact, + offerSubscriptionDetails.TechnicalUserData, + offerSubscriptionDetails.ConnectorData, + offerSubscriptionDetails.ProcessStepTypeId, + offerSubscriptionDetails.ExternalService + ); + } /// public Task GetSubscriptionDetailForSubscriber(Guid serviceId, Guid subscriptionId) => diff --git a/src/marketplace/Services.Service/ServiceSettings.cs b/src/marketplace/Services.Service/ServiceSettings.cs index d90ae22f4d..9cb40b718b 100644 --- a/src/marketplace/Services.Service/ServiceSettings.cs +++ b/src/marketplace/Services.Service/ServiceSettings.cs @@ -168,6 +168,15 @@ public class ServiceSettings [Required] [DistinctValues("x => x.ClientId")] public IEnumerable DimUserRoles { get; set; } = null!; + + [Required(AllowEmptyStrings = true)] + public string DecentralIdentityManagementAuthUrl { get; set; } = null!; + + [Required(AllowEmptyStrings = true)] + public string IssuerDid { get; set; } = null!; + + [Required(AllowEmptyStrings = true)] + public string BpnDidResolverUrl { get; set; } = null!; } public static class ServiceSettingsExtension diff --git a/src/marketplace/Services.Service/ViewModels/ProviderSubscriptionDetailData.cs b/src/marketplace/Services.Service/ViewModels/ProviderSubscriptionDetailData.cs new file mode 100644 index 0000000000..95b97dd579 --- /dev/null +++ b/src/marketplace/Services.Service/ViewModels/ProviderSubscriptionDetailData.cs @@ -0,0 +1,50 @@ +/******************************************************************************** + * Copyright (c) 2024 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 Org.Eclipse.TractusX.Portal.Backend.Offers.Library.Models; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; + +namespace Org.Eclipse.TractusX.Portal.Backend.Services.Service; + +/// +/// Detail data for a offer subscription +/// +/// Id of the Offer +/// Status of the offer subscription +/// Name of the Offer +/// Name of the company subscribing the offer +/// When called from /provider bpn of the company subscribing the offer, otherwise the provider company's bpn +/// When called from /provider the company admins of the subscribing company, otherwise the salesmanagers of the offer provider +/// Information about the technical user +/// +/// +/// +public record ProviderSubscriptionDetailData( + Guid Id, + OfferSubscriptionStatusId OfferSubscriptionStatus, + string? Name, + string Customer, + string? Bpn, + IEnumerable Contact, + IEnumerable TechnicalUserData, + IEnumerable ConnectorData, + ProcessStepTypeId? ProcessStepTypeId, + SubscriptionExternalServiceData ExternalService +); diff --git a/src/marketplace/Services.Service/appsettings.json b/src/marketplace/Services.Service/appsettings.json index c8812dfc86..26e2f4f03c 100644 --- a/src/marketplace/Services.Service/appsettings.json +++ b/src/marketplace/Services.Service/appsettings.json @@ -56,6 +56,9 @@ }, "Services": { "BasePortalAddress": "https://portal.example.org", + "DecentralIdentityManagementAuthUrl": "", + "IssuerDid": "", + "BpnDidResolverUrl": "", "ServiceOverviewAddress": "https://portal.example.org", "CatenaAdminRoles": [], "ServiceAccountRoles": [], diff --git a/src/portalbackend/PortalBackend.DBAccess/Models/OfferSubscriptionDetailData.cs b/src/portalbackend/PortalBackend.DBAccess/Models/OfferSubscriptionDetailData.cs index f7b8ca48d4..162ff7dfea 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Models/OfferSubscriptionDetailData.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Models/OfferSubscriptionDetailData.cs @@ -29,62 +29,6 @@ public record SubscriptionTechnicalUserData( IEnumerable Permissions ); -/// -/// Detail data for a offer subscription -/// -/// Id of the Offer -/// Status of the offer subscription -/// Name of the Offer -/// Name of the company subscribing the offer -/// When called from /provider bpn of the company subscribing the offer, otherwise the provider company's bpn -/// When called from /provider the company admins of the subscribing company, otherwise the salesmanagers of the offer provider -/// Information about the technical user -public record ProviderSubscriptionDetailData( - Guid Id, - OfferSubscriptionStatusId OfferSubscriptionStatus, - string? Name, - string Customer, - string? Bpn, - IEnumerable Contact, - IEnumerable TechnicalUserData -); - -/// -/// Detail data for a offer subscription -/// -/// Id of the Offer -/// Status of the offer subscription -/// Name of the Offer -/// Name of the company subscribing the offer -/// When called from /provider bpn of the company subscribing the offer, otherwise the provider company's bpn -/// When called from /provider the company admins of the subscribing company, otherwise the salesmanagers of the offer provider -/// Information about the technical user -/// Url of Tenant -/// Id of the app instance -public record AppProviderSubscriptionDetailData( - Guid Id, - OfferSubscriptionStatusId OfferSubscriptionStatus, - string? Name, - string Customer, - string? Bpn, - IEnumerable Contact, - IEnumerable TechnicalUserData, - IEnumerable ConnectorData, - string? TenantUrl, - string AppInstanceId, - ProcessStepTypeId? ProcessStepTypeId, - SubscriptionExternalServiceData ExternalService -); - -public record SubscriptionExternalServiceData( - [property: JsonPropertyName("trusted_issuer")] string TrustedIssuer, - [property: JsonPropertyName("participant_id")] string? ParticipantId, - [property: JsonPropertyName("iatp_id")] string? IatpId, - [property: JsonPropertyName("did_resolver")] string DidResolver, - [property: JsonPropertyName("decentralIdentityManagementAuthUrl")] string DecentralIdentityManagementAuthUrl, - [property: JsonPropertyName("decentralIdentityManagementServiceUrl")] string? DecentralIdentityManagementServiceUrl -); - /// /// Detail data for a offer subscription /// @@ -127,7 +71,7 @@ public record SubscriptionAssignedConnectorData( /// Information about the technical user /// Url of Tenant /// Id of the app instance -public record AppProviderSubscriptionDetail( +public record OfferProviderSubscriptionDetail( Guid Id, OfferSubscriptionStatusId OfferSubscriptionStatus, string? Name, @@ -136,7 +80,7 @@ public record AppProviderSubscriptionDetail( IEnumerable Contact, IEnumerable TechnicalUserData, string? TenantUrl, - string AppInstanceId, + string? AppInstanceId, IEnumerable<(ProcessStepTypeId ProcessStepTypeId, ProcessStepStatusId ProcessStepStatusId)> ProcessSteps, IEnumerable ConnectorData, ExternalServiceData? ExternalServiceData diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IOfferSubscriptionsRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IOfferSubscriptionsRepository.cs index d29a9cb2c1..2b569b793b 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IOfferSubscriptionsRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IOfferSubscriptionsRepository.cs @@ -83,17 +83,6 @@ public interface IOfferSubscriptionsRepository /// Returns an IAsyncEnumerable of app data IAsyncEnumerable<(Guid OfferId, Guid SubscriptionId, string? OfferName, string SubscriptionUrl, Guid LeadPictureId, string Provider)> GetAllBusinessAppDataForUserIdAsync(Guid userId); - /// - /// Gets the offer details for the offer subscription for a provider company user - /// - /// Id of the offer - /// Id of the subscription - /// Id of the user company - /// Offer type - /// Ids of the user roles the contacts should be in - /// Returns details for the offer subscription - Task<(bool Exists, bool IsUserOfCompany, ProviderSubscriptionDetailData? Details)> GetSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, Guid userCompanyId, OfferTypeId offerTypeId, IEnumerable userRoleIds); - /// /// Gets the app details for the offer subscription for a provider company user /// @@ -103,7 +92,7 @@ public interface IOfferSubscriptionsRepository /// Offer type /// Ids of the user roles the contacts should be in /// Returns details for the offer subscription - Task<(bool Exists, bool IsUserOfCompany, AppProviderSubscriptionDetail? Details)> GetAppSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, Guid userCompanyId, OfferTypeId offerTypeId, IEnumerable userRoleIds); + Task<(bool Exists, bool IsUserOfCompany, OfferProviderSubscriptionDetail? Details)> GetOfferSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, Guid userCompanyId, OfferTypeId offerTypeId, IEnumerable userRoleIds); /// /// Gets the offer details for the offer subscription for a subscribing company user diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/OfferSubscriptionsRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/OfferSubscriptionsRepository.cs index e9975890e8..04edf67fec 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/OfferSubscriptionsRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/OfferSubscriptionsRepository.cs @@ -166,9 +166,10 @@ public OfferSubscription AttachAndModifyOfferSubscription(Guid offerSubscription /// public IAsyncEnumerable<(Guid OfferId, Guid SubscriptionId, string? OfferName, string SubscriptionUrl, Guid LeadPictureId, string Provider)> GetAllBusinessAppDataForUserIdAsync(Guid userId) => dbContext.CompanyUsers.AsNoTracking() - .Where(user => user.Id == userId) + .Where(user => user.Id == userId && user.Identity!.IdentityTypeId == IdentityTypeId.COMPANY_USER) .SelectMany(user => user.Identity!.Company!.OfferSubscriptions.Where(subscription => - subscription.Offer!.UserRoles.Any(ur => ur.IdentityAssignedRoles.Any(cu => cu.IdentityId == user.Id && cu.Identity!.IdentityTypeId == IdentityTypeId.COMPANY_USER)) && + subscription.Offer!.OfferTypeId == OfferTypeId.APP && + subscription.Offer.UserRoles.Any(ur => ur.IdentityAssignedRoles.Any(iar => iar.IdentityId == userId)) && subscription.AppSubscriptionDetail!.AppInstance != null && subscription.AppSubscriptionDetail.AppSubscriptionUrl != null)) .Select(offerSubscription => new ValueTuple( @@ -180,33 +181,7 @@ public OfferSubscription AttachAndModifyOfferSubscription(Guid offerSubscription offerSubscription.Offer!.ProviderCompany!.Name )).ToAsyncEnumerable(); - /// - public Task<(bool Exists, bool IsUserOfCompany, ProviderSubscriptionDetailData? Details)> GetSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, Guid userCompanyId, OfferTypeId offerTypeId, IEnumerable userRoleIds) => - dbContext.OfferSubscriptions - .AsSplitQuery() - .Where(os => os.Id == subscriptionId && os.OfferId == offerId && os.Offer!.OfferTypeId == offerTypeId) - .Select(os => new - { - IsProviderCompany = os.Offer!.ProviderCompanyId == userCompanyId, - Subscription = os, - Company = os.Company - }) - .Select(x => new ValueTuple( - true, - x.IsProviderCompany, - x.IsProviderCompany - ? new ProviderSubscriptionDetailData( - x.Subscription.OfferId, - x.Subscription.OfferSubscriptionStatusId, - x.Subscription.Offer!.Name, - x.Company!.Name, - x.Company.BusinessPartnerNumber, - x.Company.Identities.Where(x => x.IdentityTypeId == IdentityTypeId.COMPANY_USER).Select(i => i.CompanyUser!).Where(cu => cu.Email != null && cu.Identity!.IdentityAssignedRoles.Select(ur => ur.UserRole!).Any(ur => userRoleIds.Contains(ur.Id))).Select(cu => cu.Email!), - x.Subscription.Technicalusers.Select(sa => new SubscriptionTechnicalUserData(sa.Id, sa.ClientClientId, sa.Identity!.IdentityAssignedRoles.Select(ur => ur.UserRole!).Select(ur => ur.UserRoleText)))) - : null)) - .SingleOrDefaultAsync(); - - public Task<(bool Exists, bool IsUserOfCompany, AppProviderSubscriptionDetail? Details)> GetAppSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, Guid userCompanyId, OfferTypeId offerTypeId, IEnumerable userRoleIds) => + public Task<(bool Exists, bool IsUserOfCompany, OfferProviderSubscriptionDetail? Details)> GetOfferSubscriptionDetailsForProviderAsync(Guid offerId, Guid subscriptionId, Guid userCompanyId, OfferTypeId offerTypeId, IEnumerable userRoleIds) => dbContext.OfferSubscriptions .AsSplitQuery() .Where(os => os.Id == subscriptionId && os.OfferId == offerId && os.Offer!.OfferTypeId == offerTypeId) @@ -216,11 +191,11 @@ public OfferSubscription AttachAndModifyOfferSubscription(Guid offerSubscription Subscription = os, Company = os.Company }) - .Select(x => new ValueTuple( + .Select(x => new ValueTuple( true, x.IsProviderCompany, x.IsProviderCompany - ? new AppProviderSubscriptionDetail( + ? new OfferProviderSubscriptionDetail( x.Subscription.OfferId, x.Subscription.OfferSubscriptionStatusId, x.Subscription.Offer!.Name, @@ -228,8 +203,8 @@ public OfferSubscription AttachAndModifyOfferSubscription(Guid offerSubscription x.Company.BusinessPartnerNumber, x.Company.Identities.Where(i => i.IdentityTypeId == IdentityTypeId.COMPANY_USER).Select(id => id.CompanyUser!).Where(cu => cu.Email != null && cu.Identity!.IdentityAssignedRoles.Select(ur => ur.UserRole!).Any(ur => userRoleIds.Contains(ur.Id))).Select(cu => cu.Email!), x.Subscription.Technicalusers.Select(sa => new SubscriptionTechnicalUserData(sa.Id, sa.Name, sa.Identity!.IdentityAssignedRoles.Select(ur => ur.UserRole!).Select(ur => ur.UserRoleText))), - x.Subscription.AppSubscriptionDetail!.AppSubscriptionUrl, - x.Subscription.AppSubscriptionDetail!.AppInstance!.IamClient!.ClientClientId, + offerTypeId == OfferTypeId.APP ? x.Subscription.AppSubscriptionDetail!.AppSubscriptionUrl : null, + offerTypeId == OfferTypeId.APP ? x.Subscription.AppSubscriptionDetail!.AppInstance!.IamClient!.ClientClientId : null, x.Subscription.Process!.ProcessSteps .Where(ps => ps.ProcessStepStatusId == ProcessStepStatusId.TODO) .Select(ps => new ValueTuple( diff --git a/src/portalbackend/PortalBackend.PortalEntities/Entities/CompanyUserAssignedRole.cs b/src/portalbackend/PortalBackend.PortalEntities/Entities/IdentityAssignedRole.cs similarity index 98% rename from src/portalbackend/PortalBackend.PortalEntities/Entities/CompanyUserAssignedRole.cs rename to src/portalbackend/PortalBackend.PortalEntities/Entities/IdentityAssignedRole.cs index f53873078c..a67199dbca 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Entities/CompanyUserAssignedRole.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Entities/IdentityAssignedRole.cs @@ -1,5 +1,4 @@ /******************************************************************************** - * 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 diff --git a/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyServiceAccountKindId.cs b/src/portalbackend/PortalBackend.PortalEntities/Enums/TechnicalUserKindId.cs similarity index 100% rename from src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyServiceAccountKindId.cs rename to src/portalbackend/PortalBackend.PortalEntities/Enums/TechnicalUserKindId.cs diff --git a/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyServiceAccountTypeId.cs b/src/portalbackend/PortalBackend.PortalEntities/Enums/TechnicalUserTypeId.cs similarity index 96% rename from src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyServiceAccountTypeId.cs rename to src/portalbackend/PortalBackend.PortalEntities/Enums/TechnicalUserTypeId.cs index 031114d321..723b027088 100644 --- a/src/portalbackend/PortalBackend.PortalEntities/Enums/CompanyServiceAccountTypeId.cs +++ b/src/portalbackend/PortalBackend.PortalEntities/Enums/TechnicalUserTypeId.cs @@ -1,5 +1,4 @@ /******************************************************************************** - * 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 diff --git a/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppBusinessLogicTests.cs b/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppBusinessLogicTests.cs index cdd5c1807a..cd3d661409 100644 --- a/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppBusinessLogicTests.cs +++ b/tests/marketplace/Apps.Service.Tests/BusinessLogic/AppBusinessLogicTests.cs @@ -495,7 +495,7 @@ public async Task GetSubscriptionDetailForProvider_ReturnsExpected() // Arrange var appId = Guid.NewGuid(); var subscriptionId = Guid.NewGuid(); - var data = _fixture.Create(); + var data = _fixture.Create(); var settings = new AppsSettings { CompanyAdminRoles = new[] @@ -503,7 +503,7 @@ public async Task GetSubscriptionDetailForProvider_ReturnsExpected() new UserRoleConfig("ClientTest", new[] {"Test"}) } }; - A.CallTo(() => _offerService.GetAppSubscriptionDetailsForProviderAsync(A._, A._, A._, A>._, A._)) + A.CallTo(() => _offerService.GetOfferSubscriptionDetailsForProviderAsync(A._, A._, A._, A>._, A._)) .Returns(data); var sut = new AppsBusinessLogic(null!, null!, _offerService, null!, Options.Create(settings), _identityService); @@ -512,7 +512,7 @@ public async Task GetSubscriptionDetailForProvider_ReturnsExpected() // Assert result.Should().Be(data); - A.CallTo(() => _offerService.GetAppSubscriptionDetailsForProviderAsync(appId, subscriptionId, OfferTypeId.APP, A>._, A._)) + A.CallTo(() => _offerService.GetOfferSubscriptionDetailsForProviderAsync(appId, subscriptionId, OfferTypeId.APP, A>._, A._)) .MustHaveHappenedOnceExactly(); } diff --git a/tests/marketplace/Apps.Service.Tests/Controllers/AppsControllerTests.cs b/tests/marketplace/Apps.Service.Tests/Controllers/AppsControllerTests.cs index f998dbe29d..a79f72de3d 100644 --- a/tests/marketplace/Apps.Service.Tests/Controllers/AppsControllerTests.cs +++ b/tests/marketplace/Apps.Service.Tests/Controllers/AppsControllerTests.cs @@ -379,7 +379,7 @@ public async Task GetSubscriptionDetailForProvider_ReturnsExpected() // Arrange var appId = _fixture.Create(); var subscriptionId = _fixture.Create(); - var data = _fixture.Create(); + var data = _fixture.Create(); A.CallTo(() => _logic.GetSubscriptionDetailForProvider(appId, subscriptionId)) .Returns(data); diff --git a/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs b/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs index c4abeaf861..72f32ed745 100644 --- a/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs +++ b/tests/marketplace/Offers.Library.Tests/Service/OfferServiceTests.cs @@ -2090,117 +2090,10 @@ public async Task UpdateTechnicalUserProfiles_WithoutTechnicalUserProfileAndUser } #endregion - #region GetSubscriptionDetailForProvider + #region GetOfferSubscriptionDetailForProvider [Fact] - public async Task GetSubscriptionDetailForProvider_WithNotMatchingUserRoles_ThrowsConfigurationException() - { - // Arrange - var offerId = Guid.NewGuid(); - var subscriptionId = Guid.NewGuid(); - var companyAdminRoles = _fixture.CreateMany().ToImmutableArray(); - - SetupGetSubscriptionDetailForProvider(); - - // Act - async Task Act() => await _sut.GetSubscriptionDetailsForProviderAsync(offerId, subscriptionId, OfferTypeId.SERVICE, companyAdminRoles); - - // Assert - var ex = await Assert.ThrowsAsync(Act); - ex.Message.Should().Contain("invalid configuration, at least one of the configured roles does not exist in the database:"); - A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.IsSameSequenceAs(companyAdminRoles))) - .MustHaveHappenedOnceExactly(); - A.CallTo(() => _offerSubscriptionsRepository.GetSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) - .MustNotHaveHappened(); - } - - [Fact] - public async Task GetSubscriptionDetailForProvider_WithNotExistingOffer_ThrowsNotFoundException() - { - // Arrange - var serviceId = Guid.NewGuid(); - var subscriptionId = Guid.NewGuid(); - var companyAdminRoles = new[] - { - new UserRoleConfig("ClientTest", new[] {"Test"}) - }; - SetupGetSubscriptionDetailForProvider(); - - A.CallTo(() => _offerSubscriptionsRepository.GetSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) - .Returns<(bool, bool, ProviderSubscriptionDetailData?)>(default); - - // Act - async Task Act() => await _sut.GetSubscriptionDetailsForProviderAsync(serviceId, subscriptionId, OfferTypeId.SERVICE, companyAdminRoles); - - // Assert - var ex = await Assert.ThrowsAsync(Act); - ex.Message.Should().Contain($"subscription {subscriptionId} for offer {serviceId} of type {OfferTypeId.SERVICE} does not exist"); - A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.IsSameSequenceAs(companyAdminRoles))) - .MustHaveHappenedOnceExactly(); - A.CallTo(() => _offerSubscriptionsRepository.GetSubscriptionDetailsForProviderAsync(serviceId, subscriptionId, _companyId, OfferTypeId.SERVICE, A>.That.IsSameSequenceAs(new[] { _validUserRoleId }))) - .MustHaveHappenedOnceExactly(); - } - - [Fact] - public async Task GetSubscriptionDetailForProvider_WithUserNotInProvidingCompany_ThrowsForbiddenException() - { - // Arrange - var serviceId = Guid.NewGuid(); - var subscriptionId = Guid.NewGuid(); - var companyAdminRoles = new[] - { - new UserRoleConfig("ClientTest", new[] {"Test"}) - }; - SetupGetSubscriptionDetailForProvider(); - - A.CallTo(() => _offerSubscriptionsRepository.GetSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) - .Returns((true, false, _fixture.Create())); - - // Act - async Task Act() => await _sut.GetSubscriptionDetailsForProviderAsync(serviceId, subscriptionId, OfferTypeId.SERVICE, companyAdminRoles); - - // Assert - var ex = await Assert.ThrowsAsync(Act); - ex.Message.Should().Contain($"Company {_companyId} is not part of the Provider company"); - A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.IsSameSequenceAs(companyAdminRoles))) - .MustHaveHappenedOnceExactly(); - A.CallTo(() => _offerSubscriptionsRepository.GetSubscriptionDetailsForProviderAsync(serviceId, subscriptionId, _companyId, OfferTypeId.SERVICE, A>.That.IsSameSequenceAs(new[] { _validUserRoleId }))) - .MustHaveHappenedOnceExactly(); - } - - [Fact] - public async Task GetSubscriptionDetailForProvider_WithValidData_ReturnsExpected() - { - // Arrange - var serviceId = Guid.NewGuid(); - var subscriptionId = Guid.NewGuid(); - var companyAdminRoles = new[] - { - new UserRoleConfig("ClientTest", new[] {"Test"}) - }; - SetupGetSubscriptionDetailForProvider(); - - var data = _fixture.Create(); - - A.CallTo(() => _offerSubscriptionsRepository.GetSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) - .Returns((true, true, data)); - // Act - var result = await _sut.GetSubscriptionDetailsForProviderAsync(serviceId, subscriptionId, OfferTypeId.SERVICE, companyAdminRoles); - - // Assert - result.Should().Be(data); - A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.IsSameSequenceAs(companyAdminRoles))) - .MustHaveHappenedOnceExactly(); - A.CallTo(() => _offerSubscriptionsRepository.GetSubscriptionDetailsForProviderAsync(serviceId, subscriptionId, _companyId, OfferTypeId.SERVICE, A>.That.IsSameSequenceAs(new[] { _validUserRoleId }))) - .MustHaveHappenedOnceExactly(); - } - - #endregion - - #region GetAppSubscriptionDetailForProvider - - [Fact] - public async Task GetAppSubscriptionDetailForProvider_WithNotMatchingUserRoles_ThrowsConfigurationException() + public async Task GetOfferSubscriptionDetailForProvider_WithNotMatchingUserRoles_ThrowsConfigurationException() { // Arrange var offerId = Guid.NewGuid(); @@ -2211,19 +2104,19 @@ public async Task GetAppSubscriptionDetailForProvider_WithNotMatchingUserRoles_T SetupGetSubscriptionDetailForProvider(); // Act - async Task Act() => await _sut.GetAppSubscriptionDetailsForProviderAsync(offerId, subscriptionId, OfferTypeId.APP, companyAdminRoles, walletData); + async Task Act() => await _sut.GetOfferSubscriptionDetailsForProviderAsync(offerId, subscriptionId, OfferTypeId.APP, companyAdminRoles, walletData); // Assert var ex = await Assert.ThrowsAsync(Act); ex.Message.Should().Contain("invalid configuration, at least one of the configured roles does not exist in the database:"); A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.IsSameSequenceAs(companyAdminRoles))) .MustHaveHappenedOnceExactly(); - A.CallTo(() => _offerSubscriptionsRepository.GetSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) + A.CallTo(() => _offerSubscriptionsRepository.GetOfferSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) .MustNotHaveHappened(); } [Fact] - public async Task GetAppSubscriptionDetailForProvider_WithNotExistingOffer_ThrowsNotFoundException() + public async Task GetOfferSubscriptionDetailForProvider_WithNotExistingOffer_ThrowsNotFoundException() { // Arrange var appId = Guid.NewGuid(); @@ -2235,23 +2128,23 @@ public async Task GetAppSubscriptionDetailForProvider_WithNotExistingOffer_Throw var walletData = _fixture.Create(); SetupGetSubscriptionDetailForProvider(); - A.CallTo(() => _offerSubscriptionsRepository.GetAppSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) - .Returns<(bool, bool, AppProviderSubscriptionDetail?)>(default); + A.CallTo(() => _offerSubscriptionsRepository.GetOfferSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) + .Returns<(bool, bool, OfferProviderSubscriptionDetail?)>(default); // Act - async Task Act() => await _sut.GetAppSubscriptionDetailsForProviderAsync(appId, subscriptionId, OfferTypeId.APP, companyAdminRoles, walletData); + async Task Act() => await _sut.GetOfferSubscriptionDetailsForProviderAsync(appId, subscriptionId, OfferTypeId.APP, companyAdminRoles, walletData); // Assert var ex = await Assert.ThrowsAsync(Act); ex.Message.Should().Contain($"subscription {subscriptionId} for offer {appId} of type {OfferTypeId.APP} does not exist"); A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.IsSameSequenceAs(companyAdminRoles))) .MustHaveHappenedOnceExactly(); - A.CallTo(() => _offerSubscriptionsRepository.GetAppSubscriptionDetailsForProviderAsync(appId, subscriptionId, _companyId, OfferTypeId.APP, A>.That.IsSameSequenceAs(new[] { _validUserRoleId }))) + A.CallTo(() => _offerSubscriptionsRepository.GetOfferSubscriptionDetailsForProviderAsync(appId, subscriptionId, _companyId, OfferTypeId.APP, A>.That.IsSameSequenceAs(new[] { _validUserRoleId }))) .MustHaveHappenedOnceExactly(); } [Fact] - public async Task GetAppSubscriptionDetailForProvider_WithUserNotInProvidingCompany_ThrowsForbiddenException() + public async Task GetOfferSubscriptionDetailForProvider_WithUserNotInProvidingCompany_ThrowsForbiddenException() { // Arrange var appId = Guid.NewGuid(); @@ -2263,23 +2156,23 @@ public async Task GetAppSubscriptionDetailForProvider_WithUserNotInProvidingComp var walletData = _fixture.Create(); SetupGetSubscriptionDetailForProvider(); - A.CallTo(() => _offerSubscriptionsRepository.GetAppSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) - .Returns((true, false, _fixture.Create())); + A.CallTo(() => _offerSubscriptionsRepository.GetOfferSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) + .Returns((true, false, _fixture.Create())); // Act - async Task Act() => await _sut.GetAppSubscriptionDetailsForProviderAsync(appId, subscriptionId, OfferTypeId.APP, companyAdminRoles, walletData); + async Task Act() => await _sut.GetOfferSubscriptionDetailsForProviderAsync(appId, subscriptionId, OfferTypeId.APP, companyAdminRoles, walletData); // Assert var ex = await Assert.ThrowsAsync(Act); ex.Message.Should().Contain($"Company {_companyId} is not part of the Provider company"); A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.IsSameSequenceAs(companyAdminRoles))) .MustHaveHappenedOnceExactly(); - A.CallTo(() => _offerSubscriptionsRepository.GetAppSubscriptionDetailsForProviderAsync(appId, subscriptionId, _companyId, OfferTypeId.APP, A>.That.IsSameSequenceAs(new[] { _validUserRoleId }))) + A.CallTo(() => _offerSubscriptionsRepository.GetOfferSubscriptionDetailsForProviderAsync(appId, subscriptionId, _companyId, OfferTypeId.APP, A>.That.IsSameSequenceAs(new[] { _validUserRoleId }))) .MustHaveHappenedOnceExactly(); } [Fact] - public async Task GetAppSubscriptionDetailForProvider_WithValidData_ReturnsExpected() + public async Task GetOfferSubscriptionDetailForProvider_WithValidData_ReturnsExpected() { // Arrange var appId = Guid.NewGuid(); @@ -2291,13 +2184,13 @@ public async Task GetAppSubscriptionDetailForProvider_WithValidData_ReturnsExpec var walletData = _fixture.Create(); SetupGetSubscriptionDetailForProvider(); - var data = _fixture.Create(); + var data = _fixture.Create(); - A.CallTo(() => _offerSubscriptionsRepository.GetAppSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) + A.CallTo(() => _offerSubscriptionsRepository.GetOfferSubscriptionDetailsForProviderAsync(A._, A._, A._, A._, A>._)) .Returns((true, true, data)); // Act - var result = await _sut.GetAppSubscriptionDetailsForProviderAsync(appId, subscriptionId, OfferTypeId.APP, companyAdminRoles, walletData); + var result = await _sut.GetOfferSubscriptionDetailsForProviderAsync(appId, subscriptionId, OfferTypeId.APP, companyAdminRoles, walletData); // Assert result.Id.Should().Be(data.Id); @@ -2309,7 +2202,7 @@ public async Task GetAppSubscriptionDetailForProvider_WithValidData_ReturnsExpec result.OfferSubscriptionStatus.Should().Be(data.OfferSubscriptionStatus); A.CallTo(() => _userRolesRepository.GetUserRoleIdsUntrackedAsync(A>.That.IsSameSequenceAs(companyAdminRoles))) .MustHaveHappenedOnceExactly(); - A.CallTo(() => _offerSubscriptionsRepository.GetAppSubscriptionDetailsForProviderAsync(appId, subscriptionId, _companyId, OfferTypeId.APP, A>.That.IsSameSequenceAs(new[] { _validUserRoleId }))) + A.CallTo(() => _offerSubscriptionsRepository.GetOfferSubscriptionDetailsForProviderAsync(appId, subscriptionId, _companyId, OfferTypeId.APP, A>.That.IsSameSequenceAs(new[] { _validUserRoleId }))) .MustHaveHappenedOnceExactly(); } diff --git a/tests/marketplace/Services.Service.Tests/BusinessLogic/ServiceBusinessLogicTests.cs b/tests/marketplace/Services.Service.Tests/BusinessLogic/ServiceBusinessLogicTests.cs index f809da348c..3a56adbdc1 100644 --- a/tests/marketplace/Services.Service.Tests/BusinessLogic/ServiceBusinessLogicTests.cs +++ b/tests/marketplace/Services.Service.Tests/BusinessLogic/ServiceBusinessLogicTests.cs @@ -524,7 +524,10 @@ public async Task GetSubscriptionDetailForProvider_WithNotMatchingUserRoles_Thro // Arrange var offerId = _fixture.Create(); var subscriptionId = _fixture.Create(); - var data = _fixture.Create(); + var data = _fixture.Build() + .With(x => x.AppInstanceId, default(string?)) + .With(x => x.TenantUrl, default(string?)) + .Create(); var settings = new ServiceSettings { CompanyAdminRoles = new[] @@ -532,7 +535,7 @@ public async Task GetSubscriptionDetailForProvider_WithNotMatchingUserRoles_Thro new UserRoleConfig("ClientTest", new[] {"Test"}) } }; - A.CallTo(() => _offerService.GetSubscriptionDetailsForProviderAsync(offerId, subscriptionId, OfferTypeId.SERVICE, A>._)) + A.CallTo(() => _offerService.GetOfferSubscriptionDetailsForProviderAsync(A._, A._, A._, A>._, A._)) .Returns(data); var sut = new ServiceBusinessLogic(null!, _offerService, null!, null!, _identityService, Options.Create(settings)); @@ -540,7 +543,21 @@ public async Task GetSubscriptionDetailForProvider_WithNotMatchingUserRoles_Thro var result = await sut.GetSubscriptionDetailForProvider(offerId, subscriptionId); // Assert - result.Should().Be(data); + result.Should().Match(x => + x.Id == data.Id && + x.OfferSubscriptionStatus == data.OfferSubscriptionStatus && + x.Name == data.Name && + x.Customer == data.Customer && + x.Bpn == data.Bpn && + x.Contact.SequenceEqual(data.Contact) && + x.TechnicalUserData.SequenceEqual(data.TechnicalUserData) && + x.ConnectorData.SequenceEqual(data.ConnectorData) && + x.ProcessStepTypeId == data.ProcessStepTypeId && + x.ExternalService == data.ExternalService + ); + + A.CallTo(() => _offerService.GetOfferSubscriptionDetailsForProviderAsync(offerId, subscriptionId, OfferTypeId.SERVICE, A>._, A._)) + .MustHaveHappenedOnceExactly(); } #endregion diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/OfferSubscriptionRepositoryTest.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/OfferSubscriptionRepositoryTest.cs index 5c70c0c445..95f6ca272c 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/OfferSubscriptionRepositoryTest.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/OfferSubscriptionRepositoryTest.cs @@ -122,13 +122,13 @@ public async Task GetAllBusinessAppDataForUserIdAsync_WithValidUser_ReturnsExpec var (sut, _) = await CreateSut(); // Act - var result = await sut.GetAllBusinessAppDataForUserIdAsync(new("ac1cf001-7fbc-1f2f-817f-bce058020006")).ToListAsync(); + var result = await sut.GetAllBusinessAppDataForUserIdAsync(new("8b42e6de-7b59-4217-a63c-198e83d93776")).ToListAsync(); // Assert - result.Should().NotBeNullOrEmpty(); - result.Should().HaveCount(1); - result.First().SubscriptionUrl.Should().Be("https://ec-qas.d13fe27.kyma.ondemand.com"); - result.First().OfferId.Should().Be(new Guid("a16e73b9-5277-4b69-9f8d-3b227495dfea")); + result.Should().ContainSingle().Which.Should().Match<(Guid OfferId, Guid SubscriptionId, string? OfferName, string SubscriptionUrl, Guid LeadPictureId, string Provider)>(x => + x.SubscriptionUrl == "https://ec-qas.d13fe27.kyma.ondemand.com" && + x.OfferId == new Guid("ac1cf001-7fbc-1f2f-817f-bce05744000b") + ); } #endregion @@ -243,93 +243,62 @@ public async Task GetOfferDetailsAndCheckUser_WithSubscriptionForOfferWithoutApp #endregion - #region GetSubscriptionDetailForProviderAsync + #region GetOfferSubscriptionDetailForProviderAsync [Fact] - public async Task GetSubscriptionDetailForProviderAsync_ReturnsExpected() + public async Task GetOfferSubscriptionDetailForAppProviderAsync_ReturnsExpected() { // Arrange var (sut, _) = await CreateSut(); // Act - var result = await sut.GetSubscriptionDetailsForProviderAsync(new Guid("a16e73b9-5277-4b69-9f8d-3b227495dfea"), new Guid("3DE6A31F-A5D1-4F60-AA3A-4B1A769BECBF"), _userCompanyId, OfferTypeId.SERVICE, new[] { new Guid("58f897ec-0aad-4588-8ffa-5f45d6638632") }); + var result = await sut.GetOfferSubscriptionDetailsForProviderAsync(new Guid("ac1cf001-7fbc-1f2f-817f-bce05744000b"), new Guid("0b2ca541-206d-48ad-bc02-fb61fbcb5552"), new Guid("0dcd8209-85e2-4073-b130-ac094fb47106"), OfferTypeId.APP, new[] { new Guid("7410693c-c893-409e-852f-9ee886ce94a6") }); // Assert result.Exists.Should().BeTrue(); result.IsUserOfCompany.Should().BeTrue(); - result.Details.Should().NotBeNull().And.Match(x => - x.Name == "SDE with EDC" && - x.Customer == "CX-Operator" && - x.Contact.SequenceEqual(new[] { "tobeadded@cx.com" }) && - x.OfferSubscriptionStatus == OfferSubscriptionStatusId.ACTIVE - && x.TechnicalUserData.All(x => x.Id == new Guid("d0c8ae19-d4f3-49cc-9cb4-6c766d4680f2") && x.Name == "sa-x-4")); - } - - [Fact] - public async Task GetSubscriptionDetailForProviderAsync_WithNotExistingId_ReturnsExpected() - { - // Arrange - var (sut, _) = await CreateSut(); - - // Act - var result = await sut.GetSubscriptionDetailsForProviderAsync(Guid.NewGuid(), new Guid("3DE6A31F-A5D1-4F60-AA3A-4B1A769BECBF"), _userCompanyId, OfferTypeId.SERVICE, new List()); - - // Assert - result.Exists.Should().BeFalse(); - result.IsUserOfCompany.Should().BeFalse(); - result.Details.Should().BeNull(); - } - - [Fact] - public async Task GetSubscriptionDetailForProviderAsync_WithWrongUser_ReturnsExpected() - { - // Arrange - var (sut, _) = await CreateSut(); - - // Act - var result = await sut.GetSubscriptionDetailsForProviderAsync(new Guid("a16e73b9-5277-4b69-9f8d-3b227495dfea"), new Guid("3DE6A31F-A5D1-4F60-AA3A-4B1A769BECBF"), Guid.NewGuid(), OfferTypeId.SERVICE, new List()); - - // Assert - result.Exists.Should().BeTrue(); - result.IsUserOfCompany.Should().BeFalse(); - result.Details.Should().BeNull(); + result.Details.Should().NotBeNull().And.Match(x => + x.Name == "Project Implementation: Earth Commerce" && + x.Customer == "Bayerische Motorenwerke AG" && + x.Bpn == "BPNL00000003AYRE" && + x.Contact.SequenceEqual(new[] { "test@email.com" }) && + x.OfferSubscriptionStatus == OfferSubscriptionStatusId.ACTIVE && + x.TenantUrl == "https://ec-qas.d13fe27.kyma.ondemand.com" && + x.AppInstanceId == "https://catenax-int-dismantler-s66pftcc.authentication.eu10.hana.ondemand.com" && + x.ProcessSteps.Count() == 0); } - #endregion - - #region GetAppSubscriptionDetailForProviderAsync - [Fact] - public async Task GetAppSubscriptionDetailForProviderAsync_ReturnsExpected() + public async Task GetOfferSubscriptionDetailForServiceProviderAsync_ReturnsExpected() { // Arrange var (sut, _) = await CreateSut(); // Act - var result = await sut.GetAppSubscriptionDetailsForProviderAsync(new Guid("a16e73b9-5277-4b69-9f8d-3b227495dfea"), new Guid("3DE6A31F-A5D1-4F60-AA3A-4B1A769BECBF"), _userCompanyId, OfferTypeId.SERVICE, new[] { new Guid("58f897ec-0aad-4588-8ffa-5f45d6638632") }); + var result = await sut.GetOfferSubscriptionDetailsForProviderAsync(new Guid("a16e73b9-5277-4b69-9f8d-3b227495dfea"), new Guid("3DE6A31F-A5D1-4F60-AA3A-4B1A769BECBF"), _userCompanyId, OfferTypeId.SERVICE, new[] { new Guid("58f897ec-0aad-4588-8ffa-5f45d6638632") }); // Assert result.Exists.Should().BeTrue(); result.IsUserOfCompany.Should().BeTrue(); - result.Details.Should().NotBeNull().And.Match(x => + result.Details.Should().NotBeNull().And.Match(x => x.Name == "SDE with EDC" && x.Customer == "CX-Operator" && x.Contact.SequenceEqual(new[] { "tobeadded@cx.com" }) && x.OfferSubscriptionStatus == OfferSubscriptionStatusId.ACTIVE && - x.TenantUrl == "https://ec-qas.d13fe27.kyma.ondemand.com" && - x.AppInstanceId == "https://catenax-int-dismantler-s66pftcc.authentication.eu10.hana.ondemand.com" && + x.TenantUrl == null && + x.AppInstanceId == null && x.ProcessSteps.Count() == 3 && x.ProcessSteps.Count(y => y.ProcessStepTypeId == ProcessStepTypeId.AWAIT_START_AUTOSETUP && y.ProcessStepStatusId == ProcessStepStatusId.TODO) == 1); } [Fact] - public async Task GetAppSubscriptionDetailForProviderAsync_WithNotExistingId_ReturnsExpected() + public async Task GetOfferSubscriptionDetailForProviderAsync_WithNotExistingId_ReturnsExpected() { // Arrange var (sut, _) = await CreateSut(); // Act - var result = await sut.GetAppSubscriptionDetailsForProviderAsync(Guid.NewGuid(), new Guid("3DE6A31F-A5D1-4F60-AA3A-4B1A769BECBF"), _userCompanyId, OfferTypeId.SERVICE, new List()); + var result = await sut.GetOfferSubscriptionDetailsForProviderAsync(Guid.NewGuid(), new Guid("3DE6A31F-A5D1-4F60-AA3A-4B1A769BECBF"), _userCompanyId, OfferTypeId.SERVICE, new List()); // Assert result.Exists.Should().BeFalse(); @@ -338,13 +307,13 @@ public async Task GetAppSubscriptionDetailForProviderAsync_WithNotExistingId_Ret } [Fact] - public async Task GetAppSubscriptionDetailForProviderAsync_WithWrongUserCompany_ReturnsExpected() + public async Task GetOfferSubscriptionDetailForProviderAsync_WithWrongUserCompany_ReturnsExpected() { // Arrange var (sut, _) = await CreateSut(); // Act - var result = await sut.GetAppSubscriptionDetailsForProviderAsync(new Guid("a16e73b9-5277-4b69-9f8d-3b227495dfea"), new Guid("3DE6A31F-A5D1-4F60-AA3A-4B1A769BECBF"), Guid.NewGuid(), OfferTypeId.SERVICE, new[] { new Guid("58f897ec-0aad-4588-8ffa-5f45d6638632") }); + var result = await sut.GetOfferSubscriptionDetailsForProviderAsync(new Guid("a16e73b9-5277-4b69-9f8d-3b227495dfea"), new Guid("3DE6A31F-A5D1-4F60-AA3A-4B1A769BECBF"), Guid.NewGuid(), OfferTypeId.SERVICE, new[] { new Guid("58f897ec-0aad-4588-8ffa-5f45d6638632") }); // Assert result.Exists.Should().BeTrue(); diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/OfferSubscriptionViewTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/OfferSubscriptionViewTests.cs index a21fb09929..3b9ae1f273 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/OfferSubscriptionViewTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/OfferSubscriptionViewTests.cs @@ -56,16 +56,20 @@ public async Task OfferSubscriptionView_GetAll_ReturnsExpected() public async Task OfferSubscriptionView_GetSpecific_ReturnsExpected() { // Arrange - var subscriptionId = new Guid("3de6a31f-a5d1-4f60-aa3a-4b1a769becbf"); + var subscriptionId = new Guid("0b2ca541-206d-48ad-bc02-fb61fbcb5552"); var sut = await CreateContext(); // Act - var result = await sut.OfferSubscriptionView.SingleOrDefaultAsync(x => x.SubscriptionId == subscriptionId); - result.Should().NotBeNull(); - result!.SubscriptionId.Should().Be(subscriptionId); - result.OfferTypeId.Should().Be(OfferTypeId.SERVICE); - result.TechnicalUser.Should().Be(new Guid("d0c8ae19-d4f3-49cc-9cb4-6c766d4680f2")); - result.AppInstance.Should().Be(new Guid("ab25c218-9ab3-4f1a-b6f4-6394fbc33c5b")); + var result = await sut.OfferSubscriptionView.Where(x => x.SubscriptionId == subscriptionId).ToListAsync(); + result.Should().HaveCount(2) + .And.AllSatisfy(x => + x.Should().Match(x => + x.SubscriptionId == subscriptionId && + x.OfferTypeId == OfferTypeId.APP && + x.AppInstance == new Guid("ab25c218-9ab3-4f1a-b6f4-6394fbc33c5a"))) + .And.Satisfy( + x => x.TechnicalUser == new Guid("93eecd4e-ca47-4dd2-85bf-775ea72eb000"), + x => x.TechnicalUser == new Guid("d0c8ae19-d4f3-49cc-9cb4-6c766d4680f3")); } #endregion diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/app_subscription_details.unittest.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/app_subscription_details.unittest.json index 2bdb86932e..c7e15ad196 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/app_subscription_details.unittest.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/app_subscription_details.unittest.json @@ -6,13 +6,6 @@ "app_subscription_url": "https://ec-qas.d13fe27.kyma.ondemand.com", "last_editor_id": null }, - { - "id": "88b0661c-cc22-4a4a-9721-fc4f3cec21f9", - "offer_subscription_id": "3de6a31f-a5d1-4f60-aa3a-4b1a769becbf", - "app_instance_id": "ab25c218-9ab3-4f1a-b6f4-6394fbc33c5b", - "app_subscription_url": "https://ec-qas.d13fe27.kyma.ondemand.com", - "last_editor_id": null - }, { "id": "bedb45bf-7094-4da0-9e69-0695db782a16", "offer_subscription_id": "ed4de48d-fd4b-4384-a72f-ecae3c6cc5ba", diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identity_assigned_roles.unittest.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identity_assigned_roles.unittest.json index 67e4b02a52..77430f9f61 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identity_assigned_roles.unittest.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identity_assigned_roles.unittest.json @@ -68,5 +68,15 @@ "identity_id": "8b42e6de-7b59-4217-a63c-198e83d93777", "user_role_id": "7410693c-c893-409e-852f-9ee886ce94a6", "last_editor_id": null - } + }, + { + "identity_id": "8b42e6de-7b59-4217-a63c-198e83d93776", + "user_role_id": "7410693c-c893-409e-852f-9ee886ce94a6", + "last_editor_id": null + }, + { + "identity_id": "8b42e6de-7b59-4217-a63c-198e83d93776", + "user_role_id": "efc20368-9e82-46ff-b88f-6495b9810253", + "last_editor_id": null + } ] diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/technical_users.unittest.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/technical_users.unittest.json index f6866ec5d7..3049e8ea9d 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/technical_users.unittest.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/technical_users.unittest.json @@ -1,13 +1,4 @@ [ - { - "id": "d0c8ae19-d4f3-49cc-9cb4-6c766d4680f2", - "name": "sa-test", - "description": "SA for offer subscription", - "technical_user_type_id": 2, - "technical_user_kind_id": 1, - "offer_subscription_id": "3DE6A31F-A5D1-4F60-AA3A-4B1A769BECBF", - "client_client_id":"sa-x-4" - }, { "id": "d0c8ae19-d4f3-49cc-9cb4-6c766d4680f3", "name": "sa-test", diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/user_roles.unittest.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/user_roles.unittest.json index 3bfc0f7f23..c8cf3c65ab 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/user_roles.unittest.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/user_roles.unittest.json @@ -14,19 +14,19 @@ { "id": "aabcdfeb-6669-4c74-89f0-19cda090873e", "user_role": "test", - "offer_id": "a16e73b9-5277-4b69-9f8d-3b227495dfea", + "offer_id": "9b957704-3505-4445-822c-d7ef80f27fcd", "last_editor_id": null }, { "id": "efc20368-9e82-46ff-b88f-6495b9810254", "user_role": "Company Admin", - "offer_id": "a16e73b9-5277-4b69-9f8d-3b227495dfea", + "offer_id": "9b957704-3505-4445-822c-d7ef80f27fcd", "last_editor_id": null }, { "id": "efc20368-9e82-46ff-b88f-6495b9810255", "user_role": "IT Admin", - "offer_id": "a16e73b9-5277-4b69-9f8d-3b227495dfea", + "offer_id": "9b957704-3505-4445-822c-d7ef80f27fcd", "last_editor_id": null }, { diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/TechnicalUserRepositoryTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/TechnicalUserRepositoryTests.cs index 257ee388ff..9a2ffbaaa2 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/TechnicalUserRepositoryTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/TechnicalUserRepositoryTests.cs @@ -292,9 +292,9 @@ public async Task GetOwnCompanyServiceAccountsUntracked_WithOwnerTrue_ReturnsExp // Assert result.Should().NotBeNull(); - result!.Count.Should().Be(22); + result!.Count.Should().Be(21); result.Data.Should().HaveCount(10) - .And.AllSatisfy(x => x.Should().Match(y => + .And.AllSatisfy(x => x.Should().Match(y => y.TechnicalUserTypeId == TechnicalUserTypeId.OWN && y.UserStatusId == UserStatusId.ACTIVE)) .And.BeInAscendingOrder(x => x.Name)