Skip to content

Conversation

@olavsorl
Copy link
Contributor

@olavsorl olavsorl commented Dec 5, 2025

Description

Extracted service logic from provider to service and client for reusability. Added regex pattern to match pattern decided in ADR for fetching Altinn 3 library code lists directly. Changed the options endpoint to support fetching Altinn 3 library code lists directly.

Also includes:

  • Changing the InstanceAppOptions endpoint to support fetching all the different kinds of AppOptions, so that we can get rid of the secure flag in layout. We will now try to fetch instance app options through provider, app options through provider and then Altinn 3 library app options directly in this order.
  • Improvements to AppOptionsFactory and InstanceAppOptionsFactory

Related Issue(s)

Verification

  • Your code builds clean without any errors or warnings
  • Manual testing done (required)
  • Relevant automated test added (if you find this hard, leave it and we'll help out)
  • All tests run green

Documentation

  • User documentation is updated with a separate linked PR in altinn-studio-docs. (if applicable)

Summary by CodeRabbit

  • New Features

    • Options endpoints support Altinn 3 library-reference identifiers; responses may include tags, version/source metadata and language-aware label/description/helpText; instance-scoped retrieval supports library refs.
  • Documentation

    • Added accepted ADR for Altinn 3 code-list approach; OpenAPI updated with parameter/response details and AppOption schema (including tags).
  • Public API

    • New service interface for Altinn3 library code lists; options APIs adjusted for nullable instance results and updated routes/parameters.
  • Tests

    • Expanded mapping, caching and error-path tests; removed obsolete null-provider tests.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 5, 2025

📝 Walkthrough

Walkthrough

Adds ADR and implements direct Altinn 3 library code-list support: new API client, service, provider, DI registrations, controller routing to accept library references, AppOption.tags model, OpenAPI updates, and extensive test additions/adjustments. No unrelated public signatures removed aside from options-related nullable changes.

Changes

Cohort / File(s) Summary
ADR
doc/adr/006-altinn-3-code-list.md
New ADR describing decision A1 and library-ref format for retrieving Altinn 3 code lists.
Options controller
src/Altinn.App.Api/Controllers/OptionsController.cs
Controller made public partial; constructor gains IAltinn3LibraryCodeListService; route param renamed to optionsIdOrLibraryRef; adds LibraryRefRegex; branches between existing provider and Altinn3 service; maps HttpRequestException to ProblemDetails.
DI registrations & extensions
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs, src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs
Removed previous IAppOptionsProvider registration, added AddHttpClient for IAltinn3LibraryCodeListApiClient, registered IAltinn3LibraryCodeListService, and updated Altinn3 provider construction to accept the service.
Altinn3 library implementation
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/*
New interface and implementations: IAltinn3LibraryCodeListApiClient, Altinn3LibraryCodeListApiClient, IAltinn3LibraryCodeListService, Altinn3LibraryCodeListService, Altinn3LibraryCodeListResponse. Includes HTTP calls, caching (HybridCache), MapAppOptions, language fallback, tag mapping, telemetry and error handling.
Altinn3 options provider
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cs
New Altinn3LibraryOptionsProvider : IAppOptionsProvider delegating to IAltinn3LibraryCodeListService.
Providers & factories
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs, src/Altinn.App.Core/Features/Options/InstanceAppOptionsFactory.cs, src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs
AppOptionsFactory now retains IServiceProvider and falls back to DefaultAppOptionsProvider(id, serviceProvider); InstanceAppOptionsFactory.GetOptionsProvider now nullable and may return null; DefaultAppOptionsProvider simplified (no cloning).
Service API surface
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs, src/Altinn.App.Core/Features/Options/AppOptionsService.cs
GetOptionsAsync overloads now return nullable Task<AppOptions?>; AppOptionsService updated to handle nullable instance providers and fixes a typo.
Models
src/Altinn.App.Core/Models/AppOption.cs, src/Altinn.App.Core/Models/AppOptions.cs
AppOption gains Tags: Dictionary<string,string>? with JSON attributes; minor AppOptions.Parameters initialization tweak.
OpenAPI / public API docs & snapshots
test/.../OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json, test/.../PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt, test/.../_snapshots/*
Paths/params renamed to optionsIdOrLibraryRef; AppOption schema added (includes tags); endpoint descriptions and ProblemDetails responses expanded.
Refactors / renames
src/.../Altinn3LibraryProvider/*src/.../Altinn3LibraryCodeList/*
Namespace/type renames and nullable adjustments for TagNames/Tags; files moved to Altinn3LibraryCodeList namespace.
DI/tests wiring & new tests
test/Altinn.App.Api.Tests/*, test/Altinn.App.Core.Tests/*
New tests added (Altinn3LibraryCodeListClientTests, Altinn3LibraryCodeListServiceTests); OptionsController tests extended with test doubles for IAltinn3LibraryCodeListService; many tests updated for DI wiring and assertions.
Removed tests/helpers
test/.../Altinn3LibraryOptionsProviderTests.cs, test/.../Altinn3LibraryOptionsProviderTestData.cs, test/.../NullInstanceAppOptionsProviderTests.cs, test/.../Altinn3LibraryOptionsProviderCacheTests.cs
Legacy test files and test-data helpers deleted or consolidated.
Minor test edits
test/Altinn.App.Api.Tests/Data/apps/.../FormLayout.json, test/Altinn.App.Api.Tests/Program.cs
EOF newline added and a comment typo fixed.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • ivarne

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.62% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and concisely summarizes the main change: enabling direct fetching of Altinn 3 library code lists without requiring provider configuration.
Linked Issues check ✅ Passed The pull request successfully implements all primary coding requirements from issue #1605: extracting service logic into reusable components, adding regex pattern for library code list detection, updating options endpoints for direct fetching, implementing improved resolution order for InstanceAppOptions, and enhancing AppOptionsFactory and InstanceAppOptionsFactory.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue objectives. Modifications to OptionsController, options services, factories, models, and test coverage all support the core feature of fetching Altinn 3 library code lists directly. Documentation updates (ADR and OpenAPI) and typo fixes align with the feature scope.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/new-way-of-fetching-library-code-lists

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.

@olavsorl olavsorl added the squad/data Issues that belongs to the named squad. label Dec 5, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (1)

30-35: Breaking change: Instance options now nullable.

The return type changed from Task<AppOptions> to Task<AppOptions?> for the instance-based overload. This breaking change aligns with the implementation where no instance-specific provider may be available, but requires consumers to handle null results.

According to retrieved learnings, the team accepts source compatibility without guaranteeing binary compatibility. Ensure this API change is documented in release notes with guidance on handling null returns.

test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)

3220-3265: Align options endpoint OpenAPI contract with described optionality of code list parameters

For the new route /{org}/{app}/api/options/{optionsIdOrCreatorOrg}/{codeListId}/{version} the OpenAPI snapshot marks both codeListId and version as required: true, but their descriptions imply conditional/optional usage:

  • codeListId: “Code list id, required if creatorOrg is provided”
  • version: “Code list version … defaults to latest if not provided”

Because these are path parameters on a single route template, OpenAPI (and generated clients) will treat them as always required; there is no way for a client to “not provide” them while still hitting this path. That makes the descriptions misleading.

Consider updating the controller/attribute definitions so that, after regeneration:

  • Either the descriptions clearly state that both codeListId and version are always required for this endpoint, or
  • The routing is split (e.g., separate route for legacy optionsId vs library code lists, or move version to an optional query parameter) so the OpenAPI required flags and descriptions are consistent.

Also check that the “creatorOrg” terminology in the descriptions matches the actual route parameter name optionsIdOrCreatorOrg to avoid confusion for API consumers.

Also applies to: 3267-3272

🧹 Nitpick comments (8)
test/Altinn.App.Api.Tests/Program.cs (1)

49-49: Typo fix in comment.

Spelling correction from "Allways" to "Always" — good catch.

test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (1)

3-3: Rename looks good; consider tightening visibility/sealing this test helper

The rename of the handler and its constructor to Altinn3LibraryCodeListClientMessageHandlerMock matches the new Altinn 3 code-list client naming and doesn’t change behavior. If this type is only consumed from within the test assembly and not via reflection, you could optionally align with the general guidelines by making it internal sealed:

-public class Altinn3LibraryCodeListClientMessageHandlerMock : DelegatingHandler
+internal sealed class Altinn3LibraryCodeListClientMessageHandlerMock : DelegatingHandler

Also applies to: 12-12

src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)

21-21: Consider making timeout configurable.

The 30-second timeout is hardcoded. For better flexibility, especially in testing or environments with varying network conditions, consider making this configurable through PlatformSettings.

src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (1)

1-1: Consider removing unused using directive.

The using directive for Altinn3LibraryProvider is added but doesn't appear to be used in this interface file. Consider removing it unless it's needed for future changes or XML documentation references.

-using Altinn.App.Core.Features.Options.Altinn3LibraryProvider;
 using Altinn.App.Core.Models;
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)

5-5: Consider adding sealed modifier.

Per coding guidelines, classes should be sealed unless inheritance is a valid use-case. Since this is an internal implementation detail, sealing it would be appropriate.

-internal class Altinn3LibraryOptionsProvider : IAppOptionsProvider
+internal sealed class Altinn3LibraryOptionsProvider : IAppOptionsProvider
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (1)

10-17: Consider adding CancellationToken parameter.

For async methods that may involve network calls (on cache miss), accepting a CancellationToken enables callers to cancel long-running requests. Based on learnings, adding optional parameters is acceptable in this codebase.

-Task<Altinn3LibraryCodeListResponse> GetCachedCodeListResponseAsync(string org, string codeListId, string? version);
+Task<Altinn3LibraryCodeListResponse> GetCachedCodeListResponseAsync(string org, string codeListId, string? version, CancellationToken cancellationToken = default);
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)

11-11: Consider making the class internal sealed.

Per coding guidelines, types should use internal accessibility by default, and classes should be sealed unless inheritance is a valid use-case. Since this service is resolved via DI through its interface, it doesn't need to be public.

-public class Altinn3LibraryCodeListService : IAltinn3LibraryCodeListService
+internal sealed class Altinn3LibraryCodeListService : IAltinn3LibraryCodeListService

34-54: Consider accepting CancellationToken parameter.

The method delegates to HybridCache.GetOrCreateAsync which provides a CancellationToken to the factory, but callers cannot cancel the overall operation. Consider adding a CancellationToken parameter:

 public async Task<Altinn3LibraryCodeListResponse> GetCachedCodeListResponseAsync(
     string org,
     string codeListId,
-    string? version
+    string? version,
+    CancellationToken cancellationToken = default
 )
 {
     version = !string.IsNullOrEmpty(version) ? version : "latest";
     var result = await _hybridCache.GetOrCreateAsync(
         $"Altinn3Library:{org}-{codeListId}-{version}",
         async ct =>
             await _altinn3LibraryCodeListApiClient.GetAltinn3LibraryCodeLists(
                 org,
                 codeListId,
                 version,
                 ct
             ),
-        options: _defaultCacheExpiration
+        options: _defaultCacheExpiration,
+        cancellationToken: cancellationToken
     );
     return result;
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd5ddb7 and e3aedc9.

📒 Files selected for processing (35)
  • doc/adr/006-altinn-3-code-list.md (1 hunks)
  • src/Altinn.App.Api/Controllers/OptionsController.cs (3 hunks)
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (2 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (2 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (2 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (2 hunks)
  • src/Altinn.App.Core/Features/Options/AppOptionsService.cs (3 hunks)
  • src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2 hunks)
  • src/Altinn.App.Core/Features/Options/InstanceAppOptionsFactory.cs (2 hunks)
  • src/Altinn.App.Core/Features/Options/NullInstanceAppOptionsProvider.cs (0 hunks)
  • src/Altinn.App.Core/Models/AppOption.cs (5 hunks)
  • src/Altinn.App.Core/Models/AppOptions.cs (1 hunks)
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (7 hunks)
  • test/Altinn.App.Api.Tests/Data/apps/tdd/eformidling-app/ui/layouts/FormLayout.json (1 hunks)
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2 hunks)
  • test/Altinn.App.Api.Tests/Program.cs (1 hunks)
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (2 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderCacheTests.cs (0 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderTestData.cs (0 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderTests.cs (0 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs (5 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs (2 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs (2 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/NullInstanceAppOptionsProviderTests.cs (0 hunks)
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (5 hunks)
💤 Files with no reviewable changes (5)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderCacheTests.cs
  • src/Altinn.App.Core/Features/Options/NullInstanceAppOptionsProvider.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderTestData.cs
  • test/Altinn.App.Core.Tests/Features/Options/NullInstanceAppOptionsProviderTests.cs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Api.Tests/Program.cs
  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • src/Altinn.App.Core/Features/Options/InstanceAppOptionsFactory.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs
  • src/Altinn.App.Core/Models/AppOption.cs
  • test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs
  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • src/Altinn.App.Core/Models/AppOptions.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs
  • src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • src/Altinn.App.Core/Features/Options/AppOptionsService.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Api.Tests/Program.cs
  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
🧠 Learnings (20)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Api.Tests/Program.cs
  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • src/Altinn.App.Core/Features/Options/InstanceAppOptionsFactory.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs
  • src/Altinn.App.Core/Models/AppOption.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs
  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • doc/adr/006-altinn-3-code-list.md
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • src/Altinn.App.Core/Models/AppOptions.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Api.Tests/Program.cs
  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • test/Altinn.App.Api.Tests/Program.cs
  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Api.Tests/Program.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-22T13:35:09.565Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Authentication_auth=OldUser.verified.txt:16-38
Timestamp: 2025-08-22T13:35:09.565Z
Learning: Test data in Altinn App Integration Tests snapshots (like SSNs, addresses, phone numbers in BasicAppTests.Authentication snapshots) are synthetic/fake values created for testing purposes, not real PII that needs to be scrubbed from version control.

Applied to files:

  • test/Altinn.App.Api.Tests/Program.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • test/Altinn.App.Api.Tests/Program.cs
  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Api.Tests/Program.cs
  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • test/Altinn.App.Api.Tests/Program.cs
  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which fully supports default interface methods.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which supports default interface methods.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Mock external dependencies with Moq in tests

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Prefer xUnit asserts over FluentAssertions in tests

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • doc/adr/006-altinn-3-code-list.md
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-21T09:04:43.977Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: src/Altinn.App.Core/Features/IInstanceDataAccessor.cs:36-41
Timestamp: 2025-09-21T09:04:43.977Z
Learning: The IInstanceDataAccessor interface in Altinn.App.Core is designed for consumption only - users are not expected to implement this interface themselves, only use framework-provided implementations.

Applied to files:

  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Register services in DI container properly following existing patterns

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Follow the AppFixture pattern for integration tests: Central orchestrator managing test lifecycle with feature-specific operations

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use Nullable Reference Types in C#

Applied to files:

  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (13)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
  • IAltinn3LibraryCodeListApiClient (60-61)
test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs (2)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
  • IAltinn3LibraryCodeListApiClient (60-61)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (2)
  • Altinn3LibraryCodeListApiClient (9-61)
  • Altinn3LibraryCodeListApiClient (14-24)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (3)
  • Altinn3LibraryCodeListResponse (8-34)
  • Altinn3LibraryCodeListItem (51-83)
  • Altinn3LibraryCodeListSource (39-46)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (3)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
  • AppOptions (57-93)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
  • AppOptions (230-255)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (1)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)
  • Func (9-20)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListResponse (8-34)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
  • Altinn3LibraryCodeListResponse (22-33)
  • Altinn3LibraryCodeListResponse (35-60)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
src/Altinn.App.Core/Configuration/PlatformSettings.cs (1)
  • PlatformSettings (7-74)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (5-10)
src/Altinn.App.Core/Helpers/JsonSerializerPermissive.cs (1)
  • JsonSerializerPermissive (10-48)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (3)
  • Task (34-54)
  • Altinn3LibraryCodeListService (11-124)
  • Altinn3LibraryCodeListService (24-31)
src/Altinn.App.Core/Configuration/PlatformSettings.cs (1)
  • PlatformSettings (7-74)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
  • Task (34-54)
  • AppOptions (57-93)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
  • Task (17-17)
  • AppOptions (25-25)
src/Altinn.App.Core/Features/Options/AppOptionsFileHandler.cs (1)
  • Task (30-44)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListItem (51-83)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (3)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
  • IAltinn3LibraryCodeListApiClient (60-61)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (2)
  • Altinn3LibraryCodeListApiClient (9-61)
  • Altinn3LibraryCodeListApiClient (14-24)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
  • Altinn3LibraryCodeListService (11-124)
  • Altinn3LibraryCodeListService (24-31)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (7)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
  • IAltinn3LibraryCodeListApiClient (60-61)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)
  • Task (33-37)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (1)
  • Task (17-25)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListResponse (8-34)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
  • Altinn3LibraryCodeListResponse (22-33)
  • Altinn3LibraryCodeListResponse (35-60)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
  • LanguageConst (3-8)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
  • Task (34-54)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
  • Task (26-60)
  • Altinn3LibraryCodeListApiClient (9-61)
  • Altinn3LibraryCodeListApiClient (14-24)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (5-10)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
  • Altinn3LibraryCodeListServiceTestData (7-61)
  • Func (9-20)
src/Altinn.App.Api/Controllers/OptionsController.cs (3)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
  • Task (34-54)
  • AppOptions (57-93)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
  • Task (17-17)
  • AppOptions (25-25)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md

[style] ~4-~4: Did you mean “that” or “date”?
Context: ...* Status: in progress * Deciders: Squad Data * Date: 2025-11-25 ## Result * Not co...

(DAT)


[grammar] ~10-~10: Ensure spelling is correct
Context: ... ## Result * Not concluded ## Problem context We want to be able to get code lists thr...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~26-~26: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~34-~34: Ensure spelling is correct
Context: ...list as root * B2: Simplify application layout * B3: Keep complexity low for developers *...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~36-~36: Ensure spelling is correct
Context: ...ptionId" parsed to org, codelist id and version * B5: Avoid the need to distinguish betwee...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~37-~37: Ensure spelling is correct
Context: ...guish between "secure": true/false in frontend * B6: Performance, consider parsing overhe...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~40-~40: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~76-~76: In American English, abbreviations like “etc.” require a period.
Context: ...ains special characters (hyphens, dots, etc), the delimiter choice becomes problema...

(ETC_PERIOD)


[grammar] ~99-~99: Ensure spelling is correct
Context: ...odeListId) should be in path, not query string ### A4: Modify existing path so that option...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~110-~110: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ## Decision rationale

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~112-~112: Ensure spelling is correct
Context: ...ormat optionsId should be. ## Decision rationale

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🔇 Additional comments (43)
test/Altinn.App.Api.Tests/Data/apps/tdd/eformidling-app/ui/layouts/FormLayout.json (1)

27-27: Test fixture formatting—trivial change.

Adding the end-of-file newline is a standard formatting practice for text files and carries no functional impact on this test data file.

test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs (2)

24-24: LGTM: Nullable return handling.

The change from BeOfType<NullInstanceAppOptionsProvider>() to Be(null) correctly reflects the refactored behavior where GetOptionsProvider now returns null instead of a null-object pattern implementation when no provider matches.


57-59: LGTM: Modern syntax.

Using target-typed new() expressions is idiomatic C# 9+ and improves readability.

src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (1)

13-14: LGTM: Improved documentation clarity.

The updated XML documentation better describes the provider's purpose and the relationship between the Id property and the JSON filename convention.

Also applies to: 22-22

test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs (4)

21-21: LGTM: Cleaner DI registration.

Using the non-generic AddSingleton overload is cleaner when you already have the instance.


34-34: LGTM: Simplified test setup.

Removing explicit DefaultAppOptionsProvider registration allows the tests to rely on the factory's default behavior, making them less brittle and more aligned with production usage.

Also applies to: 46-46


62-62: LGTM: More meaningful test case.

Changing the test to use "default" makes the test more explicit about verifying that the factory throws when the default provider is requested but not available.


125-126: LGTM: Modern syntax.

Target-typed new() expressions improve readability and follow C# 9+ conventions.

src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)

33-33: LGTM: Improved DTO robustness with proper null handling.

Making TagNames and Tags nullable is appropriate since these are optional grouping metadata that may not be present in all code-list responses. The consuming code in MapAppOptions correctly guards all property accesses with explicit null checks (is not null), and comprehensive test coverage validates all null scenarios including mismatches between TagNames count and Tags count.

test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (8)

1670-1670: LGTM: Tags made nullable on Altinn3LibraryCodeListItem.

Change aligns with optional tag presence from library. No action.
Based on learnings, snapshot files are verification artifacts.


1682-1682: LGTM: TagNames made nullable on Altinn3LibraryCodeListResponse.

Consistent with optional tag taxonomy.
Based on learnings, snapshot files are verification artifacts.


1686-1691: New public service surface for Altinn3 library code lists — confirm public exposure is intentional.

Interfaces and service added; ensure DI and release notes cover new APIs.
Based on learnings, snapshot files are verification artifacts.


1724-1724: Return type changed to AppOptions? — confirm nullable flow and docs.

Ensure all callers handle null and add a release-note entry since public API behavior changed.
Based on learnings, source compatibility changes are acceptable when documented.


1748-1749: IAppOptionsService now returns AppOptions? for instance overload — verify callers and release notes.

Please confirm null-handling at call sites and document in the changelog.
Based on learnings, source compatibility changes are acceptable when documented.


4056-4058: LGTM: AppOption gains nullable Tags with correct JSON behavior.

Omit-on-null is appropriate; no compatibility risk.
Based on learnings, snapshot files are verification artifacts.


1753-1754: Null handling already properly implemented — no action required.

The change to nullable return type in InstanceAppOptionsFactory.GetOptionsProvider() is already handled in the codebase. In AppOptionsService.cs, the only production usage includes a null check: if (appOptionsProvider != null) before dereferencing. No downstream issues found.

Likely an incorrect or invalid review comment.


1698-1706: Parameter nullability inconsistency between similar interface methods.

In the snapshot, IAltinn3LibraryCodeListApiClient.GetAltinn3LibraryCodeLists declares string version = null while IAltinn3LibraryCodeListService.GetCachedCodeListResponseAsync declares string? version. For consistency within the public API surface, both should use the same nullability annotation. If the parameter is intended to accept null, use string? version = null in both.

src/Altinn.App.Core/Models/AppOptions.cs (1)

18-18: LGTM! Target-typed new expression.

The change to use new() instead of new Dictionary<string, string?>() is a concise modernization that reduces verbosity while maintaining the same behavior.

src/Altinn.App.Core/Models/AppOption.cs (3)

46-52: LGTM! Tags property properly defined.

The Tags property is correctly defined with nullable type, appropriate JSON attributes, and clear documentation explaining its purpose for grouping with tagNames from library code lists.


94-134: LGTM! Tags deserialization correctly implemented.

The JSON converter properly handles the Tags property during deserialization with appropriate null handling and case-insensitive property matching.


211-215: LGTM! Tags serialization correctly implemented.

The serialization logic properly checks for null before writing the Tags property, consistent with the pattern used for other optional properties.

test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs (1)

57-62: LGTM! Test infrastructure updated for library code-list support.

The additions register the necessary services (IAltinn3LibraryCodeListApiClient and HybridCache) to support the new Altinn 3 library code-list integration path in tests. This aligns with the broader architectural changes in the PR.

src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (1)

340-343: LGTM! DI registrations follow established patterns.

The registrations for Altinn 3 library code-list services are correctly placed in the AddAppOptions method and follow the established DI patterns in this codebase:

  • Uses AddHttpClient for the API client to leverage HttpClientFactory
  • Uses TryAddTransient for the service to allow app-level overrides
  • Properly scoped within the options configuration section
src/Altinn.App.Core/Features/Options/AppOptionsService.cs (2)

10-10: LGTM! Typo fix.

Corrected the field name from _appOpptionsFactory to _appOptionsFactory, fixing a spelling error.

Also applies to: 23-23


40-55: The instance-based GetOptionsAsync method returns AppOptions? by design, not as a breaking change.

This method overload was already designed to return null when no instance-specific options provider is found (line 54). The nullable return type is intentional and consistent across the interface and implementation. The existing caller in OptionsController already handles this correctly using the null-conditional operator (appOptions?.Options). No action is required.

Likely an incorrect or invalid review comment.

src/Altinn.App.Core/Features/Options/InstanceAppOptionsFactory.cs (1)

26-40: The claim about removing NullInstanceAppOptionsProvider is incorrect. NullInstanceAppOptionsProvider does not exist in the codebase and never did. The nullable return type IInstanceAppOptionsProvider? appears to be the intended design, not a recent breaking change. Tests explicitly validate that GetOptionsProvider() returns null when no matching provider is found, confirming this is the expected behavior. Note that AppOptionsFactory.GetOptionsProvider() (a different class) returns non-nullable and provides a DefaultAppOptionsProvider fallback, while InstanceAppOptionsFactory is designed to return nullable by comparison.

Likely an incorrect or invalid review comment.

src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs (1)

93-100: Clean refactor using the new service abstraction.

The DI simplification from multiple infrastructure dependencies to a single IAltinn3LibraryCodeListService is appropriate and follows the Single Responsibility Principle. This aligns with the feature pattern guidance for DI registration.

src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)

33-37: Clean delegation to the code list service.

The implementation correctly delegates to the service for both fetching cached data and mapping to AppOptions. The unused keyValuePairs parameter is inherited from the IAppOptionsProvider interface contract.

src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (1)

5-26: Well-designed interface with clear responsibilities.

The separation between GetCachedCodeListResponseAsync (data fetching with caching) and MapAppOptions (transformation) follows single responsibility principle and makes testing easier.

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)

34-38: Good migration to xUnit asserts.

The assertion style now follows coding guidelines (preferring xUnit asserts over FluentAssertions).


170-198: Good test coverage for the new library code list path.

The test properly exercises the direct library code list retrieval path, validating both the response headers (Altinn-DownstreamParameters) and the JSON payload structure including tags support.

src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)

57-93: LGTM!

The mapping logic correctly handles the tag dictionary creation with proper count validation, applies language fallback for localized fields, and properly populates the AppOptions response with metadata parameters.


100-123: LGTM!

The language fallback logic is well-designed with a clear priority chain (requested → Nb → En → alphabetical first), and the [return: NotNullIfNotNull] attribute properly communicates nullability to callers.

test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)

11-27: Test structure looks good.

The test follows proper AAA pattern and uses xUnit asserts as per coding guidelines.

src/Altinn.App.Api/Controllers/OptionsController.cs (3)

62-81: Consider error handling for the library code-list path.

When codeListId is provided, GetCachedCodeListResponseAsync may throw (e.g., HttpRequestException for non-200 responses). Unlike the standard options path which returns NotFound() when options are null, the library path has no error handling—exceptions will propagate as 500 errors.

Consider adding try-catch or returning appropriate error responses:

 else
 {
     using var telemetry = _telemetry?.StartGetOptionsActivity();
+    try
+    {
         var altinn3LibraryCodeListResponse = await _altinn3LibraryCodeListService.GetCachedCodeListResponseAsync(
             optionsIdOrCreatorOrg,
             codeListId,
             version
         );
         appOptions = _altinn3LibraryCodeListService.MapAppOptions(altinn3LibraryCodeListResponse, language);
+    }
+    catch (HttpRequestException)
+    {
+        return NotFound();
+    }
 }

Alternatively, this behavior may be intentional to surface upstream errors—please confirm.


30-39: LGTM!

Constructor properly injects the new dependencies with appropriate nullability. The optional Telemetry? parameter follows the established pattern in the codebase.


53-59: Verify backward compatibility of route change.

The route changed from {optionsId} to {optionsIdOrCreatorOrg}/{codeListId?}/{version?}. While the optional segments should maintain compatibility for existing callers, please verify that clients using /{org}/{app}/api/options/{optionsId} continue to work correctly.

test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (6)

16-51: LGTM!

Good test design verifying that different cache keys result in separate HTTP calls. The use of separate scopes to simulate real-world DI behavior is appropriate.


53-81: LGTM!

Correctly verifies that the cache is hit on subsequent calls with identical parameters—only one HTTP call is made despite two invocations.


83-137: LGTM!

Good coverage of edge cases for empty and null language collections, correctly verifying the distinction between empty string and null returns.


139-233: LGTM!

Comprehensive coverage of language fallback scenarios: alphabetical first when no Nb/En, En fallback when only Nb is missing, and Nb as default. Tests verify the documented fallback chain.


265-407: LGTM!

Thorough testing of Tags mapping logic covering:

  • No TagNames present → null Tags
  • TagNames without Tags → null Tags
  • Mismatched counts → null Tags
  • Matching counts → properly mapped dictionary

This validates the defensive count-matching logic in MapAppOptions.


409-429: LGTM!

Fixture properly wires up DI with HybridCache, the mock HTTP handler, and required services. Clean implementation of IAsyncDisposable.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)

3-3: New library code list test and dummy service cover the new path well (with minor polish options)

The new Get_ShouldReturnLibraryOptionsDirectlyNotThroughProvider test plus DummyAltinn3LibraryCodeListService give good coverage of the Altinn3 library path, including downstream parameters and JSON payload (value/label/description/helpText/tags). A couple of minor, optional tweaks you might consider:

  • In MapAppOptions, use libraryCodeListResponse.Source / .Version rather than _codeListResponse for parameters to better mirror real behavior.
  • If the production MapAppOptions honors the language argument, you may want the dummy to respect it (with a sensible fallback) so tests stay aligned if language handling evolves.

Not blockers, but would make the dummy service closer to the real one.

Also applies to: 170-198, 201-255

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3aedc9 and 35ee12f.

📒 Files selected for processing (1)
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (7 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧠 Learnings (13)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use Nullable Reference Types in C#

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Mock external dependencies with Moq in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Prefer xUnit asserts over FluentAssertions in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which fully supports default interface methods.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which supports default interface methods.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧬 Code graph analysis (1)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (5)
test/Altinn.App.Core.Tests/Extensions/DictionaryExtensionsTests.cs (4)
  • Fact (9-23)
  • Fact (25-36)
  • Fact (38-49)
  • Fact (51-72)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
  • Task (17-17)
  • AppOptions (25-25)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
  • Task (34-54)
  • AppOptions (57-93)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListItem (51-83)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
🔇 Additional comments (2)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)

34-38: OK status and header content checks look good

The migration to Assert.Equal / Assert.Contains here is clear and directly asserts both HTTP status and the downstream parameters; no issues.


109-113: Status code and payload assertions across existing option endpoints are solid

The added xUnit assertions for non-default language behavior, file-source options, 404 for missing lists, and type-correct serialization all look consistent and precise; they validate both HTTP status and exact JSON payloads in line with existing patterns.

Also applies to: 126-130, 144-168

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (1)

20-34: Clarify XML doc to reflect nullable AppOptions return

The instance-based overload now returns Task<AppOptions?>, but the <returns> doc still implies a non-null list of options. That makes the contract unclear about when null is expected versus an AppOptions instance with Options == null.

Consider updating the doc to explicitly describe the null case (e.g., when no instance-specific provider exists for the given optionId) so callers understand the semantics and can handle it correctly.

Example:

     /// <param name="keyValuePairs">Optional list of key/value pairs to use for filtering and further lookup.</param>
-    /// <returns>The list of options</returns>
-    Task<AppOptions?> GetOptionsAsync(
+    /// <returns>
+    /// The list of options, or <see langword="null" /> if no instance-specific options are available
+    /// for the given <paramref name="instanceIdentifier" /> and <paramref name="optionId" />.
+    /// </returns>
+    Task<AppOptions?> GetOptionsAsync(
♻️ Duplicate comments (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)

3-21: Restrict interface to internal to match usage and guidelines

This interface appears to be used only inside Altinn.App.Core (implemented by an internal client and consumed by internal services/tests). Exposing it as public unnecessarily grows the public API surface and conflicts with the “use internal accessibility on types by default” guideline; DI works fine with internal interfaces.

Recommend changing the declaration to internal:

- public interface IAltinn3LibraryCodeListApiClient
+ internal interface IAltinn3LibraryCodeListApiClient

If the intent is to let apps implement this, then keep it public but clearly mark it as such (e.g., with the appropriate attribute and docs); otherwise, prefer internal.

src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (2)

40-43: Improve error handling with status code context.

The error message doesn't include the status code or response details, making debugging difficult.

Apply this diff to include status code:

             if (response.StatusCode != HttpStatusCode.OK)
             {
-                throw new HttpRequestException("Unexpected response from Altinn3Library");
+                throw new HttpRequestException(
+                    $"Unexpected response from Altinn3Library. Status: {response.StatusCode}"
+                );
             }

Alternatively, use response.EnsureSuccessStatusCode() for built-in status code handling.


36-38: Use Uri.EscapeDataString() to encode path parameters.

The org, codeListId, and version parameters are interpolated directly into the URL without encoding, which can lead to malformed URLs or potential security issues with special characters.

Apply this diff to encode the parameters:

             var response = await _httpClient.GetAsync(
-                $"{org}/code_lists/{codeListId}/{version}.json",
+                $"{Uri.EscapeDataString(org)}/code_lists/{Uri.EscapeDataString(codeListId)}/{Uri.EscapeDataString(version)}.json",
                 cancellationToken
             );
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)

86-89: Fix Assert.Contains usage - collection expression not valid as expected value.

The Assert.Contains<T>(T expected, IEnumerable<T> collection) overload expects a single expected value, not a collection expression. This will cause a compile-time error.

Apply this fix to assert each expected value individually:

-        Assert.Contains(
-            ["language=espa%C3%B1ol", "level=1", "variant=Sm%C3%A5viltjakt", "special=%2C%22.%25"],
-            splitHeader
-        );
+        Assert.Contains("language=espa%C3%B1ol", splitHeader);
+        Assert.Contains("level=1", splitHeader);
+        Assert.Contains("variant=Sm%C3%A5viltjakt", splitHeader);
+        Assert.Contains("special=%2C%22.%25", splitHeader);
🧹 Nitpick comments (3)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (2)

9-9: Consider sealing the class.

Per coding guidelines, classes should be sealed unless inheritance is a valid use-case. Since this is an internal implementation of an interface, sealing would prevent unintended inheritance.

Apply this diff:

-internal class Altinn3LibraryCodeListApiClient : IAltinn3LibraryCodeListApiClient
+internal sealed class Altinn3LibraryCodeListApiClient : IAltinn3LibraryCodeListApiClient

36-48: Dispose HttpResponseMessage to prevent resource leaks.

HttpResponseMessage implements IDisposable and should be disposed. Per coding guidelines, "Remember to dispose IDisposable/IAsyncDisposable instances."

Apply this diff to add proper disposal:

+            using var response = await _httpClient.GetAsync(
-            var response = await _httpClient.GetAsync(
                 $"{org}/code_lists/{codeListId}/{version}.json",
                 cancellationToken
             );
             if (response.StatusCode != HttpStatusCode.OK)
             {
                 throw new HttpRequestException("Unexpected response from Altinn3Library");
             }

             return await JsonSerializerPermissive.DeserializeAsync<Altinn3LibraryCodeListResponse>(
                 response.Content,
                 cancellationToken
             );
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)

230-255: Minor inconsistency in MapAppOptions implementation.

Lines 237-238 use the field _codeListResponse while lines 244-247 use the method parameter libraryCodeListResponse. While this works for this test double (same object), consider using the parameter consistently for clarity.

             Parameters = new()
             {
-                { "source", _codeListResponse.Source.Name },
-                { "version", _codeListResponse.Version },
+                { "source", libraryCodeListResponse.Source.Name },
+                { "version", libraryCodeListResponse.Version },
             },
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35ee12f and ff723d6.

📒 Files selected for processing (8)
  • src/Altinn.App.Api/Controllers/OptionsController.cs (4 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (1 hunks)
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (7 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
🧠 Learnings (19)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which supports default interface methods.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which fully supports default interface methods.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Mock external dependencies with Moq in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use Nullable Reference Types in C#

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Prefer xUnit asserts over FluentAssertions in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • src/Altinn.App.Core/Features/Options/IAppOptionsService.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use internal accessibility on types by default

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-09-21T09:04:43.977Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: src/Altinn.App.Core/Features/IInstanceDataAccessor.cs:36-41
Timestamp: 2025-09-21T09:04:43.977Z
Learning: The IInstanceDataAccessor interface in Altinn.App.Core is designed for consumption only - users are not expected to implement this interface themselves, only use framework-provided implementations.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
🧬 Code graph analysis (7)
src/Altinn.App.Api/Controllers/OptionsController.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-61)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
  • Task (17-17)
  • Task (29-34)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
  • Task (17-17)
  • AppOptions (25-25)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
  • Task (34-54)
  • AppOptions (57-93)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-61)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
  • Task (17-17)
  • AppOptions (25-25)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
  • Task (34-54)
  • AppOptions (57-93)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListItem (51-83)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (3)
  • Altinn3LibraryCodeListResponse (8-34)
  • Altinn3LibraryCodeListItem (51-83)
  • Altinn3LibraryCodeListSource (39-46)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (3)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
  • AppOptions (230-255)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
  • AppOptions (57-93)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (5)
src/Altinn.App.Core/Configuration/PlatformSettings.cs (1)
  • PlatformSettings (7-74)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (16-21)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)
  • Task (221-228)
  • Task (262-295)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
  • Altinn3LibraryCodeListResponse (22-33)
  • Altinn3LibraryCodeListResponse (35-60)
src/Altinn.App.Core/Helpers/JsonSerializerPermissive.cs (1)
  • JsonSerializerPermissive (10-48)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (6)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (5)
  • Fact (11-27)
  • Fact (29-56)
  • Fixture (63-76)
  • IAltinn3LibraryCodeListApiClient (60-61)
  • ValueTask (78-78)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
  • Task (27-61)
  • Altinn3LibraryCodeListApiClient (9-62)
  • Altinn3LibraryCodeListApiClient (14-24)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (16-21)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (3)
  • Task (34-54)
  • Altinn3LibraryCodeListService (11-124)
  • Altinn3LibraryCodeListService (24-31)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (3)
  • Task (17-25)
  • Altinn3LibraryCodeListClientMessageHandlerMock (3-26)
  • Altinn3LibraryCodeListClientMessageHandlerMock (12-15)
src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
  • LanguageConst (3-8)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (2)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
  • IAltinn3LibraryCodeListApiClient (60-61)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
  • Altinn3LibraryCodeListResponse (22-33)
  • Altinn3LibraryCodeListResponse (35-60)
🔇 Additional comments (9)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (2)

14-24: LGTM!

The constructor properly configures the HttpClient with BaseAddress and timeout, follows DI patterns, and uses strongly-typed configuration as per guidelines.


50-60: LGTM!

The exception handling properly logs context (CodeListId, Version, Org) for debugging while preserving the original exception by rethrowing.

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)

170-198: LGTM - New test for direct library code-list path.

The test correctly exercises the new route pattern /{org}/{app}/api/options/someCreatorOrg/someCodeListId/someVersion and verifies:

  • HTTP 200 status
  • Altinn-DownstreamParameters header content
  • JSON response structure with Tags support
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)

35-60: LGTM - Well-structured test data factory.

The parameterized factory method correctly handles the model's required vs. optional properties, with labels being non-nullable (matching the required Label property on Altinn3LibraryCodeListItem) while descriptions, helpTexts, tagNames, and tags are appropriately nullable.

src/Altinn.App.Api/Controllers/OptionsController.cs (2)

53-60: Route design note: Potential ambiguity between optionId and creator org.

The route pattern uses optionsIdOrCreatorOrg to serve dual purposes. If a configured optionId happens to match an organization identifier, the endpoint could behave unexpectedly. This is a design trade-off that appears intentional and is documented in the remarks.

Consider documenting this constraint in user-facing documentation to ensure developers don't configure option IDs that could conflict with organization names.


119-131: LGTM - Consistent pattern with first overload.

The use of var and the null check pattern are consistent with the updated first overload.

test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (3)

16-51: LGTM - Good caching behavior test.

The test correctly verifies that requests with different cache keys result in separate HTTP calls, while using scoped service resolution to ensure proper DI behavior.


83-137: LGTM - Good edge case coverage for empty/null language collections.

These tests properly verify the behavior when language collections are empty versus null, ensuring the mapping logic handles both cases gracefully.


265-407: LGTM - Comprehensive Tags mapping test coverage.

The tests thoroughly cover the Tags mapping logic including:

  • No TagNames present → null Tags
  • TagNames but no Tags → null Tags
  • Mismatched counts → null Tags
  • Matching counts → proper dictionary mapping

This aligns well with the production code's defensive check: code.Tags.Count == libraryCodeListResponse.TagNames.Count.

@olavsorl olavsorl added feature Label Pull requests with new features. Used when generation releasenotes backport-ignore This PR is a new feature and should not be cherry-picked onto release branches labels Dec 5, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)

48-50: Fix typo in exception message.

The exception message contains a typo: "configures" should be "configured".

Apply this diff:

-            "No app options provider found in the configured services. Please check your services configuration."
+            "No app options provider found in the configured services. Please check your services configuration."
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)

68-81: Register PlatformSettings options in the test fixture so the typed client can be resolved

The Altinn3LibraryCodeListApiClient constructor depends on IOptions<PlatformSettings>, but Fixture.Create only calls AddHttpClient and never registers PlatformSettings. This will cause DI resolution of IAltinn3LibraryCodeListApiClient to fail when the tests run.

You can fix this by configuring PlatformSettings in the test ServiceCollection before building the provider, e.g.:

         {
             var mockHandler = new Altinn3LibraryCodeListClientMessageHandlerMock(responseMessage);
             var serviceCollection = new ServiceCollection();
+            serviceCollection.Configure<PlatformSettings>(options =>
+            {
+                options.Altinn3LibraryApiEndpoint = "https://test.example.com/";
+            });
             serviceCollection
                 .AddHttpClient<IAltinn3LibraryCodeListApiClient, Altinn3LibraryCodeListApiClient>()
                 .ConfigurePrimaryHttpMessageHandler(() => mockHandler);
             configure?.Invoke(serviceCollection);

This keeps the fixture self-contained and aligned with how the client is constructed in production.

🧹 Nitpick comments (7)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)

9-9: Consider marking class as sealed.

According to the coding guidelines, classes should be sealed by default unless inheritance is a valid use-case. Since AppOptionsFactory is a factory class with no apparent need for inheritance, marking it as sealed would align with project conventions and enable compiler optimizations.

Apply this diff:

-public class AppOptionsFactory
+public sealed class AppOptionsFactory
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)

41-61: Consider limiting or sanitizing logged/exception content from upstream responses and user-influenced fields

The flow and error handling look solid, but for non-OK responses you currently:

  • Read the entire response body into content and embed it in the HttpRequestException message, and
  • Immediately log that exception together with org, codeListId, and version, which all ultimately come from request input.

Depending on log retention and where logs are shipped, this can leak larger payloads or user-related identifiers into logs. Consider truncating the response body before including it in the exception/logs, or logging only the status code plus a small snippet/diagnostic ID while keeping full content out of structured logs. This keeps diagnostics useful while reducing log volume and potential data-exposure surface.

test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)

11-27: Optional: strengthen the happy-path assertion to validate deserialized content

The success test currently only asserts that the result is non-null. Since you already use Altinn3LibraryCodeListServiceTestData.GetNbEnResponseMessage(), you could optionally assert on a known property (e.g., number of entries, specific code) or even compare against the expected Altinn3LibraryCodeListResponse instance from the same test data. This would catch subtle deserialization regressions, not just total failures.

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)

178-206: Make library options header assertion order‑insensitive

Get_ShouldReturnLibraryOptionsDirectlyNotThroughProvider currently asserts the entire downstream-parameters header string equals "source=test-name,version=1", which bakes in the iteration order of the parameters dictionary. To keep the test resilient to future changes in how that header is built (or the insertion order of Parameters), assert presence of both fragments instead of exact ordering.

Suggested refactor:

-        Assert.Equal(
-            "source=test-name,version=1",
-            string.Join(",", response.Headers.Single(x => x.Key == "Altinn-DownstreamParameters").Value)
-        );
+        var downstreamHeader = response.Headers
+            .Single(x => x.Key == "Altinn-DownstreamParameters")
+            .Value
+            .Single();
+        var downstreamParameters = downstreamHeader.Split(',');
+
+        Assert.Contains("source=test-name", downstreamParameters);
+        Assert.Contains("version=1", downstreamParameters);
+        Assert.Equal(2, downstreamParameters.Length);

This keeps the behavior check intact while avoiding brittle coupling to ordering.


209-265: Scope dummy Altinn3 library service to tests and use method parameter

Two small test-only cleanups:

  1. Limit visibility and inheritance
    This type is only used in tests, so it doesn’t need to be public or inheritable. Aligning with the guideline “use internal and sealed by default” makes the intent clearer.

  2. Use the libraryCodeListResponse argument for parameters
    MapAppOptions currently reads Source and Version from the private _codeListResponse field, even though it receives libraryCodeListResponse as an argument. Using the parameter more clearly expresses that mapping is based on the provided response instance.

Proposed diff:

-public class DummyAltinn3LibraryCodeListService : IAltinn3LibraryCodeListService
+internal sealed class DummyAltinn3LibraryCodeListService : IAltinn3LibraryCodeListService
 {
@@
-        return new AppOptions()
+        return new AppOptions()
         {
             Parameters = new()
             {
-                { "source", _codeListResponse.Source.Name },
-                { "version", _codeListResponse.Version },
+                { "source", libraryCodeListResponse.Source.Name },
+                { "version", libraryCodeListResponse.Version },
             },

This keeps behavior the same for the current tests but tightens encapsulation and makes the mapping logic more straightforward.

As per coding guidelines.

src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (2)

9-26: Constructor wiring looks good; consider null‑guarding the service dependency.

The constructor correctly validates optionId, org, and codeListId, sets Id, and normalizes version to "latest", which matches the new library code‑list behavior. One small robustness tweak would be to also guard altinn3LibraryCodeListService against null (e.g., ArgumentNullException.ThrowIfNull(...)) so misuse is caught early even outside DI.


33-37: Clarify intentional ignoring of keyValuePairs in GetAppOptionsAsync.

GetAppOptionsAsync doesn’t use keyValuePairs at all, which is probably fine if library code lists don’t support query‑based filtering. It might be worth a short XML doc comment or inline comment either here or on the interface to make it explicit that this provider ignores keyValuePairs, so future readers don’t assume it’s an oversight.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff723d6 and 38a349a.

📒 Files selected for processing (11)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (2 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (2 hunks)
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (7 hunks)
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (3 hunks)
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (2 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1 hunks)
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
🧠 Learnings (18)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Mock external dependencies with Moq in tests

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use Nullable Reference Types in C#

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Prefer xUnit asserts over FluentAssertions in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which fully supports default interface methods.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which supports default interface methods.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-21T09:04:43.977Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: src/Altinn.App.Core/Features/IInstanceDataAccessor.cs:36-41
Timestamp: 2025-09-21T09:04:43.977Z
Learning: The IInstanceDataAccessor interface in Altinn.App.Core is designed for consumption only - users are not expected to implement this interface themselves, only use framework-provided implementations.

Applied to files:

  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (6)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (1)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)
  • Func (9-20)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
src/Altinn.App.Core/Configuration/PlatformSettings.cs (1)
  • PlatformSettings (7-74)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
  • Task (34-51)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (16-21)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-65)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
  • Task (18-23)
  • AppOptions (31-31)
src/Altinn.App.Core/Features/Options/AppOptionsFileHandler.cs (1)
  • Task (30-44)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListItem (51-83)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (2)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
  • IAppOptionsProvider (30-51)
src/Altinn.App.Core/Internal/Linq/Extensions.cs (1)
  • IsNullOrEmpty (21-24)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (2)
  • DefaultAppOptionsProvider (7-35)
  • DefaultAppOptionsProvider (16-19)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
  • Task (27-65)
  • Altinn3LibraryCodeListApiClient (9-66)
  • Altinn3LibraryCodeListApiClient (14-24)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
  • Task (34-51)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (3)
  • Task (17-25)
  • Altinn3LibraryCodeListClientMessageHandlerMock (3-26)
  • Altinn3LibraryCodeListClientMessageHandlerMock (12-15)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (16-21)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Static code analysis
🔇 Additional comments (8)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (2)

12-14: LGTM!

The field declarations follow C# conventions and coding guidelines correctly.


19-23: LGTM!

The constructor correctly follows DI patterns and uses GetRequiredService for fail-fast behavior if dependencies are missing.

test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (1)

3-25: Handler mock looks solid and test-focused

The mock DelegatingHandler is simple, thread-safe (via Interlocked.Increment), and provides exactly the hooks tests need (CallCount, LastRequestUri) without extra complexity. This is a good fit for exercising the client behavior.

test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)

1-5119: Skipping snapshot file per repo policy.

This is a generated Public API snapshot (*.verified.txt). No code review feedback on snapshots. Based on learnings, ...

src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)

33-51: Caching and version normalization look solid

GetCachedCodeListResponseAsync correctly normalizes version to "latest", uses a stable cache key, and wires the CancellationToken through to both the cache and underlying client. No changes needed.


54-120: Robust mapping and language fallback

MapAppOptions and GetValueWithLanguageFallback handle nullable Description/HelpText/Tags, mismatched tag lengths, and language fallbacks cleanly. The fallback order (requested → nben → first key) is implemented as documented and should be resilient to partial localization.

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)

18-176: xUnit migration and existing options tests look correct

The conversions from FluentAssertions to xUnit (Assert.Equal, Assert.Contains, Assert.DoesNotContain) preserve the original intent across the options tests, and the added failure message in Get_ShouldReturnParametersInHeaderWithSpecialChars gives useful diagnostics if the status code isn’t OK. Header extraction and splitting logic correctly validates URL-encoded parameter values.

test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)

3220-3325: Check consistency between required path params and textual semantics for codeListId/version.

codeListId and version are modeled as required path parameters, but the descriptions say “required if creator org is provided” and “defaults to latest if not provided”. For client generators and API consumers this can be confusing if the runtime route actually treats them as optional/conditional. Please double‑check that the controller route attributes and OpenAPI annotations match the intended behavior (e.g., separate routes, optional segments, or clear “always required” docs) and re‑generate the snapshot if needed.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)

35-50: Make "default" provider check case-insensitive to avoid subtle behavior changes

Provider lookup uses StringComparison.OrdinalIgnoreCase, but the default-provider check uses a case-sensitive !=. For an optionsId like "Default" with no registered provider, this will now be treated as a non-default and fall back to a DefaultAppOptionsProvider with Id = "Default" (which may break on case-sensitive filesystems).

Consider aligning with the rest of the factory by comparing case-insensitively:

-        if (optionsId != DefaultProviderName)
+        if (!string.Equals(optionsId, DefaultProviderName, StringComparison.OrdinalIgnoreCase))
         {
             return new DefaultAppOptionsProvider(_serviceProvider) { Id = optionsId };
         }

This preserves previous behavior and avoids surprising differences between "default" and "Default".

♻️ Duplicate comments (1)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)

65-77: Register IOptions<PlatformSettings> in the fixture so the client can be resolved

The Altinn3LibraryCodeListApiClient constructor depends on IOptions<PlatformSettings> for Altinn3LibraryApiEndpoint. The fixture builds a fresh ServiceCollection but never registers PlatformSettings, so resolving the client will fail at runtime.

Register a minimal configuration for PlatformSettings in Fixture.Create (and add the necessary using):

-using System.Net;
-using Altinn.App.Core.Features.Options.Altinn3LibraryProvider;
+using System.Net;
+using Altinn.App.Core.Configuration;
+using Altinn.App.Core.Features.Options.Altinn3LibraryProvider;
@@
         {
             var mockHandler = new Altinn3LibraryCodeListClientMessageHandlerMock(responseMessage);
             var serviceCollection = new ServiceCollection();
+            serviceCollection.Configure<PlatformSettings>(options =>
+            {
+                options.Altinn3LibraryApiEndpoint = "https://altinn3-library.test/";
+            });
             serviceCollection
                 .AddHttpClient<IAltinn3LibraryCodeListApiClient, Altinn3LibraryCodeListApiClient>()
                 .ConfigurePrimaryHttpMessageHandler(() => mockHandler);
             configure?.Invoke(serviceCollection);

This satisfies the constructor dependency and keeps the tests self-contained.

🧹 Nitpick comments (2)
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (2)

1697-1700: Caching semantics for code lists

IAltinn3LibraryCodeListService exposes GetCachedCodeListResponseAsync(version nullable). Please verify cache key composition (org, codeListId, version/null), TTL/eviction, and invalidation when source changes. Consider background refresh/ETag if available.


82-82: Altinn3LibraryApiEndpoint configuration

PlatformSettings.Altinn3LibraryApiEndpoint added. Confirm validation (non-empty, well-formed URI, trailing slash handling), env overrides, and that AddHttpClient uses this with sane timeouts and resiliency (retry/backoff as appropriate).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 38a349a and a2e447c.

📒 Files selected for processing (6)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (2 hunks)
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (7 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1 hunks)
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (6 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧠 Learnings (18)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Prefer xUnit asserts over FluentAssertions in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Mock external dependencies with Moq in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use Nullable Reference Types in C#

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which fully supports default interface methods.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which supports default interface methods.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-21T09:04:43.977Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: src/Altinn.App.Core/Features/IInstanceDataAccessor.cs:36-41
Timestamp: 2025-09-21T09:04:43.977Z
Learning: The IInstanceDataAccessor interface in Altinn.App.Core is designed for consumption only - users are not expected to implement this interface themselves, only use framework-provided implementations.

Applied to files:

  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (4)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (2)
  • DefaultAppOptionsProvider (7-35)
  • DefaultAppOptionsProvider (16-19)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
  • Task (18-23)
  • AppOptions (31-31)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
  • Task (34-51)
  • AppOptions (54-90)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (6)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (2)
  • Fixture (413-426)
  • ValueTask (428-428)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
  • Task (27-64)
  • Altinn3LibraryCodeListApiClient (9-65)
  • Altinn3LibraryCodeListApiClient (14-24)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (16-21)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
  • Task (34-51)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (3)
  • Task (17-25)
  • Altinn3LibraryCodeListClientMessageHandlerMock (3-26)
  • Altinn3LibraryCodeListClientMessageHandlerMock (12-15)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
  • Altinn3LibraryCodeListServiceTestData (7-61)
  • Func (9-20)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-64)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
  • Task (18-23)
  • AppOptions (31-31)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
  • Task (34-51)
  • AppOptions (54-90)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Static code analysis
🔇 Additional comments (10)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (2)

5-8: Thin, internal sealed provider design looks good

Keeping Altinn3LibraryOptionsProvider internal sealed and delegating responsibilities to IAltinn3LibraryCodeListService matches the feature-folder + DI pattern and keeps this type small and focused. Based on coding guidelines, this is a good direction.


31-37: Delegation to IAltinn3LibraryCodeListService keeps provider logic minimal

Passing _version through as nullable and letting GetCachedCodeListResponseAsync normalize it, then mapping via MapAppOptions, keeps GetAppOptionsAsync very small and pushes caching + mapping concerns into the shared service. This is a clean separation and fits well with the new library code-list architecture.

test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (5)

1718-1718: Nullability change: GetOptionsAsync may return null

AppOptionsService/IAppOptionsService now return AppOptions? for instance overload. Verify all call sites and the OptionsController map null to the intended HTTP status (404 vs 200 empty), and add release notes for this source-visible change. Based on learnings, maintainers accept source (re)compile requirements but expect documentation.

Also applies to: 1739-1743


1747-1747: Nullable provider path introduced

InstanceAppOptionsFactory.GetOptionsProvider returns IInstanceAppOptionsProvider?. Confirm all consumers handle null (no NullInstanceAppOptionsProvider). Add tests for null path through AppOptionsService.


1692-1695: New Altinn3 library API client surface

IAltinn3LibraryCodeListApiClient added. Confirm HttpClient configuration (base address, default headers, timeouts) and that CancellationToken is threaded through implementations and controller paths.


1670-1670: Tags/TagNames → AppOption.Tags mapping

Altinn3LibraryCodeListItem.Tags and Altinn3LibraryCodeListResponse.TagNames are now nullable and AppOption gains Tags: Dictionary<string,string>?. Verify mapping rules when TagNames or item Tags are null/empty, key collisions, and that serialization matches API docs. Ensure language fallback for labels/description remains intact.

Also applies to: 1682-1682, 4050-4052


1704-1706: Sealing AppOptionsFactory

Sealed class looks fine; confirm no downstream inheritance relied on this type. If any, document in release notes.

src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)

14-24: Altinn3LibraryCodeListApiClient implementation looks solid

HTTP client configuration, URL encoding of path segments, error handling, permissive JSON deserialization, and sanitized logging are all consistent and correct. No changes needed here.

Also applies to: 27-63

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)

178-207: New Altinn3 library options test and dummy service are well-aligned with production behavior

The Get_ShouldReturnLibraryOptionsDirectlyNotThroughProvider test and DummyAltinn3LibraryCodeListService mirror the real Altinn3LibraryCodeListService shape (parameters source/version, tag mapping, and option fields), giving good coverage of the new route without over-complicating the test wiring. This looks good and follows the feature-folder/testing patterns used elsewhere.

Also applies to: 211-266

test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)

21-23: No changes needed. The IAltinn3LibraryCodeListApiClient.GetAltinn3LibraryCodeLists method defines CancellationToken cancellationToken = default, making the parameter optional. Test calls with three arguments compile successfully and use the default cancellation token value.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (1)
doc/adr/006-altinn-3-code-list.md (1)

1-127: Complete the ADR before merging.

The ADR remains marked as "in progress" with "Not concluded" status and an empty "Decision rationale" section. Based on the PR implementation (new OptionsController endpoint at {creatorOrg}/{codeListId}), it appears Alternative A5 was chosen, but this decision and rationale must be documented in the ADR before merging.

Please update:

  • Status (line 3) to "accepted" or "decided"
  • Result (line 8) to reflect the chosen alternative (A5)
  • Decision rationale section (lines 126+) with reasoning for selecting A5
🧹 Nitpick comments (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)

39-43: Consider adding CancellationToken support to enable request cancellation.

The GetAppOptionsAsync method performs async operations (caching and HTTP calls) but doesn't accept or propagate a CancellationToken. While the IAppOptionsProvider interface may not currently define this parameter, adding optional CancellationToken support would allow callers to cancel long-running operations when the client disconnects.

If the interface allows adding an optional parameter (per the learning that maintainers accept source-compatible changes), consider:

-    public async Task<AppOptions> GetAppOptionsAsync(string? language, Dictionary<string, string> keyValuePairs)
+    public async Task<AppOptions> GetAppOptionsAsync(string? language, Dictionary<string, string> keyValuePairs, CancellationToken cancellationToken = default)
     {
-        var result = await _altinn3LibraryCodeListService.GetCachedCodeListResponseAsync(_org, _codeListId, _version);
+        var result = await _altinn3LibraryCodeListService.GetCachedCodeListResponseAsync(_org, _codeListId, _version, cancellationToken);
         return _altinn3LibraryCodeListService.MapAppOptions(result, language);
     }

Based on learnings, adding optional parameters to existing methods is acceptable provided release notes document the change.

test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2)

3326-3333: Public docs shouldn’t mention Program.cs.

Replace implementation detail with neutral phrasing.

-            "description": "The optionsId configured for the provider in Program.cs",
+            "description": "The optionsId configured for the options provider in the app startup."

3349-3349: Language description nit and consistency.

Use “e.g., nb” and align phrasing across all endpoints to a single template (ISO 639‑1).

-            "description": "The language selected by the user, ISO 639-1 (eg. nb)",
+            "description": "The language selected by the user (ISO 639-1, e.g., 'nb')."

If desired, I can grep and align all “language” param descriptions repo‑wide.

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)

242-267: Consider documenting divergence from production implementation or reusing the real service.

The MapAppOptions implementation here is a simplified version that differs from the production Altinn3LibraryCodeListService:

  • Only processes the first code item (line 244) vs. iterating all codes
  • Hardcodes "nb" language (lines 257-259) vs. using GetValueWithLanguageFallback
  • Simplified tags logic vs. the more robust production implementation

While simplification in test helpers is acceptable, the divergence could mask issues if the production implementation changes.

Consider:

  • Adding a comment documenting that this is a simplified test implementation
  • Or, injecting and delegating to the real MapAppOptions logic to ensure test coverage matches production behavior
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a2e447c and 7994096.

📒 Files selected for processing (9)
  • doc/adr/006-altinn-3-code-list.md (1 hunks)
  • src/Altinn.App.Api/Controllers/OptionsController.cs (4 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1 hunks)
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (7 hunks)
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (3 hunks)
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1 hunks)
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧠 Learnings (20)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Prefer xUnit asserts over FluentAssertions in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Mock external dependencies with Moq in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use Nullable Reference Types in C#

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which fully supports default interface methods.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which supports default interface methods.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use internal accessibility on types by default

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-09-21T09:04:43.977Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: src/Altinn.App.Core/Features/IInstanceDataAccessor.cs:36-41
Timestamp: 2025-09-21T09:04:43.977Z
Learning: The IInstanceDataAccessor interface in Altinn.App.Core is designed for consumption only - users are not expected to implement this interface themselves, only use framework-provided implementations.

Applied to files:

  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (3)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-64)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
  • Task (18-23)
  • AppOptions (31-31)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
  • Task (34-51)
  • AppOptions (54-90)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListItem (51-83)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-64)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
  • Task (34-51)
  • AppOptions (54-90)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
src/Altinn.App.Api/Controllers/OptionsController.cs (6)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-64)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (1)
  • Task (18-23)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
  • Task (17-17)
  • Task (29-34)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
  • Task (34-51)
src/Altinn.App.Core/Features/Options/AppOptionsFileHandler.cs (1)
  • Task (30-44)
src/Altinn.App.Core/Extensions/DictionaryExtensions.cs (1)
  • ToUrlEncodedNameValueString (14-35)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md

[style] ~4-~4: Did you mean “that” or “date”?
Context: ...* Status: in progress * Deciders: Squad Data * Date: 2025-11-25 ## Result * Not co...

(DAT)


[uncategorized] ~45-~45: The abbreviation “e.g.” (= for example) requires two periods.
Context: ...st id and version. Formatting creator org, codelist id and version into the opt...

(E_G)


[style] ~77-~77: In American English, abbreviations like “etc.” require a period.
Context: ...ains special characters (hyphens, dots, etc), the delimiter choice becomes problema...

(ETC_PERIOD)


[misspelling] ~98-~98: This word is normally spelled as one.
Context: ...ntic distinction via source parameter. * Supports B3; no custom parsing of "optionId" ...

(EN_COMPOUNDS_ANTI_PATTERN)


[uncategorized] ~116-~116: The verb “is” doesn’t seem to fit in this context, “are” is probably more formally correct.
Context: ...structures. * Poor discoverability, API consumers can't tell from the OpenAPI/Sw...

(AI_HYDRA_LEO_CPT_IS_ARE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Static code analysis
🔇 Additional comments (6)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)

1-22: LGTM! Interface follows coding guidelines.

The interface is appropriately scoped as internal, has clear XML documentation, and the method signature properly includes a CancellationToken with a default value. This aligns with the coding guideline to use internal accessibility by default.

src/Altinn.App.Api/Controllers/OptionsController.cs (1)

20-39: LGTM! Constructor properly wired for dependency injection.

The constructor correctly initializes the new dependencies, with Telemetry appropriately marked as optional. The DI container will ensure required services are non-null.

src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)

5-7: Good refactoring! Class properly sealed and dependencies simplified.

The class is correctly marked sealed per coding guidelines, and the refactoring to use a single IAltinn3LibraryCodeListService dependency instead of multiple services improves maintainability.

test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)

1-10: Skip review: Public API snapshot file

This is a .verified.txt snapshot; we don’t review or suggest edits here. Please just confirm the public API changes captured are intentional and documented (e.g., newly nullable return types, new Altinn3 code-list interfaces). As per coding guidelines, treat this as verification-only. Based on learnings, *.verified.txt files are snapshots and should be ignored for review content.

test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2)

3374-3403: Good addition of 404 with ProblemDetails.

Improves client error handling consistency for options.


3220-3316: New library code-list endpoint looks good; tighten param docs.

  • creatorOrg/codeListId are required by route; drop conditional phrasing on codeListId.
  • Clarify “version” accepted formats (e.g., semver, date, specific label) and keep default “latest”.
  • Standardize language description (see separate nit).

Apply wording tweaks:

-            "description": "Code list id, required if creator org is provided",
+            "description": "The code list identifier.",
...
-            "description": "Code list version, only used in combination with creator org and code list id, defaults to latest if not provided",
+            "description": "Code list version. Defaults to 'latest' if omitted. Specify exact format accepted (e.g., semver, date, or label)."
⛔ Skipped due to learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (2)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)

3318-3404: Good cleanup and error surface; align contract and keep consistent language.

  • Wording no longer leaks internal “AppOption” and language description is now consistent. 404 with ProblemDetails added — good.
  • Consider adding a 200 content schema (and a shared OptionsItem schema) so the “Tags” note maps to an explicit field; otherwise, rephrase to avoid referring to fields not defined in the spec. You can reuse the same schema across both options endpoints.
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)

178-209: Remove commented-out test or track in an issue.

The commented-out test with the TODO referencing an ADR decision reduces maintainability. Either complete and enable the test if the ADR is resolved, remove the commented code, or create a tracked issue for later implementation.

Would you like me to open a new issue to track this test implementation?

🧹 Nitpick comments (2)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)

3220-3316: New library code list endpoint: tighten wording and specify 200 schema.

  • codeListId description says “required if creator org is provided,” but both are required path params. Simplify.
  • version description can drop “only used in combination with …” (already implied by the route).
  • Unify language phrasing with the other endpoint (“ISO 639‑1, e.g., 'nb'”).
  • 200 response has no schema while the description references a Tags field. Either define a concrete response schema (recommended) or reword to avoid implying fields not present in the contract.

Proposed minimal diff to fix text consistency:

         {
           "name": "codeListId",
           "in": "path",
-          "description": "Code list id, required if creator org is provided",
+          "description": "The code list identifier.",
           "required": true,
           "schema": { "type": "string" }
         },
         {
           "name": "version",
           "in": "query",
-          "description": "Code list version, only used in combination with creator org and code list id, defaults to latest if not provided",
+          "description": "Code list version; defaults to 'latest' if not provided.",
           "schema": { "type": "string", "default": "latest" }
         },
         {
           "name": "language",
           "in": "query",
-          "description": "The language selected by the user, ISO 639-1 (eg. nb)",
+          "description": "The language selected by the user (ISO 639-1, e.g., 'nb').",
           "schema": { "type": "string" }
         }

Optional (recommended): add a concrete 200 response schema used by both options endpoints, e.g.:

       "responses": {
         "200": {
-          "description": "OK"
+          "description": "OK",
+          "content": {
+            "application/json": {
+              "schema": {
+                "type": "array",
+                "items": { "$ref": "#/components/schemas/OptionsItem" }
+              }
+            }
+          }
         },

…and define components.schemas.OptionsItem (including an optional “tags” array) so the “Tags” remark is unambiguous.

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)

262-267: Simplify redundant null-safety operators in test code.

Lines 265 use TagNames?.First()! and Tags?.First()! after already verifying both collections have Count > 0 on line 262. The null-conditional operator (?.) and null-forgiving operator (!) are redundant since the pattern-match guard ensures the collections are non-null and non-empty.

Apply this diff for cleaner test code:

 Tags =
     libraryCodeListResponse.TagNames is { Count: > 0 } && responseOptionOne.Tags is { Count: > 0 }
         ? new Dictionary<string, string>
         {
-            { libraryCodeListResponse.TagNames?.First()!, responseOptionOne.Tags?.First()! },
+            { libraryCodeListResponse.TagNames.First(), responseOptionOne.Tags.First() },
         }
         : null,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7994096 and 0675633.

📒 Files selected for processing (4)
  • doc/adr/006-altinn-3-code-list.md (1 hunks)
  • src/Altinn.App.Api/Controllers/OptionsController.cs (4 hunks)
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (7 hunks)
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧠 Learnings (17)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Prefer xUnit asserts over FluentAssertions in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Mock external dependencies with Moq in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use Nullable Reference Types in C#

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which fully supports default interface methods.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which supports default interface methods.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
🧬 Code graph analysis (1)
src/Altinn.App.Api/Controllers/OptionsController.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (16-21)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-64)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
  • Task (34-51)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
  • Task (17-17)
  • Task (29-34)
src/Altinn.App.Core/Extensions/DictionaryExtensions.cs (1)
  • ToUrlEncodedNameValueString (14-35)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md

[style] ~4-~4: Did you mean “that” or “date”?
Context: ...* Status: in progress * Deciders: Squad Data * Date: 2025-11-25 ## Result * Not co...

(DAT)


[uncategorized] ~41-~41: The abbreviation “e.g.” (= for example) requires two periods.
Context: ...st id and version. Formatting creator org, codelist id and version into the opt...

(E_G)


[style] ~73-~73: In American English, abbreviations like “etc.” require a period.
Context: ...ains special characters (hyphens, dots, etc), the delimiter choice becomes problema...

(ETC_PERIOD)


[misspelling] ~94-~94: This word is normally spelled as one.
Context: ...ntic distinction via source parameter. * Supports B3; no custom parsing of "optionId" ...

(EN_COMPOUNDS_ANTI_PATTERN)


[uncategorized] ~112-~112: The verb “is” doesn’t seem to fit in this context, “are” is probably more formally correct.
Context: ...structures. * Poor discoverability, API consumers can't tell from the OpenAPI/Sw...

(AI_HYDRA_LEO_CPT_IS_ARE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Static code analysis
🔇 Additional comments (4)
src/Altinn.App.Api/Controllers/OptionsController.cs (2)

3-5: LGTM! Dependency injection follows established patterns.

The new dependencies (IAltinn3LibraryCodeListService and Telemetry) are properly injected and stored. The optional Telemetry parameter with default null is appropriate for graceful degradation.

Also applies to: 20-39


78-107: LGTM! Existing endpoints maintain proper null checks.

The refactoring to use var is appropriate, and the null checks for appOptions?.Options are properly maintained.

Also applies to: 125-157

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)

34-37: LGTM! Test assertions properly migrated to xUnit.

The refactoring from FluentAssertions to xUnit assertions follows the coding guidelines and maintains test correctness. The header parsing logic (lines 82-96) with split and individual Contains assertions is appropriate for order-insensitive validation.

Based on coding guidelines, which specify: "Prefer xUnit asserts over FluentAssertions in tests."

Also applies to: 76-97, 117-120, 134-138, 152-152, 171-176


212-272: LGTM! Test service properly implements test interface.

The DummyAltinn3LibraryCodeListService provides appropriate test data and demonstrates correct nullable property handling for Description and HelpText (lines 259-260). The hardcoded response structure supports controller testing without external dependencies.

@olavsorl
Copy link
Contributor Author

olavsorl commented Dec 8, 2025

Actionable comments posted: 3

♻️ Duplicate comments (2)

test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)> 3318-3404: Good cleanup and error surface; align contract and keep consistent language.

  • Wording no longer leaks internal “AppOption” and language description is now consistent. 404 with ProblemDetails added — good.
  • Consider adding a 200 content schema (and a shared OptionsItem schema) so the “Tags” note maps to an explicit field; otherwise, rephrase to avoid referring to fields not defined in the spec. You can reuse the same schema across both options endpoints.

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)> 178-209: Remove commented-out test or track in an issue.

The commented-out test with the TODO referencing an ADR decision reduces maintainability. Either complete and enable the test if the ADR is resolved, remove the commented code, or create a tracked issue for later implementation.
Would you like me to open a new issue to track this test implementation?

🧹 Nitpick comments (2)

test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)> 3220-3316: New library code list endpoint: tighten wording and specify 200 schema.

  • codeListId description says “required if creator org is provided,” but both are required path params. Simplify.
  • version description can drop “only used in combination with …” (already implied by the route).
  • Unify language phrasing with the other endpoint (“ISO 639‑1, e.g., 'nb'”).
  • 200 response has no schema while the description references a Tags field. Either define a concrete response schema (recommended) or reword to avoid implying fields not present in the contract.

Proposed minimal diff to fix text consistency:

         {
           "name": "codeListId",
           "in": "path",
-          "description": "Code list id, required if creator org is provided",
+          "description": "The code list identifier.",
           "required": true,
           "schema": { "type": "string" }
         },
         {
           "name": "version",
           "in": "query",
-          "description": "Code list version, only used in combination with creator org and code list id, defaults to latest if not provided",
+          "description": "Code list version; defaults to 'latest' if not provided.",
           "schema": { "type": "string", "default": "latest" }
         },
         {
           "name": "language",
           "in": "query",
-          "description": "The language selected by the user, ISO 639-1 (eg. nb)",
+          "description": "The language selected by the user (ISO 639-1, e.g., 'nb').",
           "schema": { "type": "string" }
         }

Optional (recommended): add a concrete 200 response schema used by both options endpoints, e.g.:

       "responses": {
         "200": {
-          "description": "OK"
+          "description": "OK",
+          "content": {
+            "application/json": {
+              "schema": {
+                "type": "array",
+                "items": { "$ref": "#/components/schemas/OptionsItem" }
+              }
+            }
+          }
         },

…and define components.schemas.OptionsItem (including an optional “tags” array) so the “Tags” remark is unambiguous.

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)> 262-267: Simplify redundant null-safety operators in test code.

Lines 265 use TagNames?.First()! and Tags?.First()! after already verifying both collections have Count > 0 on line 262. The null-conditional operator (?.) and null-forgiving operator (!) are redundant since the pattern-match guard ensures the collections are non-null and non-empty.
Apply this diff for cleaner test code:

 Tags =
     libraryCodeListResponse.TagNames is { Count: > 0 } && responseOptionOne.Tags is { Count: > 0 }
         ? new Dictionary<string, string>
         {
-            { libraryCodeListResponse.TagNames?.First()!, responseOptionOne.Tags?.First()! },
+            { libraryCodeListResponse.TagNames.First(), responseOptionOne.Tags.First() },
         }
         : null,

📜 Review details

@olavsorl Fix nitpick comment after ADR decision is made

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
doc/adr/006-altinn-3-code-list.md (1)

3-8: ADR remains incomplete - please finalize before merging.

The ADR status is still "in progress" with "Not concluded" result, and the Decision rationale section at line 110 is empty. The implementation in OptionsController.cs uses Alternative A5 (new endpoint /{creatorOrg}/{codeListId}). Please update:

  1. Status → "accepted"
  2. Result → "A5: Add a new controller method"
  3. Decision rationale section with reasoning for choosing A5
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)

178-209: Commented-out test should be addressed with ADR completion.

This test scaffold is tied to the ADR decision. Once the ADR is finalized (as noted in the first file's review), either enable and complete this test or remove it and track in a separate issue.

🧹 Nitpick comments (1)
doc/adr/006-altinn-3-code-list.md (1)

85-88: Minor grammar fix needed.

Static analysis flagged "anti pattern" as a compound word that should be hyphenated.

-  * Supports B3; no custom parsing of "optionId" will help maintain a lower anti-pattern complexity.
+  * Supports B3; no custom parsing of "optionId" will help maintain lower complexity.

Note: The phrase "anti-pattern complexity" is unclear - consider rewording to clarify the intended meaning.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0675633 and e15538e.

📒 Files selected for processing (3)
  • doc/adr/006-altinn-3-code-list.md (1 hunks)
  • src/Altinn.App.Api/Controllers/OptionsController.cs (4 hunks)
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (7 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧠 Learnings (17)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • doc/adr/006-altinn-3-code-list.md
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • doc/adr/006-altinn-3-code-list.md
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which supports default interface methods.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which fully supports default interface methods.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Prefer xUnit asserts over FluentAssertions in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Mock external dependencies with Moq in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use Nullable Reference Types in C#

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧬 Code graph analysis (1)
src/Altinn.App.Api/Controllers/OptionsController.cs (7)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (16-21)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)
  • Task (39-43)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (1)
  • Task (18-23)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
  • Task (34-51)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-64)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
  • Task (17-17)
  • Task (29-34)
src/Altinn.App.Core/Extensions/DictionaryExtensions.cs (1)
  • ToUrlEncodedNameValueString (14-35)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md

[style] ~4-~4: Did you mean “that” or “date”?
Context: ...* Status: in progress * Deciders: Squad Data * Date: 2025-11-25 ## Result * Not co...

(DAT)


[misspelling] ~81-~81: This word is normally spelled as one.
Context: ...on will be required. ### A3: Modify existing path with new query parameters * Pros * Cle...

(EN_COMPOUNDS_ANTI_PATTERN)


[misspelling] ~85-~85: This word is normally spelled as one.
Context: ...inction via source parameter. * Supports B3; no custom parsing of "optionId" will help mai...

(EN_COMPOUNDS_ANTI_PATTERN)


[uncategorized] ~100-~100: The verb “is” doesn’t seem to fit in this context, “are” is probably more formally correct.
Context: ...structures. * Poor discoverability, API consumers can't tell from the OpenAPI/Sw...

(AI_HYDRA_LEO_CPT_IS_ARE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Static code analysis
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (8)
src/Altinn.App.Api/Controllers/OptionsController.cs (4)

20-22: LGTM on new dependency injections.

The new fields for Telemetry? and IAltinn3LibraryCodeListService follow established patterns. The optional Telemetry? parameter with default null is consistent with how telemetry is handled elsewhere in the codebase.


30-39: Constructor properly wired for DI.

The constructor correctly initializes all dependencies, with Telemetry? as an optional parameter following the established pattern in this codebase.


52-80: New library code-list endpoint implementation looks correct.

The implementation:

  • Uses proper route differentiation ({creatorOrg}/{codeListId} vs {optionsId})
  • Passes HttpContext.RequestAborted for cancellation support
  • Includes null check before accessing appOptions.Parameters
  • Follows the established pattern for downstream parameter headers

92-111: Existing endpoint unchanged, correctly preserves behavior.

The existing options endpoint at {optionsId} maintains its current behavior. The use of var for appOptions and the null check pattern are consistent with the new endpoint.

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (4)

34-37: Test assertion correctly updated to xUnit style.

The test now uses Assert.Equal and Assert.Contains with proper header value extraction via .Single(). This aligns with the coding guidelines preferring xUnit asserts over FluentAssertions.


76-97: Header validation logic correctly implemented.

The test properly validates URL-encoded header values by splitting and checking each expected value. The approach correctly handles order-independent verification of comma-separated values.


119-120: Language assertion correctly strengthened.

The test now properly verifies that lang=nb is not present in the header value using DoesNotContain with case-insensitive comparison, addressing the previous review feedback.


212-271: Test fake implementation follows best practices.

The DummyAltinn3LibraryCodeListService:

  • Uses internal sealed class per coding guidelines
  • Properly handles nullable Description? and HelpText? with null-conditional operators
  • Guards against empty TagNames/Tags collections using pattern matching (is { Count: > 0 })
  • Returns Task.FromResult appropriately for synchronous test data

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cs (1)

9-26: Add null-guard for altinn3LibraryCodeListService (fail fast).
This avoids a later NRE if constructed manually in tests or miswired DI.

 public Altinn3LibraryOptionsProvider(
     string optionId,
     string org,
     string codeListId,
     string? version,
     IAltinn3LibraryCodeListService altinn3LibraryCodeListService
 )
 {
     ArgumentException.ThrowIfNullOrWhiteSpace(optionId);
     ArgumentException.ThrowIfNullOrWhiteSpace(org);
     ArgumentException.ThrowIfNullOrWhiteSpace(codeListId);
+    ArgumentNullException.ThrowIfNull(altinn3LibraryCodeListService);

     Id = optionId;
     _org = org;
     _codeListId = codeListId;
     _version = version;
     _altinn3LibraryCodeListService = altinn3LibraryCodeListService;
 }
doc/adr/006-altinn-3-code-list.md (1)

3-10: ADR is internally inconsistent (A1 vs lib**... format) — align Result + rationale with the actual implemented contract.
Right now A1 is selected, but the “format” described in the rationale doesn’t match A1’s own description (and A5 is listed but not chosen). Please update the ADR so Result, rationale, and examples all describe the same approach.

Also applies to: 39-45, 52-53, 111-116

🧹 Nitpick comments (9)
doc/adr/006-altinn-3-code-list.md (1)

16-19: Fix typos/grammar to avoid ambiguity in the final decision doc.
Examples: “endpoints … takes” → “endpoints … take”, “formated” → “formatted”, “doesnt” → “doesn’t”, “optionsId … that consisting” → “that consists”.

Also applies to: 64-66, 78-81, 109-116

src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (1)

6-21: Consider renaming GetAltinn3LibraryCodeLists → singular to match returned value.
It returns one Altinn3LibraryCodeListResponse, so a singular name reads clearer.

src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (2)

14-24: Validate Altinn3LibraryApiEndpoint (fail fast on invalid URI) to avoid late runtime surprises.
Right now new Uri(platformSettings.Value.Altinn3LibraryApiEndpoint) will throw at runtime if misconfigured; consider a clearer exception message (or a TryCreate + throw with context).


36-52: Consider including (bounded) response body in non-200 errors for debuggability.
Status code alone can be thin when diagnosing blob/CDN errors; if you add body, cap length and sanitize to avoid log/exception injection.

src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs (1)

8-32: Confirm intended audience: should this interface be public (and ImplementableByApps) or internal?
If apps are not expected to implement it, making it internal reduces public API surface; if apps are expected to implement it, consider marking it with ImplementableByApps per guidelines.

test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)

11-58: Tests cover the key behaviors (success + non-200 + logging).
Optional hardening: also assert the outgoing LastRequestUri from Altinn3LibraryCodeListClientMessageHandlerMock to lock down path/escaping behavior.

src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (2)

92-120: GetValueWithLanguageFallback: returning "" for empty dictionaries is a bit odd—consider returning null (or document why empty-string is desired).
Today, an empty dictionary is treated differently than null, which may leak into API output as empty strings.


16-51: Use consistent cache key delimiter (: instead of -).

The cache key should use colons to separate components, following standard caching conventions:

-            $"Altinn3Library:{org}-{codeListId}-{version}",
+            $"Altinn3Library:{org}:{codeListId}:{version}",
src/Altinn.App.Api/Controllers/OptionsController.cs (1)

123-154: (Optional) Confirm intended language defaulting behavior when instance endpoint falls back to non-instance/library paths.
The instance endpoint defaults language to nb for the instance provider call, but in the fallback it passes language as-is (potentially null) to non-instance/library resolution. If the intent is “instance route always defaults to nb”, you probably want to consistently use language ?? LanguageConst.Nb in the fallback too.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e15538e and dc3737b.

📒 Files selected for processing (18)
  • doc/adr/006-altinn-3-code-list.md (1 hunks)
  • src/Altinn.App.Api/Controllers/OptionsController.cs (4 hunks)
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (2 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (3 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs (1 hunks)
  • src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs (2 hunks)
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (8 hunks)
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (6 hunks)
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs (2 hunks)
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
  • src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧠 Learnings (20)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • doc/adr/006-altinn-3-code-list.md
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Register services in DI container properly following existing patterns

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • doc/adr/006-altinn-3-code-list.md
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which fully supports default interface methods.

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which supports default interface methods.

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Prefer xUnit asserts over FluentAssertions in tests

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Mock external dependencies with Moq in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use Nullable Reference Types in C#

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-21T09:04:43.977Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: src/Altinn.App.Core/Features/IInstanceDataAccessor.cs:36-41
Timestamp: 2025-09-21T09:04:43.977Z
Learning: The IInstanceDataAccessor interface in Altinn.App.Core is designed for consumption only - users are not expected to implement this interface themselves, only use framework-provided implementations.

Applied to files:

  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (8)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListResponse (8-34)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
  • Altinn3LibraryCodeListResponse (22-33)
  • Altinn3LibraryCodeListResponse (35-60)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (3)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
  • IAltinn3LibraryCodeListApiClient (62-63)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListResponse (8-34)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
  • Altinn3LibraryCodeListResponse (22-33)
  • Altinn3LibraryCodeListResponse (35-60)
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (2)
  • Altinn3LibraryCodeListApiClient (9-65)
  • Altinn3LibraryCodeListApiClient (14-24)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (2)
  • Altinn3LibraryCodeListService (11-121)
  • Altinn3LibraryCodeListService (24-31)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (6)
src/Altinn.App.Core/Configuration/PlatformSettings.cs (1)
  • PlatformSettings (7-74)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (1)
  • Task (34-51)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (16-21)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListResponse (8-34)
src/Altinn.App.Core/Helpers/JsonSerializerPermissive.cs (1)
  • JsonSerializerPermissive (10-48)
src/Altinn.App.Core/Helpers/LogSanitizer.cs (2)
  • LogSanitizer (9-45)
  • Sanitize (22-38)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-64)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (2)
  • Task (34-51)
  • AppOptions (54-90)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (16-21)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs (2)
  • Task (18-23)
  • AppOptions (31-31)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)
  • Altinn3LibraryOptionsProvider (13-151)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (3)
  • Altinn3LibraryCodeListResponse (8-34)
  • Altinn3LibraryCodeListItem (51-83)
  • Altinn3LibraryCodeListSource (39-46)
src/Altinn.App.Api/Controllers/OptionsController.cs (7)
src/Altinn.App.Api/Controllers/DataController.cs (9)
  • Task (213-408)
  • Task (422-452)
  • Task (462-467)
  • Task (895-917)
  • Task (919-923)
  • Task (931-996)
  • Task (998-1060)
  • Task (1062-1145)
  • Task (1163-1218)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
  • Task (17-17)
  • Task (29-34)
src/Altinn.App.Core/Features/Options/AppOptionsFileHandler.cs (1)
  • Task (30-44)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (1)
  • AppOptions (54-90)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs (1)
  • AppOptions (31-31)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
  • LanguageConst (3-8)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (8)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (10)
  • Fact (16-51)
  • Fact (53-81)
  • Fact (83-110)
  • Fact (112-137)
  • Fact (139-175)
  • Fact (177-209)
  • Fact (211-233)
  • Fact (235-263)
  • Fact (265-292)
  • Fact (294-326)
test/Altinn.App.Api.Tests/Data/TestData.cs (1)
  • PrepareInstance (147-174)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (1)
  • AppOptions (54-90)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
src/Altinn.App.Core/Models/AppOption.cs (1)
  • AppOption (88-135)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
  • IAppOptionsProvider (30-51)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (2)
  • Altinn3LibraryCodeListResponse (8-34)
  • Altinn3LibraryCodeListItem (51-83)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
  • Altinn3LibraryCodeListResponse (22-33)
  • Altinn3LibraryCodeListResponse (35-60)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md

[style] ~4-~4: Did you mean “that” or “date”?
Context: ...s * Status: Accepted * Deciders: Squad Data * Date: 2025-11-25 ## Result A1: Use...

(DAT)


[grammar] ~11-~11: Ensure spelling is correct
Context: ...g path without modifying it ## Problem context We want to be able to get code lists thr...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~23-~23: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~31-~31: Ensure spelling is correct
Context: ...list as root * B2: Simplify application layout * B3: Keep complexity low for developers *...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~33-~33: Ensure spelling is correct
Context: ...ptionId" parsed to org, codelist id and version * B5: Avoid the need to distinguish betwee...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~34-~34: Ensure spelling is correct
Context: ...guish between "secure": true/false in frontend * B6: Performance, consider parsing overhe...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~37-~37: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~89-~89: Ensure spelling is correct
Context: ...odeListId) should be in path, not query string ### A4: Modify existing path so that option...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~101-~101: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ### A5: Add a new controlle...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~111-~111: Ensure spelling is correct
Context: ...g we initially didnt want. ## Decision rationale To ease the implementation process for t...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Static code analysis
🔇 Additional comments (8)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)

3-34: Good: relaxed JSON shape by making TagNames/Tags optional, but ensure downstream never assumes non-null.
The nullable change is sensible for deserialization tolerance; just keep guarding any TagNames/Tags usage (especially count/indexing).

Also applies to: 82-83

src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (1)

13-14: DI wiring for library code lists looks correct and follows existing patterns.
Typed HttpClient + service registration is straightforward and should compose well with the rest of options infrastructure. Based on learnings, follows established feature/DI pattern.

Also applies to: 340-343

test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)

9-20: LGTM: clean test helper for building a 200 JSON response.


22-60: LGTM: sample data covers nb/en and optional tag fields without violating required Label.

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (3)

35-39: Good: assert status code before consuming headers for clearer failures.


77-99: Good: stronger diagnostics for special-char header failures + order-insensitive assertions.


179-266: Good: controller-level library-ref coverage verifies service invocation + downstream parameter header.

Also applies to: 537-578

test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)

1-5125: Skip: verification snapshot file

This is a *.verified.txt public API snapshot; changes here are expected outputs of API changes elsewhere and shouldn’t be reviewed/suggested on directly. Based on learnings, ignore for code review.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d185ae5 and 182dd2e.

📒 Files selected for processing (1)
  • doc/adr/006-altinn-3-code-list.md (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • doc/adr/006-altinn-3-code-list.md
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md

[style] ~4-~4: Did you mean “that” or “date”?
Context: ...s * Status: Accepted * Deciders: Squad Data * Date: 2025-11-25 ## Result A1: Use...

(DAT)


[grammar] ~11-~11: Ensure spelling is correct
Context: ...g path without modifying it ## Problem context We want to be able to get code lists thr...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~24-~24: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~32-~32: Ensure spelling is correct
Context: ...ptionId" parsed to org, codelist id and version * B3: Performance, consider parsing overhe...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~35-~35: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~78-~78: Ensure spelling is correct
Context: ...ger complains about required parameters missing * Route ambiguity, /options/something coul...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~88-~88: Ensure spelling is correct
Context: ...e list id) should be in path, not query string ### A4: Modify existing path so that option...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~100-~100: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ### A5: Add a new endpoint ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~112-~112: Ensure spelling is correct
Context: ...g we initially didnt want. ## Decision rationale To ease the implementation process for t...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Static code analysis
  • GitHub Check: Analyze (csharp)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/Altinn.App.Api/Controllers/OptionsController.cs (1)

1-186: LGTM - excellent implementation of library code-list integration.

The implementation demonstrates strong code quality:

  • ✅ Proper error handling with HttpRequestException catching and ProblemDetails responses
  • ✅ Null safety checks before accessing appOptions.Options and Parameters
  • ✅ Cancellation token propagation via HttpContext.RequestAborted
  • ✅ Well-anchored regex pattern with named capture groups
  • ✅ Comprehensive XML documentation and ProducesResponseType attributes
  • ✅ Correct three-tier lookup order for instance endpoint (instance → app → library)
  • ✅ Follows C# best practices: async/await, no blocking calls, nullable reference types

All past review concerns have been thoroughly addressed.

Optional documentation clarification:

Lines 44 and 109 mention "(version=latest, if you want the latest version)" — consider clarifying whether "latest" is a literal string value supported by the API or just an example. The current phrasing is slightly ambiguous, though functionally correct since the downstream service handles version resolution.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 182dd2e and 87837de.

📒 Files selected for processing (3)
  • doc/adr/006-altinn-3-code-list.md (1 hunks)
  • src/Altinn.App.Api/Controllers/DataListsController.cs (1 hunks)
  • src/Altinn.App.Api/Controllers/OptionsController.cs (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Api/Controllers/DataListsController.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
🧠 Learnings (10)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • src/Altinn.App.Api/Controllers/DataListsController.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • doc/adr/006-altinn-3-code-list.md
🧬 Code graph analysis (1)
src/Altinn.App.Api/Controllers/OptionsController.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs (3)
  • Task (19-25)
  • Task (35-40)
  • AppOptions (48-48)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (3)
  • Task (37-48)
  • Task (51-68)
  • AppOptions (71-113)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-64)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
  • LanguageConst (3-8)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md

[style] ~4-~4: Did you mean “that” or “date”?
Context: ...s * Status: Accepted * Deciders: Squad Data * Date: 2025-11-25 ## Result A1: Use...

(DAT)


[grammar] ~11-~11: Ensure spelling is correct
Context: ...g path without modifying it ## Problem context We want to be able to get code lists thr...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~24-~24: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~32-~32: Ensure spelling is correct
Context: ...ptionId" parsed to org, codelist id and version * B3: Performance, consider parsing overhe...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~35-~35: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~78-~78: Ensure spelling is correct
Context: ...ger complains about required parameters missing * Route ambiguity, /options/something coul...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~88-~88: Ensure spelling is correct
Context: ...e list id) should be in path, not query string ### A4: Modify existing path so that option...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~100-~100: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ### A5: Add a new endpoint ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~112-~112: Ensure spelling is correct
Context: ... we initially didn't want. ## Decision rationale To ease the implementation process for t...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Static code analysis
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
🔇 Additional comments (2)
doc/adr/006-altinn-3-code-list.md (1)

1-117: ADR is complete and well-documented.

The ADR has been properly updated with "Accepted" status, clearly specifies the chosen alternative (A1), and includes a complete decision rationale. The format specification is consistent throughout the document, and the pros/cons analysis provides good context for the architectural decision.

src/Altinn.App.Api/Controllers/DataListsController.cs (1)

30-30: LGTM - documentation correction.

The typo fix improves the XML documentation quality.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
doc/adr/006-altinn-3-code-list.md (1)

112-117: Strengthen the decision rationale with explicit tradeoff justification.

The decision rationale now states that A1 was chosen to ease implementation, but it doesn't explain why A1 was preferred over the simpler alternatives A2 and A5—both of which claim to support all three decision drivers (B1, B2, B3).

Given A1's documented cons (lines 59–64: increased complexity, string parsing difficulty, format conflicts, lack of framework validation), the rationale should clarify:

  1. Why A1's implementation burden on the backend was justified
  2. How the documented parsing and format-conflict risks will be mitigated (e.g., via documentation, regex validation, or future enhancements)
  3. Why A2 (cleaner path structure) or A5 (dedicated endpoint) were not selected despite their support for all drivers

Suggested revision:

 ## Decision rationale

-To ease the implementation process for the consumers/clients, we have chosen A1.
+We chose A1 to reuse the existing options endpoint and avoid introducing a new API surface, 
+supporting B1 (keep complexity low for developers). Although A1 requires string parsing 
+and careful format handling, the constraint to library references only (detected via regex 
+prefix "lib") minimizes collision risk with existing optionIds. A2 and A5 offer cleaner 
+semantics but would require more migration effort and endpoint management. We mitigate A1's 
+parsing complexity through documented format rules and regex-based validation.
 The format for Altinn 3 library code list optionIds is:

 `lib**{creatorOrg}**{codeListId}**{version}`
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad95517 and 9a048d0.

📒 Files selected for processing (3)
  • doc/adr/006-altinn-3-code-list.md (1 hunks)
  • test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txt (2 hunks)
  • test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt (2 hunks)
🧰 Additional context used
🧠 Learnings (10)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • 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
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txt
  • doc/adr/006-altinn-3-code-list.md
  • test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txt
  • doc/adr/006-altinn-3-code-list.md
  • test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt
📚 Learning: 2025-09-18T10:23:05.995Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json:7263-0
Timestamp: 2025-09-18T10:23:05.995Z
Learning: In PR #1357, ApplicationMetadata.apiScopes (now ApiScopesConfiguration) is currently unused at runtime; the schema change is acceptable without a transition mechanism for now.

Applied to files:

  • 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
📚 Learning: 2025-08-22T13:35:09.565Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Authentication_auth=OldUser.verified.txt:16-38
Timestamp: 2025-08-22T13:35:09.565Z
Learning: Test data in Altinn App Integration Tests snapshots (like SSNs, addresses, phone numbers in BasicAppTests.Authentication snapshots) are synthetic/fake values created for testing purposes, not real PII that needs to be scrubbed from version control.

Applied to files:

  • 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
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • 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
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md

[style] ~4-~4: Did you mean “that” or “date”?
Context: ...s * Status: Accepted * Deciders: Squad Data * Date: 2025-12-09 ## Result A1: Use...

(DAT)


[grammar] ~11-~11: Ensure spelling is correct
Context: ...g path without modifying it ## Problem context We want to be able to get Altinn 3 libra...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~24-~24: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~32-~32: Ensure spelling is correct
Context: ...tionId" parsed to org, code list id and version * B3: Performance, consider parsing overhe...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~35-~35: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~78-~78: Ensure spelling is correct
Context: ...ger complains about required parameters missing * Route ambiguity, /options/something coul...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~88-~88: Ensure spelling is correct
Context: ...e list id) should be in path, not query string ### A4: Modify existing path so that option...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~100-~100: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ### A5: Add a new endpoint ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~112-~112: Ensure spelling is correct
Context: ... we initially didn't want. ## Decision rationale To ease the implementation process for t...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🔇 Additional comments (2)
test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txt (1)

276-276: Snapshot verification file — skipping substantive review.

This is a *.verified.txt snapshot file capturing endpoint metadata. Per established learnings, verification snapshots are auto-managed test artifacts and are not subject to code review suggestions. The parameter name changes align with the PR's library-code-list feature. Build/test will validate snapshot consistency.

Also applies to: 565-565

test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt (1)

251-251: Snapshot verification file — skipping substantive review.

This is a *.verified.txt snapshot file capturing endpoint metadata. Per established learnings, verification snapshots are auto-managed test artifacts and are not subject to code review suggestions. The parameter name changes align with the PR's library-code-list feature. Build/test will validate snapshot consistency.

Also applies to: 485-485

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2)

3220-3425: Options endpoints: contract updates and AppOption usage look solid (minor wording nit only)

The two options endpoints now:

  • Use optionsIdOrLibraryRef with a clear library ref format description.
  • Return AppOption[] for all 200 content types.
  • Consistently describe language as “ISO 639‑1, e.g., 'nb'”.
  • Expose structured ProblemDetails payloads for 400/404/500/502, in line with other endpoints.

This addresses the earlier contract concerns around response schemas and error handling.

Very minor, optional nit: the queryParams description string differs slightly between the two options endpoints ("Query parameters supplied." vs "Query parameters supplied"). If you care about strict text consistency in the spec, consider aligning the wording/punctuation.

Also applies to: 3427-3653


7340-7372: AppOption schema aligns with options responses; consider adding a brief description

The new AppOption schema (value/label/description/helpText/tags, additionalProperties: false) matches the options endpoints’ payload and the documented tags behavior, and avoids the earlier issue of referring to an undefined type in descriptions.

Optionally, you could add a short schema-level "description" (e.g., “Represents a selectable option item returned by options endpoints”) to make the published contract slightly clearer for consumers.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a048d0 and 5fe1100.

📒 Files selected for processing (2)
  • src/Altinn.App.Api/Controllers/OptionsController.cs (4 hunks)
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (10 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
🧠 Learnings (11)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
🔇 Additional comments (5)
src/Altinn.App.Api/Controllers/OptionsController.cs (4)

18-35: LGTM: Clean class structure and dependency injection.

The addition of partial modifier for GeneratedRegex and the new IAltinn3LibraryCodeListService dependency follow established patterns. Constructor properly injects and stores the service.


37-96: LGTM: First endpoint handles both app options and library code lists correctly.

The implementation properly:

  • Detects library references using the anchored regex
  • Routes to the appropriate service based on the reference type
  • Handles HttpRequestException with detailed Problem() responses
  • Passes HttpContext.RequestAborted for proper cancellation support
  • Validates appOptions is not null before accessing properties

All concerns from previous reviews have been addressed.


98-182: LGTM: Instance endpoint with well-designed fallback logic.

The implementation correctly prioritizes:

  1. Instance-specific options via provider
  2. Falls back to app options or library code lists if instance options not found

The language default to Nb (line 132) for instance-specific requests appears intentional. Error handling and null checks are consistent with the first endpoint.


184-185: LGTM: Regex pattern is properly anchored and validated.

The GeneratedRegex provides compile-time optimization. The pattern correctly enforces:

  • Anchored format to prevent substring matches
  • Appropriate character sets for each component

The org pattern [a-zA-Z0-9]+ is more restrictive than initially suggested in review but represents a deliberate choice for the intended use case.

test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)

1687-1696: Datalist queryParams description change looks fine

The updated "Query parameters supplied" description is clear and consistent with similar datalist endpoints; no further changes needed here.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2)

3220-3423: Options endpoint now has clear contract with AppOption[] and ProblemDetails

The /api/options/{optionsIdOrLibraryRef} GET now:

  • Documents the library-ref pattern in the path parameter.
  • Returns a concrete AppOption[] payload for 200 across content types.
  • Adds structured ProblemDetails bodies for 400/404/500/502.

This aligns well with the earlier request for a shared options item schema and explicit 200 response.

If you want to tighten wording later, you could change “on the format” to “in the format” in the optionsIdOrLibraryRef description, but it’s purely editorial.


7340-7372: AppOption schema is a solid addition; consider nullability of required fields

Defining AppOption with value, label, description, helpText, and tags (dictionary) is a clear improvement and makes the options contract explicit.

If the API logically requires value and label to be non-null, you might later consider tightening the schema (dropping nullable: true for those two) to help client codegen and validation; if null is actually allowed, the current definition is fine.

src/Altinn.App.Api/Controllers/OptionsController.cs (1)

55-74: Apply consistent language default across both Get methods.

The first Get method (line 55) passes nullable language directly to services without a default, while the second Get method (line 122) applies language ??= LanguageConst.Nb before calling services. For consistency and clarity, apply the same default-setting pattern to the first method, or document why the difference is intentional.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fe1100 and f0d4bbf.

📒 Files selected for processing (2)
  • src/Altinn.App.Api/Controllers/OptionsController.cs (4 hunks)
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (12 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
🧠 Learnings (11)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Static code analysis
🔇 Additional comments (5)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2)

1670-1727: Datalists queryParams description looks good

The updated description is clear and neutral; no further changes needed here.


3427-3652: Instance options endpoint mirrors the top-level options contract correctly

/instances/{instanceOwnerPartyId}/{instanceGuid}/options/{optionsIdOrLibraryRef} now matches the non-instance options endpoint:

  • Same optionsIdOrLibraryRef semantics and description.
  • Same language and queryParams descriptions.
  • 200 response as AppOption[] plus consistent ProblemDetails for 400/404/500/502.

This symmetry should make clients’ expectations straightforward across both endpoints.

src/Altinn.App.Api/Controllers/OptionsController.cs (3)

18-35: LGTM! Class structure properly supports new library code-list feature.

The partial modifier enables GeneratedRegex, and the constructor properly injects IAltinn3LibraryCodeListService following established DI patterns.


135-158: LGTM! Fallback logic correctly prioritizes instance-specific options.

The try block properly attempts instance-specific options first (line 137), then falls back to general or library-based options (lines 145-157) when none are found. This ordering aligns with the PR objectives' stated lookup priority.


184-185: The regex pattern correctly reflects domain requirements. All organization identifiers in the codebase use alphanumeric characters only (ttd, digdir, nav, skd), making the [a-zA-Z0-9]+ restriction for org appropriate. Additionally, the IAltinn3LibraryCodeListService properly handles the "latest" version: when the version parameter is empty or null, line 52 defaults it to "latest" before passing to the API client.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs (1)

21-21: Consider using MockBehavior.Strict for consistency.

The mock registration doesn't specify MockBehavior.Strict, while other tests in the codebase (e.g., PaymentServiceTests.cs) use strict mocks. Although IAppOptionsFileHandler methods aren't called in these tests, using strict behavior would catch regressions if the implementation changes and improve consistency with the codebase pattern.

Apply this diff:

-            services.AddSingleton(new Mock<IAppOptionsFileHandler>().Object);
+            services.AddSingleton(new Mock<IAppOptionsFileHandler>(MockBehavior.Strict).Object);
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0d4bbf and 653b95d.

📒 Files selected for processing (6)
  • doc/adr/006-altinn-3-code-list.md (1 hunks)
  • src/Altinn.App.Api/Controllers/OptionsController.cs (4 hunks)
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (2 hunks)
  • src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs (4 hunks)
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (7 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
🧠 Learnings (15)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Mock external dependencies with Moq in tests

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Follow the AppFixture pattern for integration tests: Central orchestrator managing test lifecycle with feature-specific operations

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
  • src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • doc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-09-21T09:04:43.977Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: src/Altinn.App.Core/Features/IInstanceDataAccessor.cs:36-41
Timestamp: 2025-09-21T09:04:43.977Z
Learning: The IInstanceDataAccessor interface in Altinn.App.Core is designed for consumption only - users are not expected to implement this interface themselves, only use framework-provided implementations.

Applied to files:

  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (3)
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs (2)
test/Altinn.App.Core.Tests/Features/Payment/PaymentServiceTests.cs (2)
  • Mock (26-27)
  • Fixture (29-44)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (1)
  • Fixture (517-530)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (2)
  • DefaultAppOptionsProvider (7-42)
  • DefaultAppOptionsProvider (21-25)
src/Altinn.App.Api/Controllers/OptionsController.cs (6)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (3)
  • Task (37-48)
  • Task (51-68)
  • AppOptions (71-113)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (16-21)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-64)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
  • Task (17-17)
  • Task (29-34)
src/Altinn.App.Core/Models/AppOptions.cs (1)
  • AppOptions (6-24)
src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
  • LanguageConst (3-8)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md

[style] ~4-~4: Did you mean “that” or “date”?
Context: ...s * Status: Accepted * Deciders: Squad Data * Date: 2025-12-09 ## Result A1: Use...

(DAT)


[grammar] ~11-~11: Ensure spelling is correct
Context: ...g path without modifying it ## Problem context We want to be able to get Altinn 3 libra...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~24-~24: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~32-~32: Ensure spelling is correct
Context: ...tionId" parsed to org, code list id and version * B3: Performance, consider parsing overhe...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~35-~35: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~78-~78: Ensure spelling is correct
Context: ...ger complains about required parameters missing * Route ambiguity, /options/something coul...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~88-~88: Ensure spelling is correct
Context: ...e list id) should be in path, not query string ### A4: Modify existing path so that option...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~98-~98: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ### A5: Add a new endpoint ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~110-~110: Ensure spelling is correct
Context: ... we initially didn't want. ## Decision rationale To ease the implementation process for t...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Static code analysis
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (10)
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs (2)

34-34: Test setup correctly reflects new factory behavior.

The removal of explicit DefaultAppOptionsProvider registration aligns with the factory's new behavior of dynamically creating default providers when no custom provider matches. The tests correctly validate that the factory returns DefaultAppOptionsProvider instances with the requested IDs.

Also applies to: 46-46


114-115: LGTM! Modern C# syntax.

The use of target-typed new() is idiomatic modern C# and improves readability by reducing redundancy.

src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (2)

21-25: LGTM! Constructor refactoring improves clarity.

The explicit id parameter makes provider instantiation clearer and eliminates the need for cloning logic. The immediate resolution of AppImplementationFactory is appropriate since it's required for all operations.


31-31: Property access correctly restricted.

Changing from internal set to private set properly enforces that Id is immutable after construction, which aligns with the refactored constructor pattern.

doc/adr/006-altinn-3-code-list.md (1)

110-115: ADR is complete and consistent with implementation.

The decision rationale clearly explains the choice of A1, and the specified format lib**{creatorOrg}**{codeListId}**{version} matches the regex implementation in OptionsController.cs. The ADR properly documents the design decision.

src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (2)

12-12: ServiceProvider field properly supports the new provider instantiation pattern.

Storing IServiceProvider enables on-demand creation of DefaultAppOptionsProvider instances with the correct id, which aligns with the refactored constructor signature in DefaultAppOptionsProvider.

Also applies to: 19-19


41-41: Simplified fallback logic improves flexibility.

The new approach creates a DefaultAppOptionsProvider for any unmatched optionsId, removing the need for special "default" handling and cloning. This works correctly since DefaultAppOptionsProvider now accepts any id and resolves the corresponding file.

src/Altinn.App.Api/Controllers/OptionsController.cs (2)

61-73: Library reference handling implemented consistently.

Both endpoints properly detect library references using the regex pattern and route to the appropriate service. The try-catch blocks handle HTTP errors gracefully, and null checks prevent NullReferenceException. The ternary operator usage is clean and the cancellation token is correctly propagated.

Also applies to: 136-156


182-183: No changes required. The regex correctly restricts org identifiers to alphanumeric characters [a-zA-Z0-9]+, which aligns with Altinn organization code naming conventions. All test cases confirm this pattern: ttd, digdir, nav, and skd are alphanumeric-only org identifiers.

Likely an incorrect or invalid review comment.

test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)

1658-1697: Snapshot file – no code-level feedback here

This file is the generated public API snapshot (PublicApi_ShouldNotChange_Unintentionally.verified.txt). Per project guidance, changes here should mirror the real code and are not reviewed for behavior or design. Please just confirm that these snapshot updates (Altinn3 library code-list APIs, AppOptions/AppOption surface, etc.) match the intentional code changes in src/* and associated tests.

Also applies to: 1712-1716, 1726-1731, 1736-1745, 4036-4055

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (3)

727-739: Make test helper class internal sealed per coding guidelines.

DummyInstanceProvider should follow the same accessibility pattern as DummyAltinn3LibraryCodeListService to align with the project's coding guidelines.

🔎 Apply this diff:
-public class DummyInstanceProvider : IInstanceAppOptionsProvider
+internal sealed class DummyInstanceProvider : IInstanceAppOptionsProvider

As per coding guidelines, use internal accessibility on types by default and sealed for classes unless inheritance is considered valid.


741-749: Make test helper class internal sealed per coding guidelines.

DummyProvider should be marked internal sealed for consistency with other test helpers and project coding guidelines.

🔎 Apply this diff:
-public class DummyProvider : IAppOptionsProvider
+internal sealed class DummyProvider : IAppOptionsProvider

As per coding guidelines, use internal accessibility on types by default and sealed for classes unless inheritance is considered valid.


751-785: Make test helper class internal per coding guidelines.

TestDataOptionsController should use internal accessibility to align with the project's coding guidelines for test helper classes.

🔎 Apply this diff:
-public static class TestDataOptionsController
+internal static class TestDataOptionsController

As per coding guidelines, use internal accessibility on types by default.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 653b95d and f71f4b7.

📒 Files selected for processing (3)
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (8 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1 hunks)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧠 Learnings (16)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Include integration tests for platform service interactions

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-22T13:35:09.565Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Authentication_auth=OldUser.verified.txt:16-38
Timestamp: 2025-08-22T13:35:09.565Z
Learning: Test data in Altinn App Integration Tests snapshots (like SSNs, addresses, phone numbers in BasicAppTests.Authentication snapshots) are synthetic/fake values created for testing purposes, not real PII that needs to be scrubbed from version control.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Mock external dependencies with Moq in tests

Applied to files:

  • test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Prefer xUnit asserts over FluentAssertions in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Use Nullable Reference Types in C#

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Static code analysis
🔇 Additional comments (3)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (1)

1-534: LGTM! Comprehensive test coverage for Altinn3LibraryCodeListService.

The test suite is well-structured and covers all critical scenarios:

  • Caching behavior: Verifies HybridCache works correctly across DI scopes with different and identical cache keys
  • Language fallback logic: Tests all scenarios (empty, null, nb default, en fallback, alphabetical fallback)
  • Tag mapping: Thoroughly tests tag dictionary construction under various conditions (missing, mismatched counts, proper mapping)
  • Test infrastructure: Proper DI setup with mocked HTTP client, sealed Fixture record with async disposal
  • Code quality: Follows coding guidelines (xUnit asserts, no blocking async calls, efficient patterns)

The Fixture helper correctly relies on PlatformSettings default property values (as confirmed in past review discussions), eliminating the need for explicit configuration registration.

test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)

19-647: Comprehensive test coverage for OptionsController endpoints.

The test suite thoroughly covers both instance and non-instance endpoints across multiple scenarios: parameter handling, special characters, language defaults, file sources, 404 responses, serialization, and library reference regex validation. The tests follow xUnit patterns, use appropriate assertions, and properly clean up test data.


650-725: LGTM! Well-structured test service implementation.

The DummyAltinn3LibraryCodeListService correctly follows coding guidelines (internal sealed), provides controlled test data, includes proper null-safety guards for collections (lines 702-707), and uses a CallCounter pattern for verification.

@olavsorl olavsorl moved this to 🔎 In review in Team Altinn Studio Dec 19, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/Altinn.App.Api/Controllers/OptionsController.cs (1)

55-95: Address language parameter handling inconsistency between endpoints.

Line 131 in the instance-specific endpoint applies language ??= LanguageConst.Nb to default the language, but the non-instance endpoint (lines 55-95) passes the nullable language parameter directly to services without defaulting. Both endpoints call the same service methods that accept string? language. This inconsistency should either be justified (if the difference is intentional) or standardized by applying the same defaulting pattern to both endpoints.

🧹 Nitpick comments (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (1)

37-69: Clarify version handling: "latest" vs null/empty produce different cache keys.

The version normalization logic is inconsistent:

  • When GetAppOptionsAsync receives "latest" (line 46), GetLatestVersion transforms it to "_latest"
  • When it receives null/empty, GetLatestVersion leaves it unchanged, then GetCachedCodeListResponseAsync (line 59) defaults it to "latest"

This means semantically identical requests (both intending "latest version") produce different cache keys ("_latest" vs "latest"), leading to cache duplication and potentially stale data.

Consider normalizing earlier or using a consistent default so both paths result in the same cache key.

🔎 Suggested fix: normalize version consistently
 public async Task<AppOptions> GetAppOptionsAsync(
     string org,
     string codeListId,
     string version,
     string? language,
     CancellationToken cancellationToken
 )
 {
     using var telemetry = _telemetry?.StartGetOptionsActivity();
-    version = GetLatestVersion(version);
+    version = string.IsNullOrEmpty(version) ? "latest" : version;
     var response = await GetCachedCodeListResponseAsync(org, codeListId, version, cancellationToken);
     return MapAppOptions(response, language);
 }

And update GetCachedCodeListResponseAsync to use GetLatestVersion:

 public async Task<Altinn3LibraryCodeListResponse> GetCachedCodeListResponseAsync(
     string org,
     string codeListId,
     string? version,
     CancellationToken cancellationToken = default
 )
 {
-    version = !string.IsNullOrEmpty(version) ? version : "latest";
+    version = GetLatestVersion(!string.IsNullOrEmpty(version) ? version : "latest");
     var result = await _hybridCache.GetOrCreateAsync(
         $"Altinn3Library:{org}:{codeListId}:{version}",
         async cancel =>
             await _altinn3LibraryCodeListApiClient.GetAltinn3LibraryCodeList(org, codeListId, version, cancel),
         options: _defaultCacheExpiration,
         cancellationToken: cancellationToken
     );

     return result;
 }
src/Altinn.App.Api/Controllers/OptionsController.cs (1)

134-165: Consider extracting common library reference handling logic.

The library reference matching and service invocation pattern (lines 146-155) is duplicated from the first endpoint (lines 61-73). Consider extracting a private helper method to reduce duplication:

🔎 Suggested refactor: extract common logic
+private async Task<AppOptions> GetLibraryOrStandardOptionsAsync(
+    string optionsIdOrLibraryRef,
+    string? language,
+    Dictionary<string, string> queryParams,
+    CancellationToken cancellationToken)
+{
+    var libRefMatch = LibraryRefRegex().Match(optionsIdOrLibraryRef);
+    return libRefMatch.Success
+        ? await _altinn3LibraryCodeListService.GetAppOptionsAsync(
+            libRefMatch.Groups["org"].Value,
+            libRefMatch.Groups["codeListId"].Value,
+            libRefMatch.Groups["version"].Value,
+            language,
+            cancellationToken
+        )
+        : await _appOptionsService.GetOptionsAsync(optionsIdOrLibraryRef, language, queryParams);
+}

Then use it in both endpoints:

-var libRefMatch = LibraryRefRegex().Match(optionsIdOrLibraryRef);
-appOptions = libRefMatch.Success is false
-    ? await _appOptionsService.GetOptionsAsync(optionsIdOrLibraryRef, language, queryParams)
-    : await _altinn3LibraryCodeListService.GetAppOptionsAsync(
-        libRefMatch.Groups["org"].Value,
-        libRefMatch.Groups["codeListId"].Value,
-        libRefMatch.Groups["version"].Value,
-        language,
-        HttpContext.RequestAborted
-    );
+appOptions = await GetLibraryOrStandardOptionsAsync(
+    optionsIdOrLibraryRef,
+    language,
+    queryParams,
+    HttpContext.RequestAborted
+);
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e796ea and 99604a0.

📒 Files selected for processing (2)
  • src/Altinn.App.Api/Controllers/OptionsController.cs
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
🧠 Learnings (9)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • src/Altinn.App.Api/Controllers/OptionsController.cs
🧬 Code graph analysis (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (3)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-64)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListResponse (8-34)
src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
  • LanguageConst (3-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Static code analysis
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (3)

1-35: LGTM! Proper service structure and dependency injection.

The service correctly follows the coding guidelines: internal accessibility, sealed class, proper DI constructor pattern, and clear separation of concerns with HybridCache for caching and the API client for external calls.


72-114: LGTM! Proper tag mapping with duplicate protection.

The tag dictionary construction correctly handles potential duplicate tag names (lines 83-90) and only maps tags when counts match. The language-aware mapping for label, description, and help text follows the established fallback pattern.


116-144: LGTM! Language fallback logic is clear and correct.

The fallback order (requested language → Nb → En → first alphabetically) is well-documented and correctly implemented. The NotNullIfNotNull attribute properly documents the null-safety contract.

src/Altinn.App.Api/Controllers/OptionsController.cs (2)

1-35: LGTM! Clean dependency injection and controller setup.

The addition of the library code list service dependency follows established patterns, and making the controller partial is appropriate for the GeneratedRegex helper method.


182-183: The regex pattern is correct as-is; the inconsistency is intentional.

The test suite explicitly validates that organization identifiers must be alphanumeric only ([a-zA-Z0-9]+), while code list IDs and versions allow underscores and hyphens. This is confirmed by test case at line 221 of OptionsControllerTests.cs:

[InlineData("lib**ttd-org**CodeListId**1.0")] // Dash in org (invalid - only alphanumeric allowed)

The positive test cases show org identifiers can contain uppercase letters and numbers (e.g., lib**TTD** and lib**Org123**), but dashes are explicitly rejected. The pattern is working as designed.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI Agents
In
@src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs:
- Around line 145-148: The GetLatestVersion method currently has a single long
return line that violates CSharpier length limits; refactor the method body to
avoid the long inline ternary by splitting the logic across multiple lines
(e.g., use an if/else or assign intermediate boolean/variable) so the return
expression is wrapped and shorter—update the GetLatestVersion(string? version)
method accordingly to return "_latest" when version is null/empty or equals
"latest" (case-insensitive), otherwise return version.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99604a0 and 348a8c6.

📒 Files selected for processing (1)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧠 Learnings (3)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧬 Code graph analysis (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (1)
  • Task (16-21)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (1)
  • Task (27-64)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListResponse (8-34)
src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
  • LanguageConst (3-8)
🪛 GitHub Actions: Verify dotnet format
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs

[error] 147-147: CSharpier formatting check failed. The code around line 147 is not formatted as expected. Run 'dotnet csharpier check .' to fix.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Static code analysis
🔇 Additional comments (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (5)

11-20: LGTM!

Good adherence to coding guidelines: internal sealed class, nullable telemetry for optional dependency, and static cache options to avoid per-instance allocation.


36-48: LGTM!

Clean async method without Async suffix (per guidelines), proper telemetry activity scoping with using, and clear separation between fetching and mapping.


59-65: Cache key delimiter consideration.

The cache key uses colons as delimiters. If org, codeListId, or version could contain colons, this might cause key collisions. If these values are validated upstream (e.g., from URL path segments), this is acceptable.


70-113: LGTM!

The tag mapping correctly uses "first wins" strategy for duplicate tag names. Graceful degradation when tag counts don't match (tagDict remains null) is reasonable.


115-143: LGTM!

Good use of NotNullIfNotNull attribute. The language fallback priority (requested → Nb → En → alphabetically first) is well-documented and correctly implemented.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (1)

115-143: Language fallback logic is correct.

The fallback priority (requested → Nb → En → alphabetically first) is well-implemented with short-circuit evaluation for efficiency. The NotNullIfNotNull attribute correctly documents null behavior.

💡 Optional: Consider using MinBy for slightly better performance

Line 142 could use MinBy instead of OrderBy().First() to avoid allocating an ordered enumerable:

-        return languageCollection.OrderBy(x => x.Key).First().Value;
+        return languageCollection.MinBy(x => x.Key).Value;

This is a minor optimization but more semantically direct.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 348a8c6 and 8f2e1ba.

📒 Files selected for processing (1)
  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧠 Learnings (4)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧬 Code graph analysis (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (3)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
  • Altinn3LibraryCodeListResponse (33-48)
  • Altinn3LibraryCodeListResponse (50-79)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
  • Altinn3LibraryCodeListResponse (8-34)
src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
  • LanguageConst (3-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Static code analysis
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
🔇 Additional comments (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (5)

1-34: LGTM! Well-structured service implementation.

The class declaration, dependencies, and constructor follow coding guidelines correctly. The internal sealed class with dependency injection and optional telemetry is appropriate. The 15-minute cache expiration is reasonable for library code lists.


36-48: LGTM! Proper telemetry and async handling.

The telemetry activity is correctly disposed using using var, and the async flow properly propagates the cancellation token through to the caching and mapping layers.


50-68: LGTM! Proper caching implementation.

The cache key structure is well-formed, version normalization happens before caching (ensuring consistent keys), and the cancellation token is properly propagated to both the cache and API client layers.


70-113: LGTM! Tag mapping correctly handles edge cases.

The duplicate tag name protection (lines 85-88) properly addresses the past review comment. The count check (line 79) prevents index-out-of-range errors, and the first-wins strategy for duplicate tag names is sensible. Setting IsCacheable = true and including version/source metadata in Parameters aligns well with the library code list use case.


145-150: LGTM! Version normalization correctly implemented.

The formatting issue from the past review has been properly resolved by splitting the ternary across multiple lines. The case-insensitive handling of "latest" and normalization to "_latest" is appropriate.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)

7364-7396: AppOption schema definition looks good; consider a short description on tags.

The AppOption schema (value/label/description/helpText + tags as a string map) is well‑formed and matches the new options responses.

If you want to make the tags semantics clearer, you could add a brief description to the tags property (e.g., “Additional metadata tags for the option, keyed by tag name”) in the C# model so it flows into the generated spec, but this is purely optional.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f2e1ba and 74795ae.

📒 Files selected for processing (4)
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • 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/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
🧠 Learnings (12)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • 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/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/*.cs : Register services in DI container properly following existing patterns

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which fully supports default interface methods.

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which supports default interface methods.

Applied to files:

  • src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
📚 Learning: 2025-09-21T09:04:43.977Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: src/Altinn.App.Core/Features/IInstanceDataAccessor.cs:36-41
Timestamp: 2025-09-21T09:04:43.977Z
Learning: The IInstanceDataAccessor interface in Altinn.App.Core is designed for consumption only - users are not expected to implement this interface themselves, only use framework-provided implementations.

Applied to files:

  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Static code analysis
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Run dotnet build and test (macos-latest)
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (6)
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (1)

13-13: LGTM! DI registrations follow established patterns.

The new service registrations correctly follow the established patterns in the codebase:

  • The HttpClient registration matches the pattern used for other platform clients (lines 102-119)
  • TryAddTransient for the service layer allows app-level overrides while providing a sensible default
  • Transient lifetime is appropriate for stateless services
  • Placement within AddAppOptions is correct for options-related functionality
  • The comment clearly documents the purpose

Based on learnings, these registrations properly follow existing DI patterns.

Also applies to: 339-342

test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (3)

1670-1697: LGTM: datalist queryParams description is clear and consistent.

The updated "Query parameters supplied" phrasing matches similar endpoints and keeps the deepObject semantics understandable.


3220-3425: Options endpoint now has explicit typed 200 responses and error contracts.

The /{org}/{app}/api/options/{optionsIdOrLibraryRef} definition looks solid:

  • 200 returns an array of AppOption for all three content types.
  • 400/404/500/502 consistently use ProblemDetails across media types.
  • optionsIdOrLibraryRef description clearly explains the library-ref format and “latest” behavior.
  • Language parameter description matches the ISO 639‑1 guidance from the review thread.

No further changes needed here from an OpenAPI perspective.


3427-3653: Instance‑scoped options endpoint is aligned with the plain options endpoint.

/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/options/{optionsIdOrLibraryRef}:

  • Mirrors the non‑instance options endpoint (array of AppOption for 200; ProblemDetails for 400/404/500/502).
  • Adds clear descriptions for instance path parameters and language.
  • Keeps queryParams shape and wording consistent with other deepObject query patterns.

This nicely fulfils the earlier request to support all app option kinds and exposes them cleanly in the spec.

test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)

373-390: Snapshot file — no review necessary.

Per established practice in this repository, .verified.txt files are automatically maintained snapshots that guard the public API surface. The changes here reflect intentional public API modifications from this PR (parameter renaming, dependency injection, response type documentation). These updates are expected and will be validated by the public API breaking change detection test.

test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)

1658-1685: Public API snapshot changes acknowledged (no review of generated content).

This .verified.txt file is a generated public‑API snapshot used by the PublicApiTests. I’m not reviewing or suggesting changes based on its contents; the important thing is that it accurately reflects the real code after your Altinn 3 library code‑list and AppOption.Tags changes. As long as this snapshot was regenerated from the updated source and tests pass, it looks fine.

Also applies to: 1692-1697, 1715-1716, 1728-1745, 4066-4068

@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 6, 2026

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

Labels

backport-ignore This PR is a new feature and should not be cherry-picked onto release branches feature Label Pull requests with new features. Used when generation releasenotes squad/data Issues that belongs to the named squad.

Projects

Status: 🔎 In review

Development

Successfully merging this pull request may close these issues.

feat: Get library code lists directly without configuring provider and option id

1 participant