-
Notifications
You must be signed in to change notification settings - Fork 24
feat: instance contextual layout fetching #1544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
5ce876f
3218e40
ca3b07d
271ca38
301807c
733ec02
cf8a7aa
ec066af
fad3f05
0bfe1ba
6adad98
f6c3740
33b9d3f
bffb111
171de8c
f6c572c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,4 +12,11 @@ public static class FeatureFlags | |||||||||||||||||||||||
| /// return validation errors in the response body instead of a string. | ||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||
| public const string JsonObjectInDataResponse = "JsonObjectInDataResponse"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // TODO: write a better summary here | ||||||||||||||||||||||||
| /// <summary> | ||||||||||||||||||||||||
| /// Enabling this feature changes backend endpoint used for layouts to | ||||||||||||||||||||||||
| /// add instance identifier. | ||||||||||||||||||||||||
| /// </summary> | ||||||||||||||||||||||||
| public const string AddInstanceIdentifierToLayoutRequests = "AddInstanceIdentifierToLayoutRequests"; | ||||||||||||||||||||||||
|
Comment on lines
+16
to
+21
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace the TODO with a concrete summary before release. Leaving a TODO in a public API constant’s XML doc makes the documentation incomplete and leaks into generated docs. 📝 Suggested update- // TODO: write a better summary here
- /// <summary>
- /// Enabling this feature changes backend endpoint used for layouts to
- /// add instance identifier.
- /// </summary>
+ /// <summary>
+ /// When enabled, layout fetches use instance-scoped endpoints so layout requests
+ /// include the instance identifier.
+ /// </summary>
public const string AddInstanceIdentifierToLayoutRequests = "AddInstanceIdentifierToLayoutRequests";📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| using Altinn.App.Core.Features; | ||
|
|
||
| namespace Altinn.App.Core.Internal.App; | ||
|
|
||
| /// <summary> | ||
| /// Interface for getting custom layouts for an instance. | ||
| /// </summary> | ||
| [ImplementableByApps] | ||
| public interface ICustomLayoutForInstance | ||
| { | ||
| /// <summary> | ||
| /// Gets the custom layout | ||
| /// </summary> | ||
| /// <param name="layoutSetId">The layout set ID</param> | ||
| /// <param name="instanceOwnerPartyId">The instance owner party ID</param> | ||
| /// <param name="instanceGuid">The instance GUID</param> | ||
| Task<string?> GetCustomLayoutForInstance(string layoutSetId, int instanceOwnerPartyId, Guid instanceGuid); | ||
|
|
||
| /// <summary> | ||
| /// Gets the custom layout settings | ||
| /// </summary> | ||
| /// <param name="layoutSetId">The layout set ID</param> | ||
| /// <param name="instanceOwnerPartyId">The instance owner party ID</param> | ||
| /// <param name="instanceGuid">The instance GUID</param> | ||
| Task<string?> GetCustomLayoutSettingsForInstance(string layoutSetId, int instanceOwnerPartyId, Guid instanceGuid); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| using System.Net; | ||
| using System.Text.Json; | ||
| using Altinn.App.Api.Tests.Data; | ||
| using Altinn.App.Core.Internal.App; | ||
| using Microsoft.AspNetCore.Mvc.Testing; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using Xunit.Abstractions; | ||
|
|
||
| namespace Altinn.App.Api.Tests.Controllers; | ||
|
|
||
| public class ResourceController_CustomLayoutTests : ApiTestBase, IClassFixture<WebApplicationFactory<Program>> | ||
| { | ||
| public ResourceController_CustomLayoutTests(WebApplicationFactory<Program> factory, ITestOutputHelper outputHelper) | ||
| : base(factory, outputHelper) { } | ||
|
|
||
| private class CustomLayoutForInstance : ICustomLayoutForInstance | ||
| { | ||
| public Task<string?> GetCustomLayoutForInstance(string layoutSetId, int instanceOwnerPartyId, Guid instanceId) | ||
| { | ||
| return Task.FromResult<string?>(instanceId.ToString()); | ||
| } | ||
|
|
||
| public Task<string?> GetCustomLayoutSettingsForInstance( | ||
| string layoutSetId, | ||
| int instanceOwnerPartyId, | ||
| Guid instanceId | ||
| ) | ||
| { | ||
| return Task.FromResult<string?>(instanceId.ToString()); | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public async Task GetLayoutsForSet_WithCustomLayoutForInstanceService_ReturnsOk() | ||
| { | ||
| OverrideServicesForThisTest = (services) => | ||
| { | ||
| services.AddSingleton<ICustomLayoutForInstance, CustomLayoutForInstance>(); | ||
| }; | ||
|
|
||
| string org = "tdd"; | ||
| string app = "contributer-restriction"; | ||
| int instanceOwnerPartyId = 500600; | ||
| Guid instanceGuid = Guid.Parse("cff1cb24-5bc1-4888-8e06-c634753c5144"); | ||
| string layoutSetId = "default"; | ||
| using HttpClient client = GetRootedUserClient(org, app, 1337, instanceOwnerPartyId); | ||
|
|
||
| TestData.PrepareInstance(org, app, instanceOwnerPartyId, instanceGuid); | ||
| var response = await client.GetAsync( | ||
| $"/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/layouts/{layoutSetId}" | ||
| ); | ||
|
|
||
| Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
| var content = await response.Content.ReadAsStringAsync(); | ||
| Assert.Equal(instanceGuid.ToString(), content); | ||
| } | ||
|
|
||
| [Fact] | ||
| public async Task GetLayoutsForSet_WithoutCustomLayoutForInstanceService_ReturnsOk() | ||
| { | ||
| string org = "tdd"; | ||
| string app = "contributer-restriction"; | ||
| int instanceOwnerPartyId = 500600; | ||
| Guid instanceGuid = Guid.Parse("cff1cb24-5bc1-4888-8e06-c634753c5144"); | ||
| string layoutSetId = "default"; | ||
| using HttpClient client = GetRootedUserClient(org, app, 1337, instanceOwnerPartyId); | ||
|
|
||
| TestData.PrepareInstance(org, app, instanceOwnerPartyId, instanceGuid); | ||
| var response = await client.GetAsync( | ||
| $"/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/layouts/{layoutSetId}" | ||
| ); | ||
|
|
||
| Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
| var content = await response.Content.ReadAsStringAsync(); | ||
| using var jsonDoc = JsonDocument.Parse(content); | ||
| var root = jsonDoc.RootElement; | ||
| Assert.Equal(JsonValueKind.Object, root.ValueKind); | ||
| Assert.True(root.TryGetProperty("page", out var pageLayout)); | ||
| Assert.True(pageLayout.TryGetProperty("data", out var data)); | ||
| Assert.True(data.TryGetProperty("layout", out var layout)); | ||
| Assert.Equal(JsonValueKind.Array, layout.ValueKind); | ||
| Assert.True(layout.GetArrayLength() > 0); | ||
| } | ||
|
|
||
| [Fact] | ||
| public async Task GetLayoutSettingsForSet_WithCustomLayoutForInstanceService_ReturnsOk() | ||
| { | ||
| OverrideServicesForThisTest = (services) => | ||
| { | ||
| services.AddSingleton<ICustomLayoutForInstance, CustomLayoutForInstance>(); | ||
| }; | ||
|
|
||
| string org = "tdd"; | ||
| string app = "contributer-restriction"; | ||
| int instanceOwnerPartyId = 500600; | ||
| Guid instanceGuid = Guid.Parse("cff1cb24-5bc1-4888-8e06-c634753c5144"); | ||
| string layoutSetId = "default"; | ||
| using HttpClient client = GetRootedUserClient(org, app, 1337, instanceOwnerPartyId); | ||
|
|
||
| TestData.PrepareInstance(org, app, instanceOwnerPartyId, instanceGuid); | ||
| var response = await client.GetAsync( | ||
| $"/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/layoutsettings/{layoutSetId}" | ||
| ); | ||
|
|
||
| Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
| var content = await response.Content.ReadAsStringAsync(); | ||
| Assert.Equal(instanceGuid.ToString(), content); | ||
| } | ||
|
|
||
| [Fact] | ||
| public async Task GetLayoutSettingsForSet_WithoutCustomLayoutForInstanceService_ReturnsOk() | ||
| { | ||
| string org = "tdd"; | ||
| string app = "contributer-restriction"; | ||
| int instanceOwnerPartyId = 500600; | ||
| Guid instanceGuid = Guid.Parse("cff1cb24-5bc1-4888-8e06-c634753c5144"); | ||
| string layoutSetId = "default"; | ||
| using HttpClient client = GetRootedUserClient(org, app, 1337, instanceOwnerPartyId); | ||
|
|
||
| TestData.PrepareInstance(org, app, instanceOwnerPartyId, instanceGuid); | ||
| var response = await client.GetAsync( | ||
| $"/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/layoutsettings/{layoutSetId}" | ||
| ); | ||
|
|
||
| Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
| var content = await response.Content.ReadAsStringAsync(); | ||
| using var jsonDoc = JsonDocument.Parse(content); | ||
| var root = jsonDoc.RootElement; | ||
| Assert.Equal(JsonValueKind.Object, root.ValueKind); | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.