diff --git a/Documentation/OMC - Documentation.md b/Documentation/OMC - Documentation.md index 1106bbae..963eb2a8 100644 --- a/Documentation/OMC - Documentation.md +++ b/Documentation/OMC - Documentation.md @@ -1,6 +1,6 @@ # **OMC** Documentation -v.1.8.14 +v.1.8.15 © 2024, Worth Systems. diff --git a/EventsHandler/Api/EventsHandler/Constants/DefaultValues.cs b/EventsHandler/Api/EventsHandler/Constants/DefaultValues.cs index f255bdd8..b30b2681 100644 --- a/EventsHandler/Api/EventsHandler/Constants/DefaultValues.cs +++ b/EventsHandler/Api/EventsHandler/Constants/DefaultValues.cs @@ -12,7 +12,7 @@ internal static class ApiController { internal const string Route = "[controller]"; - internal const string Version = "1.814"; + internal const string Version = "1.815"; } #endregion diff --git a/EventsHandler/Api/EventsHandler/Extensions/UriExtensions.cs b/EventsHandler/Api/EventsHandler/Extensions/UriExtensions.cs index 94daf00f..94be0af6 100644 --- a/EventsHandler/Api/EventsHandler/Extensions/UriExtensions.cs +++ b/EventsHandler/Api/EventsHandler/Extensions/UriExtensions.cs @@ -89,7 +89,7 @@ internal static bool IsNotCaseType(this Uri? uri) } /// - /// Determines whether the given doesn't contain object (e.g., or ) . + /// Determines whether the given doesn't contain object (e.g., from Task or ) . /// /// The source URI. /// diff --git a/EventsHandler/Api/EventsHandler/Mapping/Enums/NotificatieApi/Resources.cs b/EventsHandler/Api/EventsHandler/Mapping/Enums/NotificatieApi/Resources.cs index e8ae85dc..40771959 100644 --- a/EventsHandler/Api/EventsHandler/Mapping/Enums/NotificatieApi/Resources.cs +++ b/EventsHandler/Api/EventsHandler/Mapping/Enums/NotificatieApi/Resources.cs @@ -2,8 +2,6 @@ using EventsHandler.Constants; using EventsHandler.Mapping.Converters; -using EventsHandler.Mapping.Models.POCOs.Objecten.Message; -using EventsHandler.Mapping.Models.POCOs.Objecten.Task; using System.Text.Json.Serialization; namespace EventsHandler.Mapping.Enums.NotificatieApi diff --git a/EventsHandler/Api/EventsHandler/Mapping/Enums/Objecten/TaskStatuses.cs b/EventsHandler/Api/EventsHandler/Mapping/Enums/Objecten/TaskStatuses.cs index ab7db91b..18b84f73 100644 --- a/EventsHandler/Api/EventsHandler/Mapping/Enums/Objecten/TaskStatuses.cs +++ b/EventsHandler/Api/EventsHandler/Mapping/Enums/Objecten/TaskStatuses.cs @@ -8,7 +8,7 @@ namespace EventsHandler.Mapping.Enums.Objecten { /// - /// The status of the from "Objecten" Web API service. + /// The status of the from "Objecten" Web API service. /// [JsonConverter(typeof(SafeJsonStringEnumMemberConverter))] public enum TaskStatuses diff --git a/EventsHandler/Api/EventsHandler/Mapping/Enums/Objecten/vNijmegen/Registrations.cs b/EventsHandler/Api/EventsHandler/Mapping/Enums/Objecten/vNijmegen/Registrations.cs new file mode 100644 index 00000000..69105581 --- /dev/null +++ b/EventsHandler/Api/EventsHandler/Mapping/Enums/Objecten/vNijmegen/Registrations.cs @@ -0,0 +1,28 @@ +// © 2024, Worth Systems. + +using EventsHandler.Constants; +using EventsHandler.Mapping.Converters; +using EventsHandler.Mapping.Models.POCOs.Objecten.Task.vNijmegen; +using System.Text.Json.Serialization; + +namespace EventsHandler.Mapping.Enums.Objecten.vNijmegen +{ + /// + /// The type of the from "Objecten" Web API service. + /// + [JsonConverter(typeof(SafeJsonStringEnumMemberConverter))] + public enum Registrations + { + /// + /// The default value. + /// + [JsonPropertyName(DefaultValues.Models.DefaultEnumValueName)] + Unknown = 0, + + /// + /// The case type of the . + /// + [JsonPropertyName("zaak")] + Case = 1 + } +} \ No newline at end of file diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/NotificatieApi/EventAttributes.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/NotificatieApi/EventAttributes.cs index 0f190aef..117558bb 100644 --- a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/NotificatieApi/EventAttributes.cs +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/NotificatieApi/EventAttributes.cs @@ -89,7 +89,7 @@ internal readonly PropertiesMetadata Properties(Channels channel) #region Object properties /// - /// The or type in format: + /// The from Task or type in format: /// /// http(s)://Domain/ApiEndpoint/[UUID] /// diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Identification.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Identification.cs index bbb89712..76e985d2 100644 --- a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Identification.cs +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Identification.cs @@ -9,7 +9,7 @@ namespace EventsHandler.Mapping.Models.POCOs.Objecten { /// - /// The identification related to the different Data (associated with , + /// The identification related to the different Data (associated with from Task, /// , etc.) retrieved from "Objecten" Web API service. /// /// diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/CommonTaskData.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/CommonTaskData.cs new file mode 100644 index 00000000..af3e36f7 --- /dev/null +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/CommonTaskData.cs @@ -0,0 +1,68 @@ +// © 2024, Worth Systems. + +using EventsHandler.Mapping.Enums.Objecten; +using EventsHandler.Mapping.Models.Interfaces; +using System.Text.Json.Serialization; + +namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task +{ + /// + /// The data related to the Task (from vHague or vNijmegen versions) retrieved from "Objecten" Web API service. + /// + /// + /// Common DTO for all versions of "Objecten" Web API service. + /// + /// + internal readonly struct CommonTaskData : IJsonSerializable + { + /// + /// The reference to related object in format: + /// + /// http(s)://Domain/ApiEndpoint/[UUID] + /// + /// + [JsonInclude] + [JsonPropertyOrder(0)] + internal Uri CaseUri { get; init; } // NOTE: Some task data might not have it (recreating of URI is necessary) + + /// + /// The ID of the related object. + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyOrder(1)] + internal Guid CaseId { get; init; } + + /// + /// The title of the task. + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyOrder(2)] + internal string Title { get; init; } + + /// + /// The status of the task. + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyOrder(3)] + internal TaskStatuses Status { get; init; } + + /// + /// The deadline by which the task should be completed. + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyOrder(4)] + internal DateTime ExpirationDate { get; init; } + + /// + /// The identification details of the task. + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyOrder(5)] + internal Identification Identification { get; init; } + } +} \ No newline at end of file diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/Converters/CommonTaskDataConverter.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/Converters/CommonTaskDataConverter.cs new file mode 100644 index 00000000..f88a102d --- /dev/null +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/Converters/CommonTaskDataConverter.cs @@ -0,0 +1,60 @@ +// © 2024, Worth Systems. + +using EventsHandler.Extensions; +using EventsHandler.Services.Settings.Extensions; +using ConfigurationExtensions = EventsHandler.Services.Settings.Extensions.ConfigurationExtensions; + +namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task.Converters +{ + /// + /// Converts task data from different versions of "Objecten" into a unified . + /// + internal static class CommonTaskDataConverter + { + /// + /// Converts (version used by The Hague) from "Objecten" Web API service. + /// + /// + /// The unified DTO model. + /// + internal static CommonTaskData ConvertToUnified(this vHague.TaskObject taskDataHague) + { + return new CommonTaskData + { + CaseUri = taskDataHague.Record.Data.CaseUri, + CaseId = taskDataHague.Record.Data.CaseUri.GetGuid(), // NOTE: URI is given, GUID needs to be extracted + Title = taskDataHague.Record.Data.Title, + Status = taskDataHague.Record.Data.Status, + ExpirationDate = taskDataHague.Record.Data.ExpirationDate, + Identification = taskDataHague.Record.Data.Identification + }; + } + + /// + /// Converts (version used by Nijmegen) from "Objecten" Web API service. + /// + /// + /// The unified DTO model. + /// + internal static CommonTaskData ConvertToUnified(this vNijmegen.TaskObject taskNijmegen) + { + return new CommonTaskData + { + CaseUri = RecreateCaseUri(taskNijmegen.Record.Data.Coupling.Id), // NOTE: GUID is given, URI needs to be recreated + CaseId = taskNijmegen.Record.Data.Coupling.Id, + Title = taskNijmegen.Record.Data.Title, + Status = taskNijmegen.Record.Data.Status, + ExpirationDate = taskNijmegen.Record.Data.ExpirationDate, + Identification = taskNijmegen.Record.Data.Identification + }; + } + + #region Helper methods + private const string CaseUri = "https://{0}/zaken/api/v1/zaken/{1}"; + + private static Uri RecreateCaseUri(Guid caseId) + => string.Format(CaseUri, ConfigurationExtensions.OpenZaakDomain(), caseId) + .GetValidUri(); + #endregion + } +} \ No newline at end of file diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/Data.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vHague/Data.cs similarity index 66% rename from EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/Data.cs rename to EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vHague/Data.cs index c20ebd9a..8b76989e 100644 --- a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/Data.cs +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vHague/Data.cs @@ -3,59 +3,49 @@ using EventsHandler.Constants; using EventsHandler.Mapping.Enums.Objecten; using EventsHandler.Mapping.Models.Interfaces; -using EventsHandler.Mapping.Models.POCOs.OpenZaak; using System.Text.Json.Serialization; -namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task +namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task.vHague { /// /// The data related to the retrieved from "Objecten" Web API service. /// + /// + /// Version used by The Hague. + /// + /// /// public struct Data : IJsonSerializable { - /// - /// The reference to in format: - /// - /// http(s)://Domain/ApiEndpoint/[UUID] - /// - /// + /// [JsonRequired] [JsonInclude] [JsonPropertyName("zaak")] [JsonPropertyOrder(0)] public Uri CaseUri { get; internal set; } = DefaultValues.Models.EmptyUri; - /// - /// The title of the . - /// + /// [JsonRequired] [JsonInclude] [JsonPropertyName("title")] [JsonPropertyOrder(1)] public string Title { get; internal set; } = string.Empty; - /// - /// The status of the . - /// + /// [JsonRequired] [JsonInclude] [JsonPropertyName("status")] [JsonPropertyOrder(2)] public TaskStatuses Status { get; internal set; } - /// - /// The deadline by which the should be completed. - /// + /// [JsonRequired] [JsonInclude] [JsonPropertyName("verloopdatum")] [JsonPropertyOrder(3)] public DateTime ExpirationDate { get; internal set; } - /// - /// The identification details of the . - /// + /// [JsonRequired] [JsonInclude] [JsonPropertyName("identificatie")] diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/Record.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vHague/Record.cs similarity index 81% rename from EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/Record.cs rename to EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vHague/Record.cs index f3fc1382..8314bd0f 100644 --- a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/Record.cs +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vHague/Record.cs @@ -3,11 +3,14 @@ using EventsHandler.Mapping.Models.Interfaces; using System.Text.Json.Serialization; -namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task +namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task.vHague { /// /// The record related to the retrieved from "Objecten" Web API service. /// + /// + /// Version used by The Hague. + /// /// public struct Record : IJsonSerializable { diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/TaskObject.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vHague/TaskObject.cs similarity index 80% rename from EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/TaskObject.cs rename to EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vHague/TaskObject.cs index 0e0385a8..8e3fc0e0 100644 --- a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/TaskObject.cs +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vHague/TaskObject.cs @@ -3,11 +3,14 @@ using EventsHandler.Mapping.Models.Interfaces; using System.Text.Json.Serialization; -namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task +namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task.vHague { /// /// The task retrieved from "Objecten" Web API service. /// + /// + /// Version used by The Hague. + /// /// public struct TaskObject : IJsonSerializable { diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/Coupling.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/Coupling.cs new file mode 100644 index 00000000..8579523c --- /dev/null +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/Coupling.cs @@ -0,0 +1,40 @@ +// © 2024, Worth Systems. + +using EventsHandler.Mapping.Enums.Objecten.vNijmegen; +using EventsHandler.Mapping.Models.Interfaces; +using System.Text.Json.Serialization; + +namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task.vNijmegen +{ + /// + /// The coupling related to the retrieved from "Objecten" Web API service. + /// + /// + public struct Coupling : IJsonSerializable + { + /// + /// The type of the . + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyName("registratie")] + [JsonPropertyOrder(0)] + public Registrations Type { get; internal set; } + + /// + /// The ID of the object (e.g., case). + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyName("uuid")] + [JsonPropertyOrder(1)] + public Guid Id { get; internal set; } = Guid.Empty; + + /// + /// Initializes a new instance of the struct. + /// + public Coupling() + { + } + } +} \ No newline at end of file diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/Data.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/Data.cs new file mode 100644 index 00000000..cc35c9cd --- /dev/null +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/Data.cs @@ -0,0 +1,61 @@ +// © 2024, Worth Systems. + +using EventsHandler.Mapping.Enums.Objecten; +using EventsHandler.Mapping.Models.Interfaces; +using System.Text.Json.Serialization; + +namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task.vNijmegen +{ + /// + /// The data related to the retrieved from "Objecten" Web API service. + /// + /// + /// Version used by Nijmegen. + /// + /// + /// + public struct Data : IJsonSerializable + { + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyName("titel")] + [JsonPropertyOrder(0)] + public string Title { get; internal set; } = string.Empty; + + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyName("status")] + [JsonPropertyOrder(1)] + public TaskStatuses Status { get; internal set; } + + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyName("verloopdatum")] + [JsonPropertyOrder(2)] + public DateTime ExpirationDate { get; internal set; } + + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyName("identificatie")] + [JsonPropertyOrder(3)] + public Identification Identification { get; internal set; } + + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyName("koppeling")] + [JsonPropertyOrder(4)] + public Coupling Coupling { get; internal set; } + + /// + /// Initializes a new instance of the struct. + /// + public Data() + { + } + } +} \ No newline at end of file diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/Record.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/Record.cs new file mode 100644 index 00000000..327ae030 --- /dev/null +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/Record.cs @@ -0,0 +1,26 @@ +// © 2024, Worth Systems. + +using EventsHandler.Mapping.Models.Interfaces; +using System.Text.Json.Serialization; + +namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task.vNijmegen +{ + /// + /// The record related to the retrieved from "Objecten" Web API service. + /// + /// + /// Version used by Nijmegen. + /// + /// + public struct Record : IJsonSerializable + { + /// + /// The data related to the . + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyName("data")] + [JsonPropertyOrder(0)] + public Data Data { get; internal set; } + } +} \ No newline at end of file diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/TaskObject.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/TaskObject.cs new file mode 100644 index 00000000..31c01419 --- /dev/null +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/Objecten/Task/vNijmegen/TaskObject.cs @@ -0,0 +1,33 @@ +// © 2024, Worth Systems. + +using EventsHandler.Mapping.Models.Interfaces; +using System.Text.Json.Serialization; + +namespace EventsHandler.Mapping.Models.POCOs.Objecten.Task.vNijmegen +{ + /// + /// The task retrieved from "Objecten" Web API service. + /// + /// + /// Version used by Nijmegen. + /// + /// + public struct TaskObject : IJsonSerializable + { + /// + /// The record related to the . + /// + [JsonRequired] + [JsonInclude] + [JsonPropertyName("record")] + [JsonPropertyOrder(0)] + public Record Record { get; internal set; } + + /// + /// Initializes a new instance of the struct. + /// + public TaskObject() + { + } + } +} \ No newline at end of file diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/OpenKlant/CommonPartyData.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/OpenKlant/CommonPartyData.cs index c98903ec..4f4f58c4 100644 --- a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/OpenKlant/CommonPartyData.cs +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/OpenKlant/CommonPartyData.cs @@ -12,7 +12,7 @@ namespace EventsHandler.Mapping.Models.POCOs.OpenKlant /// Common DTO for all versions of "OpenKlant" Web API service. /// /// - public readonly struct CommonPartyData : IJsonSerializable + internal readonly struct CommonPartyData : IJsonSerializable { /// /// The first name of the citizen. @@ -32,7 +32,7 @@ namespace EventsHandler.Mapping.Models.POCOs.OpenKlant /// /// The last name (surname) of the citizen. /// - public string Surname { get; internal init; } + internal string Surname { get; init; } /// internal DistributionChannels DistributionChannel { get; init; } @@ -46,18 +46,5 @@ namespace EventsHandler.Mapping.Models.POCOs.OpenKlant /// The telephone number of the citizen. /// internal string TelephoneNumber { get; init; } - - /// - /// Determines whether this instance is not initialized properly. - /// - internal bool IsDefault() - { - return this.DistributionChannel == DistributionChannels.Unknown && - this.Name == null && - this.SurnamePrefix == null && - this.Surname == null && - this.EmailAddress == null && - this.TelephoneNumber == null; - } } } \ No newline at end of file diff --git a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/OpenKlant/Converters/CitizenDataConverter.cs b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/OpenKlant/Converters/CommonPartyDataConverter.cs similarity index 97% rename from EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/OpenKlant/Converters/CitizenDataConverter.cs rename to EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/OpenKlant/Converters/CommonPartyDataConverter.cs index 5304e8f4..cbc4e9ef 100644 --- a/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/OpenKlant/Converters/CitizenDataConverter.cs +++ b/EventsHandler/Api/EventsHandler/Mapping/Models/POCOs/OpenKlant/Converters/CommonPartyDataConverter.cs @@ -9,7 +9,7 @@ namespace EventsHandler.Mapping.Models.POCOs.OpenKlant.Converters /// /// Converts subject data from different versions of "OpenKlant" into a unified . /// - internal static class CitizenDataConverter + internal static class CommonPartyDataConverter { /// /// Converts from "OpenKlant" (1.0) Web API service. diff --git a/EventsHandler/Api/EventsHandler/Program.cs b/EventsHandler/Api/EventsHandler/Program.cs index d8b3e792..684c9cc1 100644 --- a/EventsHandler/Api/EventsHandler/Program.cs +++ b/EventsHandler/Api/EventsHandler/Program.cs @@ -34,6 +34,7 @@ using EventsHandler.Services.Serialization.Interfaces; using EventsHandler.Services.Settings; using EventsHandler.Services.Settings.Configuration; +using EventsHandler.Services.Settings.Extensions; using EventsHandler.Services.Settings.Strategy.Interfaces; using EventsHandler.Services.Settings.Strategy.Manager; using EventsHandler.Services.Templates; @@ -53,7 +54,6 @@ using Swashbuckle.AspNetCore.Filters; using System.Diagnostics.CodeAnalysis; using System.Reflection; -using ConfigurationExtensions = EventsHandler.Extensions.ConfigurationExtensions; using OpenKlant = EventsHandler.Services.DataQuerying.Composition.Strategy.OpenKlant; using OpenZaak = EventsHandler.Services.DataQuerying.Composition.Strategy.OpenZaak; using Register = EventsHandler.Services.Register; @@ -316,23 +316,25 @@ private static void RegisterNotifyStrategies(this IServiceCollection services) private static void RegisterOpenServices(this WebApplicationBuilder builder) { + byte omvWorkflowVersion = builder.Services.GetRequiredService() + .OMC.Features.Workflow_Version(); // Common query methods builder.Services.AddSingleton(); // Strategies - builder.Services.AddSingleton(typeof(OpenZaak.Interfaces.IQueryZaak), DetermineOpenZaakVersion()); - builder.Services.AddSingleton(typeof(OpenKlant.Interfaces.IQueryKlant), DetermineOpenKlantVersion()); - builder.Services.AddSingleton(typeof(IQueryObjecten), DetermineObjectenVersion()); - builder.Services.AddSingleton(typeof(IQueryObjectTypen), DetermineObjectTypenVersion()); + builder.Services.AddSingleton(typeof(OpenZaak.Interfaces.IQueryZaak), DetermineOpenZaakVersion(omvWorkflowVersion)); + builder.Services.AddSingleton(typeof(OpenKlant.Interfaces.IQueryKlant), DetermineOpenKlantVersion(omvWorkflowVersion)); + builder.Services.AddSingleton(typeof(IQueryObjecten), DetermineObjectenVersion(omvWorkflowVersion)); + builder.Services.AddSingleton(typeof(IQueryObjectTypen), DetermineObjectTypenVersion(omvWorkflowVersion)); // Feedback and telemetry - builder.Services.AddSingleton(typeof(ITelemetryService), DetermineTelemetryVersion()); + builder.Services.AddSingleton(typeof(ITelemetryService), DetermineTelemetryVersion(omvWorkflowVersion)); return; - static Type DetermineOpenZaakVersion() + static Type DetermineOpenZaakVersion(byte omvWorkflowVersion) { - return ConfigurationExtensions.OmcWorkflowVersion() switch + return omvWorkflowVersion switch { 1 => typeof(OpenZaak.v1.QueryZaak), 2 => typeof(OpenZaak.v2.QueryZaak), @@ -340,9 +342,9 @@ static Type DetermineOpenZaakVersion() }; } - static Type DetermineOpenKlantVersion() + static Type DetermineOpenKlantVersion(byte omvWorkflowVersion) { - return ConfigurationExtensions.OmcWorkflowVersion() switch + return omvWorkflowVersion switch { 1 => typeof(OpenKlant.v1.QueryKlant), 2 => typeof(OpenKlant.v2.QueryKlant), @@ -350,27 +352,27 @@ static Type DetermineOpenKlantVersion() }; } - static Type DetermineObjectenVersion() + static Type DetermineObjectenVersion(byte omvWorkflowVersion) { - return ConfigurationExtensions.OmcWorkflowVersion() switch + return omvWorkflowVersion switch { 1 or 2 => typeof(QueryObjecten), _ => throw new NotImplementedException(Resources.Configuration_ERROR_VersionObjectenUnknown) }; } - static Type DetermineObjectTypenVersion() + static Type DetermineObjectTypenVersion(byte omvWorkflowVersion) { - return ConfigurationExtensions.OmcWorkflowVersion() switch + return omvWorkflowVersion switch { 1 or 2 => typeof(QueryObjectTypen), _ => throw new NotImplementedException(Resources.Configuration_ERROR_VersionObjectTypenUnknown) }; } - static Type DetermineTelemetryVersion() + static Type DetermineTelemetryVersion(byte omvWorkflowVersion) { - return ConfigurationExtensions.OmcWorkflowVersion() switch + return omvWorkflowVersion switch { 1 => typeof(Register.v1.ContactRegistration), 2 => typeof(Register.v2.ContactRegistration), @@ -387,17 +389,20 @@ private static void RegisterClientFactories(this IServiceCollection services) private static void RegisterResponders(this WebApplicationBuilder builder) { + byte omvWorkflowVersion = builder.Services.GetRequiredService() + .OMC.Features.Workflow_Version(); + // Implicit interface (Adapter) used by EventsController => check "IRespondingService" builder.Services.AddSingleton, Responder.OmcResponder>(); // Explicit interfaces (generic) used by other controllers => check "IRespondingService" - builder.Services.AddSingleton(typeof(Responder.NotifyResponder), DetermineResponderVersion()); + builder.Services.AddSingleton(typeof(Responder.NotifyResponder), DetermineResponderVersion(omvWorkflowVersion)); return; - static Type DetermineResponderVersion() + static Type DetermineResponderVersion(byte omvWorkflowVersion) { - return ConfigurationExtensions.OmcWorkflowVersion() switch + return omvWorkflowVersion switch { 1 => typeof(Responder.v1.NotifyCallbackResponder), 2 => typeof(Responder.v2.NotifyCallbackResponder), diff --git a/EventsHandler/Api/EventsHandler/Services/DataProcessing/Strategy/Implementations/TaskAssignedScenario.cs b/EventsHandler/Api/EventsHandler/Services/DataProcessing/Strategy/Implementations/TaskAssignedScenario.cs index 0c0e9ae3..df2cfe2a 100644 --- a/EventsHandler/Api/EventsHandler/Services/DataProcessing/Strategy/Implementations/TaskAssignedScenario.cs +++ b/EventsHandler/Api/EventsHandler/Services/DataProcessing/Strategy/Implementations/TaskAssignedScenario.cs @@ -28,7 +28,7 @@ namespace EventsHandler.Services.DataProcessing.Strategy.Implementations internal sealed class TaskAssignedScenario : BaseScenario { private IQueryContext _queryContext = null!; - private Data _taskData; + private CommonTaskData _taskData; /// /// Initializes a new instance of the class. @@ -55,7 +55,7 @@ protected override async Task PrepareDataAsync(NotificationEven throw new AbortedNotifyingException(Resources.Processing_ABORT_DoNotSendNotification_TaskType); } - this._taskData = (await this._queryContext.GetTaskAsync()).Record.Data; + this._taskData = await this._queryContext.GetTaskAsync(); // Validation #2: The task needs to have an open status if (this._taskData.Status != TaskStatuses.Open) diff --git a/EventsHandler/Api/EventsHandler/Services/DataQuerying/Adapter/Interfaces/IQueryContext.cs b/EventsHandler/Api/EventsHandler/Services/DataQuerying/Adapter/Interfaces/IQueryContext.cs index 293360ac..0a818e95 100644 --- a/EventsHandler/Api/EventsHandler/Services/DataQuerying/Adapter/Interfaces/IQueryContext.cs +++ b/EventsHandler/Api/EventsHandler/Services/DataQuerying/Adapter/Interfaces/IQueryContext.cs @@ -154,7 +154,7 @@ internal interface IQueryContext #region IQueryObjecten /// - internal Task GetTaskAsync(); + internal Task GetTaskAsync(); /// internal Task GetMessageAsync(); diff --git a/EventsHandler/Api/EventsHandler/Services/DataQuerying/Adapter/QueryContext.cs b/EventsHandler/Api/EventsHandler/Services/DataQuerying/Adapter/QueryContext.cs index fb4de75d..58a4a2e8 100644 --- a/EventsHandler/Api/EventsHandler/Services/DataQuerying/Adapter/QueryContext.cs +++ b/EventsHandler/Api/EventsHandler/Services/DataQuerying/Adapter/QueryContext.cs @@ -145,7 +145,7 @@ async Task IQueryContext.LinkToSubjectObjectAsync(string jsonBody) #region IQueryObjecten /// - Task IQueryContext.GetTaskAsync() + Task IQueryContext.GetTaskAsync() => this._queryObjecten.GetTaskAsync(this._queryBase); /// diff --git a/EventsHandler/Api/EventsHandler/Services/DataQuerying/Composition/Strategy/Objecten/Interfaces/IQueryObjecten.cs b/EventsHandler/Api/EventsHandler/Services/DataQuerying/Composition/Strategy/Objecten/Interfaces/IQueryObjecten.cs index 0de444d6..6e2e3072 100644 --- a/EventsHandler/Api/EventsHandler/Services/DataQuerying/Composition/Strategy/Objecten/Interfaces/IQueryObjecten.cs +++ b/EventsHandler/Api/EventsHandler/Services/DataQuerying/Composition/Strategy/Objecten/Interfaces/IQueryObjecten.cs @@ -29,13 +29,13 @@ internal interface IQueryObjecten : IVersionDetails, IDomain #pragma warning disable CA1822 // These methods can be marked as static but that would be inconsistent for interfaces #region Parent (Task) /// - /// Gets the from "Objecten" Web API service. + /// Gets the from "Objecten" Web API service. /// /// /// - /// This method might fail when deserializing generic JSON response from Objects endpoint to model. + /// This method might fail when deserializing generic JSON response from Objects endpoint to model. /// - internal sealed async Task GetTaskAsync(IQueryBase queryBase) + internal sealed async Task GetTaskAsync(IQueryBase queryBase) { // Request URL Uri taskObjectUri = queryBase.Notification.MainObjectUri; @@ -45,7 +45,7 @@ internal sealed async Task GetTaskAsync(IQueryBase queryBase) throw new ArgumentException(Resources.Operation_ERROR_Internal_NotObjectUri); } - return await queryBase.ProcessGetAsync( + return await queryBase.ProcessGetAsync( httpClientType: HttpClientTypes.Objecten, uri: taskObjectUri, fallbackErrorMessage: Resources.HttpRequest_ERROR_NoTask); diff --git a/EventsHandler/Api/EventsHandler/Services/DataQuerying/Composition/Strategy/OpenZaak/Interfaces/IQueryZaak.cs b/EventsHandler/Api/EventsHandler/Services/DataQuerying/Composition/Strategy/OpenZaak/Interfaces/IQueryZaak.cs index f0419580..d78323f7 100644 --- a/EventsHandler/Api/EventsHandler/Services/DataQuerying/Composition/Strategy/OpenZaak/Interfaces/IQueryZaak.cs +++ b/EventsHandler/Api/EventsHandler/Services/DataQuerying/Composition/Strategy/OpenZaak/Interfaces/IQueryZaak.cs @@ -64,9 +64,6 @@ internal sealed async Task TryGetCaseAsync(IQueryBase queryBase, Uri? case /// internal sealed async Task TryGetCaseStatusesAsync(IQueryBase queryBase, Uri? caseUri) { - // Predefined URL components - string statusesEndpoint = $"https://{GetDomain()}/zaken/api/v1/statussen"; - // Case #1: The Case URI was provided // Case #2: The Case URI needs to obtained from elsewhere if ((caseUri ??= queryBase.Notification.MainObjectUri).IsNotCase()) @@ -74,6 +71,9 @@ internal sealed async Task TryGetCaseStatusesAsync(IQueryBase quer throw new ArgumentException(Resources.Operation_ERROR_Internal_NotCaseUri); } + // Predefined URL components + string statusesEndpoint = $"https://{GetDomain()}/zaken/api/v1/statussen"; + // Request URL Uri caseStatusesUri = new($"{statusesEndpoint}?zaak={caseUri}"); diff --git a/EventsHandler/Api/EventsHandler/Services/Serialization/Converters/CommonTaskDataJsonConverter.cs b/EventsHandler/Api/EventsHandler/Services/Serialization/Converters/CommonTaskDataJsonConverter.cs new file mode 100644 index 00000000..5090cad3 --- /dev/null +++ b/EventsHandler/Api/EventsHandler/Services/Serialization/Converters/CommonTaskDataJsonConverter.cs @@ -0,0 +1,60 @@ +// © 2024, Worth Systems. + +using EventsHandler.Mapping.Models.POCOs.Objecten.Task; +using EventsHandler.Mapping.Models.POCOs.Objecten.Task.Converters; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace EventsHandler.Services.Serialization.Converters +{ + /// + /// The custom converter specialized in handling types. + /// + /// + internal sealed class CommonTaskDataJsonConverter : JsonConverter + { + private static readonly object s_padlock = new(); + private static readonly Dictionary s_serializedCommonTaskData = new() + { + { nameof(CommonTaskData.CaseUri), string.Empty }, + { nameof(CommonTaskData.CaseId), string.Empty }, + { nameof(CommonTaskData.Title), string.Empty }, + { nameof(CommonTaskData.Status), string.Empty }, + { nameof(CommonTaskData.ExpirationDate), string.Empty }, + { nameof(CommonTaskData.Identification), string.Empty } + }; + + public override bool HandleNull => true; + + /// + public override CommonTaskData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + try + { + return JsonSerializer.Deserialize(ref reader, options) + .ConvertToUnified(); + } + catch (JsonException) + { + return JsonSerializer.Deserialize(ref reader, options) + .ConvertToUnified(); + } + } + + /// + public override void Write(Utf8JsonWriter writer, CommonTaskData value, JsonSerializerOptions options) + { + lock (s_padlock) + { + s_serializedCommonTaskData[nameof(CommonTaskData.CaseUri)] = value.CaseUri; + s_serializedCommonTaskData[nameof(CommonTaskData.CaseId)] = value.CaseId; + s_serializedCommonTaskData[nameof(CommonTaskData.Title)] = value.Title; + s_serializedCommonTaskData[nameof(CommonTaskData.Status)] = value.Status; + s_serializedCommonTaskData[nameof(CommonTaskData.ExpirationDate)] = value.ExpirationDate; + s_serializedCommonTaskData[nameof(CommonTaskData.Identification)] = value.Identification; + + JsonSerializer.Serialize(writer, s_serializedCommonTaskData, options); + } + } + } +} \ No newline at end of file diff --git a/EventsHandler/Api/EventsHandler/Services/Serialization/SpecificSerializer.cs b/EventsHandler/Api/EventsHandler/Services/Serialization/SpecificSerializer.cs index a3b5a481..5346bc59 100644 --- a/EventsHandler/Api/EventsHandler/Services/Serialization/SpecificSerializer.cs +++ b/EventsHandler/Api/EventsHandler/Services/Serialization/SpecificSerializer.cs @@ -25,6 +25,7 @@ internal sealed class SpecificSerializer : ISerializationService Converters = { new BoolJsonConverter(), + new CommonTaskDataJsonConverter(), new DateOnlyJsonConverter(), new DateTimeJsonConverter(), new DocumentsJsonConverter(), diff --git a/EventsHandler/Api/EventsHandler/Services/Settings/AppSettingsLoader.cs b/EventsHandler/Api/EventsHandler/Services/Settings/AppSettingsLoader.cs index bc9f481b..e3044d67 100644 --- a/EventsHandler/Api/EventsHandler/Services/Settings/AppSettingsLoader.cs +++ b/EventsHandler/Api/EventsHandler/Services/Settings/AppSettingsLoader.cs @@ -2,6 +2,7 @@ using EventsHandler.Extensions; using EventsHandler.Properties; +using EventsHandler.Services.Settings.Extensions; using EventsHandler.Services.Settings.Interfaces; namespace EventsHandler.Services.Settings diff --git a/EventsHandler/Api/EventsHandler/Services/Settings/Configuration/WebApiConfiguration.cs b/EventsHandler/Api/EventsHandler/Services/Settings/Configuration/WebApiConfiguration.cs index eb88b289..8c382f03 100644 --- a/EventsHandler/Api/EventsHandler/Services/Settings/Configuration/WebApiConfiguration.cs +++ b/EventsHandler/Api/EventsHandler/Services/Settings/Configuration/WebApiConfiguration.cs @@ -4,6 +4,7 @@ using EventsHandler.Mapping.Models.POCOs.OpenZaak; using EventsHandler.Services.Settings.Attributes; using EventsHandler.Services.Settings.Enums; +using EventsHandler.Services.Settings.Extensions; using EventsHandler.Services.Settings.Interfaces; using EventsHandler.Services.Settings.Strategy.Interfaces; using EventsHandler.Services.Settings.Strategy.Manager; diff --git a/EventsHandler/Api/EventsHandler/Services/Settings/EnvironmentLoader.cs b/EventsHandler/Api/EventsHandler/Services/Settings/EnvironmentLoader.cs index cc1641cd..33cd84cf 100644 --- a/EventsHandler/Api/EventsHandler/Services/Settings/EnvironmentLoader.cs +++ b/EventsHandler/Api/EventsHandler/Services/Settings/EnvironmentLoader.cs @@ -4,6 +4,7 @@ using EventsHandler.Properties; using EventsHandler.Services.Settings.DAO; using EventsHandler.Services.Settings.DAO.Interfaces; +using EventsHandler.Services.Settings.Extensions; using EventsHandler.Services.Settings.Interfaces; namespace EventsHandler.Services.Settings diff --git a/EventsHandler/Api/EventsHandler/Extensions/ConfigurationExtensions.cs b/EventsHandler/Api/EventsHandler/Services/Settings/Extensions/ConfigurationExtensions.cs similarity index 64% rename from EventsHandler/Api/EventsHandler/Extensions/ConfigurationExtensions.cs rename to EventsHandler/Api/EventsHandler/Services/Settings/Extensions/ConfigurationExtensions.cs index 43024ed0..7187f613 100644 --- a/EventsHandler/Api/EventsHandler/Extensions/ConfigurationExtensions.cs +++ b/EventsHandler/Api/EventsHandler/Services/Settings/Extensions/ConfigurationExtensions.cs @@ -4,7 +4,7 @@ using EventsHandler.Properties; using EventsHandler.Services.Settings.Configuration; -namespace EventsHandler.Extensions +namespace EventsHandler.Services.Settings.Extensions { /// /// Extension methods for used in .cs @@ -26,22 +26,24 @@ internal static bool IsEncryptionAsymmetric(this IConfiguration configuration) return configuration.GetValue(key); } - private static string? s_omcWorkflowVersionKey; - private static byte? s_omcWorkflowVersionValue; + private static string? s_openZaakDomainKey; + private static string? s_openZaakDomainValue; - /// - /// Gets the version of Open services ("OpenNotificaties", "OpenZaak", "OpenKlant") which should be used in business logic. - /// - internal static byte OmcWorkflowVersion() + internal static string OpenZaakDomain(WebApiConfiguration? configuration = null) { - s_omcWorkflowVersionKey ??= ($"{nameof(WebApiConfiguration.OMC)}_" + - $"{nameof(WebApiConfiguration.OMC.Features)}_" + - $"{nameof(WebApiConfiguration.OMC.Features.Workflow_Version)}") - .ToUpper(); + // Case #1: Instance usage + if (configuration != null) + { + return configuration.User.Domain.OpenZaak(); + } - return s_omcWorkflowVersionValue ??= - byte.Parse( - Environment.GetEnvironmentVariable(s_omcWorkflowVersionKey) ?? "0"); + // Case #2: Static usage + s_openZaakDomainKey ??= ($"{nameof(WebApiConfiguration.User)}_" + + $"{nameof(WebApiConfiguration.User.Domain)}_" + + $"{nameof(WebApiConfiguration.User.Domain.OpenZaak)}") + .ToUpper(); + + return s_openZaakDomainValue ??= Environment.GetEnvironmentVariable(s_openZaakDomainKey) ?? "domain"; } #endregion @@ -55,15 +57,11 @@ internal static T GetNotEmpty(this T? value, string key) return value switch { string stringValue => string.IsNullOrWhiteSpace(stringValue) - ? throw new ArgumentException(string.Format(Resources.Configuration_ERROR_ValueNotFoundOrEmpty, key)) - : value, - - object objectValue => objectValue == null - ? throw new ArgumentException(string.Format(Resources.Configuration_ERROR_ValueNotFoundOrEmpty, key)) + ? ThrowArgumentException(Resources.Configuration_ERROR_ValueNotFoundOrEmpty, key) : value, _ => value ?? // Valid value - throw new ArgumentException(string.Format(Resources.Configuration_ERROR_ValueNotFoundOrEmpty, key)) + ThrowArgumentException(Resources.Configuration_ERROR_ValueNotFoundOrEmpty, key) }; } @@ -75,7 +73,7 @@ internal static string GetWithoutProtocol(this string value) { return !value.StartsWith(DefaultValues.Request.HttpProtocol) // HTTPS will be also handled this way ? value - : throw new ArgumentException(string.Format(Resources.Configuration_ERROR_ContainsHttp, value)); + : ThrowArgumentException(Resources.Configuration_ERROR_ContainsHttp, value); } /// @@ -86,7 +84,7 @@ internal static string GetWithoutEndpoint(this string value) { return !value.Contains('/') ? value - : throw new ArgumentException(string.Format(Resources.Configuration_ERROR_ContainsEndpoint, value)); + : ThrowArgumentException(Resources.Configuration_ERROR_ContainsEndpoint, value); } #endregion @@ -99,7 +97,7 @@ internal static Guid GetValidGuid(this string value) { return Guid.TryParse(value, out Guid createdGuid) ? createdGuid - : throw new ArgumentException(string.Format(Resources.Configuration_ERROR_InvalidTemplateId, value)); + : ThrowArgumentException(Resources.Configuration_ERROR_InvalidTemplateId, value); } /// @@ -111,7 +109,14 @@ internal static Uri GetValidUri(this string value) return Uri.TryCreate(value, UriKind.Absolute, out Uri? createdUri) && createdUri != DefaultValues.Models.EmptyUri ? createdUri - : throw new ArgumentException(string.Format(Resources.Configuration_ERROR_InvalidUri, value)); + : ThrowArgumentException(Resources.Configuration_ERROR_InvalidUri, value); + } + #endregion + + #region Helper methods + private static T ThrowArgumentException(string errorMessage, string key) + { + throw new ArgumentException(string.Format(errorMessage, key)); } #endregion } diff --git a/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Extensions/ConfigurationExtensionsTests.cs b/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Extensions/ConfigurationExtensionsTests.cs index 1403f171..6715f419 100644 --- a/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Extensions/ConfigurationExtensionsTests.cs +++ b/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Extensions/ConfigurationExtensionsTests.cs @@ -1,23 +1,32 @@ // © 2024, Worth Systems. using EventsHandler.Constants; -using EventsHandler.Extensions; using EventsHandler.Properties; +using EventsHandler.Services.Settings.Configuration; +using EventsHandler.Services.Settings.Extensions; using EventsHandler.Utilities._TestHelpers; using Microsoft.Extensions.Configuration; -using ConfigurationExtensions = EventsHandler.Extensions.ConfigurationExtensions; +using ConfigurationExtensions = EventsHandler.Services.Settings.Extensions.ConfigurationExtensions; namespace EventsHandler.UnitTests.Extensions { [TestFixture] internal sealed class ConfigurationExtensionsTests { - private IConfiguration? _configuration; + private IConfiguration _appSettingsConfiguration = null!; + private WebApiConfiguration _webApiConfiguration = null!; [OneTimeSetUp] public void InitializeTests() { - this._configuration = ConfigurationHandler.GetConfiguration(); + this._appSettingsConfiguration = ConfigurationHandler.GetConfiguration(); + this._webApiConfiguration = ConfigurationHandler.GetWebApiConfigurationWith(ConfigurationHandler.TestLoaderTypes.ValidEnvironment_v1); + } + + [OneTimeTearDown] + public void CleanupTests() + { + this._webApiConfiguration.Dispose(); } #region Specific GetValue methods @@ -25,25 +34,26 @@ public void InitializeTests() public void Encryption_ReturnsExpectedValue() { // Act - bool actualValue = this._configuration!.IsEncryptionAsymmetric(); + bool actualValue = this._appSettingsConfiguration.IsEncryptionAsymmetric(); // Assert Assert.That(actualValue, Is.False); } [Test] - public void Features_ReturnsExpectedValue() + public void OpenZaakDomain_ReturnsExpectedValue() { // Act - byte actualValue = ConfigurationExtensions.OmcWorkflowVersion(); + string actualValue = ConfigurationExtensions.OpenZaakDomain(this._webApiConfiguration); // Assert - Assert.That(actualValue, Is.GreaterThanOrEqualTo(0)); + Assert.That(actualValue, Is.Not.Empty); } #endregion #region GetNotEmpty [TestCase("")] + [TestCase(" ")] public void ValidateNotEmpty_ForInvalidValue_ThrowsArgumentException(string testValue) { // Act & Assert diff --git a/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/DataProcessing/Strategy/Implementations/TaskAssignedScenarioTests.cs b/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/DataProcessing/Strategy/Implementations/TaskAssignedScenarioTests.cs index 3ffe4859..0d3285fd 100644 --- a/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/DataProcessing/Strategy/Implementations/TaskAssignedScenarioTests.cs +++ b/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/DataProcessing/Strategy/Implementations/TaskAssignedScenarioTests.cs @@ -67,64 +67,40 @@ public void TestsCleanup() } }; - private static readonly TaskObject s_taskClosed = new() + private static readonly CommonTaskData s_taskClosed = new() { - Record = new Record - { - Data = new Data - { - Status = TaskStatuses.Closed - } - } + Status = TaskStatuses.Closed }; - private static readonly TaskObject s_taskOpenNotAssignedToPerson = new() + private static readonly CommonTaskData s_taskOpenNotAssignedToPerson = new() { - Record = new Record + Status = TaskStatuses.Open, + Identification = new Identification { - Data = new Data - { - Status = TaskStatuses.Open, - Identification = new Identification - { - Type = IdTypes.Unknown - } - } + Type = IdTypes.Unknown } }; private const string TestTaskTitle = "Test title"; - private static readonly TaskObject s_taskOpenAssignedToPersonWithoutExpirationDate = new() + private static readonly CommonTaskData s_taskOpenAssignedToPersonWithoutExpirationDate = new() { - Record = new Record + Title = TestTaskTitle, + Status = TaskStatuses.Open, + // Missing "ExpirationDate" => default + Identification = new Identification { - Data = new Data - { - Title = TestTaskTitle, - Status = TaskStatuses.Open, - // Missing "ExpirationDate" => default - Identification = new Identification - { - Type = IdTypes.Bsn - } - } + Type = IdTypes.Bsn } }; - private static readonly TaskObject s_taskOpenAssignedToPersonWithExpirationDate = new() + private static readonly CommonTaskData s_taskOpenAssignedToPersonWithExpirationDate = new() { - Record = new Record + Title = TestTaskTitle, + Status = TaskStatuses.Open, + ExpirationDate = new DateTime(2024, 7, 24, 14, 10, 40, DateTimeKind.Utc), + Identification = new Identification { - Data = new Data - { - Title = TestTaskTitle, - Status = TaskStatuses.Open, - ExpirationDate = new DateTime(2024, 7, 24, 14, 10, 40, DateTimeKind.Utc), - Identification = new Identification - { - Type = IdTypes.Bsn - } - } + Type = IdTypes.Bsn } }; @@ -342,13 +318,13 @@ public async Task TryGetDataAsync_ValidTaskType_Open_AssignedToPerson_Whiteliste public async Task GetPersonalizationAsync_SpecificDateTime_ReturnsExpectedPersonalization( DistributionChannels testDistributionChannel, bool isExpirationDateGiven, string testExpirationDate, string isExpirationDateGivenText) { - TaskObject testTask = isExpirationDateGiven + CommonTaskData testTaskData = isExpirationDateGiven ? s_taskOpenAssignedToPersonWithExpirationDate : s_taskOpenAssignedToPersonWithoutExpirationDate; INotifyScenario scenario = ArrangeTaskScenario_TryGetData( testDistributionChannel, - testTask, + testTaskData, isCaseTypeIdWhitelisted: true, isNotificationExpected: true); @@ -483,7 +459,7 @@ public async Task ProcessDataAsync_ValidNotifyData_ValidNotifyMethod_SendingSucc #region Setup private INotifyScenario ArrangeTaskScenario_TryGetData( - DistributionChannels testDistributionChannel, TaskObject testTask, bool isCaseTypeIdWhitelisted, bool isNotificationExpected) + DistributionChannels testDistributionChannel, CommonTaskData testTask, bool isCaseTypeIdWhitelisted, bool isNotificationExpected) { // IQueryContext this._mockedQueryContext diff --git a/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/Serialization/SpecificSerializerTests.cs b/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/Serialization/SpecificSerializerTests.cs index 3cfd47b2..ebc6a84a 100644 --- a/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/Serialization/SpecificSerializerTests.cs +++ b/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/Serialization/SpecificSerializerTests.cs @@ -7,6 +7,7 @@ using EventsHandler.Mapping.Models.POCOs.NotificatieApi; using EventsHandler.Mapping.Models.POCOs.Objecten; using EventsHandler.Mapping.Models.POCOs.Objecten.Task; +using EventsHandler.Mapping.Models.POCOs.Objecten.Task.vHague; using EventsHandler.Mapping.Models.POCOs.OpenKlant; using EventsHandler.Mapping.Models.POCOs.OpenZaak; using EventsHandler.Mapping.Models.POCOs.OpenZaak.Decision; @@ -27,7 +28,8 @@ public sealed class SpecificSerializerTests #region Test data (fields) private const string TestString = "text"; private const string TestBoolean = "false"; - private const string TestUrl = "https://www.domain.test/00000000-0000-0000-0000-000000000000"; + private const string TestGuid = "00000000-0000-0000-0000-000000000000"; + private const string TestUrl = $"https://www.domain.test/{TestGuid}"; #endregion [OneTimeSetUp] @@ -139,11 +141,7 @@ public void Deserialize_CaseType_EmptyJson_ThrowsJsonException_ListsRequiredProp }); } - [Test] - public void Deserialize_TaskObject_ValidJson_ReturnsExpectedModel() // Nested objects and enums should be deserialized properly - { - // Arrange - const string testJson = + private const string TaskDataJsonTheHague = $"{{" + $"\"url\":\"https://objecten.test.notifynl.nl/api/v1/objects/ced88e8f-83fb-4f9d-866e-33b4bd0e4e78\"," + $"\"uuid\":\"ced88e8f-83fb-4f9d-866e-33b4bd0e4e78\"," + @@ -184,7 +182,7 @@ public void Deserialize_TaskObject_ValidJson_ReturnsExpectedModel() // Nested o $"\"type\":\"url\"," + $"\"value\":\"http://localhost:8010/api/v2/objects/0db2a8a0-1ca8-4395-8a7a-c6293e33b4cd\"" + $"}}," + - $"\"verloopdatum\":null," + + $"\"verloopdatum\":\"2024-05-03T21:59:59.999Z\"," + $"\"identificatie\":{{" + $"\"type\":\"bsn\"," + $"\"value\":\"569312863\"" + @@ -202,11 +200,73 @@ public void Deserialize_TaskObject_ValidJson_ReturnsExpectedModel() // Nested o $"}}" + $"}}"; + private const string TaskDataJsonNijmegen = + $"{{" + + $"\"record\":{{" + + $"\"data\":{{" + + $"\"titel\":\"Check loan\"," + + $"\"status\":\"open\"," + + $"\"soort\":\"formtaak\"," + + $"\"verloopdatum\":\"2023-09-20T18:25:43.524Z\"," + + $"\"identificatie\":{{" + + $"\"type\":\"bsn\"," + + $"\"value\":\"82395551\"" + + $"}}," + + $"\"koppeling\":{{" + + $"\"registratie\":\"zaak\"," + + $"\"uuid\":\"5551a7c5-4e92-43e6-8d23-80359b7e22b7\"" + + $"}}," + + $"\"url\":{{" + + $"\"uri\":\"https://google.com\"" + + $"}}," + + $"\"portaalformulier\":{{" + + $"\"formulier\":{{" + + $"\"soort\":\"url\"," + + $"\"value\":\"http://localhost:8010/api/v2/objects/4e40fb4c-a29a-4e48-944b-c34a1ff6c8f4\"" + + $"}}," + + $"\"data\":{{" + + $"\"voornaam\":\"Jan\"," + + $"\"achternaam\":\"Smit\"," + + $"\"toestemming\":true," + + $"\"geboortedatum\":\"01-01-1970\"" + + $"}}," + + $"\"verzonden_data\":{{" + + $"\"voornaam\":\"Jan\"," + + $"\"achternaam\":\"Smit\"," + + $"\"toestemming\":false," + + $"\"geboortedatum\":\"01-01-1971\"" + + $"}}" + + $"}}," + + $"\"ogonebetaling\":{{" + + $"\"bedrag\":147.43," + + $"\"betaalkenmerk\":\"abcdef1234\"," + + $"\"pspid\":\"MyID\"" + + $"}}," + + $"\"verwerker_taak_id\":\"18af0b6a-967b-4f81-bb8e-a44988e0c2f0\"," + + $"\"eigenaar\":\"gzac-sd\"" + + $"}}" + + $"}}" + + $"}}"; + + [TestCase(TaskDataJsonTheHague)] + [TestCase(TaskDataJsonNijmegen)] + public void Deserialize_CommonTaskData_ValidJson_ReturnsExpectedModel(string testJson) // Nested objects and enums should be deserialized properly + { + // Arrange + // Act - TaskObject actualResult = this._serializer.Deserialize(testJson); + CommonTaskData actualResult = this._serializer.Deserialize(testJson); // Assert - AssertRequiredProperties(actualResult); + Assert.Multiple(() => + { + Assert.That(actualResult.CaseUri, Is.Not.Default); + Assert.That(actualResult.CaseId, Is.Not.Default); + Assert.That(actualResult.Title, Is.Not.Default); + Assert.That(actualResult.Status, Is.Not.Default); + Assert.That(actualResult.ExpirationDate, Is.Not.Default); + Assert.That(actualResult.Identification, Is.Not.Default); + }); } [TestCase("null")] @@ -220,16 +280,16 @@ public void Deserialize_DecisionType_ValidJson_Booleans_ReturnsExpectedModel(str // Arrange const string testJson = $"{{" + - $"\"catalogus\": \"https://openzaak.test.notifynl.nl/catalogi/api/v1/catalogussen/8399feb6-1349-401c-8c07-f6a49209089a\", " + + $"\"catalogus\":\"https://openzaak.test.notifynl.nl/catalogi/api/v1/catalogussen/8399feb6-1349-401c-8c07-f6a49209089a\", " + $"\"publicatieIndicatie\": {{0}}, " + - $"\"beginGeldigheid\": \"2001-01-04\", " + - $"\"omschrijving\": \"Omschrijving besluit a\", " + - $"\"omschrijvingGeneriek\": \"Omschrijving besluit generiek\", " + - $"\"besluitcategorie\": \"Categorie1\", " + - $"\"reactietermijn\": \"P1Y1M1D\", " + - $"\"publicatietekst\": \"Publicatie tekst\", " + - $"\"publicatietermijn\": \"P1Y1M1D\", " + - $"\"toelichting\": \"Toelichting besluit\", " + + $"\"beginGeldigheid\":\"2001-01-04\", " + + $"\"omschrijving\":\"Omschrijving besluit a\", " + + $"\"omschrijvingGeneriek\":\"Omschrijving besluit generiek\", " + + $"\"besluitcategorie\":\"Categorie1\", " + + $"\"reactietermijn\":\"P1Y1M1D\", " + + $"\"publicatietekst\":\"Publicatie tekst\", " + + $"\"publicatietermijn\":\"P1Y1M1D\", " + + $"\"toelichting\":\"Toelichting besluit\", " + $"\"informatieobjecttypen\": [\"https://openzaak.test.notifynl.nl/catalogi/api/v1/informatieobjecttypen/5e11506b-d685-4db1-908a-5c2e472c81e6\"]" + $"}}"; @@ -321,7 +381,15 @@ public void Deserialize_ContactMoment_PartiallyValidJson_ReturnsExpectedModel() string actualResult = this._serializer.Serialize(isDefault ? default : new Case()); // Assert - Assert.That(actualResult, Is.EqualTo("{\"identificatie\":\"\",\"omschrijving\":\"\",\"zaaktype\":\"http://0.0.0.0:0/\",\"registratiedatum\":\"0001-01-01\"}")); + string expectedResult = + $"{{" + + $"\"identificatie\":\"\"," + + $"\"omschrijving\":\"\"," + + $"\"zaaktype\":\"{DefaultValues.Models.EmptyUri}\"," + + $"\"registratiedatum\":\"0001-01-01\"" + + $"}}"; + + Assert.That(actualResult, Is.EqualTo(expectedResult)); } [Test] @@ -408,21 +476,21 @@ public void Serialize_TaskObject_Default_ReturnsExpectedJson(bool isDefault) // string actualResult = this._serializer.Serialize(isDefault ? default : new TaskObject()); // Assert - const string expectedResult = - "{" + - "\"record\":{" + - "\"data\":{" + - "\"zaak\":\"http://0.0.0.0:0/\"," + - "\"title\":\"\"," + - "\"status\":\"-\"," + - "\"verloopdatum\":\"0001-01-01T00:00:00.0000000\"," + - "\"identificatie\":{" + - "\"type\":\"-\"," + - "\"value\":\"\"" + - "}" + - "}" + - "}" + - "}"; + string expectedResult = + $"{{" + + $"\"record\":{{" + + $"\"data\":{{" + + $"\"zaak\":\"{DefaultValues.Models.EmptyUri}\"," + + $"\"title\":\"\"," + + $"\"status\":\"-\"," + + $"\"verloopdatum\":\"0001-01-01T00:00:00.0000000\"," + + $"\"identificatie\":{{" + + $"\"type\":\"-\"," + + $"\"value\":\"\"" + + $"}}" + + $"}}" + + $"}}" + + $"}}"; Assert.That(actualResult, Is.EqualTo(expectedResult)); } @@ -520,18 +588,55 @@ public void Serialize_Documents_ReturnsExpectedJson() // Act string actualResult = this._serializer.Serialize(documents); + // Assert + string expectedResult = + $"{{" + + $"\"results\":[" + + $"{{\"informatieobject\":\"{DefaultValues.Models.EmptyUri}\"}}," + + $"{{\"informatieobject\":\"{DefaultValues.Models.EmptyUri}\"}}" + + $"]" + + $"}}"; + + Assert.That(actualResult, Is.EqualTo(expectedResult)); + } + + [Test] + public void Serialize_CommonTaskData_ReturnsExpectedJson() + { + // Arrange + const string testGuid = "12345678-1234-0000-4321-123456789012"; + const string testUrl = $"https://www.domain.test/{testGuid}"; + + var documents = new CommonTaskData + { + CaseUri = new Uri(testUrl), + CaseId = new Guid(testGuid), + Title = TestString, + Status = TaskStatuses.Open, + ExpirationDate = DateTime.MaxValue, + Identification = new Identification + { + Type = IdTypes.Bsn, + Value = "123456789" + } + }; + + // Act + string actualResult = this._serializer.Serialize(documents); + // Assert const string expectedResult = - "{" + - "\"results\":[" + - "{" + - "\"informatieobject\":\"http://0.0.0.0:0/\"" + - "}," + - "{" + - "\"informatieobject\":\"http://0.0.0.0:0/\"" + - "}" + - "]" + - "}"; + $"{{" + + $"\"CaseUri\":\"{testUrl}\"," + + $"\"CaseId\":\"{testGuid}\"," + + $"\"Title\":\"text\"," + + $"\"Status\":\"open\"," + + $"\"ExpirationDate\":\"9999-12-31T23:59:59.9999999\"," + + $"\"Identification\":{{" + + $"\"type\":\"bsn\"," + + $"\"value\":\"123456789\"" + + $"}}" + + $"}}"; Assert.That(actualResult, Is.EqualTo(expectedResult)); } @@ -544,11 +649,11 @@ public void Serialize_ContactMoment_Default_ReturnsExpectedJson(bool isDefault) string actualResult = this._serializer.Serialize(isDefault ? default : new ContactMoment()); // Assert - const string expectedResult = - "{" + - "\"uuid\":\"00000000-0000-0000-0000-000000000000\"," + - "\"url\":\"http://0.0.0.0:0/\"" + - "}"; + string expectedResult = + $"{{" + + $"\"uuid\":\"{TestGuid}\"," + + $"\"url\":\"{DefaultValues.Models.EmptyUri}\"" + + $"}}"; Assert.That(actualResult, Is.EqualTo(expectedResult)); } diff --git a/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/Settings/Configuration/WepApiConfigurationTests.cs b/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/Settings/Configuration/WepApiConfigurationTests.cs index 396889e6..11355c59 100644 --- a/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/Settings/Configuration/WepApiConfigurationTests.cs +++ b/EventsHandler/Tests/UnitTests/EventsHandler.Tests/Services/Settings/Configuration/WepApiConfigurationTests.cs @@ -1,11 +1,11 @@ // © 2023, Worth Systems. +using EventsHandler.Extensions; using EventsHandler.Properties; using EventsHandler.Services.Settings.Attributes; using EventsHandler.Services.Settings.Configuration; using EventsHandler.Utilities._TestHelpers; using System.Reflection; -using EventsHandler.Extensions; using static EventsHandler.Utilities._TestHelpers.ConfigurationHandler; #pragma warning disable IDE0008 // Declaration of static types would be too long diff --git a/NotifyNL.sln.DotSettings b/NotifyNL.sln.DotSettings index 781e71e7..462deeff 100644 --- a/NotifyNL.sln.DotSettings +++ b/NotifyNL.sln.DotSettings @@ -99,6 +99,7 @@ True True True + True True True True @@ -112,6 +113,7 @@ True True True + True True True True @@ -148,6 +150,7 @@ True True True + True True True True @@ -170,6 +173,7 @@ True True True + True True True True