Skip to content

Add support for xsd validation of form data#1796

Open
ivarne wants to merge 11 commits into
mainfrom
magnusxsd
Open

Add support for xsd validation of form data#1796
ivarne wants to merge 11 commits into
mainfrom
magnusxsd

Conversation

@ivarne

@ivarne ivarne commented Jun 4, 2026

Copy link
Copy Markdown
Member
  • New endpoints and methods to access xsd (http and IAppResources)
  • New config AppSettings.XsdValidation to enable validation form data using xsd schema with the new

Thanks to @MagnusNordboe for the initial work in #1668

Summary by CodeRabbit

Release Notes

  • New Features

    • Added XSD schema retrieval endpoint to access model schemas via API
    • Introduced configurable XSD validation to validate form data against XML schema definitions
  • Tests

    • Added test coverage for XSD schema retrieval and validation workflows
    • Updated test models with XSD schema definitions

Copilot AI review requested due to automatic review settings June 4, 2026 11:13
@ivarne ivarne added the feature Label Pull requests with new features. Used when generation releasenotes label Jun 4, 2026
@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@ivarne, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 15 minutes and 12 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aa8e9ac7-151d-4f59-ac14-fe1e73dbb062

📥 Commits

Reviewing files that changed from the base of the PR and between 6f4d79f and 7259dc2.

📒 Files selected for processing (3)
  • src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs
  • test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.xsd
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📝 Walkthrough

Walkthrough

This PR introduces XSD validation support across the Altinn app framework. It adds a new /api/xsdschema/{id} endpoint to retrieve XSD schemas, implements a configurable XSD validator integrated into the validation pipeline, and updates test data models with schema-aware XML serialization.

Changes

XSD Schema Validation

