From 3e0f321137e1f4cdd17b071d26c654201403bf94 Mon Sep 17 00:00:00 2001 From: Kjetil Haugland Date: Tue, 5 Nov 2024 14:13:00 +0100 Subject: [PATCH 1/5] Fix warnings in project --- .../Queries/ContextTypes/ContextTypeDto.cs | 5 +- .../GetContextTypes/GetContextTypesQuery.cs | 4 - .../GetOnboardedApps/GetOnboardedAppsQuery.cs | 4 - .../Queries/OnboardedApps/OnboardedAppDto.cs | 2 +- .../GetOnboardedContextByContextIdQuery.cs | 6 +- ...rdedContextByExternalIdContextTypeQuery.cs | 8 +- .../OnboardedContexts/OnboardedContextDto.cs | 6 +- .../Portals/GetPortals/GetPortalsQuery.cs | 9 -- .../Queries/Portals/PortalAppDto.cs | 12 +- .../Queries/Portals/PortalDto.cs | 29 ++-- .../Queries/Portals/PortalOnboardedAppDto.cs | 4 +- .../ContextTypeService/ContextTypeService.cs | 3 +- .../Entities/ContextType.cs | 29 ++-- .../Entities/PortalApp.cs | 6 +- .../Controllers/ApiControllerBase.cs | 25 ---- .../Controllers/ContextTypeController.cs | 141 +++++++++--------- .../ViewModels/ContextType/ApiContextType.cs | 7 +- .../ViewModels/FusionApp/ApiFusionApp.cs | 2 + .../FusionApp/ApiFusionAppCategory.cs | 7 +- .../FusionApp/ApiFusionAppVersion.cs | 7 +- .../OnboardedApp/ApiOnboardAppRequest.cs | 4 + .../OnboardedApp/ApiOnboardedApp.cs | 7 +- .../ApiUpdateOnboardedAppRequest.cs | 6 +- .../OnboardedContext/ApiOnboardedContext.cs | 2 + .../ViewModels/Portal/ApiPortal.cs | 2 + .../ViewModels/PortalApp/ApiPortalApp.cs | 4 +- .../PortalApp/ApiPortalOnboardedApp.cs | 7 +- .../ContextTypeControllerTests.cs | 2 +- .../Setup/IntegrationTestAuthHandler.cs | 13 +- .../TestFactory.cs | 14 +- 30 files changed, 180 insertions(+), 197 deletions(-) diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/ContextTypes/ContextTypeDto.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/ContextTypes/ContextTypeDto.cs index aa62bb817..316c36fd2 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/ContextTypes/ContextTypeDto.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/ContextTypes/ContextTypeDto.cs @@ -4,6 +4,5 @@ namespace Equinor.ProjectExecutionPortal.Application.Queries.ContextTypes; public class ContextTypeDto : IMapFrom { - public string ContextTypeKey { get; set; } - -} \ No newline at end of file + public required string ContextTypeKey { get; set; } +} diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/ContextTypes/GetContextTypes/GetContextTypesQuery.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/ContextTypes/GetContextTypes/GetContextTypesQuery.cs index 699f42695..b364259f5 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/ContextTypes/GetContextTypes/GetContextTypesQuery.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/ContextTypes/GetContextTypes/GetContextTypesQuery.cs @@ -8,10 +8,6 @@ namespace Equinor.ProjectExecutionPortal.Application.Queries.ContextTypes.GetCon public class GetContextTypesQuery : QueryBase> { - public GetContextTypesQuery() - { - } - public class Handler : IRequestHandler> { private readonly IReadWriteContext _context; diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedApps/GetOnboardedApps/GetOnboardedAppsQuery.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedApps/GetOnboardedApps/GetOnboardedAppsQuery.cs index 87b4a322e..f8b0f4933 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedApps/GetOnboardedApps/GetOnboardedAppsQuery.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedApps/GetOnboardedApps/GetOnboardedAppsQuery.cs @@ -9,10 +9,6 @@ namespace Equinor.ProjectExecutionPortal.Application.Queries.OnboardedApps.GetOn public class GetOnboardedAppsQuery : QueryBase> { - public GetOnboardedAppsQuery() - { - } - public class Handler : IRequestHandler> { private readonly IReadWriteContext _context; diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedApps/OnboardedAppDto.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedApps/OnboardedAppDto.cs index 4684d013d..533ba8556 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedApps/OnboardedAppDto.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedApps/OnboardedAppDto.cs @@ -7,7 +7,7 @@ namespace Equinor.ProjectExecutionPortal.Application.Queries.OnboardedApps; public class OnboardedAppDto : IMapFrom { public Guid Id { get; set; } - public string AppKey { get; set; } + public required string AppKey { get; set; } public string? DisplayName { get; set; } public string? Description { get; set; } public App? AppInformation { get; set; } diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/GetOnboardedContext/GetOnboardedContextByContextIdQuery.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/GetOnboardedContext/GetOnboardedContextByContextIdQuery.cs index 83761a99c..2de791e41 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/GetOnboardedContext/GetOnboardedContextByContextIdQuery.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/GetOnboardedContext/GetOnboardedContextByContextIdQuery.cs @@ -41,7 +41,10 @@ public Handler(IReadWriteContext readWriteContext, IMapper mapper, IContextServi var onboardedContext = _mapper.Map(entity); - await _contextService.EnrichContextWithFusionContextData(onboardedContext, cancellationToken); + if (onboardedContext != null) + { + await _contextService.EnrichContextWithFusionContextData(onboardedContext, cancellationToken); + } return onboardedContext; } @@ -49,7 +52,6 @@ public Handler(IReadWriteContext readWriteContext, IMapper mapper, IContextServi { return null; } - } } } diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/GetOnboardedContext/GetOnboardedContextByExternalIdContextTypeQuery.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/GetOnboardedContext/GetOnboardedContextByExternalIdContextTypeQuery.cs index aefca5719..ebf9100f3 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/GetOnboardedContext/GetOnboardedContextByExternalIdContextTypeQuery.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/GetOnboardedContext/GetOnboardedContextByExternalIdContextTypeQuery.cs @@ -36,9 +36,13 @@ public Handler(IReadWriteContext readWriteContext, IMapper mapper, IContextServi var entity = await _readWriteContext.Set() .AsNoTracking() .FirstOrDefaultAsync(x => x.ExternalId == request.ExternalId && x.Type == request.ContextType, cancellationToken); + var onboardedContext = _mapper.Map(entity); - - await _contextService.EnrichContextWithFusionContextData(onboardedContext, cancellationToken); + + if (onboardedContext != null) + { + await _contextService.EnrichContextWithFusionContextData(onboardedContext, cancellationToken); + } return onboardedContext; } diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/OnboardedContextDto.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/OnboardedContextDto.cs index 51917bd1f..a3ac6ab64 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/OnboardedContextDto.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/OnboardedContexts/OnboardedContextDto.cs @@ -7,10 +7,10 @@ namespace Equinor.ProjectExecutionPortal.Application.Queries.OnboardedContexts; public class OnboardedContextDto : IMapFrom { public Guid Id { get; set; } - public string ExternalId { get; set; } - public string Type { get; set; } + public required string ExternalId { get; set; } + public required string Type { get; set; } public Guid ContextId { get; set; } - public string Title { get; set; } + public string Title { get; set; } = string.Empty; public string? Description { get; set; } public void SupplyWithFusionData(FusionContext context) diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/GetPortals/GetPortalsQuery.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/GetPortals/GetPortalsQuery.cs index 0a9cea133..c70b5ef5f 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/GetPortals/GetPortalsQuery.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/GetPortals/GetPortalsQuery.cs @@ -8,10 +8,6 @@ namespace Equinor.ProjectExecutionPortal.Application.Queries.Portals.GetPortals; public class GetPortalsQuery : QueryBase> { - public GetPortalsQuery() - { - } - public class Handler : IRequestHandler> { private readonly IReadWriteContext _context; @@ -32,11 +28,6 @@ public async Task> Handle(GetPortalsQuery request, Cancellation var portals = _mapper.Map, List>(entities); - // This causes projection to lazy load - //var entities = await _context.Set() - // .AsNoTracking() - // .ProjectToListAsync(_mapper.ConfigurationProvider); - return portals; } } diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalAppDto.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalAppDto.cs index 0e1b81f28..b3f335c52 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalAppDto.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalAppDto.cs @@ -1,11 +1,9 @@ using Equinor.ProjectExecutionPortal.Application.Infrastructure.Mappings; using Equinor.ProjectExecutionPortal.Application.Queries.OnboardedApps; -namespace Equinor.ProjectExecutionPortal.Application.Queries.Portals +namespace Equinor.ProjectExecutionPortal.Application.Queries.Portals; + +public class PortalAppDto : IMapFrom { - public class PortalAppDto : IMapFrom - { - public bool IsHidden { get; set; } - public OnboardedAppDto OnboardedApp { get; set; } - } -} + public required OnboardedAppDto OnboardedApp { get; set; } +} \ No newline at end of file diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalDto.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalDto.cs index 928137283..dbeefe812 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalDto.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalDto.cs @@ -1,19 +1,18 @@ using Equinor.ProjectExecutionPortal.Application.Infrastructure.Mappings; using Equinor.ProjectExecutionPortal.Application.Queries.ContextTypes; -namespace Equinor.ProjectExecutionPortal.Application.Queries.Portals +namespace Equinor.ProjectExecutionPortal.Application.Queries.Portals; + +public class PortalDto : IMapFrom { - public class PortalDto : IMapFrom - { - public Guid Id { get; set; } - public required string Key { get; set; } - public required string Name { get; set; } - public required string ShortName { get; set; } - public required string SubText { get; set; } - public string? Description { get; set; } - public required string Icon { get; set; } - public required IList ContextTypes { get; set; } - public required List Apps { get; set; } - public PortalConfigurationDto? Configuration { get; set; } - } -} + public Guid Id { get; set; } + public required string Key { get; set; } + public required string Name { get; set; } + public required string ShortName { get; set; } + public required string SubText { get; set; } + public string? Description { get; set; } + public required string Icon { get; set; } + public required IList ContextTypes { get; set; } + public required List Apps { get; set; } + public PortalConfigurationDto? Configuration { get; set; } +} \ No newline at end of file diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalOnboardedAppDto.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalOnboardedAppDto.cs index 9e3df76ff..f5e293973 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalOnboardedAppDto.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Queries/Portals/PortalOnboardedAppDto.cs @@ -5,9 +5,9 @@ namespace Equinor.ProjectExecutionPortal.Application.Queries.Portals; public class PortalOnboardedAppDto : IMapFrom { - public OnboardedAppDto OnboardedApp { get; set; } + public required OnboardedAppDto OnboardedApp { get; set; } public List ContextIds { get; set; } = []; - public bool IsActive { get; set; } = false; + public bool IsActive { get; set; } public bool IsGlobal { get; set; } public bool IsContextual { get; set; } } diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Services/ContextTypeService/ContextTypeService.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Services/ContextTypeService/ContextTypeService.cs index 2028ff67a..1da3e6665 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Services/ContextTypeService/ContextTypeService.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Services/ContextTypeService/ContextTypeService.cs @@ -1,5 +1,4 @@ -using Equinor.ProjectExecutionPortal.Domain.Common.Exceptions; -using Equinor.ProjectExecutionPortal.Domain.Entities; +using Equinor.ProjectExecutionPortal.Domain.Entities; using Equinor.ProjectExecutionPortal.Infrastructure; using Microsoft.EntityFrameworkCore; diff --git a/backend/src/Equinor.ProjectExecutionPortal.Domain/Entities/ContextType.cs b/backend/src/Equinor.ProjectExecutionPortal.Domain/Entities/ContextType.cs index b5b83e548..5ac855951 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Domain/Entities/ContextType.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Domain/Entities/ContextType.cs @@ -1,23 +1,22 @@ using Equinor.ProjectExecutionPortal.Domain.Common; using Equinor.ProjectExecutionPortal.Domain.Common.Audit; -namespace Equinor.ProjectExecutionPortal.Domain.Entities +namespace Equinor.ProjectExecutionPortal.Domain.Entities; + +public class ContextType : AuditableEntityBase, ICreationAuditable, IModificationAuditable { - public class ContextType : AuditableEntityBase, ICreationAuditable, IModificationAuditable - { - public const int ContextTypeKeyLengthMax = 200; + public const int ContextTypeKeyLengthMax = 200; - private readonly List _portals = []; - private readonly List _onboardedApps = []; + private readonly List _portals = []; + private readonly List _onboardedApps = []; - public ContextType(string contextTypeKey) - { - ContextTypeKey = contextTypeKey; - } + public ContextType(string contextTypeKey) + { + ContextTypeKey = contextTypeKey; + } - public string ContextTypeKey { get; set; } + public string ContextTypeKey { get; set; } - public IReadOnlyCollection Portals => _portals.AsReadOnly(); - public IReadOnlyCollection OnboardedApps => _onboardedApps.AsReadOnly(); - } -} + public IReadOnlyCollection Portals => _portals.AsReadOnly(); + public IReadOnlyCollection OnboardedApps => _onboardedApps.AsReadOnly(); +} \ No newline at end of file diff --git a/backend/src/Equinor.ProjectExecutionPortal.Domain/Entities/PortalApp.cs b/backend/src/Equinor.ProjectExecutionPortal.Domain/Entities/PortalApp.cs index 10c1ab004..3f14badda 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Domain/Entities/PortalApp.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Domain/Entities/PortalApp.cs @@ -26,10 +26,10 @@ public PortalApp(Guid onboardedAppId, Guid portalId, bool isHidden = false) public bool IsHidden { get; set; } public Guid OnboardedAppId { get; set; } - public OnboardedApp OnboardedApp { get; set; } - + public OnboardedApp OnboardedApp { get; set; } = null!; + public Guid PortalId { get; set; } - public Portal Portal { get; set; } + public Portal Portal { get; set; } = null!; public Guid? OnboardedContextId { get; set; } public OnboardedContext? OnboardedContext { get; set; } diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/ApiControllerBase.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/ApiControllerBase.cs index 2403e3524..0f17b97f3 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/ApiControllerBase.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/ApiControllerBase.cs @@ -20,29 +20,4 @@ public abstract class ApiControllerBase : Controller protected ILogger Logger => _logger; protected IAuthorizationService AuthorizationService => _authorizationService ??= HttpContext.RequestServices.GetRequiredService(); protected IFusionContextResolver ContextResolver => _contextResolver ??= HttpContext.RequestServices.GetRequiredService(); - - private protected async Task SetAuthorizedVerbsHeader(List<(string verb, string policy)> verbPolicyMap, object? resource) - { - var allowedVerbs = await GetAuthorizedVerbs(verbPolicyMap, resource); - HttpContext.Response.Headers.Add("Allow", string.Join(',', allowedVerbs)); - - return Unit.Value; - } - - private async Task> GetAuthorizedVerbs(List<(string verb, string policy)> verbPolicyMap, object? resource) - { - var allowedVerbs = new List { HttpMethod.Options.Method }; // Always allowed - - foreach (var (verb, policy) in verbPolicyMap) - { - var authResult = await AuthorizationService.AuthorizeAsync(User, resource, policy); - - if (authResult.Succeeded) - { - allowedVerbs.Add(verb); - } - } - - return allowedVerbs; - } } diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/ContextTypeController.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/ContextTypeController.cs index a1f1e2fff..aa7da497e 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/ContextTypeController.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/ContextTypeController.cs @@ -7,85 +7,84 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace Equinor.ProjectExecutionPortal.WebApi.Controllers +namespace Equinor.ProjectExecutionPortal.WebApi.Controllers; + +[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] +[ApiVersion("0.1")] +[Route("api/context-types")] +public class ContextTypeController : ApiControllerBase { - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] - [ApiVersion("0.1")] - [Route("api/context-types")] - public class ContextTypeController : ApiControllerBase + // GET: api/ + [HttpGet("")] + [Produces(MediaTypeNames.Application.Json)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + public async Task>> ContextTypes() { - // GET: api/ - [HttpGet("")] - [Produces(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - public async Task>> ContextTypes() - { - var contextTypesDto = await Mediator.Send(new GetContextTypesQuery()); + var contextTypesDto = await Mediator.Send(new GetContextTypesQuery()); - return Ok(contextTypesDto.Select(contextTypeDto => new ApiContextType(contextTypeDto)).ToList()); - } + return Ok(contextTypesDto.Select(contextTypeDto => new ApiContextType(contextTypeDto)).ToList()); + } - // POST api/ - [HttpPost("")] - [Authorize(Policy = Policies.ProjectPortal.Admin)] - [Consumes(MediaTypeNames.Application.Json)] - [Produces(MediaTypeNames.Application.Json)] - [ProducesResponseType(StatusCodes.Status201Created)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status409Conflict)] - public async Task> AddContextType([FromBody] ApiAddContextTypeRequest request) + // POST api/ + [HttpPost("")] + [Authorize(Policy = Policies.ProjectPortal.Admin)] + [Consumes(MediaTypeNames.Application.Json)] + [Produces(MediaTypeNames.Application.Json)] + [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] + [ProducesResponseType(typeof(void), StatusCodes.Status409Conflict)] + public async Task> AddContextType([FromBody] ApiAddContextTypeRequest request) + { + try { - try - { - await Mediator.Send(request.ToCommand()); - } - catch (NotFoundException ex) - { - return FusionApiError.NotFound(request.Type, ex.Message); - } - catch (InvalidActionException ex) - { - return FusionApiError.ResourceExists(request.Type, "Context type is already supported", ex); - } - catch (Exception) - { - return FusionApiError.InvalidOperation("500", "An error occurred while adding context type"); - } - - return Created("Created", request); + await Mediator.Send(request.ToCommand()); } - - // DELETE api//5 - [HttpDelete("{contextType}")] - [Authorize(Policy = Policies.ProjectPortal.Admin)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status400BadRequest)] - public async Task RemoveContextType([FromRoute] string contextType) + catch (NotFoundException ex) + { + return FusionApiError.NotFound(request.Type, ex.Message); + } + catch (InvalidActionException ex) { - var request = new ApiRemoveContextTypeRequest { Type = contextType }; + return FusionApiError.ResourceExists(request.Type, "Context type is already supported", ex); + } + catch (Exception) + { + return FusionApiError.InvalidOperation("500", "An error occurred while adding context type"); + } - try - { - await Mediator.Send(request.ToCommand()); - } - catch (NotFoundException ex) - { - return FusionApiError.NotFound(contextType, ex.Message); - } - catch (InvalidActionException ex) - { - return FusionApiError.InvalidOperation("404", ex.Message); - } - catch (Exception) - { - return FusionApiError.InvalidOperation("500", "An error occurred while removing context type"); - } + return Created("Created", request); + } + + // DELETE api//5 + [HttpDelete("{contextType}")] + [Authorize(Policy = Policies.ProjectPortal.Admin)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] + [ProducesResponseType(typeof(void), StatusCodes.Status400BadRequest)] + public async Task RemoveContextType([FromRoute] string contextType) + { + var request = new ApiRemoveContextTypeRequest { Type = contextType }; - return Ok(); + try + { + await Mediator.Send(request.ToCommand()); + } + catch (NotFoundException ex) + { + return FusionApiError.NotFound(contextType, ex.Message); } + catch (InvalidActionException ex) + { + return FusionApiError.InvalidOperation("404", ex.Message); + } + catch (Exception) + { + return FusionApiError.InvalidOperation("500", "An error occurred while removing context type"); + } + + return Ok(); } -} +} \ No newline at end of file diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/ContextType/ApiContextType.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/ContextType/ApiContextType.cs index 6500eb50c..cd4badda9 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/ContextType/ApiContextType.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/ContextType/ApiContextType.cs @@ -4,8 +4,11 @@ namespace Equinor.ProjectExecutionPortal.WebApi.ViewModels.ContextType; public class ApiContextType { +#pragma warning disable CS8618 // For integration tests only public ApiContextType() - { } +#pragma warning restore CS8618 // For integration tests only + { + } public ApiContextType(ContextTypeDto contextTypeDto) { @@ -13,4 +16,4 @@ public ApiContextType(ContextTypeDto contextTypeDto) } public string Type { get; set; } -} \ No newline at end of file +} diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionApp.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionApp.cs index 1d24b8e85..15ca805d4 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionApp.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionApp.cs @@ -4,7 +4,9 @@ namespace Equinor.ProjectExecutionPortal.WebApi.ViewModels.FusionApp; public class ApiFusionApp { +#pragma warning disable CS8618 // For integration tests only public ApiFusionApp() +#pragma warning restore CS8618 // For integration tests only { } diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionAppCategory.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionAppCategory.cs index 7412e8d54..3fc7bbeb8 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionAppCategory.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionAppCategory.cs @@ -4,8 +4,11 @@ namespace Equinor.ProjectExecutionPortal.WebApi.ViewModels.FusionApp; public class ApiFusionAppCategory { +#pragma warning disable CS8618 // // For integration tests only public ApiFusionAppCategory() - { } +#pragma warning restore CS8618 // // For integration tests only + { + } public ApiFusionAppCategory(AppCategory fusionAppCategory) { @@ -23,4 +26,4 @@ public ApiFusionAppCategory(AppCategory fusionAppCategory) public string Color { get; set; } public string DefaultIcon { get; set; } public short SortOrder { get; set; } -} \ No newline at end of file +} diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionAppVersion.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionAppVersion.cs index b5bfd6d6a..59cb5815c 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionAppVersion.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/FusionApp/ApiFusionAppVersion.cs @@ -4,8 +4,11 @@ namespace Equinor.ProjectExecutionPortal.WebApi.ViewModels.FusionApp; public class ApiFusionAppVersion { +#pragma warning disable CS8618 // For integration tests only public ApiFusionAppVersion() - { } +#pragma warning restore CS8618 // For integration tests only + { + } public ApiFusionAppVersion(AppVersion fusionAppVersion) { @@ -13,4 +16,4 @@ public ApiFusionAppVersion(AppVersion fusionAppVersion) } public string Version { get; set; } -} \ No newline at end of file +} diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiOnboardAppRequest.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiOnboardAppRequest.cs index bae9bac8c..25408076a 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiOnboardAppRequest.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiOnboardAppRequest.cs @@ -21,6 +21,10 @@ public OnboardAppRequestValidator() .NotEmpty() .NotContainScriptTag() .WithMessage("AppKey is required"); + + RuleFor(x => x.ContextTypes) + .NotEmpty() + .WithMessage("Context Types is required"); } } } diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiOnboardedApp.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiOnboardedApp.cs index a4067943a..68f004541 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiOnboardedApp.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiOnboardedApp.cs @@ -5,8 +5,11 @@ namespace Equinor.ProjectExecutionPortal.WebApi.ViewModels.OnboardedApp; public class ApiOnboardedApp { +#pragma warning disable CS8618 // For integration tests only public ApiOnboardedApp() - { } +#pragma warning restore CS8618 // For integration tests only + { + } public ApiOnboardedApp(OnboardedAppDto onboardedAppDto) { @@ -24,4 +27,4 @@ public ApiOnboardedApp(OnboardedAppDto onboardedAppDto) public string? Description { get; set; } public IList Contexts { get; set; } = new List(); public IList ContextTypes { get; set; } = new List(); -} \ No newline at end of file +} diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiUpdateOnboardedAppRequest.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiUpdateOnboardedAppRequest.cs index 9625984f8..7e15e7001 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiUpdateOnboardedAppRequest.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedApp/ApiUpdateOnboardedAppRequest.cs @@ -16,7 +16,9 @@ public class ApiUpdateOnboardedAppRequestValidator : AbstractValidator x.ContextTypes) + .NotNull() + .WithMessage("Context Types is required"); } } -} \ No newline at end of file +} diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedContext/ApiOnboardedContext.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedContext/ApiOnboardedContext.cs index 9b81379c9..aeb70901f 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedContext/ApiOnboardedContext.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/OnboardedContext/ApiOnboardedContext.cs @@ -4,7 +4,9 @@ namespace Equinor.ProjectExecutionPortal.WebApi.ViewModels.OnboardedContext; public class ApiOnboardedContext { +#pragma warning disable CS8618 // For integration tests only public ApiOnboardedContext() { } +#pragma warning restore CS8618 // For integration tests only public ApiOnboardedContext(OnboardedContextDto onboardedAppDto) { diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/Portal/ApiPortal.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/Portal/ApiPortal.cs index cd618113b..9ae5619c6 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/Portal/ApiPortal.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/Portal/ApiPortal.cs @@ -6,7 +6,9 @@ namespace Equinor.ProjectExecutionPortal.WebApi.ViewModels.Portal; public class ApiPortal { +#pragma warning disable CS8618 // For integration tests only public ApiPortal() { } +#pragma warning restore CS8618 // For integration tests only public ApiPortal(PortalDto portalDto) { diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalApp.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalApp.cs index a5529e90e..27cb04fee 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalApp.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalApp.cs @@ -7,10 +7,12 @@ namespace Equinor.ProjectExecutionPortal.WebApi.ViewModels.PortalApp; // TODO: Should be removed public class ApiPortalApp { +#pragma warning disable CS8618 // For integration tests only public ApiPortalApp() +#pragma warning restore CS8618 // For integration tests only { - } + public ApiPortalApp(PortalAppDto portalAppDto) { AppKey = portalAppDto.OnboardedApp.AppKey; diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalOnboardedApp.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalOnboardedApp.cs index 956ae0a9b..24cca089d 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalOnboardedApp.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalOnboardedApp.cs @@ -5,8 +5,11 @@ namespace Equinor.ProjectExecutionPortal.WebApi.ViewModels.PortalApp; public class ApiPortalOnboardedApp { +#pragma warning disable CS8618 // For integration tests only public ApiPortalOnboardedApp() - { } +#pragma warning restore CS8618 // For integration tests only + { + } public ApiPortalOnboardedApp(PortalOnboardedAppDto portalOnboardedAppDto) { @@ -26,4 +29,4 @@ public ApiPortalOnboardedApp(PortalOnboardedAppDto portalOnboardedAppDto) public bool IsGlobal { get; set; } public bool IsContextual { get; set; } public ApiFusionApp? AppManifest { get; set; } -} \ No newline at end of file +} diff --git a/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/IntegrationTests/ContextTypeControllerTests.cs b/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/IntegrationTests/ContextTypeControllerTests.cs index faaa92b49..caa08e24f 100644 --- a/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/IntegrationTests/ContextTypeControllerTests.cs +++ b/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/IntegrationTests/ContextTypeControllerTests.cs @@ -230,7 +230,7 @@ private static async Task> AssertGetAllContextTypes(UserTy if (response.StatusCode != HttpStatusCode.OK) { - return contextTypes; + return contextTypes!; } Assert.IsNotNull(content); diff --git a/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/Setup/IntegrationTestAuthHandler.cs b/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/Setup/IntegrationTestAuthHandler.cs index 67e88d72f..18a1e5698 100644 --- a/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/Setup/IntegrationTestAuthHandler.cs +++ b/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/Setup/IntegrationTestAuthHandler.cs @@ -11,7 +11,7 @@ namespace Equinor.ProjectExecutionPortal.Tests.WebApi.Setup; internal class IntegrationTestAuthHandler : AuthenticationHandler { - public static string TestAuthenticationScheme = "AuthScheme"; + public const string TestAuthenticationScheme = "AuthScheme"; private enum AuthType { @@ -19,12 +19,7 @@ private enum AuthType Delegated } - public IntegrationTestAuthHandler( - IOptionsMonitor options, - ILoggerFactory logger, - UrlEncoder encoder, - ISystemClock clock) - : base(options, logger, encoder, clock) + public IntegrationTestAuthHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder) { } @@ -83,6 +78,7 @@ private Task> GatherTestUserClaimsAsync() { claims.AddRange(profile.AppRoles.Select(role => new Claim(ClaimTypes.Role, role))); } + break; case AuthType.Application: @@ -90,9 +86,10 @@ private Task> GatherTestUserClaimsAsync() { claims.AddRange(profile.AppRoles.Select(role => new Claim(ClaimTypes.Role, role))); } + break; } return Task.FromResult(claims); } -} \ No newline at end of file +} diff --git a/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/TestFactory.cs b/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/TestFactory.cs index 8fdd810b0..c09c4607f 100644 --- a/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/TestFactory.cs +++ b/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/TestFactory.cs @@ -23,13 +23,13 @@ public sealed class TestFactory : WebApplicationFactory private const string IntegrationTestEnvironment = "IntegrationTests"; private readonly string _localDbConnectionString; private readonly string _configPath; - private readonly List _teardownList = new(); - private readonly List _disposables = new(); + private readonly List _teardownList = []; + private readonly List _disposables = []; private readonly Mock _fusionContextResolverMock = new(); private readonly Mock _fusionAppsClientMock = new(); public static Dictionary TestUsersDictionary = new(); private static TestFactory? _sInstance; - private static readonly object _sPadlock = new(); + private static readonly object SPadlock = new(); public static TestFactory Instance { @@ -37,7 +37,7 @@ public static TestFactory Instance { if (_sInstance == null) { - lock (_sPadlock) + lock (SPadlock) { if (_sInstance == null) { @@ -183,11 +183,11 @@ private ProjectExecutionPortalContext DatabaseContext(IServiceCollection service private static string GetTestLocalDbConnectionString(string projectDir) { - const string DbName = "ProjectPortalIntegrationTestsDB2"; - var dbPath = Path.Combine(projectDir, $"{DbName}.mdf"); + const string dbName = "ProjectPortalIntegrationTestsDB2"; + var dbPath = Path.Combine(projectDir, $"{dbName}.mdf"); // Set Initial Catalog to be able to delete database! - return $"Server=(LocalDB)\\MSSQLLocalDB;Initial Catalog={DbName};Integrated Security=true;AttachDbFileName={dbPath}"; + return $"Server=(LocalDB)\\MSSQLLocalDB;Initial Catalog={dbName};Integrated Security=true;AttachDbFileName={dbPath}"; } //private string GetSqlLiteConnectionString() From 9e99aee03eb68ed12f61815e76b19728af98ff00 Mon Sep 17 00:00:00 2001 From: Kjetil Haugland Date: Tue, 5 Nov 2024 14:17:56 +0100 Subject: [PATCH 2/5] Fix warnings --- .../Cache/CacheManager.cs | 4 +- .../Cache/FusionAppsCache.cs | 2 +- .../Cache/ICacheManager.cs | 2 +- .../Cache/IFusionAppsCache.cs | 2 +- .../Services/AppService/AppService.cs | 4 +- .../FusionAppsService/FusionAppsService.cs | 65 +++++++++---------- .../FusionAppsService/IFusionAppsService.cs | 17 +++-- 7 files changed, 47 insertions(+), 49 deletions(-) diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/CacheManager.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/CacheManager.cs index ebab21d28..ffeb48e3e 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/CacheManager.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/CacheManager.cs @@ -14,9 +14,9 @@ public class CacheManager : ICacheManager public void Remove(string key) => _cache.Remove(key); - public async Task GetOrCreateAsync(string key, Func> fetch, CacheDuration duration, long expiration) where T : class + public async Task GetOrCreateAsync(string key, Func> fetch, CacheDuration duration, long expiration) where T : class { - if (_cache.TryGetValue(key, out T instance)) + if (_cache.TryGetValue(key, out T? instance)) { return instance; } diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/FusionAppsCache.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/FusionAppsCache.cs index 3c7499ba2..ee20f0cd2 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/FusionAppsCache.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/FusionAppsCache.cs @@ -19,7 +19,7 @@ public FusionAppsCache(ICacheManager cacheManager, IAppsClient fusionAppsClient, _cacheOptions = cacheOptions; } - public async Task> GetFusionApps() + public async Task?> GetFusionApps() { return await _cacheManager.GetOrCreateAsync(FusionAppCacheKey, async () => diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/ICacheManager.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/ICacheManager.cs index b1e0f2a77..aad579e36 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/ICacheManager.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/ICacheManager.cs @@ -6,5 +6,5 @@ public interface ICacheManager void Remove(string key); - Task GetOrCreateAsync(string key, Func> fetch, CacheDuration duration, long expiration) where T : class?; + Task GetOrCreateAsync(string key, Func> fetch, CacheDuration duration, long expiration) where T : class?; } diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/IFusionAppsCache.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/IFusionAppsCache.cs index f59bd739b..d05b30a85 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/IFusionAppsCache.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Cache/IFusionAppsCache.cs @@ -4,7 +4,7 @@ namespace Equinor.ProjectExecutionPortal.Application.Cache; public interface IFusionAppsCache { - Task> GetFusionApps(); + Task?> GetFusionApps(); Task GetFusionApp(string appKey); } diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Services/AppService/AppService.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Services/AppService/AppService.cs index ffaf7a9c6..3ca13a5e0 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Services/AppService/AppService.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Services/AppService/AppService.cs @@ -37,9 +37,9 @@ public async Task> EnrichWithFusionAppData(IList fusionApps) + private static void CombineAppWithFusionAppData(OnboardedAppDto onboardedApp, IEnumerable? fusionApps) { - var fusionApp = fusionApps.FirstOrDefault(fusionApp => string.Equals(fusionApp.AppKey, onboardedApp.AppKey, StringComparison.CurrentCultureIgnoreCase)); + var fusionApp = fusionApps?.FirstOrDefault(fusionApp => string.Equals(fusionApp.AppKey, onboardedApp.AppKey, StringComparison.CurrentCultureIgnoreCase)); if (fusionApp != null) { diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Services/FusionAppsService/FusionAppsService.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Services/FusionAppsService/FusionAppsService.cs index bb300acc7..790f9faae 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Services/FusionAppsService/FusionAppsService.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Services/FusionAppsService/FusionAppsService.cs @@ -2,39 +2,38 @@ using Fusion.Integration.Apps.Abstractions.Abstractions; using Fusion.Integration.Apps.Abstractions.Models; -namespace Equinor.ProjectExecutionPortal.Application.Services.FusionAppsService +namespace Equinor.ProjectExecutionPortal.Application.Services.FusionAppsService; + +public class FusionAppsService : IFusionAppsService { - public class FusionAppsService : IFusionAppsService + private readonly IFusionAppsCache _fusionAppsCache; + private readonly IAppsClient _fusionAppsClient; + + public FusionAppsService(IFusionAppsCache fusionAppsCache, IAppsClient fusionAppsClient) + { + _fusionAppsCache = fusionAppsCache; + _fusionAppsClient = fusionAppsClient; + } + + public async Task FusionAppExist(string appKey, CancellationToken cancellationToken) + { + var fusionApps = await _fusionAppsCache.GetFusionApps(); + + return fusionApps != null && fusionApps.Any(app => app.AppKey == appKey); + } + + public async Task?> GetFusionApps() + { + return await _fusionAppsCache.GetFusionApps(); + } + + public async Task GetFusionApp(string appKey) + { + return await _fusionAppsCache.GetFusionApp(appKey); + } + + public async Task GetFusionAppConfig(string appKey) { - private readonly IFusionAppsCache _fusionAppsCache; - private readonly IAppsClient _fusionAppsClient; - - public FusionAppsService(IFusionAppsCache fusionAppsCache, IAppsClient fusionAppsClient) - { - _fusionAppsCache = fusionAppsCache; - _fusionAppsClient = fusionAppsClient; - } - - public async Task FusionAppExist(string appKey, CancellationToken cancellationToken) - { - var fusionApps = await _fusionAppsCache.GetFusionApps(); - - return fusionApps.Any(app => app.AppKey == appKey); - } - - public async Task> GetFusionApps() - { - return await _fusionAppsCache.GetFusionApps(); - } - - public async Task GetFusionApp(string appKey) - { - return await _fusionAppsCache.GetFusionApp(appKey); - } - - public async Task GetFusionAppConfig(string appKey) - { - return await _fusionAppsClient.GetAppConfig(appKey, new TagNameIdentifier("latest")); - } + return await _fusionAppsClient.GetAppConfig(appKey, new TagNameIdentifier("latest")); } -} +} \ No newline at end of file diff --git a/backend/src/Equinor.ProjectExecutionPortal.Application/Services/FusionAppsService/IFusionAppsService.cs b/backend/src/Equinor.ProjectExecutionPortal.Application/Services/FusionAppsService/IFusionAppsService.cs index a7bf1f33c..a12f3bcd3 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.Application/Services/FusionAppsService/IFusionAppsService.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.Application/Services/FusionAppsService/IFusionAppsService.cs @@ -1,15 +1,14 @@ using Fusion.Integration.Apps.Abstractions.Models; -namespace Equinor.ProjectExecutionPortal.Application.Services.FusionAppsService +namespace Equinor.ProjectExecutionPortal.Application.Services.FusionAppsService; + +public interface IFusionAppsService { - public interface IFusionAppsService - { - Task FusionAppExist(string appKey, CancellationToken cancellationToken); + Task FusionAppExist(string appKey, CancellationToken cancellationToken); - Task> GetFusionApps(); + Task?> GetFusionApps(); - Task GetFusionApp(string appKey); + Task GetFusionApp(string appKey); - Task GetFusionAppConfig(string appKey); - } -} + Task GetFusionAppConfig(string appKey); +} \ No newline at end of file From eb71f1836fcf4061eb9d0f434e2c6c26ca4cdc00 Mon Sep 17 00:00:00 2001 From: Kjetil Haugland Date: Tue, 5 Nov 2024 14:33:50 +0100 Subject: [PATCH 3/5] Portal apps: Remove get PortalApps as objects endpoint --- .../Controllers/PortalController.cs | 59 ++----------------- .../ViewModels/PortalApp/ApiPortalApp.cs | 1 - .../IntegrationTests/PortalControllerTests.cs | 22 +++---- 3 files changed, 17 insertions(+), 65 deletions(-) diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/PortalController.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/PortalController.cs index e7b6cdfa1..20731f1a7 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/PortalController.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/Controllers/PortalController.cs @@ -1,7 +1,6 @@ using System.Net.Mime; using Equinor.ProjectExecutionPortal.Application.Queries.Portals.GetPortal; using Equinor.ProjectExecutionPortal.Application.Queries.Portals.GetPortalAppKeys; -using Equinor.ProjectExecutionPortal.Application.Queries.Portals.GetPortalApps; using Equinor.ProjectExecutionPortal.Application.Queries.Portals.GetPortalConfiguration; using Equinor.ProjectExecutionPortal.Application.Queries.Portals.GetPortalOnboardedApp; using Equinor.ProjectExecutionPortal.Application.Queries.Portals.GetPortalOnboardedApps; @@ -204,10 +203,10 @@ public async Task> PortalOnboardedApp([FromR return new ApiPortalOnboardedApp(portalOnboardedAppDto); } - // App Keys + // Apps - // TODO: Rename to /apps - [HttpGet("{portalId:guid}/appkeys")] + [HttpGet("{portalId:guid}/apps")] + [HttpGet("{portalId:guid}/appkeys")] // TODO: DEPRECATED [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] public async Task>> PortalAppKeys([FromRoute] Guid portalId) @@ -228,8 +227,8 @@ public async Task>> PortalAppKeys([FromRoute] Guid por } } - // TODO Rename to /apps - [HttpGet("{portalId:guid}/contexts/{contextId:guid}/appkeys")] + [HttpGet("{portalId:guid}/contexts/{contextId:guid}/apps")] + [HttpGet("{portalId:guid}/contexts/{contextId:guid}/appkeys")] // TODO: DEPRECATED [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] public async Task>> PortalAppKeys([FromRoute] Guid portalId, [FromRoute] Guid contextId) @@ -250,52 +249,6 @@ public async Task>> PortalAppKeys([FromRoute] Guid por } } - // Apps - - // TODO: Remove - [HttpGet("{portalId:guid}/apps")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - public async Task>> PortalApps([FromRoute] Guid portalId) - { - try - { - var portalAppsDto = await Mediator.Send(new GetGlobalAppsForPortalQuery(portalId)); - - return Ok(portalAppsDto.Select(portalAppDto => new ApiPortalApp(portalAppDto)).ToList()); - } - catch (NotFoundException ex) - { - return FusionApiError.NotFound(portalId, ex.Message); - } - catch (Exception) - { - return FusionApiError.InvalidOperation("500", "An error occurred"); - } - } - - // TODO: Remove - [HttpGet("{portalId:guid}/contexts/{contextId:guid}/apps")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - public async Task>> PortalApps([FromRoute] Guid portalId, [FromRoute] Guid contextId) - { - try - { - var portalAppsDto = await Mediator.Send(new GetContextualAndGlobalAppsByPortalAndContextQuery(portalId, contextId)); - - return Ok(portalAppsDto.Select(portalAppDto => new ApiPortalApp(portalAppDto)).ToList()); - } - catch (NotFoundException ex) - { - return FusionApiError.NotFound(portalId, ex.Message); - } - catch (Exception) - { - return FusionApiError.InvalidOperation("500", "An error occurred"); - } - } - [HttpPost("{portalId:guid}/apps")] [Authorize(Policy = Policies.ProjectPortal.Admin)] [Consumes(MediaTypeNames.Application.Json)] @@ -478,4 +431,4 @@ public async Task RemoveContextType([FromRoute] Guid portalId, [Fr return Ok(); } -} \ No newline at end of file +} diff --git a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalApp.cs b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalApp.cs index 27cb04fee..ddaff6e53 100644 --- a/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalApp.cs +++ b/backend/src/Equinor.ProjectExecutionPortal.WebApi/ViewModels/PortalApp/ApiPortalApp.cs @@ -4,7 +4,6 @@ namespace Equinor.ProjectExecutionPortal.WebApi.ViewModels.PortalApp; -// TODO: Should be removed public class ApiPortalApp { #pragma warning disable CS8618 // For integration tests only diff --git a/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/IntegrationTests/PortalControllerTests.cs b/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/IntegrationTests/PortalControllerTests.cs index 4643e9cac..56718f833 100644 --- a/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/IntegrationTests/PortalControllerTests.cs +++ b/backend/src/tests/Equinor.ProjectExecutionPortal.Tests.WebApi/IntegrationTests/PortalControllerTests.cs @@ -532,13 +532,13 @@ public async Task Delete_PortalApp_AsAdministrator_ShouldReturnOk() var appToDelete = apps.First(); // Act - var response = await DeletePortalApp(portalToTest.Id, appToDelete.AppKey, UserType.Administrator); + var response = await DeletePortalApp(portalToTest.Id, appToDelete, UserType.Administrator); // Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); // Verify the app is actually deleted - var deletedApp = await AssertGetPortalApp(portalToTest.Id, appToDelete.AppKey, UserType.Authenticated, HttpStatusCode.NotFound); + var deletedApp = await AssertGetPortalApp(portalToTest.Id, appToDelete, UserType.Authenticated, HttpStatusCode.NotFound); Assert.IsNull(deletedApp); } @@ -558,7 +558,7 @@ public async Task Delete_PortalApp_AsAuthenticatedUser_ShouldReturnForbidden() var appToDelete = apps.First(); // Act - var response = await DeletePortalApp(portalToTest.Id, appToDelete.AppKey, UserType.Authenticated); + var response = await DeletePortalApp(portalToTest.Id, appToDelete, UserType.Authenticated); // Assert Assert.AreEqual(HttpStatusCode.Forbidden, response.StatusCode); @@ -580,7 +580,7 @@ public async Task Delete_PortalApp_AsAnonymousUser_ShouldReturnUnauthorized() var appToDelete = apps.First(); // Act - var response = await DeletePortalApp(portalToTest.Id, appToDelete.AppKey, UserType.Anonymous); + var response = await DeletePortalApp(portalToTest.Id, appToDelete, UserType.Anonymous); // Assert Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode); @@ -708,30 +708,30 @@ public async Task Delete_PortalApp_AsAnonymousUser_ShouldReturnUnauthorized() return appKeys; } - private static async Task?> AssertGetAppsForPortal(Guid portalId, Guid? contextId, UserType userType, HttpStatusCode expectedStatusCode) + private static async Task?> AssertGetAppsForPortal(Guid portalId, Guid? contextId, UserType userType, HttpStatusCode expectedStatusCode) { // Act var response = await GetAppsForPortal(portalId, contextId, userType); var content = await response.Content.ReadAsStringAsync(); - var apps = JsonConvert.DeserializeObject>(content); + var appKeys = JsonConvert.DeserializeObject>(content); // Assert Assert.AreEqual(expectedStatusCode, response.StatusCode); if (response.StatusCode != HttpStatusCode.OK) { - return apps; + return appKeys; } Assert.IsNotNull(content); - Assert.IsNotNull(apps); + Assert.IsNotNull(appKeys); - foreach (var app in apps) + foreach (var appKey in appKeys) { - AssertHelpers.AssertPortalAppValues(app); + Assert.IsNotNull(appKey); } - return apps; + return appKeys; } private static async Task CreatePortal(UserType userType, ApiCreatePortalRequest createdPortal) From ea38497dba0d5f8acace74b567bc10441f9d31e8 Mon Sep 17 00:00:00 2001 From: Kjetil Haugland Date: Thu, 7 Nov 2024 08:45:56 +0100 Subject: [PATCH 4/5] Update editorconfig --- .editorconfig | 394 ++++++++++++++++++++++++++++---------------------- 1 file changed, 225 insertions(+), 169 deletions(-) diff --git a/.editorconfig b/.editorconfig index d617e8163..b5cef9f5a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,155 +1,205 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories root = true -# top-most EditorConfig file -# Don't use tabs for indentation. +# All files [*] indent_style = space -# ReSharper inspection severities -resharper_arrange_constructor_or_destructor_body_highlighting = hint -resharper_arrange_method_or_operator_body_highlighting = hint -# (Please don't specify an indent_size here; that has too many unintended consequences.) - -# Code files -[*.{cs,csx,vb,vbx}] -indent_size = 4 -insert_final_newline = true -charset = utf-8-bom - # XML project files [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] -indent_size = 4 +indent_size = 2 +tab_width=2 # XML config files [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] indent_size = 2 +tab_width=2 -# JSON files -[*.json] +# JSON Files +[*.{json,json5,webmanifest}] indent_size = 2 +tab_width=2 -# Powershell files -[*.ps1] +# YAML Files +[*.{yml,yaml}] indent_size = 2 +tab_width=2 -# Shell script files -[*.sh] -end_of_line = lf -indent_size = 2 - -# Dotnet code style settings: -[*.{cs,vb}] -# Sort using and Import directives with System.* appearing first -dotnet_sort_system_directives_first = true -# Avoid "this." and "Me." if not necessary -dotnet_style_qualification_for_field = false:refactoring -dotnet_style_qualification_for_property = false:refactoring -dotnet_style_qualification_for_method = false:refactoring -dotnet_style_qualification_for_event = false:refactoring - -# Use language keywords instead of framework type names for type references -dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion -dotnet_style_predefined_type_for_member_access = true:suggestion - -# Suggest more modern language features when available -dotnet_style_object_initializer = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_explicit_tuple_names = true:suggestion +# Markdown Files +[*.{md,mdx}] +trim_trailing_whitespace = false -# Non-private static fields are PascalCase -dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non_private_static_fields -dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style - -dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field -dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected -dotnet_naming_symbols.non_private_static_fields.required_modifiers = static - -dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case - -# Non-private readonly fields are PascalCase -dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.symbols = non_private_readonly_fields -dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.style = non_private_static_field_style - -dotnet_naming_symbols.non_private_readonly_fields.applicable_kinds = field -dotnet_naming_symbols.non_private_readonly_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected -dotnet_naming_symbols.non_private_readonly_fields.required_modifiers = readonly - -dotnet_naming_style.non_private_readonly_field_style.capitalization = pascal_case - -# Constants are PascalCase -dotnet_naming_rule.constants_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.constants_should_be_pascal_case.symbols = constants -dotnet_naming_rule.constants_should_be_pascal_case.style = non_private_static_field_style - -dotnet_naming_symbols.constants.applicable_kinds = field, local -dotnet_naming_symbols.constants.required_modifiers = const - -dotnet_naming_style.constant_style.capitalization = pascal_case - -# Instance fields are camelCase and start with _ -dotnet_naming_rule.instance_fields_should_be_camel_case.severity = suggestion -dotnet_naming_rule.instance_fields_should_be_camel_case.symbols = instance_fields -dotnet_naming_rule.instance_fields_should_be_camel_case.style = instance_field_style - -dotnet_naming_symbols.instance_fields.applicable_kinds = field - -dotnet_naming_style.instance_field_style.capitalization = camel_case -dotnet_naming_style.instance_field_style.required_prefix = _ +# Web Files +[*.{htm,html,js,jsm,ts,tsx,cjs,cts,ctsx,mjs,mts,mtsx,css,sass,scss,less,pcss,svg,vue}] +indent_size = 2 +tab_width=2 -# Locals and parameters are camelCase -dotnet_naming_rule.locals_should_be_camel_case.severity = suggestion -dotnet_naming_rule.locals_should_be_camel_case.symbols = locals_and_parameters -dotnet_naming_rule.locals_should_be_camel_case.style = camel_case_style +# Batch Files +[*.{cmd,bat}] +end_of_line = crlf -dotnet_naming_symbols.locals_and_parameters.applicable_kinds = parameter, local +# Bash Files +[*.sh] +end_of_line = lf -dotnet_naming_style.camel_case_style.capitalization = camel_case +# Powershell +[*.{ps1,psd1,psm1}] +indent_size = 4 +tab_width=4 -# Local functions are PascalCase -dotnet_naming_rule.local_functions_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.local_functions_should_be_pascal_case.symbols = local_functions -dotnet_naming_rule.local_functions_should_be_pascal_case.style = non_private_static_field_style +# Protobuf Files +[*.proto] +indent_style=tab +indent_size=tab +tab_width=4 -dotnet_naming_symbols.local_functions.applicable_kinds = local_function +# Code files +[*.{cs,csx,vb,vbx}] +max_line_length = 200 -dotnet_naming_style.local_function_style.capitalization = pascal_case +#### Core EditorConfig Options #### -# By default, name items with PascalCase -dotnet_naming_rule.members_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.members_should_be_pascal_case.symbols = all_members -dotnet_naming_rule.members_should_be_pascal_case.style = non_private_static_field_style +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 -dotnet_naming_symbols.all_members.applicable_kinds = * +# New line preferences +end_of_line = crlf +insert_final_newline = true -dotnet_naming_style.pascal_case_style.capitalization = pascal_case +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = false +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_method = false +dotnet_style_qualification_for_property = false + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_predefined_type_for_member_access = true + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_operators = never_if_unnecessary +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members + +# Expression-level preferences +dotnet_style_coalesce_expression = true +dotnet_style_collection_initializer = true +dotnet_style_explicit_tuple_names = true +dotnet_style_namespace_match_folder = true +dotnet_style_null_propagation = true +dotnet_style_object_initializer = true dotnet_style_operator_placement_when_wrapping = beginning_of_line -tab_width = 4 -end_of_line = crlf -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion -dotnet_style_prefer_auto_properties = true:silent -dotnet_style_prefer_simplified_boolean_expressions = true:suggestion -dotnet_style_prefer_conditional_expression_over_assignment = true:silent -dotnet_style_prefer_conditional_expression_over_return = true:silent -dotnet_style_prefer_inferred_tuple_names = true:suggestion -dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion -dotnet_style_prefer_compound_assignment = true:suggestion -dotnet_style_prefer_simplified_interpolation = true:suggestion -dotnet_style_namespace_match_folder = true:suggestion -dotnet_style_readonly_field = true:suggestion - -# CSharp code style settings: -[*.cs] -# Newline settings -csharp_new_line_before_open_brace = all -csharp_new_line_before_else = true +dotnet_style_prefer_auto_properties = true +dotnet_style_prefer_compound_assignment = true +dotnet_style_prefer_conditional_expression_over_assignment = true +dotnet_style_prefer_conditional_expression_over_return = true +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed +dotnet_style_prefer_inferred_anonymous_type_member_names = true +dotnet_style_prefer_inferred_tuple_names = true +dotnet_style_prefer_is_null_check_over_reference_equality_method = true +dotnet_style_prefer_simplified_boolean_expressions = true +dotnet_style_prefer_simplified_interpolation = true + +# Field preferences +dotnet_style_readonly_field = true + +# Parameter preferences +dotnet_code_quality_unused_parameters = all + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +# New line preferences +dotnet_style_allow_multiple_blank_lines_experimental = true +dotnet_style_allow_statement_immediately_after_block_experimental = true + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = true +csharp_style_var_for_built_in_types = true +csharp_style_var_when_type_is_apparent = true + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true +csharp_style_expression_bodied_constructors = false +csharp_style_expression_bodied_indexers = true +csharp_style_expression_bodied_lambdas = true +csharp_style_expression_bodied_local_functions = false +csharp_style_expression_bodied_methods = false +csharp_style_expression_bodied_operators = false +csharp_style_expression_bodied_properties = true + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true +csharp_style_pattern_matching_over_is_with_cast_check = true +csharp_style_prefer_extended_property_pattern = true +csharp_style_prefer_not_pattern = true +csharp_style_prefer_pattern_matching = true +csharp_style_prefer_switch_expression = true + +# Null-checking preferences +csharp_style_conditional_delegate_call = true + +# Modifier preferences +csharp_prefer_static_local_function = true +csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async +csharp_style_prefer_readonly_struct = true + +# Code-block preferences +csharp_prefer_braces = true +csharp_prefer_simple_using_statement = true +csharp_style_namespace_declarations = file_scoped:warning +csharp_style_prefer_method_group_conversion = true +csharp_style_prefer_top_level_statements = true + +# Expression-level preferences +csharp_prefer_simple_default_expression = true +csharp_style_deconstructed_variable_declaration = true +csharp_style_implicit_object_creation_when_type_is_apparent = true +csharp_style_inlined_variable_declaration = true +csharp_style_prefer_index_operator = true +csharp_style_prefer_local_over_anonymous_function = true +csharp_style_prefer_null_check_over_type_check = true +csharp_style_prefer_range_operator = true +csharp_style_prefer_tuple_swap = true +csharp_style_prefer_utf8_string_literals = true +csharp_style_throw_expression = true +csharp_style_unused_value_assignment_preference = discard_variable +csharp_style_unused_value_expression_statement_preference = discard_variable + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace + +# New line preferences +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true +csharp_style_allow_embedded_statements_on_same_line_experimental = true + +#### C# Formatting Rules #### + +# New line preferences csharp_new_line_before_catch = true +csharp_new_line_before_else = true csharp_new_line_before_finally = true -csharp_new_line_before_members_in_object_initializers = true csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all csharp_new_line_between_query_expression_clauses = true # Indentation preferences @@ -157,30 +207,8 @@ csharp_indent_block_contents = true csharp_indent_braces = false csharp_indent_case_contents = true csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current csharp_indent_switch_labels = true -csharp_indent_labels = flush_left - -# Prefer "var" everywhere -csharp_style_var_for_built_in_types = true:suggestion -csharp_style_var_when_type_is_apparent = true:suggestion -csharp_style_var_elsewhere = true:suggestion - -# Prefer method-like constructs to have a block body -csharp_style_expression_bodied_methods = false:silent -csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_operators = false:none - -# Prefer property-like constructs to have an expression-body -csharp_style_expression_bodied_properties = true:none -csharp_style_expression_bodied_indexers = true:none -csharp_style_expression_bodied_accessors = true:none - -# Suggest more modern language features when available -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -csharp_style_throw_expression = true:suggestion -csharp_style_conditional_delegate_call = true:suggestion # Space preferences csharp_space_after_cast = false @@ -190,7 +218,7 @@ csharp_space_after_dot = false csharp_space_after_keywords_in_control_flow_statements = true csharp_space_after_semicolon_in_for_statement = true csharp_space_around_binary_operators = before_and_after -csharp_space_around_declaration_statements = do_not_ignore +csharp_space_around_declaration_statements = false csharp_space_before_colon_in_inheritance_clause = true csharp_space_before_comma = false csharp_space_before_dot = false @@ -206,31 +234,59 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false csharp_space_between_parentheses = false csharp_space_between_square_brackets = false -# Blocks are allowed -csharp_prefer_braces = true:suggestion +# Wrapping preferences csharp_preserve_single_line_blocks = true csharp_preserve_single_line_statements = true -csharp_using_directive_placement = outside_namespace:silent -csharp_prefer_simple_using_statement = true:suggestion -csharp_style_namespace_declarations = block_scoped:silent -csharp_style_prefer_method_group_conversion = true:silent -csharp_style_expression_bodied_lambdas = true:silent -csharp_style_expression_bodied_local_functions = false:silent -csharp_style_prefer_null_check_over_type_check = true:suggestion -csharp_prefer_simple_default_expression = true:suggestion -csharp_style_prefer_local_over_anonymous_function = true:suggestion -csharp_style_prefer_index_operator = true:suggestion -csharp_style_prefer_range_operator = true:suggestion -csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion -csharp_style_prefer_tuple_swap = true:suggestion -csharp_style_deconstructed_variable_declaration = true:suggestion -csharp_style_unused_value_assignment_preference = discard_variable:suggestion -csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +# Migration files +[**/Migrations/*.cs] +csharp_style_namespace_declarations = file_scoped:off +dotnet_sort_system_directives_first = true [*.cs] -# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0290 -csharp_style_prefer_primary_constructors = false -dotnet_diagnostic.IDE0290.severity = warning +resharper_unused_auto_property_accessor_global_highlighting=none -# https://www.jetbrains.com/help/rider/ConvertToPrimaryConstructor.html -resharper_convert_to_primary_constructor_highlighting = none +[*.{cs,vb}] +dotnet_diagnostic.CA1812.severity = none \ No newline at end of file From 853a4768dab2dfc5677d27417d23b48ed22383f5 Mon Sep 17 00:00:00 2001 From: kjetilhau Date: Fri, 8 Nov 2024 09:44:13 +0000 Subject: [PATCH 5/5] chore: create pr-853-2163110665.md --- .changeset/pr-853-2163110665.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .changeset/pr-853-2163110665.md diff --git a/.changeset/pr-853-2163110665.md b/.changeset/pr-853-2163110665.md new file mode 100644 index 000000000..849b5df54 --- /dev/null +++ b/.changeset/pr-853-2163110665.md @@ -0,0 +1,19 @@ + +--- +"fusion-project-portal": major +--- +BREAKING CHANGE: + +Updates the API endpoints that gives Portal Apps as list of objects: + +{portalId:guid}/apps +{portalId:guid}/contexts/{contextId:guid}/apps +Now instead, these endpoint returns a list of appKeys (strings). + +The old ones: + +{portalId:guid}/appkeys +{portalId:guid}/contexts/{contextId:guid}/appkeys +are now identical, and are deprecated and will be removed when front-end has adopted the updated endpoints. + +In addition some refactoring has been done. As a result, compiler warnings has been greatly reduced