From e069007b87302d39d8dee4cd1ec47328c7879a17 Mon Sep 17 00:00:00 2001 From: Erling Hauan <148075168+ErlingHauan@users.noreply.github.com> Date: Thu, 11 Jul 2024 08:14:39 +0200 Subject: [PATCH] Create controller and service for options/code lists (#13046) * Add GET endpoint for fetching an options list * Add PUT endpoint for creating or overwriting an options list * Implement 'Option' model * Add DELETE endpoint * Add GET endpoint for fetching list of options * Add tests for all return codes * Add tests for new methods in AltinnAppGitRepository --- .../Controllers/AppDevelopmentController.cs | 2 +- .../Designer/Controllers/OptionsController.cs | 127 +++++++++ .../Designer/Controllers/PreviewController.cs | 4 +- .../GitRepository/AltinnAppGitRepository.cs | 73 +++-- .../Infrastructure/ServiceRegistration.cs | 1 + backend/src/Designer/Models/Option.cs | 37 +++ .../Services/Implementation/OptionsService.cs | 93 +++++++ .../Services/Implementation/TextsService.cs | 2 +- .../Services/Interfaces/IOptionsService.cs | 63 +++++ .../OptionsController/DeleteOptionsTests.cs | 66 +++++ .../OptionsController/GetOptionsTests.cs | 99 +++++++ .../OptionsController/UpdateOptionsTests.cs | 156 +++++++++++ .../AltinnAppGitRepositoryTests.cs | 85 +++++- .../Services/OptionsServiceTests.cs | 261 ++++++++++++++++++ 14 files changed, 1042 insertions(+), 27 deletions(-) create mode 100644 backend/src/Designer/Controllers/OptionsController.cs create mode 100644 backend/src/Designer/Models/Option.cs create mode 100644 backend/src/Designer/Services/Implementation/OptionsService.cs create mode 100644 backend/src/Designer/Services/Interfaces/IOptionsService.cs create mode 100644 backend/tests/Designer.Tests/Controllers/OptionsController/DeleteOptionsTests.cs create mode 100644 backend/tests/Designer.Tests/Controllers/OptionsController/GetOptionsTests.cs create mode 100644 backend/tests/Designer.Tests/Controllers/OptionsController/UpdateOptionsTests.cs create mode 100644 backend/tests/Designer.Tests/Services/OptionsServiceTests.cs diff --git a/backend/src/Designer/Controllers/AppDevelopmentController.cs b/backend/src/Designer/Controllers/AppDevelopmentController.cs index 714114556bb..c94aa1d0291 100644 --- a/backend/src/Designer/Controllers/AppDevelopmentController.cs +++ b/backend/src/Designer/Controllers/AppDevelopmentController.cs @@ -515,7 +515,7 @@ public ActionResult GetOptionListIds(string org, string app) { string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext); AltinnAppGitRepository altinnAppGitRepository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(org, app, developer); - string[] optionListIds = altinnAppGitRepository.GetOptionListIds(); + string[] optionListIds = altinnAppGitRepository.GetOptionsListIds(); return Ok(optionListIds); } catch (LibGit2Sharp.NotFoundException) diff --git a/backend/src/Designer/Controllers/OptionsController.cs b/backend/src/Designer/Controllers/OptionsController.cs new file mode 100644 index 00000000000..b11d7cc2c26 --- /dev/null +++ b/backend/src/Designer/Controllers/OptionsController.cs @@ -0,0 +1,127 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Altinn.Studio.Designer.Helpers; +using Altinn.Studio.Designer.Models; +using Altinn.Studio.Designer.Services.Interfaces; +using LibGit2Sharp; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace Altinn.Studio.Designer.Controllers; + +/// +/// Controller containing actions related to options (code lists). +/// +[ApiController] +[Authorize] +[AutoValidateAntiforgeryToken] +[Route("designer/api/{org}/{repo:regex(^(?!datamodels$)[[a-z]][[a-z0-9-]]{{1,28}}[[a-z0-9]]$)}/options")] +public class OptionsController : ControllerBase +{ + private readonly IOptionsService _optionsService; + + /// + /// Initializes a new instance of the class. + /// + /// The options service. + public OptionsController(IOptionsService optionsService) + { + _optionsService = optionsService; + } + + /// + /// Fetches the IDs of the options lists belonging to the app. + /// + /// Unique identifier of the organisation responsible for the app. + /// Application identifier which is unique within an organisation. + /// Array of options list's IDs. Empty array if none are found + [HttpGet] + [Produces("application/json")] + [ProducesResponseType(StatusCodes.Status200OK)] + public ActionResult GetOptionsListIds(string org, string repo) + { + string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext); + + string[] optionsListIds = _optionsService.GetOptionsListIds(org, repo, developer); + + return Ok(optionsListIds); + } + + /// + /// Fetches a specific option list. + /// + /// Unique identifier of the organisation responsible for the app. + /// Application identifier which is unique within an organisation. + /// Name of the option list. + /// A that observes if operation is cancelled. + [HttpGet] + [Produces("application/json")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [Route("{optionsListId}")] + public async Task>> GetOptionsList(string org, string repo, [FromRoute] string optionsListId, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext); + + try + { + List