Support calculating into lists and objects - #1821
Conversation
📝 WalkthroughWalkthroughUpdates typed calculation config handling, JSON serialization behavior for expression-related types, calculator tests for multi-model inputs, and integration fixtures and snapshots for the new calculated fields. ChangesCore JSON and expression types
Calculation schema and data processing tests
ExpressionValue and layout expression tests
Integration test artifacts and snapshots
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR extends the expression/calculation pipeline to better support list/object values and updates tests to exercise DataModelFieldCalculator.Calculate end-to-end (instead of the per-data-element internal method).
Changes:
- Updated calculation tests to run through
DataModelFieldCalculator.Calculateand added a multi-data-model object calculation fixture. - Added JSON serialization/deserialization support improvements for
DataElementIdentifierandExpressionValue(lists/objects). - Improved raw JSON writing to preserve formatting/round-tripping behavior for complex JSON values.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/Altinn.App.Core.Tests/Helpers/Utf8JsonReaderExtensionsTests.cs | Adjusts comment/number adjacency in JSON comment round-trip test. |
| test/Altinn.App.Core.Tests/Features/DataProcessing/DataModelFieldCalculatorTests.cs | Refactors tests to call Calculate(...), adds multi-data-model test support. |
| test/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.json | Adds fixture for calculating object values into array elements across multiple data elements. |
| src/Altinn.App.Core/Models/DataElementIdentifier.cs | Adds a JsonConverter to serialize/deserialize the identifier as a GUID string. |
| src/Altinn.App.Core/Internal/Expressions/ExpressionValue.cs | Extends TryDeserialize handling for complex (array/object) targets and adjusts JSON writing path for arrays/objects. |
| src/Altinn.App.Core/Helpers/Extensions/Utf8JsonReaderExtentions.cs | Adds WriteRawFormattedValue and tightens reader-copy behavior (incl. number handling). |
| src/Altinn.App.Core/Features/DataProcessing/DataModelFieldCalculator.cs | Narrows CalculateFormData visibility from internal to private (tests now use public Calculate). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| case JsonValueKind.Array when underlyingType.IsAssignableTo(typeof(IEnumerable<>)): | ||
| case JsonValueKind.Object: |
| // Multiple data elements. The calculation runs against the first element in the list, | ||
| // but expressions may reference the other data models. Either this or <see cref="FormData"/> must be set. | ||
| [JsonPropertyName("dataModels")] | ||
| public List<DataModelAndElement>? DataModels { get; set; } |
| internal static void WriteRawFormattedValue(this Utf8JsonWriter writer, string json) | ||
| { | ||
| var jsonReader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json), isFinalBlock: true, state: default); | ||
| jsonReader.Read(); // Need to read first token to initialize the reader | ||
| Copy(ref jsonReader, writer); | ||
| } |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
test/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.json (1)
1-134:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix typo in filename.
The filename "calclulate-object.json" contains a typo. It should be "calculate-object.json".
🤖 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/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.json` around lines 1 - 134, The test file filename contains a typo where "calclulate" is misspelled with an extra "l". Rename the file from "calclulate-object.json" to "calculate-object.json". This file is a test data configuration file for the test case "Should set multiple values when resolving keys in a datamodel array" and the corrected spelling will ensure the filename matches the standard naming convention.
🧹 Nitpick comments (2)
src/Altinn.App.Core/Models/DataElementIdentifier.cs (1)
120-147: ⚡ Quick winAdd
sealedmodifier to the converter class.Per coding guidelines, classes should be
sealedunless inheritance is a valid use-case. There's no reason to inherit from this converter.♻️ Suggested fix
- public class DataElementIdentifierConverter : JsonConverter<DataElementIdentifier> + public sealed class DataElementIdentifierConverter : JsonConverter<DataElementIdentifier>🤖 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 `@src/Altinn.App.Core/Models/DataElementIdentifier.cs` around lines 120 - 147, The DataElementIdentifierConverter class declaration is missing the sealed modifier. Add the sealed keyword to the class declaration of DataElementIdentifierConverter to prevent inheritance, as there is no valid use-case for inheriting from this JSON converter class per the coding guidelines.Source: Coding guidelines
test/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.json (1)
50-56: Single-argumentmultiplyexpression is valid and intentional.The expression evaluator supports single-argument
multiplyvia theAggregatereducer pattern, which preserves the input value unchanged—this behavior is confirmed by the test expectations showing quantity passing through unmodified. However, for improved clarity, consider using["dataModel", "form.children.quantity"]directly instead of wrapping it inmultiply.🤖 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/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.json` around lines 50 - 56, In the test JSON file at the specified location, simplify the multiply expression by removing the unnecessary wrapping. Replace the current multiply operation that contains a single dataModel argument with a direct reference to the data field. Instead of the structure ["multiply", ["dataModel", "form.children.quantity"]], use just ["dataModel", "form.children.quantity"] directly to improve clarity and readability of the test case.
🤖 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/Internal/Expressions/ExpressionValue.cs`:
- Around line 626-647: The condition
`underlyingType.IsAssignableTo(typeof(IEnumerable<>))` in the case statement for
JsonValueKind.Array does not correctly identify closed generic collection types
like List<T> or T[], causing array deserialization to fail silently. Remove the
`when underlyingType.IsAssignableTo(typeof(IEnumerable<>))` condition from the
`case JsonValueKind.Array` statement so that the case matches all array values.
Since both Array and Object cases use identical JSON round-trip deserialization
logic through JsonSerializer, the condition is unnecessary and the deserializer
will handle type compatibility correctly.
---
Outside diff comments:
In
`@test/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.json`:
- Around line 1-134: The test file filename contains a typo where "calclulate"
is misspelled with an extra "l". Rename the file from "calclulate-object.json"
to "calculate-object.json". This file is a test data configuration file for the
test case "Should set multiple values when resolving keys in a datamodel array"
and the corrected spelling will ensure the filename matches the standard naming
convention.
---
Nitpick comments:
In `@src/Altinn.App.Core/Models/DataElementIdentifier.cs`:
- Around line 120-147: The DataElementIdentifierConverter class declaration is
missing the sealed modifier. Add the sealed keyword to the class declaration of
DataElementIdentifierConverter to prevent inheritance, as there is no valid
use-case for inheriting from this JSON converter class per the coding
guidelines.
In
`@test/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.json`:
- Around line 50-56: In the test JSON file at the specified location, simplify
the multiply expression by removing the unnecessary wrapping. Replace the
current multiply operation that contains a single dataModel argument with a
direct reference to the data field. Instead of the structure ["multiply",
["dataModel", "form.children.quantity"]], use just ["dataModel",
"form.children.quantity"] directly to improve clarity and readability of the
test case.
🪄 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: bd846af6-9ca6-4fc7-8955-1e147242a1df
📒 Files selected for processing (7)
src/Altinn.App.Core/Features/DataProcessing/DataModelFieldCalculator.cssrc/Altinn.App.Core/Helpers/Extensions/Utf8JsonReaderExtentions.cssrc/Altinn.App.Core/Internal/Expressions/ExpressionValue.cssrc/Altinn.App.Core/Models/DataElementIdentifier.cstest/Altinn.App.Core.Tests/Features/DataProcessing/DataModelFieldCalculatorTests.cstest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.jsontest/Altinn.App.Core.Tests/Helpers/Utf8JsonReaderExtensionsTests.cs
554da86 to
b67040a
Compare
c7d1e2e to
0fcfbb0
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/Altinn.App.Core/Internal/Expressions/ExpressionValue.cs (1)
626-647: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRemove the
IEnumerablegate from the array fast-path.Line 626 still rejects array payloads before they reach the same JSON round-trip used for objects. That makes
TryDeserializereturnfalsefor array targets thatJsonSerializer.Deserializecan handle but that are notIEnumerablethemselves, such asJsonElement,object, orMemory<T>. Let the serializer decide compatibility here, just like the object branch.Suggested fix
- case JsonValueKind.Array when underlyingType.IsAssignableTo(typeof(IEnumerable)): + case JsonValueKind.Array: case JsonValueKind.Object:🤖 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 `@src/Altinn.App.Core/Internal/Expressions/ExpressionValue.cs` around lines 626 - 647, The array fast-path in ExpressionValue.TryDeserialize still blocks non-IEnumerable array targets before the JSON round-trip, so remove the underlyingType.IsAssignableTo(typeof(IEnumerable)) gate from the JsonValueKind.Array case. Keep the same serialize-to-UTF8 and JsonSerializer.Deserialize flow used by the JsonValueKind.Object branch so the serializer can decide whether array payloads are compatible with targets like JsonElement, object, or Memory<T>. Ensure the catch handling and null/false fallback remain unchanged.
🤖 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 `@test/Altinn.App.Integration.Tests/_fixture/AppFixture.ApiResponse.cs`:
- Line 78: The generic Read<T>() fallback in ApiResponse currently uses
Argon.JsonConvert, which can hide validation payload issues; replace it with
System.Text.Json deserialization in the same fallback path. Because ApiResponse
cannot access AppFixture._jsonSerializerOptions directly, either make that
options field accessible from AppFixture (for example, internal/protected) or
create a local JsonSerializerOptions with web defaults inside the fallback
block. Keep the change scoped to the Read<T>() method and ensure the generic
model assignment uses the new serializer path.
---
Duplicate comments:
In `@src/Altinn.App.Core/Internal/Expressions/ExpressionValue.cs`:
- Around line 626-647: The array fast-path in ExpressionValue.TryDeserialize
still blocks non-IEnumerable array targets before the JSON round-trip, so remove
the underlyingType.IsAssignableTo(typeof(IEnumerable)) gate from the
JsonValueKind.Array case. Keep the same serialize-to-UTF8 and
JsonSerializer.Deserialize flow used by the JsonValueKind.Object branch so the
serializer can decide whether array payloads are compatible with targets like
JsonElement, object, or Memory<T>. Ensure the catch handling and null/false
fallback remain unchanged.
🪄 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: 4714edcc-c84d-478e-81e7-01b5f2fa1683
📒 Files selected for processing (91)
src/Altinn.App.Core/Features/DataProcessing/DataModelFieldCalculator.cssrc/Altinn.App.Core/Helpers/Extensions/Utf8JsonReaderExtentions.cssrc/Altinn.App.Core/Internal/Expressions/ExpressionValue.cssrc/Altinn.App.Core/Models/DataElementIdentifier.cstest/Altinn.App.Core.Tests/Features/DataProcessing/DataModelFieldCalculatorTests.cstest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.jsontest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calculate-list.jsontest/Altinn.App.Core.Tests/Helpers/Utf8JsonReaderExtensionsTests.cstest/Altinn.App.Core.Tests/LayoutExpressions/CommonTests/TestFunctions.cstest/Altinn.App.Core.Tests/LayoutExpressions/ExpressionEvaluatorTests/ExpressionValueTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.DataUpload_filenameQuoted=False_useNewEndpoint=True_0_UploadResponse.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.DataUpload_filenameQuoted=True_useNewEndpoint=True_0_UploadResponse.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=ServiceOwner_scope=custom-serviceowner-instances.read-custom-serviceowner-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=SystemUser_scope=custom-instances.read-custom-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=User_scope=altinn-portal-enduser_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=User_scope=custom-instances.read-custom-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesWithPlaceholderTests.Full_auth=ServiceOwner_scope=custom-basic-serviceowner-instances.read-custom-basic-serviceowner-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesWithPlaceholderTests.Full_auth=SystemUser_scope=custom-basic-instances.read-custom-basic-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesWithPlaceholderTests.Full_auth=User_scope=custom-basic-instances.read-custom-basic-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/PartyTypesAllowed/_snapshots/SubunitOnlyAppTests.Instantiate_partyId=500002_0_Instance.verified.txttest/Altinn.App.Integration.Tests/_fixture/AppFixture.ApiResponse.cstest/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.calculation.jsontest/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.cstest/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.metadata.jsontest/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.schema.jsontest/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.xsd
💤 Files with no reviewable changes (1)
- test/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.metadata.json
✅ Files skipped from review due to trivial changes (28)
- test/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.calculation.json
- test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesWithPlaceholderTests.Full_auth=User_scope=custom-basic-instances.read-custom-basic-instances.write_1_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=User_scope=altinn-portal-enduser_1_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesWithPlaceholderTests.Full_auth=SystemUser_scope=custom-basic-instances.read-custom-basic-instances.write_1_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Core.Tests/Helpers/Utf8JsonReaderExtensionsTests.cs
- test/Altinn.App.Integration.Tests/PartyTypesAllowed/_snapshots/SubunitOnlyAppTests.Instantiate_partyId=500002_0_Instance.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txt
🚧 Files skipped from review as they are similar to previous changes (7)
- src/Altinn.App.Core/Features/DataProcessing/DataModelFieldCalculator.cs
- src/Altinn.App.Core/Models/DataElementIdentifier.cs
- test/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.json
- test/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calculate-list.json
- test/Altinn.App.Core.Tests/LayoutExpressions/CommonTests/TestFunctions.cs
- test/Altinn.App.Core.Tests/Features/DataProcessing/DataModelFieldCalculatorTests.cs
- src/Altinn.App.Core/Helpers/Extensions/Utf8JsonReaderExtentions.cs
| else | ||
| { | ||
| model = JsonSerializer.Deserialize<T>(body, _jsonSerializerOptions); | ||
| model = Argon.JsonConvert.DeserializeObject<T>(body); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major
Use System.Text.Json in the generic response path, but fix the scope issue.
The concern about Argon.JsonConvert masking validation errors in the generic Read<T>() fallback (line 78) is valid and a potential functional correctness issue. However, the suggested fix JsonSerializer.Deserialize<T>(body, _jsonSerializerOptions) will not compile because _jsonSerializerOptions is a private field in the parent AppFixture class and is not accessible within the nested ApiResponse class in this file.
To resolve this correctly:
- Either expose the options by changing
_jsonSerializerOptionstointernalorprotectedinAppFixture.cs, or - Instantiate
new JsonSerializerOptions(JsonSerializerDefaults.Web)directly in the fallback block inAppFixture.ApiResponse.cs.
Please apply one of these valid fixes to ensure validation payloads are not coerced into empty models.
Corrected fix options
Option A: Expose options in AppFixture.cs (preferred for consistency)
// In test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs
- private static readonly JsonSerializerOptions _jsonSerializerOptions = new(JsonSerializerDefaults.Web);
+ internal static readonly JsonSerializerOptions _jsonSerializerOptions = new(JsonSerializerDefaults.Web);Option B: Create local options in AppFixture.ApiResponse.cs
// In test/Altinn.App.Integration.Tests/_fixture/AppFixture.ApiResponse.cs
else
{
- model = Argon.JsonConvert.DeserializeObject<T>(body);
+ model = JsonSerializer.Deserialize<T>(body, new JsonSerializerOptions(JsonSerializerDefaults.Web));
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| model = Argon.JsonConvert.DeserializeObject<T>(body); | |
| model = JsonSerializer.Deserialize<T>(body, new JsonSerializerOptions(JsonSerializerDefaults.Web)); |
🤖 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.Integration.Tests/_fixture/AppFixture.ApiResponse.cs` at line
78, The generic Read<T>() fallback in ApiResponse currently uses
Argon.JsonConvert, which can hide validation payload issues; replace it with
System.Text.Json deserialization in the same fallback path. Because ApiResponse
cannot access AppFixture._jsonSerializerOptions directly, either make that
options field accessible from AppFixture (for example, internal/protected) or
create a local JsonSerializerOptions with web defaults inside the fallback
block. Keep the change scoped to the Read<T>() method and ensure the generic
model assignment uses the new serializer path.
Improve testing test the full DataModelFieldCalculator.Calculate instead of the internal per element version.
…non existing open generic IEnumerable<>) Add tests for calculating lists Update TestFunctions.cs to use datamodelaccessor and ExpressionValue
0fcfbb0 to
127cb9b
Compare
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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
`@test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt`:
- Around line 4667-4684: `CalculationSchema.Schema` is currently getter-only, so
the `$schema` JSON value cannot be populated during deserialization. Update
`CalculationSchema` to allow `System.Text.Json` to bind this property by adding
an `init` or setter (while keeping the existing `JsonPropertyName("$schema")` on
`Schema`), and verify the public API contract in the
`CalculationSchema`/`CalculationItem` models remains consistent with JSON
round-tripping.
🪄 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: 9c2a5e25-634b-48e7-a104-c1de9060a5f0
📒 Files selected for processing (105)
src/Altinn.App.Core/Features/DataProcessing/DataModelFieldCalculator.cssrc/Altinn.App.Core/Helpers/Extensions/Utf8JsonReaderExtentions.cssrc/Altinn.App.Core/Implementation/AppResourcesSI.cssrc/Altinn.App.Core/Internal/App/IAppResources.cssrc/Altinn.App.Core/Internal/Expressions/ExpressionValue.cssrc/Altinn.App.Core/Models/Calculation/CalculationItem.cssrc/Altinn.App.Core/Models/Calculation/CalculationSchema.cssrc/Altinn.App.Core/Models/DataElementIdentifier.cssrc/Altinn.App.Core/Models/RawDataModelFieldCalculation.cstest/Altinn.App.Core.Tests/Features/DataProcessing/DataModelFieldCalculatorTests.cstest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/assert-logger/parse-none-existing-definition.jsontest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/assert-logger/parse-none-existing-expression.jsontest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/assert-logger/unsupported-data-type.jsontest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.jsontest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calculate-in-group.jsontest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calculate-list.jsontest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/component-lookup-hidden.jsontest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/hidden-field.jsontest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/hidden-page.jsontest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/single-expression-boolean.jsontest/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/single-expression-number.jsontest/Altinn.App.Core.Tests/Helpers/Utf8JsonReaderExtensionsTests.cstest/Altinn.App.Core.Tests/LayoutExpressions/CommonTests/TestFunctions.cstest/Altinn.App.Core.Tests/LayoutExpressions/ExpressionEvaluatorTests/ExpressionValueTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.DataUpload_filenameQuoted=False_useNewEndpoint=True_0_UploadResponse.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.DataUpload_filenameQuoted=True_useNewEndpoint=True_0_UploadResponse.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txttest/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=ServiceOwner_scope=custom-serviceowner-instances.read-custom-serviceowner-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=SystemUser_scope=custom-instances.read-custom-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=User_scope=altinn-portal-enduser_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=User_scope=custom-instances.read-custom-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesWithPlaceholderTests.Full_auth=ServiceOwner_scope=custom-basic-serviceowner-instances.read-custom-basic-serviceowner-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesWithPlaceholderTests.Full_auth=SystemUser_scope=custom-basic-instances.read-custom-basic-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesWithPlaceholderTests.Full_auth=User_scope=custom-basic-instances.read-custom-basic-instances.write_1_Instantiation.verified.txttest/Altinn.App.Integration.Tests/PartyTypesAllowed/_snapshots/SubunitOnlyAppTests.Instantiate_partyId=500002_0_Instance.verified.txttest/Altinn.App.Integration.Tests/_fixture/AppFixture.ApiResponse.cstest/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.calculation.jsontest/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.cstest/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.metadata.jsontest/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.schema.jsontest/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.xsd
💤 Files with no reviewable changes (4)
- test/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/assert-logger/parse-none-existing-expression.json
- src/Altinn.App.Core/Models/RawDataModelFieldCalculation.cs
- test/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/assert-logger/parse-none-existing-definition.json
- test/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.metadata.json
✅ Files skipped from review due to trivial changes (58)
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=ServiceOwner_scope=custom-serviceowner-instances.read-custom-serviceowner-instances.write_1_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesWithPlaceholderTests.Full_auth=User_scope=custom-basic-instances.read-custom-basic-instances.write_1_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=User_scope=custom-instances.read-custom-instances.write_1_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/PartyTypesAllowed/_snapshots/SubunitOnlyAppTests.Instantiate_partyId=500002_0_Instance.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesWithPlaceholderTests.Full_auth=ServiceOwner_scope=custom-basic-serviceowner-instances.read-custom-basic-serviceowner-instances.write_1_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.DataUpload_filenameQuoted=False_useNewEndpoint=True_0_UploadResponse.verified.txt
- test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=User_scope=altinn-portal-enduser_1_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Core.Tests/Helpers/Utf8JsonReaderExtensionsTests.cs
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.DataUpload_filenameQuoted=True_useNewEndpoint=True_0_UploadResponse.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calculate-list.json
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartNoPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Core.Tests/Features/DataProcessing/data-field-value-calculator-tests/calclulate-object.json
🚧 Files skipped from review as they are similar to previous changes (29)
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesWithPlaceholderTests.Full_auth=SystemUser_scope=custom-basic-instances.read-custom-basic-instances.write_1_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedWithPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedWithPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=User_testCase=MultipartXmlPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.calculation.json
- test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Full_auth=SystemUser_scope=custom-instances.read-custom-instances.write_1_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.cs
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartXmlPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=MultipartNoPrefill_2_PatchFormData.verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldServiceOwner_testCase=SimplifiedWithPrefill_5_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=OldUser_testCase=SimplifiedNoPrefill_1_Download-Data[0].verified.txt
- test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=SimplifiedNoPrefill_0_Instantiation.verified.txt
- test/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.xsd
- test/Altinn.App.Core.Tests/LayoutExpressions/CommonTests/TestFunctions.cs
- test/Altinn.App.Integration.Tests/_fixture/AppFixture.ApiResponse.cs
- test/Altinn.App.Integration.Tests/_testapps/basic/App/models/model.schema.json
- src/Altinn.App.Core/Models/DataElementIdentifier.cs
- src/Altinn.App.Core/Internal/Expressions/ExpressionValue.cs
- src/Altinn.App.Core/Helpers/Extensions/Utf8JsonReaderExtentions.cs
- test/Altinn.App.Core.Tests/LayoutExpressions/ExpressionEvaluatorTests/ExpressionValueTests.cs
- test/Altinn.App.Core.Tests/Features/DataProcessing/DataModelFieldCalculatorTests.cs
| namespace Altinn.App.Core.Models.Calculation | ||
| { | ||
| public class CalculationItem | ||
| { | ||
| public CalculationItem() { } | ||
| [System.Text.Json.Serialization.JsonPropertyName("expression")] | ||
| public required Altinn.App.Core.Models.Expressions.Expression Expression { get; init; } | ||
| [System.Text.Json.Serialization.JsonPropertyName("field")] | ||
| public required string Field { get; init; } | ||
| } | ||
| public class CalculationSchema | ||
| { | ||
| public CalculationSchema() { } | ||
| public required System.Collections.Generic.List<Altinn.App.Core.Models.Calculation.CalculationItem> Calculations { get; init; } | ||
| [System.Text.Json.Serialization.JsonPropertyName("$schema")] | ||
| public string Schema { get; } | ||
| } | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
CalculationSchema.Schema is getter-only — "$schema" field in JSON files will be silently dropped during deserialization.
Line 4682 shows public string Schema { get; } with no init or set. The [JsonPropertyName("$schema")] attribute enables writing the value, but System.Text.Json cannot populate a property without a setter/init during deserialization. If calculation.json files include a $schema field, it will be ignored without error, meaning round-trip fidelity is lost and schema validation logic (if any) won't see the value.
If Schema is intentionally a computed/constant property, this is fine — but if it's meant to capture the file's declared schema URI, an init accessor is needed.
🤖 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/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt`
around lines 4667 - 4684, `CalculationSchema.Schema` is currently getter-only,
so the `$schema` JSON value cannot be populated during deserialization. Update
`CalculationSchema` to allow `System.Text.Json` to bind this property by adding
an `init` or setter (while keeping the existing `JsonPropertyName("$schema")` on
`Schema`), and verify the public API contract in the
`CalculationSchema`/`CalculationItem` models remains consistent with JSON
round-tripping.




Improve testing test the full DataModelFieldCalculator.Calculate instead of the internal per element version.
Related Issue(s)
Summary by CodeRabbit