diff --git a/src/Altinn.App.Clients.Fiks/Constants/FiksArkivConstants.cs b/src/Altinn.App.Clients.Fiks/Constants/FiksArkivConstants.cs
index 3026c63d71..f1e330a834 100644
--- a/src/Altinn.App.Clients.Fiks/Constants/FiksArkivConstants.cs
+++ b/src/Altinn.App.Clients.Fiks/Constants/FiksArkivConstants.cs
@@ -1,3 +1,5 @@
+using Altinn.App.Clients.Fiks.FiksArkiv.Models;
+using KS.Fiks.Arkiv.Models.V1.Kodelister;
using KS.Fiks.Arkiv.Models.V1.Meldingstyper;
namespace Altinn.App.Clients.Fiks.Constants;
@@ -37,11 +39,16 @@ public static class MessageTypes
public const string ArchiveRecordCreationReceipt = FiksArkivMeldingtype.ArkivmeldingOpprettKvittering;
}
+ ///
+ /// Classification IDs for Fiks Arkiv messages.
+ ///
+ /// Callers can also specify their own, additional, classifications via
+ /// .
internal static class ClassificationId
{
- public const string NationalIdentityNumber = "Fødselsnummer";
- public const string OrganizationNumber = "Organisasjonsnummer";
+ public static readonly string NationalIdentityNumber = KlassifikasjonstypeKoder.Foedselsnummer.Verdi;
+ public const string OrganizationNumber = "ORGNR";
public const string AltinnUserId = "AltinnBrukerId";
- public const string SystemUserId = "SystembrukerId";
+ public const string SystemUserId = "AltinnSystembrukerId";
}
}
diff --git a/src/Altinn.App.Clients.Fiks/Extensions/FiksArkivClassificationExtensions.cs b/src/Altinn.App.Clients.Fiks/Extensions/FiksArkivClassificationExtensions.cs
new file mode 100644
index 0000000000..5e4d5f56d1
--- /dev/null
+++ b/src/Altinn.App.Clients.Fiks/Extensions/FiksArkivClassificationExtensions.cs
@@ -0,0 +1,16 @@
+using Altinn.App.Clients.Fiks.FiksArkiv.Models;
+using KS.Fiks.Arkiv.Models.V1.Arkivering.Arkivmelding;
+
+namespace Altinn.App.Clients.Fiks.Extensions;
+
+internal static class FiksArkivClassificationExtensions
+{
+ public static Klassifikasjon ToKlassifikasjon(this FiksArkivClassification classification) =>
+ new()
+ {
+ KlassifikasjonssystemID = classification.SystemId,
+ KlasseID = classification.ClassificationId,
+ Tittel = classification.Title,
+ ErSkjermet = classification.IsRestricted,
+ };
+}
diff --git a/src/Altinn.App.Clients.Fiks/Factories/KlassifikasjonFactory.cs b/src/Altinn.App.Clients.Fiks/Factories/KlassifikasjonFactory.cs
index 525a61c851..b2bda3f491 100644
--- a/src/Altinn.App.Clients.Fiks/Factories/KlassifikasjonFactory.cs
+++ b/src/Altinn.App.Clients.Fiks/Factories/KlassifikasjonFactory.cs
@@ -25,6 +25,7 @@ public static async Task CreateUser(Authenticated.User user)
.Party.SSN.ToString(CultureInfo.InvariantCulture)
.EnsureNotNullOrEmpty("Classification.Id"),
Tittel = userProfile.Party.Name.EnsureNotEmpty("Classification.Title"),
+ ErSkjermet = true,
}
: new Klassifikasjon
{
diff --git a/src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivConfigResolver.cs b/src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivConfigResolver.cs
index 130aa626e5..434f34e82b 100644
--- a/src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivConfigResolver.cs
+++ b/src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivConfigResolver.cs
@@ -212,23 +212,16 @@ public Korrespondansepart GetRecipientParty(Instance instance, FiksArkivRecipien
);
///
- public async Task GetInstanceOwnerClassification(
+ public async Task> GetCaseFileClassifications(
Authenticated auth,
CancellationToken cancellationToken = default
)
{
- cancellationToken.ThrowIfCancellationRequested();
-
- return auth switch
- {
- Authenticated.User user => await KlassifikasjonFactory.CreateUser(user), // Note: Doesn't accept cancellation token.. yet
- Authenticated.SystemUser systemUser => KlassifikasjonFactory.CreateSystemUser(systemUser),
- Authenticated.ServiceOwner serviceOwner => KlassifikasjonFactory.CreateServiceOwner(serviceOwner),
- Authenticated.Org org => KlassifikasjonFactory.CreateOrganization(org),
- _ => throw new FiksArkivException(
- $"Could not determine submitter details from authentication context: {auth}"
- ),
- };
+ return
+ [
+ await GetInstanceOwnerClassification(auth, cancellationToken: cancellationToken),
+ .. _fiksArkivSettings.Metadata?.CaseFileClassifications?.Select(x => x.ToKlassifikasjon()) ?? [],
+ ];
}
///
@@ -300,6 +293,25 @@ private async Task GetLayoutState(Instance instance)
return await _layoutStateInitializer.Init(unitOfWork, null);
}
+ private static async Task GetInstanceOwnerClassification(
+ Authenticated auth,
+ CancellationToken cancellationToken = default
+ )
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ return auth switch
+ {
+ Authenticated.User user => await KlassifikasjonFactory.CreateUser(user), // Note: Doesn't accept cancellation token.. yet
+ Authenticated.SystemUser systemUser => KlassifikasjonFactory.CreateSystemUser(systemUser),
+ Authenticated.ServiceOwner serviceOwner => KlassifikasjonFactory.CreateServiceOwner(serviceOwner),
+ Authenticated.Org org => KlassifikasjonFactory.CreateOrganization(org),
+ _ => throw new FiksArkivException(
+ $"Could not determine submitter details from authentication context: {auth}"
+ ),
+ };
+ }
+
private static async Task GetBindableConfigValue(
LayoutEvaluatorState layoutState,
Instance instance,
diff --git a/src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivDefaultPayloadGenerator.cs b/src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivDefaultPayloadGenerator.cs
index 7cf2008fe1..ad28b0d5cf 100644
--- a/src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivDefaultPayloadGenerator.cs
+++ b/src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivDefaultPayloadGenerator.cs
@@ -14,7 +14,6 @@
using KS.Fiks.Arkiv.Models.V1.Metadatakatalog;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
using Kode = KS.Fiks.Arkiv.Models.V1.Kodelister.Kode;
namespace Altinn.App.Clients.Fiks.FiksArkiv;
@@ -27,7 +26,6 @@ internal sealed class FiksArkivDefaultPayloadGenerator : IFiksArkivPayloadGenera
private readonly ILogger _logger;
private readonly IHostEnvironment _hostEnvironment;
private readonly IFiksArkivConfigResolver _fiksArkivConfigResolver;
- private readonly FiksIOSettings _fiksIOSettings;
private readonly TimeProvider _timeProvider;
private bool _indentXmlSerialization => !_hostEnvironment.IsProduction();
@@ -39,7 +37,6 @@ public FiksArkivDefaultPayloadGenerator(
ILogger logger,
IHostEnvironment hostEnvironment,
IFiksArkivConfigResolver fiksArkivConfigResolver,
- IOptions fiksIOSettings,
TimeProvider? timeProvider = null
)
{
@@ -49,7 +46,6 @@ public FiksArkivDefaultPayloadGenerator(
_logger = logger;
_hostEnvironment = hostEnvironment;
_fiksArkivConfigResolver = fiksArkivConfigResolver;
- _fiksIOSettings = fiksIOSettings.Value;
_timeProvider = timeProvider ?? TimeProvider.System;
}
@@ -67,6 +63,7 @@ public async Task> GeneratePayload(
$"Unsupported message type: {messageType}. {nameof(FiksArkivDefaultPayloadGenerator)} can only handle {FiksArkivConstants.MessageTypes.CreateArchiveRecord} requests."
);
+ var now = _timeProvider.GetUtcNow();
var appMetadata = await _appMetadata.GetApplicationMetadata();
var documentCreator = appMetadata.AppIdentifier.Org;
var archiveDocuments = await GetArchiveDocuments(instance, cancellationToken);
@@ -74,7 +71,7 @@ public async Task> GeneratePayload(
var documentMetadata = await _fiksArkivConfigResolver.GetArchiveDocumentMetadata(instance, cancellationToken);
var recipientParty = _fiksArkivConfigResolver.GetRecipientParty(instance, recipient);
var instanceOwnerParty = await _fiksArkivConfigResolver.GetInstanceOwnerParty(instance, cancellationToken);
- var instanceOwnerClassification = await _fiksArkivConfigResolver.GetInstanceOwnerClassification(
+ var caseFileClassifications = await _fiksArkivConfigResolver.GetCaseFileClassifications(
_authenticationContext.Current,
cancellationToken
);
@@ -84,8 +81,8 @@ public async Task> GeneratePayload(
Tittel = documentMetadata?.CaseFileTitle ?? defaultDocumentTitle,
OffentligTittel = documentMetadata?.CaseFileTitle ?? defaultDocumentTitle,
AdministrativEnhet = new AdministrativEnhet { Navn = documentCreator },
- Saksaar = _timeProvider.GetLocalNow().Year,
- Saksdato = _timeProvider.GetLocalNow().DateTime,
+ Saksaar = now.Year,
+ Saksdato = now.UtcDateTime,
ReferanseEksternNoekkel = new EksternNoekkel
{
Fagsystem = appMetadata.AppIdentifier.ToString(),
@@ -93,13 +90,16 @@ public async Task> GeneratePayload(
},
};
- caseFile.Klassifikasjon.Add(instanceOwnerClassification);
+ foreach (var classification in caseFileClassifications)
+ {
+ caseFile.Klassifikasjon.Add(classification);
+ }
var journalEntry = new Journalpost
{
- Journalaar = _timeProvider.GetLocalNow().Year,
- DokumentetsDato = _timeProvider.GetLocalNow().DateTime,
- SendtDato = _timeProvider.GetLocalNow().DateTime,
+ Journalaar = now.Year,
+ DokumentetsDato = now.UtcDateTime,
+ SendtDato = now.UtcDateTime,
Tittel = documentMetadata?.JournalEntryTitle ?? defaultDocumentTitle,
OffentligTittel = documentMetadata?.JournalEntryTitle ?? defaultDocumentTitle,
OpprettetAv = documentCreator,
@@ -131,12 +131,12 @@ public async Task> GeneratePayload(
}
// Main form data file
- journalEntry.Dokumentbeskrivelse.Add(GetDocumentDescription(archiveDocuments.PrimaryDocument));
+ journalEntry.Dokumentbeskrivelse.Add(GetDocumentDescription(archiveDocuments.PrimaryDocument, now));
// Attachments
foreach (var attachment in archiveDocuments.AttachmentDocuments)
{
- journalEntry.Dokumentbeskrivelse.Add(GetDocumentDescription(attachment));
+ journalEntry.Dokumentbeskrivelse.Add(GetDocumentDescription(attachment, now));
}
// Archive record
@@ -170,6 +170,7 @@ private async Task GetArchiveDocuments(
primaryDataElement,
primaryDocumentSettings.Filename,
DokumenttypeKoder.Dokument,
+ primaryDocumentSettings.FormatCode,
instanceId,
cancellationToken
);
@@ -191,6 +192,7 @@ await GetPayload(
x,
attachmentSetting.Filename,
DokumenttypeKoder.Vedlegg,
+ attachmentSetting.FormatCode,
instanceId,
cancellationToken
)
@@ -206,6 +208,7 @@ private async Task GetPayload(
DataElement dataElement,
string? filename,
Kode fileTypeCode,
+ string? fileFormatCode,
InstanceIdentifier instanceId,
CancellationToken cancellationToken = default
)
@@ -225,11 +228,12 @@ await _dataClient.GetDataBytes(
cancellationToken: cancellationToken
)
),
- fileTypeCode
+ fileTypeCode,
+ fileFormatCode
);
}
- private Dokumentbeskrivelse GetDocumentDescription(MessagePayloadWrapper payloadWrapper)
+ private static Dokumentbeskrivelse GetDocumentDescription(MessagePayloadWrapper payloadWrapper, DateTimeOffset now)
{
var documentClassification =
payloadWrapper.FileTypeCode == DokumenttypeKoder.Dokument
@@ -254,24 +258,19 @@ private Dokumentbeskrivelse GetDocumentDescription(MessagePayloadWrapper payload
KodeProperty = documentClassification.Verdi,
Beskrivelse = documentClassification.Beskrivelse,
},
- OpprettetDato = _timeProvider.GetLocalNow().DateTime,
+ OpprettetDato = now.UtcDateTime,
};
metadata.Dokumentobjekt.Add(
new Dokumentobjekt
{
- SystemID = new SystemID
- {
- Value = _fiksIOSettings.AccountId.ToString(),
- Label = FiksArkivConstants.AltinnSystemId,
- },
Filnavn = payloadWrapper.Payload.Filename,
ReferanseDokumentfil = payloadWrapper.Payload.Filename,
- Format = new Format { KodeProperty = payloadWrapper.Payload.GetDotlessFileExtension() },
+ Format = payloadWrapper.GetFileFormat(),
Variantformat = new Variantformat
{
- KodeProperty = VariantformatKoder.Produksjonsformat.Verdi,
- Beskrivelse = VariantformatKoder.Produksjonsformat.Beskrivelse,
+ KodeProperty = VariantformatKoder.Arkivformat.Verdi,
+ Beskrivelse = VariantformatKoder.Arkivformat.Beskrivelse,
},
}
);
diff --git a/src/Altinn.App.Clients.Fiks/FiksArkiv/IFiksArkivConfigResolver.cs b/src/Altinn.App.Clients.Fiks/FiksArkiv/IFiksArkivConfigResolver.cs
index 406bcd7e1d..ab5bad2450 100644
--- a/src/Altinn.App.Clients.Fiks/FiksArkiv/IFiksArkivConfigResolver.cs
+++ b/src/Altinn.App.Clients.Fiks/FiksArkiv/IFiksArkivConfigResolver.cs
@@ -54,9 +54,11 @@ public interface IFiksArkivConfigResolver
Task GetInstanceOwnerParty(Instance instance, CancellationToken cancellationToken = default);
///
- /// Gets the classification of the instance owner (klassifikasjon).
+ /// Gets the case file classifications (klassifikasjoner) for the shipment.
+ /// Always includes the instance owner classification derived from , followed by any
+ /// classifications configured in .
///
- Task GetInstanceOwnerClassification(
+ Task> GetCaseFileClassifications(
Authenticated auth,
CancellationToken cancellationToken = default
);
diff --git a/src/Altinn.App.Clients.Fiks/FiksArkiv/Models/FiksArkivSettings.cs b/src/Altinn.App.Clients.Fiks/FiksArkiv/Models/FiksArkivSettings.cs
index ef05ded3e1..fc29a21ad9 100644
--- a/src/Altinn.App.Clients.Fiks/FiksArkiv/Models/FiksArkivSettings.cs
+++ b/src/Altinn.App.Clients.Fiks/FiksArkiv/Models/FiksArkivSettings.cs
@@ -122,6 +122,13 @@ public sealed record FiksArkivMetadataSettings
[JsonPropertyName("caseFileTitle")]
public FiksArkivBindableValue? CaseFileTitle { get; set; }
+ ///
+ /// Optional classifications (klassifikasjon) to attach to the generated saksmappe (case file) element in the arkivmelding.xml.
+ /// These are appended in order after the implicit instance-owner classification.
+ ///
+ [JsonPropertyName("caseFileClassifications")]
+ public IReadOnlyList? CaseFileClassifications { get; set; }
+
///
/// The title to use for the generated journalpost (journal entry) element in the arkivmelding.xml.
/// If no title is provided, the value will default to the application title as defined in applicationmetadata.json.
@@ -141,6 +148,11 @@ internal void Validate(IReadOnlyList dataTypes, IAppModel appModelReso
CaseFileId?.Validate($"{propertyName}.{nameof(CaseFileId)}", dataTypes, appModelResolver);
CaseFileTitle?.Validate($"{propertyName}.{nameof(CaseFileTitle)}", dataTypes, appModelResolver);
JournalEntryTitle?.Validate($"{propertyName}.{nameof(JournalEntryTitle)}", dataTypes, appModelResolver);
+
+ foreach (var classification in CaseFileClassifications ?? [])
+ {
+ classification.Validate($"{propertyName}.{nameof(CaseFileClassifications)}");
+ }
}
}
@@ -411,6 +423,13 @@ public sealed record FiksArkivDataTypeSettings
[JsonPropertyName("filename")]
public string? Filename { get; set; }
+ ///
+ /// Optional override for the document format code (e.g. PDF/A) recorded in the arkivmelding.xml
+ /// (dokumentobjekt.format.kode). If not specified, the dotless file extension is used.
+ ///
+ [JsonPropertyName("formatCode")]
+ public string? FormatCode { get; set; }
+
///
/// Internal validation based on the requirements of
///
@@ -429,6 +448,11 @@ internal void Validate(string propertyName, IReadOnlyList dataTypes, b
throw new FiksArkivConfigurationException(
$"{propertyName}.{nameof(Filename)} configuration is required, but missing."
);
+
+ if (FormatCode is not null && string.IsNullOrWhiteSpace(FormatCode))
+ throw new FiksArkivConfigurationException(
+ $"{propertyName}.{nameof(FormatCode)} cannot be empty or whitespace if specified."
+ );
}
///
@@ -437,3 +461,53 @@ internal void Validate(string propertyName, IReadOnlyList dataTypes, b
public string GetFilenameOrDefault(string defaultExtension = "xml") =>
!string.IsNullOrWhiteSpace(Filename) ? Filename : $"{DataType}.{defaultExtension.TrimStart('.')}";
}
+
+///
+/// Represents a single classification (klassifikasjon) entry attached to the saksmappe (case file)
+/// in the generated arkivmelding.xml.
+///
+public sealed record FiksArkivClassification
+{
+ ///
+ /// The identifier of the classification system this entry belongs to (klassifikasjonssystemID).
+ ///
+ [JsonPropertyName("systemId")]
+ public required string SystemId { get; set; }
+
+ ///
+ /// The identifier of the class within the classification system (klasseID).
+ ///
+ [JsonPropertyName("classificationId")]
+ public required string ClassificationId { get; set; }
+
+ ///
+ /// A human-readable title for the classification entry (tittel).
+ ///
+ [JsonPropertyName("title")]
+ public required string Title { get; set; }
+
+ ///
+ /// Optional flag indicating that the classification is restricted (erSkjermet).
+ /// Leave null to omit the property from the resulting XML.
+ ///
+ [JsonPropertyName("isRestricted")]
+ public bool? IsRestricted { get; set; }
+
+ internal void Validate(string propertyName)
+ {
+ if (string.IsNullOrWhiteSpace(SystemId))
+ throw new FiksArkivConfigurationException(
+ $"{propertyName}.{nameof(SystemId)} configuration is required, but missing."
+ );
+
+ if (string.IsNullOrWhiteSpace(ClassificationId))
+ throw new FiksArkivConfigurationException(
+ $"{propertyName}.{nameof(ClassificationId)} configuration is required, but missing."
+ );
+
+ if (string.IsNullOrWhiteSpace(Title))
+ throw new FiksArkivConfigurationException(
+ $"{propertyName}.{nameof(Title)} configuration is required, but missing."
+ );
+ }
+}
diff --git a/src/Altinn.App.Clients.Fiks/FiksArkiv/Models/MessagePayloadWrapper.cs b/src/Altinn.App.Clients.Fiks/FiksArkiv/Models/MessagePayloadWrapper.cs
index 18e451320a..1756c79d14 100644
--- a/src/Altinn.App.Clients.Fiks/FiksArkiv/Models/MessagePayloadWrapper.cs
+++ b/src/Altinn.App.Clients.Fiks/FiksArkiv/Models/MessagePayloadWrapper.cs
@@ -1,6 +1,16 @@
using Altinn.App.Clients.Fiks.FiksIO.Models;
-using KS.Fiks.Arkiv.Models.V1.Kodelister;
+using KS.Fiks.Arkiv.Models.V1.Metadatakatalog;
+using Kode = KS.Fiks.Arkiv.Models.V1.Kodelister.Kode;
namespace Altinn.App.Clients.Fiks.FiksArkiv.Models;
-internal sealed record MessagePayloadWrapper(FiksIOMessagePayload Payload, Kode FileTypeCode);
+internal sealed record MessagePayloadWrapper(FiksIOMessagePayload Payload, Kode FileTypeCode, string? FileFormatCode)
+{
+ public Format GetFileFormat() =>
+ new()
+ {
+ KodeProperty = !string.IsNullOrWhiteSpace(FileFormatCode)
+ ? FileFormatCode
+ : Payload.GetDotlessFileExtension(),
+ };
+}
diff --git a/test/Altinn.App.Clients.Fiks.Tests/Extensions/ListExtensionsTests.cs b/test/Altinn.App.Clients.Fiks.Tests/Extensions/ListExtensionsTests.cs
index 615178fce5..9ce64af0ca 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/Extensions/ListExtensionsTests.cs
+++ b/test/Altinn.App.Clients.Fiks.Tests/Extensions/ListExtensionsTests.cs
@@ -12,7 +12,8 @@ private static IReadOnlyList GetPayloads(params string[]
return filenames
.Select(filename => new MessagePayloadWrapper(
new FiksIOMessagePayload(filename, Stream.Null),
- new Kode(".", string.Empty)
+ new Kode(".", string.Empty),
+ FileFormatCode: null
))
.ToList();
}
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.Org.verified.txt b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.Org.verified.txt
similarity index 80%
rename from test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.Org.verified.txt
rename to test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.Org.verified.txt
index df1b4569ab..c54df44b7b 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.Org.verified.txt
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.Org.verified.txt
@@ -1,5 +1,5 @@
- Organisasjonsnummer
+ ORGNR
405003309
\ No newline at end of file
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.ServiceOwner.verified.txt b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.ServiceOwner.verified.txt
similarity index 81%
rename from test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.ServiceOwner.verified.txt
rename to test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.ServiceOwner.verified.txt
index 1b26e0750b..3375594991 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.ServiceOwner.verified.txt
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.ServiceOwner.verified.txt
@@ -1,6 +1,6 @@
- Organisasjonsnummer
+ ORGNR
405003309
tdd
\ No newline at end of file
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.SystemUser.verified.txt b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.SystemUser.verified.txt
similarity index 82%
rename from test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.SystemUser.verified.txt
rename to test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.SystemUser.verified.txt
index b5e8b61a20..30b064600f 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.SystemUser.verified.txt
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.SystemUser.verified.txt
@@ -1,6 +1,6 @@
- SystembrukerId
+ AltinnSystembrukerId
f58fe166-bc22-4899-beb7-c3e8e3332f43
310702641
\ No newline at end of file
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.User.verified.txt b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.User.verified.txt
similarity index 79%
rename from test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.User.verified.txt
rename to test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.User.verified.txt
index 412d42207f..83334a6882 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes.User.verified.txt
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.User.verified.txt
@@ -1,6 +1,7 @@
- Fødselsnummer
+ PNR
12345678901
Test Testesen
+ true
\ No newline at end of file
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.1.verified.txt b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.1.verified.txt
index c05767faa9..7d4ecc35dd 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.1.verified.txt
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.1.verified.txt
@@ -6,9 +6,10 @@
Test app
Test app
- Fødselsnummer
+ PNR
12345678901
Test Testesen
+ true
ttd/test-app
@@ -39,16 +40,15 @@
Dokumentet er ferdigstilt
model.xml
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
H
Hoveddokument
- f41af07b-47c3-4d3a-9a34-1baa0f575101
- P
- Produksjonsformat
+ A
+ Arkivformat
XML
@@ -67,16 +67,15 @@
Dokumentet er ferdigstilt
ref-data-as-pdf.pdf
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
V
Vedlegg
- f41af07b-47c3-4d3a-9a34-1baa0f575101
- P
- Produksjonsformat
+ A
+ Arkivformat
PDF
@@ -109,6 +108,6 @@
Journalført
2025-10-24
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
\ No newline at end of file
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.2.verified.txt b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.2.verified.txt
index 862512b2fb..ec3829b7e1 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.2.verified.txt
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.2.verified.txt
@@ -7,7 +7,7 @@
Custom Case File Title
Custom Case File Title
- SystembrukerId
+ AltinnSystembrukerId
f58fe166-bc22-4899-beb7-c3e8e3332f43
310702641
@@ -40,16 +40,15 @@
Dokumentet er ferdigstilt
Form.xml
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
H
Hoveddokument
- f41af07b-47c3-4d3a-9a34-1baa0f575101
- P
- Produksjonsformat
+ A
+ Arkivformat
XML
@@ -68,16 +67,15 @@
Dokumentet er ferdigstilt
Form.pdf
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
V
Vedlegg
- f41af07b-47c3-4d3a-9a34-1baa0f575101
- P
- Produksjonsformat
+ A
+ Arkivformat
PDF
@@ -96,16 +94,15 @@
Dokumentet er ferdigstilt
receipt2.pdf
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
V
Vedlegg
- f41af07b-47c3-4d3a-9a34-1baa0f575101
- P
- Produksjonsformat
+ A
+ Arkivformat
PDF
@@ -124,16 +121,15 @@
Dokumentet er ferdigstilt
letter.docx
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
V
Vedlegg
- f41af07b-47c3-4d3a-9a34-1baa0f575101
- P
- Produksjonsformat
+ A
+ Arkivformat
DOCX
@@ -152,16 +148,15 @@
Dokumentet er ferdigstilt
drawing_1a.jpg
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
V
Vedlegg
- f41af07b-47c3-4d3a-9a34-1baa0f575101
- P
- Produksjonsformat
+ A
+ Arkivformat
JPG
@@ -194,6 +189,6 @@
Journalført
2025-10-24
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
\ No newline at end of file
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.3.verified.txt b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.3.verified.txt
index ac24e3402e..3a01d9b5dd 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.3.verified.txt
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.3.verified.txt
@@ -6,7 +6,7 @@
Test app
Test app
- Organisasjonsnummer
+ ORGNR
405003309
tdd
@@ -39,16 +39,15 @@
Dokumentet er ferdigstilt
Form.xml
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
H
Hoveddokument
- f41af07b-47c3-4d3a-9a34-1baa0f575101
- P
- Produksjonsformat
+ A
+ Arkivformat
XML
@@ -97,6 +96,6 @@
Journalført
2025-10-24
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
\ No newline at end of file
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.4.verified.txt b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.4.verified.txt
index e643c82339..15767f0c05 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.4.verified.txt
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.4.verified.txt
@@ -6,7 +6,7 @@
Custom Case File Title
Custom Case File Title
- Organisasjonsnummer
+ ORGNR
405003309
@@ -38,16 +38,15 @@
Dokumentet er ferdigstilt
Form.xml
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
H
Hoveddokument
- f41af07b-47c3-4d3a-9a34-1baa0f575101
- P
- Produksjonsformat
+ A
+ Arkivformat
XML
@@ -91,6 +90,6 @@
Journalført
2025-10-24
- 2025-10-24T09:58:00
+ 2025-10-24T09:58:00Z
\ No newline at end of file
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.5.verified.txt b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.5.verified.txt
new file mode 100644
index 0000000000..9b7b4f2587
--- /dev/null
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.5.verified.txt
@@ -0,0 +1,124 @@
+
+
+ Altinn Studio
+ 2
+
+ Test app
+ Test app
+
+ PNR
+ 12345678901
+ Test Testesen
+ true
+
+
+ custom-system
+ custom-class
+ Custom Classification
+
+
+ custom-system-2
+ custom-class-2
+ Restricted Classification
+ true
+
+
+ ttd/test-app
+ 12345/88d9baf8-2f9f-4e66-9a2f-7d345e60ed90
+
+ 2025
+ 2025-10-24
+
+ ttd
+
+
+
+ ttd
+ ttd
+
+
+ ttd/test-app
+ 12345/88d9baf8-2f9f-4e66-9a2f-7d345e60ed90
+
+
+
+
+ DOKUMENT
+ Dokument
+
+
+ F
+ Dokumentet er ferdigstilt
+
+ Form.pdf
+ 2025-10-24T09:58:00Z
+
+ H
+ Hoveddokument
+
+
+
+ A
+ Arkivformat
+
+
+ PDF/A
+
+ Form.pdf
+ Form.pdf
+
+
+
+
+ VEDLEGG
+ Vedlegg
+
+
+ F
+ Dokumentet er ferdigstilt
+
+ ref-data-as-pdf.pdf
+ 2025-10-24T09:58:00Z
+
+ V
+ Vedlegg
+
+
+
+ A
+ Arkivformat
+
+
+ PDF
+
+ ref-data-as-pdf.pdf
+ ref-data-as-pdf.pdf
+
+
+ Test app
+ Test app
+
+ recipient-id
+
+ EM
+ Mottaker
+
+ Recipient Name
+
+
+ ttd/test-app
+ 12345/88d9baf8-2f9f-4e66-9a2f-7d345e60ed90
+
+ 2025
+
+ I
+ Inngående dokument
+
+
+ J
+ Journalført
+
+ 2025-10-24
+ 2025-10-24T09:58:00Z
+
+
\ No newline at end of file
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivConfigResolverTest.cs b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivConfigResolverTest.cs
index 47b4071fda..7569076b86 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivConfigResolverTest.cs
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivConfigResolverTest.cs
@@ -455,7 +455,7 @@ public async Task GetRecipientParty_ReturnsExpectedValue(
[InlineData(typeof(Authenticated.SystemUser))]
[InlineData(typeof(Authenticated.ServiceOwner))]
[InlineData(typeof(Authenticated.Org))]
- public async Task GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAuthenticationTypes(Type authType)
+ public async Task GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes(Type authType)
{
// Arrange
Authenticated auth = authType switch
@@ -469,20 +469,24 @@ public async Task GetInstanceOwnerClassification_ReturnsExpectedValue_ForKnownAu
_ => throw new NotSupportedException(),
};
- await using var fixture = TestFixture.Create(services => services.AddFiksArkiv());
+ await using var fixture = TestFixture.Create(
+ services => services.AddFiksArkiv(),
+ useDefaultFiksArkivSettings: false
+ );
// Act
- var result = await fixture.FiksArkivConfigResolver.GetInstanceOwnerClassification(auth);
+ var result = await fixture.FiksArkivConfigResolver.GetCaseFileClassifications(auth);
// Assert
Assert.NotNull(result);
- var serialized = result.SerializeXml(indent: true);
+ Assert.Single(result);
+ var serialized = result[0].SerializeXml(indent: true);
var xml = Encoding.UTF8.GetString(serialized.Span);
await Verify(xml).UseDefaultSettings(authType.Name.Split("+").Last());
}
[Fact]
- public async Task GetInstanceOwnerClassification_ThrowsException_ForUnknownAuthenticationTypes()
+ public async Task GetCaseFileClassifications_ThrowsException_ForUnknownAuthenticationTypes()
{
// Arrange
var auth = TestAuthentication.GetNoneAuthentication();
@@ -490,10 +494,77 @@ public async Task GetInstanceOwnerClassification_ThrowsException_ForUnknownAuthe
// Act
await Assert.ThrowsAsync(() =>
- fixture.FiksArkivConfigResolver.GetInstanceOwnerClassification(auth)
+ fixture.FiksArkivConfigResolver.GetCaseFileClassifications(auth)
);
}
+ [Fact]
+ public async Task GetCaseFileClassifications_AppendsConfiguredClassifications_AfterOwnerClassification()
+ {
+ // Arrange
+ var fiksArkivSettingsOverride = new FiksArkivSettings
+ {
+ Metadata = new FiksArkivMetadataSettings
+ {
+ CaseFileClassifications =
+ [
+ new FiksArkivClassification
+ {
+ SystemId = "configured-system-1",
+ ClassificationId = "configured-class-1",
+ Title = "Configured 1",
+ },
+ new FiksArkivClassification
+ {
+ SystemId = "configured-system-2",
+ ClassificationId = "configured-class-2",
+ Title = "Configured 2",
+ IsRestricted = true,
+ },
+ ],
+ },
+ };
+ await using var fixture = TestFixture.Create(
+ services => services.AddFiksArkiv().WithFiksArkivConfig("CustomFiksArkivSettings"),
+ [("CustomFiksArkivSettings", fiksArkivSettingsOverride)],
+ useDefaultFiksArkivSettings: false
+ );
+
+ // Act
+ var result = await fixture.FiksArkivConfigResolver.GetCaseFileClassifications(
+ TestAuthentication.GetServiceOwnerAuthentication()
+ );
+
+ // Assert
+ Assert.Equal(3, result.Count);
+ Assert.Equal("configured-system-1", result[1].KlassifikasjonssystemID);
+ Assert.Equal("configured-class-1", result[1].KlasseID);
+ Assert.Equal("Configured 1", result[1].Tittel);
+ Assert.Null(result[1].ErSkjermet);
+ Assert.Equal("configured-system-2", result[2].KlassifikasjonssystemID);
+ Assert.Equal("configured-class-2", result[2].KlasseID);
+ Assert.Equal("Configured 2", result[2].Tittel);
+ Assert.True(result[2].ErSkjermet);
+ }
+
+ [Fact]
+ public async Task GetCaseFileClassifications_ReturnsOwnerOnly_WhenNoConfiguredClassifications()
+ {
+ // Arrange
+ await using var fixture = TestFixture.Create(
+ services => services.AddFiksArkiv(),
+ useDefaultFiksArkivSettings: false
+ );
+
+ // Act
+ var result = await fixture.FiksArkivConfigResolver.GetCaseFileClassifications(
+ TestAuthentication.GetServiceOwnerAuthentication()
+ );
+
+ // Assert
+ Assert.Single(result);
+ }
+
// csharpier-ignore-start
[Theory]
[InlineData(1, PartyType.None, null, null, null, null, null, null, null, null)]
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivDefaultPayloadGeneratorTest.cs b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivDefaultPayloadGeneratorTest.cs
index bd337b75a6..b77f671836 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivDefaultPayloadGeneratorTest.cs
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivDefaultPayloadGeneratorTest.cs
@@ -15,7 +15,6 @@
using KS.Fiks.Arkiv.Models.V1.Arkivering.Arkivmelding;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
using Microsoft.Extensions.Time.Testing;
using Moq;
@@ -26,19 +25,21 @@ public class FiksArkivDefaultPayloadGeneratorTest
//Example Instance ID = "12345/88d9baf8-2f9f-4e66-9a2f-7d345e60ed90"
private static readonly XsdValidator _xsdValidator = new();
- private static readonly Guid _fiksIOSenderAccount = Guid.Parse("f41af07b-47c3-4d3a-9a34-1baa0f575101");
private static readonly DateTimeOffset _now = DateTimeOffset.Parse("2025-10-24T09:58:00.000000Z");
- private static readonly Instance _defaultInstance = Factories.Instance(
- "12345/88d9baf8-2f9f-4e66-9a2f-7d345e60ed90",
- [
- Factories.DataElement("model", null, "application/xml"),
- Factories.DataElement("ref-data-as-pdf", null, "application/pdf"),
- Factories.DataElement("something-uploaded", "receipt2.pdf", null),
- Factories.DataElement("something-uploaded", "letter.docx", null),
- Factories.DataElement("something-uploaded", "drawing_1a.jpg", null),
- ]
- );
+ // Built fresh per test invocation because the production code mutates DataElement.Filename;
+ // reusing a static instance leaks state across test cases.
+ private static Instance NewDefaultInstance() =>
+ Factories.Instance(
+ "12345/88d9baf8-2f9f-4e66-9a2f-7d345e60ed90",
+ [
+ Factories.DataElement("model", null, "application/xml"),
+ Factories.DataElement("ref-data-as-pdf", null, "application/pdf"),
+ Factories.DataElement("something-uploaded", "receipt2.pdf", null),
+ Factories.DataElement("something-uploaded", "letter.docx", null),
+ Factories.DataElement("something-uploaded", "drawing_1a.jpg", null),
+ ]
+ );
private static class Auth
{
@@ -130,6 +131,27 @@ private static class Auth
),
instanceOwnerClassification: Factories.InstanceOwnerClassification(Auth.Org)
),
+ TestCase.Create(
+ testIdentifier: "5",
+ fiksArkivMessageType: FiksArkivConstants.MessageTypes.CreateArchiveRecord,
+ expectedAttachmentFilenames: ["Form.pdf", "ref-data-as-pdf.pdf"],
+ primaryDocumentSettings: Factories.DocumentSettings("model", "Form.pdf", formatCode: "PDF/A"),
+ attachmentSettings: [Factories.DocumentSettings("ref-data-as-pdf")],
+ archiveDocumentMetadata: null,
+ recipientParty: Factories.RecipientParty("recipient-id", "Recipient Name"),
+ instanceOwnerParty: null,
+ instanceOwnerClassification: Factories.InstanceOwnerClassification(Auth.User),
+ additionalClassifications:
+ [
+ Factories.ConfiguredClassification("custom-system", "custom-class", "Custom Classification"),
+ Factories.ConfiguredClassification(
+ "custom-system-2",
+ "custom-class-2",
+ "Restricted Classification",
+ isRestricted: true
+ ),
+ ]
+ ),
];
[Theory]
@@ -141,7 +163,7 @@ internal async Task GeneratePayload_GeneratesCorrectPayload(TestCase testCase)
// Act
var result = await fixture.GeneratePayload(
- _defaultInstance,
+ NewDefaultInstance(),
FiksArkivConstants.MessageTypes.CreateArchiveRecord
);
@@ -189,6 +211,7 @@ public static TestCase Create(
Korrespondansepart recipientParty,
Korrespondansepart? instanceOwnerParty,
Klassifikasjon instanceOwnerClassification,
+ IReadOnlyList? additionalClassifications = null,
string applicationTitle = "Test app",
string appId = "ttd/test-app"
)
@@ -201,6 +224,7 @@ public static TestCase Create(
recipientParty,
instanceOwnerParty,
instanceOwnerClassification,
+ additionalClassifications,
applicationTitle,
appId
),
@@ -242,6 +266,7 @@ public static PayloadGeneratorFixture Create(
Korrespondansepart recipientParty,
Korrespondansepart? instanceOwnerParty,
Klassifikasjon instanceOwnerClassification,
+ IReadOnlyList? additionalClassifications = null,
string applicationTitle = "Test app",
string appId = "ttd/test-app"
)
@@ -272,8 +297,8 @@ public static PayloadGeneratorFixture Create(
.Setup(x => x.GetInstanceOwnerParty(It.IsAny(), It.IsAny()))
.ReturnsAsync(instanceOwnerParty);
configResolverMock
- .Setup(x => x.GetInstanceOwnerClassification(It.IsAny(), It.IsAny()))
- .ReturnsAsync(instanceOwnerClassification);
+ .Setup(x => x.GetCaseFileClassifications(It.IsAny(), It.IsAny()))
+ .ReturnsAsync([instanceOwnerClassification, .. additionalClassifications ?? []]);
var payloadGenerator = new FiksArkivDefaultPayloadGenerator(
appMetadataMock.Object,
@@ -282,7 +307,6 @@ public static PayloadGeneratorFixture Create(
loggerMock.Object,
Mock.Of(x => x.EnvironmentName == Environments.Development),
configResolverMock.Object,
- Options.Create(Factories.FiksIOSettings(_fiksIOSenderAccount)),
fakeTime
);
@@ -311,22 +335,36 @@ public static PayloadGeneratorFixture Create(
private static class Factories
{
- public static FiksIOSettings FiksIOSettings(Guid accountId) =>
- new()
- {
- AccountId = accountId,
- IntegrationId = Guid.Empty,
- IntegrationPassword = "-",
- AccountPrivateKeyBase64 = "-",
- };
-
public static Instance Instance(string id, IEnumerable dataElements) =>
new() { Id = id, Data = [.. dataElements] };
public static FiksArkivRecipient Recipient() => new(Guid.NewGuid(), "-", "-", "-");
- public static FiksArkivDataTypeSettings DocumentSettings(string dataType, string? filename = null) =>
- new() { DataType = dataType, Filename = filename };
+ public static FiksArkivDataTypeSettings DocumentSettings(
+ string dataType,
+ string? filename = null,
+ string? formatCode = null
+ ) =>
+ new()
+ {
+ DataType = dataType,
+ Filename = filename,
+ FormatCode = formatCode,
+ };
+
+ public static Klassifikasjon ConfiguredClassification(
+ string systemId,
+ string classificationId,
+ string title,
+ bool? isRestricted = null
+ ) =>
+ new FiksArkivClassification
+ {
+ SystemId = systemId,
+ ClassificationId = classificationId,
+ Title = title,
+ IsRestricted = isRestricted,
+ }.ToKlassifikasjon();
public static FiksArkivDocumentMetadata Metadata(
string? systemId,
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivDocumentsTest.cs b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivDocumentsTest.cs
index fb1df82e0f..be7107b7f8 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivDocumentsTest.cs
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivDocumentsTest.cs
@@ -11,7 +11,7 @@ public class FiksArkivDocumentsTest
private static FiksIOMessagePayload CreatePayload(string filename) => new(filename, Stream.Null);
private MessagePayloadWrapper CreateMessagePayloadWrapper(string filename, Kode? code = null) =>
- new(CreatePayload(filename), code ?? _dummyCode);
+ new(CreatePayload(filename), code ?? _dummyCode, FileFormatCode: null);
[Fact]
public void ToPaylods_ContainsAllDocuments_InTheCorrectOrder()
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivSettingsTest.cs b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivSettingsTest.cs
index f5e06d6858..5fea883b1d 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivSettingsTest.cs
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivSettingsTest.cs
@@ -1,4 +1,5 @@
using Altinn.App.Clients.Fiks.Exceptions;
+using Altinn.App.Clients.Fiks.Extensions;
using Altinn.App.Clients.Fiks.FiksArkiv.Models;
using Altinn.Platform.Storage.Interface.Models;
@@ -6,6 +7,71 @@ namespace Altinn.App.Clients.Fiks.Tests.FiksArkiv.Models;
public class FiksArkivSettingsTest
{
+ [Theory]
+ [InlineData("sys", "cls", "title", null, null)]
+ [InlineData("sys", "cls", "title", true, null)]
+ [InlineData("sys", "cls", "title", false, null)]
+ [InlineData("", "cls", "title", null, "SystemId configuration is required")]
+ [InlineData(" ", "cls", "title", null, "SystemId configuration is required")]
+ [InlineData("sys", "", "title", null, "ClassificationId configuration is required")]
+ [InlineData("sys", "cls", "", null, "Title configuration is required")]
+ public void FiksArkivClassification_ValidatesCorrectly(
+ string systemId,
+ string classificationId,
+ string title,
+ bool? isRestricted,
+ string? expectedErrorMessage
+ )
+ {
+ // Arrange
+ var classification = new FiksArkivClassification
+ {
+ SystemId = systemId,
+ ClassificationId = classificationId,
+ Title = title,
+ IsRestricted = isRestricted,
+ };
+
+ // Act
+ var ex = Record.Exception(() => classification.Validate("TestSetting"));
+
+ // Assert
+ if (expectedErrorMessage is null)
+ {
+ Assert.Null(ex);
+ return;
+ }
+
+ Assert.NotNull(ex);
+ Assert.IsType(ex);
+ Assert.Contains(expectedErrorMessage, ex.Message);
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData(true)]
+ [InlineData(false)]
+ public void FiksArkivClassification_ToKlassifikasjon_MapsAllFields(bool? isRestricted)
+ {
+ // Arrange
+ var classification = new FiksArkivClassification
+ {
+ SystemId = "system-1",
+ ClassificationId = "class-1",
+ Title = "The Title",
+ IsRestricted = isRestricted,
+ };
+
+ // Act
+ var result = classification.ToKlassifikasjon();
+
+ // Assert
+ Assert.Equal("system-1", result.KlassifikasjonssystemID);
+ Assert.Equal("class-1", result.KlasseID);
+ Assert.Equal("The Title", result.Tittel);
+ Assert.Equal(isRestricted, result.ErSkjermet);
+ }
+
[Theory]
[InlineData("datatype1", "customfile.xml", null, "customfile.xml")]
[InlineData("datatype2", null, ".pdf", "datatype2.pdf")]
@@ -58,4 +124,30 @@ public void FiksArkivDataTypeSettings_ValidatesCorrectly(
Assert.IsType(ex);
Assert.Contains(expectedErrorMessage, ex.Message);
}
+
+ [Theory]
+ [InlineData(null, null)]
+ [InlineData("PDF/A", null)]
+ [InlineData("anything goes verbatim", null)]
+ [InlineData("", "FormatCode cannot be empty or whitespace")]
+ [InlineData(" ", "FormatCode cannot be empty or whitespace")]
+ public void FiksArkivDataTypeSettings_ValidatesFormatCode(string? formatCode, string? expectedErrorMessage)
+ {
+ // Arrange
+ var settings = new FiksArkivDataTypeSettings { DataType = "valid-datatype", FormatCode = formatCode };
+
+ // Act
+ var ex = Record.Exception(() => settings.Validate("TestSetting", [new DataType { Id = "valid-datatype" }]));
+
+ // Assert
+ if (expectedErrorMessage is null)
+ {
+ Assert.Null(ex);
+ return;
+ }
+
+ Assert.NotNull(ex);
+ Assert.IsType(ex);
+ Assert.Contains(expectedErrorMessage, ex.Message);
+ }
}
diff --git a/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/MessagePayloadWrapperTest.cs b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/MessagePayloadWrapperTest.cs
new file mode 100644
index 0000000000..b8c8f97f21
--- /dev/null
+++ b/test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/MessagePayloadWrapperTest.cs
@@ -0,0 +1,58 @@
+using Altinn.App.Clients.Fiks.FiksArkiv.Models;
+using Altinn.App.Clients.Fiks.FiksIO.Models;
+using KS.Fiks.Arkiv.Models.V1.Kodelister;
+
+namespace Altinn.App.Clients.Fiks.Tests.FiksArkiv.Models;
+
+public class MessagePayloadWrapperTest
+{
+ private static readonly Kode _dummyCode = new(".", string.Empty);
+
+ [Theory]
+ [InlineData("PDF/A")]
+ [InlineData("XML")]
+ [InlineData("anything-goes")]
+ public void GetFileFormat_UsesOverride_WhenFormatCodeIsProvided(string formatCode)
+ {
+ var wrapper = new MessagePayloadWrapper(
+ new FiksIOMessagePayload("document.pdf", Stream.Null),
+ _dummyCode,
+ FileFormatCode: formatCode
+ );
+
+ var result = wrapper.GetFileFormat();
+
+ Assert.Equal(formatCode, result.KodeProperty);
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData(" ")]
+ public void GetFileFormat_FallsBackToFileExtension_WhenFormatCodeIsMissing(string? formatCode)
+ {
+ var wrapper = new MessagePayloadWrapper(
+ new FiksIOMessagePayload("report.pdf", Stream.Null),
+ _dummyCode,
+ FileFormatCode: formatCode
+ );
+
+ var result = wrapper.GetFileFormat();
+
+ Assert.Equal("PDF", result.KodeProperty);
+ }
+
+ [Fact]
+ public void GetFileFormat_FallsBackToUppercasedFilename_WhenNoExtensionAndNoOverride()
+ {
+ var wrapper = new MessagePayloadWrapper(
+ new FiksIOMessagePayload("extensionless", Stream.Null),
+ _dummyCode,
+ FileFormatCode: null
+ );
+
+ var result = wrapper.GetFileFormat();
+
+ Assert.Equal("EXTENSIONLESS", result.KodeProperty);
+ }
+}
diff --git a/test/Altinn.App.Clients.Fiks.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt b/test/Altinn.App.Clients.Fiks.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
index 393181c7b5..7ead0b6e75 100644
--- a/test/Altinn.App.Clients.Fiks.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
+++ b/test/Altinn.App.Clients.Fiks.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
@@ -68,8 +68,8 @@ namespace Altinn.App.Clients.Fiks.FiksArkiv
Altinn.App.Clients.Fiks.FiksArkiv.Models.FiksArkivDataTypeSettings PrimaryDocumentSettings { get; }
System.Threading.Tasks.Task GetApplicationTitle(System.Threading.CancellationToken cancellationToken = default);
System.Threading.Tasks.Task GetArchiveDocumentMetadata(Altinn.Platform.Storage.Interface.Models.Instance instance, System.Threading.CancellationToken cancellationToken = default);
+ System.Threading.Tasks.Task> GetCaseFileClassifications(Altinn.App.Core.Features.Auth.Authenticated auth, System.Threading.CancellationToken cancellationToken = default);
string GetCorrelationId(Altinn.Platform.Storage.Interface.Models.Instance instance);
- System.Threading.Tasks.Task GetInstanceOwnerClassification(Altinn.App.Core.Features.Auth.Authenticated auth, System.Threading.CancellationToken cancellationToken = default);
System.Threading.Tasks.Task GetInstanceOwnerParty(Altinn.Platform.Storage.Interface.Models.Instance instance, System.Threading.CancellationToken cancellationToken = default);
System.Threading.Tasks.Task GetRecipient(Altinn.Platform.Storage.Interface.Models.Instance instance, System.Threading.CancellationToken cancellationToken = default);
KS.Fiks.Arkiv.Models.V1.Arkivering.Arkivmelding.Korrespondansepart GetRecipientParty(Altinn.Platform.Storage.Interface.Models.Instance instance, Altinn.App.Clients.Fiks.FiksArkiv.Models.FiksArkivRecipient recipient);
@@ -99,6 +99,18 @@ namespace Altinn.App.Clients.Fiks.FiksArkiv.Models
[System.Text.Json.Serialization.JsonPropertyName("value")]
public T Value { get; set; }
}
+ public sealed class FiksArkivClassification : System.IEquatable
+ {
+ public FiksArkivClassification() { }
+ [System.Text.Json.Serialization.JsonPropertyName("classificationId")]
+ public required string ClassificationId { get; set; }
+ [System.Text.Json.Serialization.JsonPropertyName("isRestricted")]
+ public bool? IsRestricted { get; set; }
+ [System.Text.Json.Serialization.JsonPropertyName("systemId")]
+ public required string SystemId { get; set; }
+ [System.Text.Json.Serialization.JsonPropertyName("title")]
+ public required string Title { get; set; }
+ }
public sealed class FiksArkivDataModelBinding : System.IEquatable
{
public FiksArkivDataModelBinding() { }
@@ -115,6 +127,8 @@ namespace Altinn.App.Clients.Fiks.FiksArkiv.Models
public required string DataType { get; set; }
[System.Text.Json.Serialization.JsonPropertyName("filename")]
public string? Filename { get; set; }
+ [System.Text.Json.Serialization.JsonPropertyName("formatCode")]
+ public string? FormatCode { get; set; }
public string GetFilenameOrDefault(string defaultExtension = "xml") { }
}
public sealed class FiksArkivDocumentMetadata : System.IEquatable
@@ -145,6 +159,8 @@ namespace Altinn.App.Clients.Fiks.FiksArkiv.Models
public sealed class FiksArkivMetadataSettings : System.IEquatable
{
public FiksArkivMetadataSettings() { }
+ [System.Text.Json.Serialization.JsonPropertyName("caseFileClassifications")]
+ public System.Collections.Generic.IReadOnlyList? CaseFileClassifications { get; set; }
[System.Text.Json.Serialization.JsonPropertyName("caseFileId")]
public Altinn.App.Clients.Fiks.FiksArkiv.Models.FiksArkivBindableValue? CaseFileId { get; set; }
[System.Text.Json.Serialization.JsonPropertyName("caseFileTitle")]