Layer / File(s) Summary
Schema resource access
src/Altinn.App.Core/Internal/App/IAppResources.cs, src/Altinn.App.Core/Implementation/AppResourcesSI.cs
IAppResources interface adds GetXsdSchema contract; AppResourcesSI implements file-based XSD retrieval using .xsd naming convention with path validation.
Configuration and validator registration
src/Altinn.App.Core/Configuration/AppSettings.cs, src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
AppSettings introduces XsdValidation boolean flag; DI registration conditionally adds XsdValidator when enabled.
Validator implementation
src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs, src/Altinn.App.Core/Internal/Texts/TranslationService.cs
XsdValidator implements IValidator with secure XML processing and incremental validation disabled. Validates XML against XSD schemas with localized error messages via TranslationService backend fallback.
XSD retrieval endpoint
src/Altinn.App.Api/Controllers/ResourceController.cs, test/Altinn.App.Api.Tests/OpenApi/*, test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
GET /{org}/{app}/api/xsdschema/{id} returns XSD content or 404; GetLayoutSettings marked obsolete. OpenAPI specs and public API verifications updated.
Test data models and schemas
test/Altinn.App.Api.Tests/Data/apps/tdd/*/models/Skjema.*, test/Altinn.App.Api.Tests/Data/TestData.cs
Test models updated with XML array attributes and MissingFromXsd property. Schema files define XSD and JSON structure. TestData helper serializes form data to XML blob storage.
Validation and integration tests
test/Altinn.App.Api.Tests/Controllers/ValidateController_ValidateInstanceTests.cs, test/Altinn.App.Api.Tests/Controllers/ResourceControllerTests.cs, test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/*
ValidateControllerValidateInstanceTests refactored for DI clarity and adds ValidateInstance_WithXsdValidator test case. ResourceControllerTests exercises schema endpoints. Custom scopes snapshots updated.
Public API surface and type safety
src/Altinn.App.Core/Internal/Data/IDataElementAccessChecker.cs, test/Altinn.App.Core.Tests/Implementation/AppResourcesSITests.cs, test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
IDataElementAccessChecker changed to public. AppResourcesSITests enables nullable context and updates null-coalescing. Public API snapshots track all XSD-related additions and new interface.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes


Suggested labels

feature, squad/data


Suggested reviewers

  • martinothamar
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add support for xsd validation of form data' accurately describes the primary change: introducing XSD validation functionality for form data through new validators, configuration, and supporting infrastructure.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch magnusxsd

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds opt-in XSD-based validation of XML form data, and exposes XSD schemas via a new resource endpoint so apps (and tooling) can retrieve schemas by model id.

Changes:

  • Introduces XsdValidator and registers it behind AppSettings.XsdValidation.
  • Extends IAppResources/AppResourcesSI and ResourceController with GetXsdSchema + GET /{org}/{app}/api/xsdschema/{id}.
  • Updates translations, public API baselines, OpenAPI snapshots, and adds/adjusts tests + test app artifacts to cover the new behavior.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt Snapshot update to include new XSD schema endpoint metadata.
test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txt Snapshot update to include new XSD schema endpoint metadata.
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt Public API baseline updated for new setting, validator, and IAppResources.GetXsdSchema.
test/Altinn.App.Core.Tests/Implementation/AppResourcesSITests.cs Test nullability updates for AppResourcesSI construction.
test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt Public API baseline updated for new XSD endpoint + deprecation attribute.
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json Swagger snapshot updated for new endpoint + deprecated layoutsettings.
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveCustomOpenApiSpec.verified.json OpenAPI snapshot updated for schema content changes in test app model.
test/Altinn.App.Api.Tests/Data/TestData.cs Adds helper to rewrite XML data elements for tests.
test/Altinn.App.Api.Tests/Data/apps/tdd/permissive-app/models/Skjema.cs Adjusts XML serialization patterns for AltinnRowId emission.
test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.xsd Adds XSD used by integration tests for validation.
test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.schema.json Adds minimal JSON schema placeholder for resource tests.
test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.cs Updates XML array serialization and adds a field used to trigger XSD validation errors.
test/Altinn.App.Api.Tests/Controllers/ValidateController_ValidateInstanceTests.cs Adds test coverage for XSD validation via XsdValidator.
test/Altinn.App.Api.Tests/Controllers/ResourceControllerTests.cs Adds tests for new XSD schema endpoint (and existing JSON schema behavior).
src/Altinn.App.Core/Internal/Texts/TranslationService.cs Adds default text resource for XSD validation issues.
src/Altinn.App.Core/Internal/Data/IDataElementAccessChecker.cs Makes interface public and documents it (public API surface change).
src/Altinn.App.Core/Internal/App/IAppResources.cs Adds GetXsdSchema(modelId) to app resource abstraction.
src/Altinn.App.Core/Implementation/AppResourcesSI.cs Implements GetXsdSchema by reading {modelId}.xsd from models folder.
src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs New validator that validates serialized XML against XSD schema if present.
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs Registers XsdValidator when AppSettings.XsdValidation is enabled.
src/Altinn.App.Core/Configuration/AppSettings.cs Adds XsdValidation setting.
src/Altinn.App.Api/Controllers/ResourceController.cs Adds XSD schema endpoint and marks legacy layoutsettings endpoint as obsolete.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs
Comment thread src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs
Comment thread src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs
Comment thread src/Altinn.App.Core/Implementation/AppResourcesSI.cs
Comment thread test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.xsd Outdated
Comment thread src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs
Comment thread src/Altinn.App.Api/Controllers/ResourceController.cs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (2)
test/Altinn.App.Core.Tests/Implementation/AppResourcesSITests.cs (1)

32-32: ⚡ Quick win

Replace repeated null! constructor injections with an explicit test double.

Lines [32], [83], [137], [192], [208], [224], [242], [259], and [277] bypass nullable safety and make these tests fragile if AppResourcesSI starts using that dependency on covered paths. Prefer a shared Moq/fake dependency instead.

As per coding guidelines: "Use Nullable Reference Types in C# code".

Also applies to: 83-83, 137-137, 192-192, 208-208, 224-224, 242-242, 259-259, 277-277

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/Altinn.App.Core.Tests/Implementation/AppResourcesSITests.cs` at line 32,
Replace the repeated null! constructor arguments in AppResourcesSITests with a
shared explicit test double (e.g., a Moq mock or simple fake) and inject that
into the AppResourcesSI instances used by the tests; specifically, create a
single mocked dependency (using Moq or a lightweight fake) in the
AppResourcesSITests setup and use it instead of null! for every constructor
parameter currently passed as null! (the instances of AppResourcesSI constructed
across the test methods), so the tests no longer bypass nullable safety and will
be resilient if AppResourcesSI starts using that dependency.
test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.schema.json (1)

1-3: ⚡ Quick win

Replace the placeholder schema with a minimal concrete test schema.

Keeping only a TODO payload makes the fixture ambiguous and reduces confidence in schema-related tests. A minimal explicit JSON schema would make intent and failures clearer.

If you want, I can draft a minimal schema content for this fixture and open a follow-up issue text.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.schema.json`
around lines 1 - 3, The current Skjema.schema.json contains only a "$comment"
placeholder; replace it with a minimal concrete JSON Schema (e.g., a top-level
"type": "object" with a small "properties" map and a "required" array) so tests
have an explicit schema to validate against; update the file Skjema.schema.json
accordingly and ensure the schema is valid JSON and matches any expectations in
tests that reference this fixture (look for usages of Skjema.schema.json or the
"$comment" placeholder to confirm compatibility).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs`:
- Line 15: Change the XsdValidator class declaration from public to internal
sealed to narrow its visibility and prevent inheritance: update the declaration
for the class named XsdValidator that implements IValidator from "public class
XsdValidator" to "internal sealed class XsdValidator" (ensure any tests or
callers in other assemblies are adjusted if they require access).
- Around line 46-49: ShouldRunForTask synchronously blocks on
_appMetadata.GetApplicationMetadata().Result — change design to consult an
asynchronously populated cache (preload metadata during startup and expose it
for synchronous reads) so ShouldRunForTask can read the cached
ApplicationMetadata.DataTypes without awaiting; also change the XsdValidator
class declaration to internal sealed (if no inheritance intended). For schema
parsing, wrap the parsedSchema.Add(null, xsdReader) call in a try/catch that
catches XmlSchemaException (optionally XmlException) and convert parse failures
into a ValidationIssue (do not throw), ensuring validation continues gracefully;
refer to ShouldRunForTask, _appMetadata.GetApplicationMetadata(),
parsedSchema.Add(null, xsdReader), and class XsdValidator when making these
edits.
- Around line 102-105: Wrap the parsedSchema.Add(null, xsdReader) call in a
try/catch that specifically catches XmlSchemaException and converts the failure
into the existing validation error handling used by the XsdValidator class
instead of letting the exception bubble (i.e., catch XmlSchemaException around
the parsedSchema.Add call where the XmlReader is created and do the same for the
second parsedSchema.Add block later). Ensure you reference and use the
validator's existing mechanism for reporting schema errors (add the error to the
validation result/collection or call the class's error reporting helper) so
malformed XSDs surface as validation issues rather than causing a 500.

In
`@test/Altinn.App.Api.Tests/Controllers/ValidateController_ValidateInstanceTests.cs`:
- Around line 168-170: Replace FluentAssertions usages in the
ValidateController_ValidateInstanceTests method with xUnit Assert calls: instead
of response.Should().HaveStatusCode(HttpStatusCode.OK) use
Assert.Equal(HttpStatusCode.OK, response.StatusCode); instead of
parsedResponse.Should().HaveCount(1) use Assert.Single(parsedResponse) (or
Assert.Equal(1, parsedResponse.Count)); keep the call to
ParseResponse<List<ValidationIssue>>(responseString) as-is and add any necessary
Assert.NotNull(parsedResponse) if desired. This targets the assertions around
response and parsedResponse in the test method.
- Around line 174-177: Replace the brittle exact string equality assertion in
ValidateController_ValidateInstanceTests (the Assert.Equal comparing the full
XSD parser message for issue.Description) with stable substring checks: assert
that issue.Description contains the invariant user-facing prefix (e.g., "Et felt
bryter reglene satt av XSD") and the relevant element name (e.g.,
"missing-from-xsd") or use a regex match for those stable parts; update the test
where the Assert.Equal appears to use Assert.Contains/Assert.Matches against
issue.Description instead.

---

Nitpick comments:
In
`@test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.schema.json`:
- Around line 1-3: The current Skjema.schema.json contains only a "$comment"
placeholder; replace it with a minimal concrete JSON Schema (e.g., a top-level
"type": "object" with a small "properties" map and a "required" array) so tests
have an explicit schema to validate against; update the file Skjema.schema.json
accordingly and ensure the schema is valid JSON and matches any expectations in
tests that reference this fixture (look for usages of Skjema.schema.json or the
"$comment" placeholder to confirm compatibility).

In `@test/Altinn.App.Core.Tests/Implementation/AppResourcesSITests.cs`:
- Line 32: Replace the repeated null! constructor arguments in
AppResourcesSITests with a shared explicit test double (e.g., a Moq mock or
simple fake) and inject that into the AppResourcesSI instances used by the
tests; specifically, create a single mocked dependency (using Moq or a
lightweight fake) in the AppResourcesSITests setup and use it instead of null!
for every constructor parameter currently passed as null! (the instances of
AppResourcesSI constructed across the test methods), so the tests no longer
bypass nullable safety and will be resilient if AppResourcesSI starts using that
dependency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1395d518-ae45-4438-a5a7-f51cc33be1f4

📥 Commits

Reviewing files that changed from the base of the PR and between 3c66644 and 6f4d79f.

📒 Files selected for processing (22)
  • src/Altinn.App.Api/Controllers/ResourceController.cs
  • src/Altinn.App.Core/Configuration/AppSettings.cs
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs
  • src/Altinn.App.Core/Implementation/AppResourcesSI.cs
  • src/Altinn.App.Core/Internal/App/IAppResources.cs
  • src/Altinn.App.Core/Internal/Data/IDataElementAccessChecker.cs
  • src/Altinn.App.Core/Internal/Texts/TranslationService.cs
  • test/Altinn.App.Api.Tests/Controllers/ResourceControllerTests.cs
  • test/Altinn.App.Api.Tests/Controllers/ValidateController_ValidateInstanceTests.cs
  • test/Altinn.App.Api.Tests/Data/TestData.cs
  • test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.cs
  • test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.schema.json
  • test/Altinn.App.Api.Tests/Data/apps/tdd/contributer-restriction/models/Skjema.xsd
  • test/Altinn.App.Api.Tests/Data/apps/tdd/permissive-app/models/Skjema.cs
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveCustomOpenApiSpec.verified.json
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/Implementation/AppResourcesSITests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txt
  • test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt

Comment thread src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs Outdated
Comment thread src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs
Comment thread src/Altinn.App.Core/Features/Validation/Default/XsdValidator.cs
@sonarqubecloud

sonarqubecloud Bot commented Jun 4, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
E Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Label Pull requests with new features. Used when generation releasenotes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants