-
Notifications
You must be signed in to change notification settings - Fork 74
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
feat: Delete all Summary 2.0 components that has a reference to a deleted component #14126
base: main
Are you sure you want to change the base?
Conversation
…elete-all-summary-20-components-that-has-a-reference-to-deleted-element-component-page-or-layout-set
backend/tests/Designer.Tests/Controllers/AppDevelopmentController/SaveFormLayoutTests.cs
Fixed
Show fixed
Hide fixed
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #14126 +/- ##
=======================================
Coverage 95.65% 95.65%
=======================================
Files 1889 1889
Lines 24550 24550
Branches 2817 2817
=======================================
Hits 23484 23484
Misses 805 805
Partials 261 261 ☔ View full report in Codecov by Sentry. |
backend/src/Designer/EventHandlers/LayoutPageDeleted/LayoutPageDeletedHandler.cs
Fixed
Show fixed
Hide fixed
backend/src/Designer/EventHandlers/LayoutSetDeleted/LayoutSetDeletedComponentRefHandler.cs
Fixed
Show fixed
Hide fixed
backend/src/Designer/EventHandlers/LayoutSetDeleted/LayoutSetDeletedComponentRefHandler.cs
Fixed
Show fixed
Hide fixed
…elete-all-summary-20-components-that-has-a-reference-to-deleted-element-component-page-or-layout-set
d881911
to
160d666
Compare
backend/src/Designer/EventHandlers/LayoutPageDeleted/LayoutPageDeletedHandler.cs
Fixed
Show fixed
Hide fixed
…elete-all-summary-20-components-that-has-a-reference-to-deleted-element-component-page-or-layout-set
…mponents-that-has-a-reference-to-deleted-element-component-page-or-layout-set
There was a problem hiding this 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
🧹 Nitpick comments (15)
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component2/layouts/Side2.json (1)
1-49
: Consider enhancing test data to better represent post-cleanup state.Given that this file is meant to represent the state after deleting references (based on the file path
app-with-summary2-components-after-deleting-references
), consider:
- Documenting which Summary2 components should remain vs. be deleted
- Adding test cases for various reference scenarios (deleted pages, components, etc.)
- Including comments in the JSON to explain the test scenarios
This will help ensure that the test data accurately validates the component cleanup functionality.
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet/layouts/Side2.json (1)
5-11
: Consider adding meaningful data bindings for test completeness.While empty bindings might be intentional for testing, having meaningful data model bindings in test fixtures helps ensure more comprehensive test coverage and better documentation of expected usage patterns.
"dataModelBindings": { - "simpleBinding": "" + "simpleBinding": "testModel.field1" },backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet2/layouts/Side2.json (1)
4-48
: Consider reducing Summary2 component duplication.The layout contains multiple Summary2 components targeting different elements (layoutSet, pages, and a component). This might lead to maintenance challenges. Consider:
- Consolidating summary views where possible
- Documenting the purpose of each Summary2 component
- Implementing a more hierarchical summary structure
backend/src/Designer/Services/Implementation/AppDevelopmentService.cs (1)
632-632
: Address the TODO commentThere's a TODO comment referencing issue #14073. Would you like assistance in addressing this?
Do you want me to help implement a solution for this TODO or open a new GitHub issue to track this task?
backend/src/Designer/Events/LayoutPageDeletedEvent.cs (1)
6-11
: Consider making properties immutable and adding validation.The event class should enforce immutability and property validation:
- Make properties immutable by removing setters
- Add a constructor to initialize properties
- Add null/empty validation for required properties
public class LayoutPageDeletedEvent : INotification { - public AltinnRepoEditingContext EditingContext { get; set; } - public string LayoutSetName { get; set; } - public string LayoutName { get; set; } + public AltinnRepoEditingContext EditingContext { get; } + public string LayoutSetName { get; } + public string LayoutName { get; } + + public LayoutPageDeletedEvent( + AltinnRepoEditingContext editingContext, + string layoutSetName, + string layoutName) + { + EditingContext = editingContext ?? throw new ArgumentNullException(nameof(editingContext)); + LayoutSetName = !string.IsNullOrEmpty(layoutSetName) ? layoutSetName : throw new ArgumentException("Cannot be null or empty", nameof(layoutSetName)); + LayoutName = !string.IsNullOrEmpty(layoutName) ? layoutName : throw new ArgumentException("Cannot be null or empty", nameof(layoutName)); + } }backend/src/Designer/Events/ComponentDeletedEvent.cs (1)
6-11
: Apply the same immutability and validation pattern as LayoutPageDeletedEvent.For consistency, apply the same improvements:
- Make properties immutable
- Add constructor
- Add validation
public class ComponentDeletedEvent : INotification { - public AltinnRepoEditingContext EditingContext { get; set; } - public string LayoutSetName { get; set; } - public string ComponentId { get; set; } + public AltinnRepoEditingContext EditingContext { get; } + public string LayoutSetName { get; } + public string ComponentId { get; } + + public ComponentDeletedEvent( + AltinnRepoEditingContext editingContext, + string layoutSetName, + string componentId) + { + EditingContext = editingContext ?? throw new ArgumentNullException(nameof(editingContext)); + LayoutSetName = !string.IsNullOrEmpty(layoutSetName) ? layoutSetName : throw new ArgumentException("Cannot be null or empty", nameof(layoutSetName)); + ComponentId = !string.IsNullOrEmpty(componentId) ? componentId : throw new ArgumentException("Cannot be null or empty", nameof(componentId)); + } }backend/src/Designer/EventHandlers/LayoutPageDeleted/LayoutPageDeletedLayoutsHandler.cs (1)
12-26
: Implementation looks good but consider reducing duplication.The handler follows the same good practices as ComponentDeletedLayoutsHandler. However, since both handlers share similar structure, consider:
- Creating a base handler class
- Or extracting common logic to a helper class
Example base handler:
public abstract class BaseDeletedLayoutsHandler<TNotification>( IFileSyncHandlerExecutor fileSyncHandlerExecutor, IAppDevelopmentService appDevelopmentService) : INotificationHandler<TNotification> where TNotification : INotification { protected abstract (string LayoutSetName, string Id, ReferenceType Type) GetReferenceInfo(TNotification notification); public async Task Handle(TNotification notification, CancellationToken cancellationToken) { await fileSyncHandlerExecutor.ExecuteWithExceptionHandlingAndConditionalNotification( (notification as dynamic).EditingContext, GetSyncErrorCode(), "layouts", async () => { var (layoutSetName, id, type) = GetReferenceInfo(notification); List<Reference> referencesToDelete = [new Reference(type, layoutSetName, id)]; return await appDevelopmentService.UpdateLayoutReferences( (notification as dynamic).EditingContext, referencesToDelete, cancellationToken); }); } protected abstract SyncErrorCodes GetSyncErrorCode(); }backend/src/Designer/EventHandlers/LayoutSetDeleted/LayoutSetDeletedLayoutsHandler.cs (1)
14-25
: Consider adding debug logging.While the implementation is correct, adding debug logging would help with troubleshooting issues in production.
public async Task Handle(LayoutSetDeletedEvent notification, CancellationToken cancellationToken) { + _logger.LogDebug("Handling LayoutSetDeletedEvent for layout set {LayoutSetName}", notification.LayoutSetName); await fileSyncHandlerExecutor.ExecuteWithExceptionHandlingAndConditionalNotification(
frontend/packages/process-editor/src/bpmnProviders/SupportedContextPadProvider.js (1)
19-19
: Consider extracting UI text to a translation file.While the Norwegian text is consistent with the UI, consider moving it to a translation file for better maintainability and localization support.
- 'Prosess-steget du vil slette kan være knyttet til en sidegruppe. Den kan inneholde visningsoppsett eller skjema du har satt opp. Hvis du sletter steget, sletter du også hele sidegruppen og alt som hører til.\nAlle Summary2-komponenter knyttet til dette prosess-steget vil også bli slettet.' + i18n.t('process.delete.confirmation.withSummary2')backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteFormLayoutTests.cs (2)
61-90
: LGTM! Comprehensive test coverage for Summary2 component deletion.The test thoroughly verifies the deletion of associated Summary2 components and their references. Good use of test data and deep comparison.
However, consider adding a test case for error scenarios:
[Theory] [InlineData("ttd", "testUser", "layout", "NonExistentSide")] public async Task DeleteFormLayout_WithNonExistentSummary2Components_ReturnsNotFound(...)
77-82
: Consider using a more maintainable approach for test data paths.The hardcoded array of layout paths could become difficult to maintain. Consider moving these to a test data configuration file.
backend/src/Designer/Services/Interfaces/IAppDevelopmentService.cs (1)
217-223
: Add return value documentation.The XML documentation is missing the
<returns>
tag. Consider adding it to maintain consistency with other methods in the interface:/// <summary> /// Update layout references /// </summary> /// <param name="altinnRepoEditingContext">An <see cref="AltinnRepoEditingContext"/>.</param> /// <param name="referencesToUpdate">The references to update.</param> /// <param name="cancellationToken">An <see cref="CancellationToken"/> that observes if operation is cancelled.</param> + /// <returns>A task that represents the asynchronous operation. The task result contains a boolean indicating whether the update was successful.</returns> public Task<bool> UpdateLayoutReferences(AltinnRepoEditingContext altinnRepoEditingContext, List<Reference> referencesToUpdate, CancellationToken cancellationToken);
backend/src/Designer/Controllers/AppDevelopmentController.cs (1)
127-137
: LGTM! Consider extracting the component deletion logic.The changes correctly handle component deletions by publishing a
ComponentDeletedEvent
. The LINQ filter ensures we only process actual changes.Consider extracting the component deletion logic into a private method for better readability:
-if (componentIdChange.NewComponentId == null) -{ - await _mediator.Publish(new ComponentDeletedEvent - { - ComponentId = componentIdChange.OldComponentId, - LayoutSetName = layoutSetName, - EditingContext = editingContext - }, cancellationToken); -} +await PublishComponentDeletedEventIfNeeded(componentIdChange, layoutSetName, editingContext, cancellationToken);backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout/Settings.json (1)
1-9
: Add documentation for the layout settings configuration.Consider adding a comment block at the top of the file to explain:
- The purpose of this configuration
- The significance of the page order
- Any constraints or requirements for the pages
{ + // This configuration defines the layout settings for the application + // - $schema: Validates the configuration structure + // - pages.order: Determines the sequence of pages in the application "$schema": "https://altinncdn.no/schemas/json/layout/layoutSettings.schema.v1.json", "pages": { "order": [backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet/layouts/Side1.json (1)
1-13
: Consider adding text resource bindings for navigation buttons.The NavigationButtons component has empty textResourceBindings. Consider adding text resources for better accessibility and internationalization.
"textResourceBindings": { + "next": "next_button_text", + "back": "back_button_text" },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (52)
backend/src/Designer/Controllers/AppDevelopmentController.cs
(4 hunks)backend/src/Designer/EventHandlers/ComponentDeleted/ComponentDeletedLayoutsHandler.cs
(1 hunks)backend/src/Designer/EventHandlers/ComponentIdChanged/ComponentIdChangedLayoutsHandler.cs
(1 hunks)backend/src/Designer/EventHandlers/LayoutPageDeleted/LayoutPageDeletedLayoutsHandler.cs
(1 hunks)backend/src/Designer/EventHandlers/LayoutSetDeleted/LayoutSetDeletedComponentRefHandler.cs
(0 hunks)backend/src/Designer/EventHandlers/LayoutSetDeleted/LayoutSetDeletedLayoutsHandler.cs
(1 hunks)backend/src/Designer/Events/ComponentDeletedEvent.cs
(1 hunks)backend/src/Designer/Events/LayoutPageDeletedEvent.cs
(1 hunks)backend/src/Designer/Events/LayoutSetDeletedEvent.cs
(1 hunks)backend/src/Designer/Hubs/SyncHub/SyncErrorCodes.cs
(1 hunks)backend/src/Designer/Models/Reference.cs
(1 hunks)backend/src/Designer/Services/Implementation/AppDevelopmentService.cs
(1 hunks)backend/src/Designer/Services/Interfaces/IAppDevelopmentService.cs
(1 hunks)backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteFormLayoutTests.cs
(3 hunks)backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteLayoutSetTests.cs
(1 hunks)backend/tests/Designer.Tests/Controllers/AppDevelopmentController/SaveFormLayoutTests.cs
(2 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component/Settings.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component/layouts/Side1.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component/layouts/Side2.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component2/Settings.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component2/layouts/Side1.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component2/layouts/Side2.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout-sets.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout/Settings.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout/layouts/Side1.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout2/Settings.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout2/layouts/Side1.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout2/layouts/Side2.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layoutSet2/Settings.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layoutSet2/layouts/Side1.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layoutSet2/layouts/Side2.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component/Settings.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component/layouts/Side1.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component/layouts/Side2.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component2/Settings.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component2/layouts/Side1.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component2/layouts/Side2.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout-sets.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout/Settings.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout/layouts/Side1.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout/layouts/Side2.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/Settings.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/Side1.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/Side2.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet/Settings.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet/layouts/Side1.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet/layouts/Side2.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet2/Settings.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet2/layouts/Side1.json
(1 hunks)backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet2/layouts/Side2.json
(1 hunks)frontend/language/src/nb.json
(2 hunks)frontend/packages/process-editor/src/bpmnProviders/SupportedContextPadProvider.js
(1 hunks)
💤 Files with no reviewable changes (1)
- backend/src/Designer/EventHandlers/LayoutSetDeleted/LayoutSetDeletedComponentRefHandler.cs
✅ Files skipped from review due to trivial changes (15)
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component/Settings.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet/Settings.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/Settings.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout-sets.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout/Settings.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component2/Settings.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout2/Settings.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet2/Settings.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout-sets.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component/Settings.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component2/Settings.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component/layouts/Side1.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout/layouts/Side2.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layoutSet2/layouts/Side2.json
- backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layoutSet2/Settings.json
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Testing
🔇 Additional comments (48)
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component2/layouts/Side2.json (3)
1-4
: LGTM! Schema and structure are well-defined.The layout schema reference and structure follow the standard format.
41-46
: LGTM! NavigationButtons configuration is valid.The component configuration is minimal but sufficient for test data purposes.
33-40
: Verify if the referenced component still exists.This Summary2 component references a specific component ID "Input-qWr0oa". Given that this test file represents the state after deleting references (based on the file path), we should verify if this component still exists.
✅ Verification successful
The referenced component "Input-qWr0oa" exists and is valid.
The component ID is present in multiple layout files within the test data, including the state after deleting references. This indicates that the reference is valid and the target component was not deleted.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for the referenced component ID in the test data directory rg -g '*.json' '"Input-qWr0oa"' backend/tests/Designer.Tests/_TestData/Length of output: 1121
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/Side2.json (5)
1-2
: LGTM! Schema reference is correctly specified.The layout schema reference points to a valid CDN URL with proper versioning.
41-46
: LGTM! Navigation component is correctly configured.The NavigationButtons component is properly configured with showBackButton enabled and empty text resource bindings.
5-13
: Verify if these Summary2 components should be included.These Summary2 components are targeting pages and layout sets. According to the PR objective to "Delete all Summary2 components that has a reference to a deleted component", we should verify if these components should remain or be removed based on whether their target pages/layouts still exist.
Also applies to: 14-22, 23-31
✅ Verification successful
Summary2 components referencing pages and layout sets should be retained
These Summary2 components are targeting existing pages (Side1.json, Side2.json) and layout sets, not deleted components. They should remain in the codebase as they don't match the PR objective of "Delete all Summary2 components that has a reference to a deleted component".
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check if the referenced pages and layout sets exist # Expected: If any of these files don't exist, their corresponding Summary2 components should be removed # Check for Side1 page fd -t f "Side1.json" backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/ # Check for Side2 page fd -t f "Side2.json" backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/Length of output: 533
Script:
#!/bin/bash # Check the content of Side1.json and Side2.json to verify they contain valid layout configurations cat backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/Side1.json echo "---" cat backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/Side2.jsonLength of output: 2484
32-40
: Verify if the referenced Input component exists.This Summary2 component references an Input component with id "Input-AVRSNf". According to the PR objective, this Summary2 component should be removed if the referenced Input component has been deleted.
✅ Verification successful
Input component "Input-AVRSNf" exists and is actively used
The referenced Input component is properly defined in
layout/layouts/Side2.json
and is being used by multiple Summary2 components. The component reference is valid and should be maintained.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check if the referenced Input component exists in any layout files # Expected: If no matches are found, this Summary2 component should be removed rg -l "Input-AVRSNf" backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/Length of output: 266
Script:
#!/bin/bash # Search for the Input component definition in the entire app directory # Using context to see the component definition rg -C 5 "Input-AVRSNf" backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/Length of output: 5036
1-49
: Verify if this test file is intentionally set up for deletion tests.Since this is a test data file and contains multiple Summary2 components with various references, we should verify if this file is intentionally set up to test the Summary2 component deletion functionality mentioned in the PR objective.
✅ Verification successful
Test file is correctly set up for deletion tests
This test file is intentionally structured as the "before" state for various deletion scenarios, with a corresponding "after" state in "app-with-summary2-components-after-deleting-references". The multiple Summary2 components with different target types are necessary for comprehensive deletion testing.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Look for test cases that use this test data file # Expected: Find test cases that verify the deletion of Summary2 components # Search for test files that reference this test data rg -l "app-with-summary2-components" backend/tests/Designer.Tests/ # Search for test methods related to Summary2 deletion rg -l "Summary2.*Delete" backend/tests/Designer.Tests/Length of output: 393
Script:
#!/bin/bash # Look for specific test cases using this test data rg -A 10 "app-with-summary2-components" backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteFormLayoutTests.cs rg -A 10 "app-with-summary2-components" backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteLayoutSetTests.cs rg -A 10 "app-with-summary2-components" backend/tests/Designer.Tests/Controllers/AppDevelopmentController/SaveFormLayoutTests.csLength of output: 3392
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet/layouts/Side2.json (2)
1-4
: LGTM! Schema and structure are well-defined.The layout follows the correct schema version and structure.
Also applies to: 18-20
1-20
: Confirm the purpose of this test fixture.This new test file doesn't contain any Summary 2.0 components or references to deleted components. Could you clarify its role in testing the component deletion functionality? It might be helpful to add a comment in the test file or test case explaining how this fixture is used.
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet2/layouts/Side2.json (3)
1-4
: LGTM! Schema and structure are well-defined.The layout follows the correct schema version and structure.
41-46
: LGTM! NavigationButtons configuration is valid.The NavigationButtons component is correctly configured with basic navigation functionality.
32-40
: Verify if the referenced component 'Input-hqcYqo' exists.This Summary2 component references a specific component ID. Given the PR's objective to delete Summary2 components with references to deleted components, we should verify if this component still exists.
Let's check for the existence of the referenced component:
✅ Verification successful
The referenced component 'Input-hqcYqo' exists and is valid
The component is properly defined in
layoutSet/layouts/Side2.json
as an Input component and is correctly referenced by the Summary2 component. No action needed.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for the referenced component ID in all layout files rg -l "Input-hqcYqo" backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/Length of output: 383
Script:
#!/bin/bash # Check the content of files containing Input-hqcYqo to find component definition rg -U "Input-hqcYqo" backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet2/layouts/Side2.json backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet/layouts/Side2.jsonLength of output: 604
Script:
#!/bin/bash # Get full context around Input-hqcYqo component definitions rg -U -B 5 -A 5 "Input-hqcYqo" backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet/layouts/Side2.json backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet2/layouts/Side2.jsonLength of output: 3645
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component/layouts/Side2.json (2)
1-27
: LGTM! The layout structure follows the schema.The layout definition is well-structured and follows the specified schema. All components have proper IDs and required properties.
1-27
: Verify if this test file serves its intended purpose.This file is located in a directory named "app-with-summary2-components" but doesn't contain any Summary 2.0 components. Please verify if:
- This is intentional (e.g., part of a test case verifying cleanup)
- The file should be moved to a different test directory
- Summary 2.0 components need to be added for test coverage
✅ Verification successful
The file's state is intentional and serves its test purpose correctly
This file is part of a test suite that verifies the proper cleanup of Summary2 components during layout deletion. The file represents the expected state after deletion, where Summary2 components have been removed, leaving only the basic Input components. This is confirmed by the test method
DeleteFormLayout_DeletesAssociatedSummary2Components_ReturnsOk
in DeleteFormLayoutTests.cs.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check if other files in the same directory contain Summary 2.0 components # and verify the test coverage for Summary 2.0 component cleanup # Look for other layout files in the same directory echo "Checking other layout files in the same directory:" fd -e json . "backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component/layouts" --exec cat {} \; | jq -c 'if (.data.layout[] | select(.type | contains("Summary"))) then . else empty end' # Look for test files that might be using this test data echo "Checking test files that might use this test data:" rg -l "app-with-summary2-components" "backend/tests/Designer.Tests"Length of output: 4771
Script:
#!/bin/bash # Check the content of test files to understand the purpose echo "Checking DeleteFormLayoutTests.cs:" rg -A 5 -B 5 "app-with-summary2-components.*Side2" "backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteFormLayoutTests.cs" echo -e "\nChecking DeleteLayoutSetTests.cs:" rg -A 5 -B 5 "app-with-summary2-components.*Side2" "backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteLayoutSetTests.cs" echo -e "\nChecking SaveFormLayoutTests.cs:" rg -A 5 -B 5 "app-with-summary2-components.*Side2" "backend/tests/Designer.Tests/Controllers/AppDevelopmentController/SaveFormLayoutTests.cs"Length of output: 671
Script:
#!/bin/bash # Broader search for test context echo "Checking test files for app-with-summary2-components context:" rg -A 10 "app-with-summary2-components" "backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteFormLayoutTests.cs" echo -e "\nChecking for Summary2 test patterns:" rg -A 10 "Summary2" "backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteFormLayoutTests.cs" echo -e "\nChecking test class setup:" rg -A 10 "^ public class DeleteFormLayoutTests" "backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteFormLayoutTests.cs"Length of output: 3097
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layoutSet2/layouts/Side1.json (4)
37-45
: Verify if referenced Input component exists.The Summary2 component with ID "Summary2-2YoJGY" references the Input component "Input-wrspcN". While this Input component exists in the current layout, verify if this is the intended reference.
46-51
: LGTM!The NavigationButtons component configuration is correct with proper showBackButton setting and empty textResourceBindings.
28-36
: Fix empty taskId in Summary2 component.The Summary2 component with ID "Summary2-Orxmu1" has an empty taskId field. While this might be optional, verify if this is intentional.
Run this script to check the usage pattern:
✅ Verification successful
Empty taskId is a valid pattern in Summary2 components
Analysis of the test files shows that empty taskId is a common and valid pattern for Summary2 components with page-type targets. This is consistently demonstrated across multiple test files and maintained even after reference deletions.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check if taskId is required for page-type targets in Summary2 components # by analyzing other test files rg -l --json "Summary2.*page.*taskId" | jq -r '.data.path' | while read -r file; do echo "Found in: $file" cat "$file" | jq '.data.layout[] | select(.type == "Summary2" and .target.type == "page" and .target.taskId != null)' doneLength of output: 469
Script:
#!/bin/bash # Search for Summary2 components and analyze their taskId patterns rg -l "\"type\":\s*\"Summary2\"" | while read -r file; do echo "=== File: $file ===" # Parse JSON and find Summary2 components with page-type targets cat "$file" | jq -c '.data.layout[]? | select(.type == "Summary2" and .target.type == "page") | {id: .id, taskId: .target.taskId}' doneLength of output: 10813
20-27
: Verify potential circular reference in Summary2 component.The Summary2 component with ID "Summary2-4069IB" is referencing "Side1" page, which is the current page itself (based on the file path). This might create a circular reference.
Run this script to check if this is a valid use case:
✅ Verification successful
Self-reference is an intentional test case
The file is part of a test suite specifically designed to test Summary2 component reference handling. The self-reference appears in multiple test layouts and is part of the test scenarios for verifying component behavior after deleting references.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check if other test files have similar self-referencing Summary2 components # and verify if this is an intentional test case rg -l --json "Summary2.*Side1.*Side1.json" | jq -r '.data.path' | while read -r file; do echo "Found in: $file" cat "$file" | jq '.data.layout[] | select(.type == "Summary2" and .target.id == "Side1")' doneLength of output: 474
Script:
#!/bin/bash # Search for Summary2 components referencing Side1 in test data rg -C 5 '"type": "Summary2".*"id": "Side1"' backend/tests/Designer.Tests/_TestData # Look for Summary2 component implementation ast-grep --pattern 'class Summary2 { $$$ }'Length of output: 132
Script:
#!/bin/bash # Search for Summary2 components in the specific test directory echo "=== Summary2 components in the test directory ===" rg -A 3 '"type": "Summary2"' backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/ # Search for Side1 references echo "=== Side1 references ===" rg -B 3 '"id": "Side1"' backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/Length of output: 22098
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet2/layouts/Side1.json (5)
6-8
: Verify if empty simpleBinding is intentional.The Input component has an empty data binding. While this might be intentional for test data, please verify that the test cases handle this scenario correctly.
47-50
: Consider adding text resources for the back button.The NavigationButtons component has showBackButton enabled but no text resources defined. While this might be intentional for test data, verify that the component handles missing text resources gracefully.
21-24
: Verify the existence of referenced pages.The Summary2 components reference pages "Side1" and "Side2". Ensure these pages exist to prevent invalid references.
Also applies to: 29-33
✅ Verification successful
Referenced pages "Side1" and "Side2" exist
Both referenced pages are present in the correct directory structure, ensuring valid references in the Summary2 components.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for the existence of referenced pages # Expected: Find layout files for Side1 and Side2 fd -g 'Side[12].json' backend/tests/Designer.Tests/_TestDataLength of output: 3017
1-4
: Verify the schema version is up to date.The layout is using schema version 4. Please verify this is the latest version to ensure all new features and validations are available.
✅ Verification successful
Schema version is correct and up to date
The layout file is using schema version 4, which is confirmed to be the latest available version (last updated Dec 19, 2024). No changes needed.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for the latest schema version # Expected: Version 4 or higher should be available at the CDN curl -I https://altinncdn.no/toolkits/altinn-app-frontend/5/schemas/json/layout/layout.schema.v1.jsonLength of output: 795
Script:
#!/bin/bash # Verify that version 4 exists at the CDN curl -I https://altinncdn.no/toolkits/altinn-app-frontend/4/schemas/json/layout/layout.schema.v1.jsonLength of output: 1099
1-54
: Verify test data coverage for component deletion scenarios.This test file appears to be designed to test the deletion of Summary2 components with invalid references. Please ensure that the test cases using this data cover all scenarios:
- Deletion when layoutSet reference is empty
- Deletion when referenced pages don't exist
- Deletion when referenced component exists
- Deletion when taskId is empty
✅ Verification successful
Test data coverage appears adequate for Summary2 component scenarios
The test data is being used by multiple test files that cover form layout deletion, layout set deletion, and form layout saving operations. The test data structure appropriately supports these test scenarios with its various Summary2 component configurations.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Look for related test cases # Expected: Find test files covering Summary2 component deletion scenarios rg -l "Summary2.*Delete" backend/tests/Designer.Tests/Length of output: 56
Script:
#!/bin/bash # Search for Summary2-related test files echo "=== Searching for Summary2 test files ===" rg -l "Summary2" backend/tests/Designer.Tests/ --type cs echo -e "\n=== Searching for files referencing the test data path ===" rg -l "app-with-summary2-components" backend/tests/Designer.Tests/ echo -e "\n=== Looking for Summary2 class/method definitions in test files ===" ast-grep --pattern 'class $_ { $$$ $_Summary2$_($$$) { $$$ } $$$ }'Length of output: 1245
backend/src/Designer/Models/Reference.cs (1)
1-10
: Usage of enumReferenceType
enhances code clarityThe introduction of the
ReferenceType
enum and theReference
record improves type safety and readability.backend/src/Designer/Events/LayoutSetDeletedEvent.cs (1)
9-9
: Verify impact of changing property fromLayoutSetId
toLayoutSetName
Ensure that all references to
LayoutSetId
have been updated toLayoutSetName
throughout the codebase to prevent any runtime errors or build issues.Run the following script to check for any remaining references to
LayoutSetId
:backend/src/Designer/EventHandlers/ComponentDeleted/ComponentDeletedLayoutsHandler.cs (1)
12-26
: Implementation looks good!The handler demonstrates good practices:
- Proper dependency injection
- Async/await usage
- Delegated error handling
- Clear single responsibility
backend/src/Designer/EventHandlers/LayoutSetDeleted/LayoutSetDeletedLayoutsHandler.cs (1)
12-13
: LGTM! Clean constructor using primary constructor syntax.The implementation follows C# best practices using dependency injection and the new primary constructor syntax.
backend/src/Designer/Hubs/SyncHub/SyncErrorCodes.cs (1)
12-17
: LGTM! Error codes follow consistent naming pattern.The new error codes align well with the existing pattern and use the nameof operator for type safety.
backend/tests/Designer.Tests/Controllers/AppDevelopmentController/SaveFormLayoutTests.cs (2)
98-140
: LGTM! Well-structured test case.The test follows the Arrange-Act-Assert pattern and effectively verifies that deleting a component also deletes its associated Summary 2.0 components by comparing the actual and expected layouts.
108-109
:⚠️ Potential issueAdd null check before accessing layoutArray.
The current code could throw a
NullReferenceException
if the layout array is not found. Consider adding a null check:-JsonArray layoutArray = layoutWithDeletedComponent["data"]["layout"] as JsonArray; -layoutArray?.RemoveAt(0); +JsonArray layoutArray = layoutWithDeletedComponent["data"]?["layout"] as JsonArray; +if (layoutArray == null) +{ + throw new InvalidOperationException("Layout array not found in the layout file."); +} +layoutArray.RemoveAt(0);Likely invalid or redundant comment.
backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteLayoutSetTests.cs (1)
163-192
: LGTM! Well-structured test case.The test follows the established patterns in the file and effectively verifies that deleting a layout set also deletes its associated Summary 2.0 components by comparing the actual and expected layouts.
backend/src/Designer/Controllers/AppDevelopmentController.cs (2)
172-191
: LGTM! Good improvements to the DeleteFormLayout method.The changes enhance the method by:
- Adding cancellation support for better resource management
- Publishing the
LayoutPageDeletedEvent
before deletion, allowing proper cleanup of references
429-433
: LGTM! Property name change in LayoutSetDeletedEvent.The change correctly updates the property name from
LayoutSetId
toLayoutSetName
in the event publishing.backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component/layouts/Side2.json (1)
6-8
: Verify the empty data model binding.The Input component has an empty simpleBinding which might cause issues. Either:
- Remove the binding if it's not needed
- Add the correct data model path
✅ Verification successful
Empty binding is valid in this context
This is test data specifically designed to verify application behavior after deleting references, as indicated by the directory name and consistent empty bindings across multiple test files in the same test suite. The empty binding is intentional and should be left as is.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for any data model definitions that might be relevant for this input rg -g "*.schema.json" -l "simpleBinding|properties"Length of output: 2561
Script:
#!/bin/bash # Check for similar patterns in the same test app directory rg -g "*.json" --type-add 'json:*.json' -C 3 '"simpleBinding": ""' backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/Length of output: 5166
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout/layouts/Side1.json (1)
8-9
: Verify target references in Summary2 components.Several target references need verification:
- Empty layoutSet ID at line 8-9
- Page references to "Side1" and "Side2"
- Component reference to "Input-AVRSNf"
Also applies to: 16-18, 25-27, 34-36
✅ Verification successful
All referenced components and pages exist in the test data
The empty layoutSet and taskId fields appear to be intentional in this test data context. All referenced pages (Side1, Side2) and the Input-AVRSNf component exist within the appropriate layout directories.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the existence of referenced pages and components # Check for Side1 and Side2 page definitions echo "Checking for page definitions..." rg -l "\"id\": \"Side[12]\"" -g "*.json" # Check for Input-AVRSNf component echo "Checking for Input component..." rg -l "\"id\": \"Input-AVRSNf\"" -g "*.json"Length of output: 2736
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout/layouts/Side1.json (1)
1-31
: Confirm correct removal of Summary2 components.The following changes are observed:
- Removed Summary2 component targeting Page "Side2"
- Removed Summary2 component targeting Component "Input-AVRSNf"
- Retained Summary2 components for layoutSet and Page "Side1"
✅ Verification successful
Verified: Summary2 components were correctly removed
The removal of Summary2 components targeting Side2 page and Input-AVRSNf component is correct, while maintaining the required Summary2 components for layoutSet and Side1 page.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that removed components are actually deleted # Check if Side2 page still exists echo "Checking if Side2 page still exists..." rg -l "\"id\": \"Side2\"" -g "*.json" # Check if Input-AVRSNf component still exists echo "Checking if Input component still exists..." rg -l "\"id\": \"Input-AVRSNf\"" -g "*.json"Length of output: 2462
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout2/layouts/Side1.json (2)
6-8
: Verify empty data model binding for Input component.The Input component has an empty
simpleBinding
. This should be validated to ensure it's intentional and won't cause runtime issues.
38-44
: Review self-referential Summary2 component.The Summary2 component (id: Summary2-aI91Tv) references the Input component (Input-QCSonu) defined in the same layout. While this is valid, verify that this self-reference is intentional and properly handled by the component deletion logic.
✅ Verification successful
Self-referential Summary2 component is part of test coverage
The component reference appears in test data specifically designed to verify Summary2 component behavior and deletion logic. The file structure and naming (
app-with-summary2-components
andapp-with-summary2-components-after-deleting-references
) indicates this is an intentional test case.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for other instances of self-referential Summary2 components # Search for Summary2 components referencing components in the same file ast-grep --pattern $'{\n $$$\n "target": {\n "type": "component",\n "id": "$_"\n },\n "id": "Summary2-$_",\n "type": "Summary2"\n}'Length of output: 135
Script:
#!/bin/bash # Search for Summary2 components in JSON files echo "=== Summary2 Components ===" rg -U --json '"type":\s*"Summary2"' -g '*.json' -A 5 -B 5 echo -e "\n=== Component Deletion Logic ===" # Look for files related to component deletion rg -l "deleteComponent|removeComponent" --type-add 'code:*.{ts,js,cs}' -t code echo -e "\n=== Related Test Cases ===" # Search for test files mentioning Summary2 or component deletion rg -l "Summary2|(?i)delete.*component" --type-add 'test:*.{test,spec,Tests}.{ts,js,cs}' -t testLength of output: 82515
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout2/layouts/Side2.json (1)
9-9
: Verify taskId consistency.The
taskId
field is set to "layout" for both Summary2 components. This differs from other layout files wheretaskId
is empty. Verify if this inconsistency is intentional.Also applies to: 18-18
✅ Verification successful
TaskId usage is consistent with codebase patterns
The
taskId
value "layout" in Side2.json follows the established pattern where Side2 layouts use taskIds that reflect their parent directory's purpose (e.g., "component" in component2/layouts, "layoutSet" in layoutSet2/layouts).🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check taskId usage patterns across layouts # Search for taskId patterns echo "Checking taskId patterns..." rg -A 1 "\"taskId\":" -g "*.json"Length of output: 22481
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component/layouts/Side1.json (1)
33-40
: Verify Input component reference.The Summary2 component references "Input-qWr0oa". Ensure this component exists and is not scheduled for deletion.
✅ Verification successful
Reference to deleted component is expected in test data
This file is part of test data specifically designed to test behavior after component deletion (located in "app-with-summary2-components-after-deleting-references"). The missing Input component reference appears to be intentional for testing purposes.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify referenced Input component # Check for Input-qWr0oa component echo "Checking for Input component..." rg -l "\"id\": \"Input-qWr0oa\"" -g "*.json"Length of output: 975
Script:
#!/bin/bash # Search for Input component definition echo "Searching for Input component definition..." rg -l "\"component\": \"Input\"" -g "*.json" # Search for any file that might contain the Input component echo -e "\nSearching for Input component files..." fd -g "*Input*.json"Length of output: 547
Script:
#!/bin/bash # Search for Input component definition in test data directories echo "Searching in test data directories..." rg -l "\"id\": \"Input-qWr0oa\".*\"component\": \"Input\"" -g "*.json" backend/tests/Designer.Tests/_TestData/ # List all json files in components directories echo -e "\nListing component directories content..." fd -g "*.json" . backend/tests/Designer.Tests/_TestData/ -t f | grep -i "/component"Length of output: 11829
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/Side1.json (2)
13-19
: Verify empty layoutSet target ID.The Summary2 component has an empty target ID for the layoutSet type. This could cause issues when testing component deletion behavior.
38-44
: Verify component reference integrity.The Summary2 component references Input-QCSonu which exists in this file. However, if Input-QCSonu is deleted, this Summary2 component should also be deleted.
✅ Verification successful
Component reference integrity is properly maintained
The test cases demonstrate that Summary2 components are automatically removed when their target components are deleted, as shown in the "after-deleting-references" version where Summary2 components targeting specific components are properly cleaned up.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check for any dangling references to Input-QCSonu in other files rg "Input-QCSonu" --type jsonLength of output: 715
Script:
#!/bin/bash # Compare the two versions of Side1.json diff backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/Side1.json backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout2/layouts/Side1.jsonLength of output: 288
Script:
#!/bin/bash # View the content of Side1.json cat backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/Side1.json # List files in both directories echo "=== Files in app-with-summary2-components ===" fd . backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/ echo -e "\n=== Files in app-with-summary2-components-after-deleting-references ===" fd . backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/Length of output: 9717
Script:
#!/bin/bash # Check Side2.json and Settings.json in both directories echo "=== Original Side2.json ===" cat backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/layouts/Side2.json echo -e "\n=== After-deleting Side2.json ===" cat backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/layout2/layouts/Side2.json echo -e "\n=== Settings.json ===" cat backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layout2/Settings.jsonLength of output: 2553
frontend/language/src/nb.json (2)
1202-1202
: LGTM! Clear warning message for component deletion.The updated message properly warns users that deleting a component will also delete any Summary2 components referencing it.
1806-1806
: LGTM! Clear warning message for page deletion.The updated message properly warns users that deleting a page will also delete any Summary2 components referencing it.
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component2/layouts/Side1.json (1)
1-56
: LGTM! Test data file with similar structure.This file follows the same pattern as the first Side1.json, serving as test data for Summary2 component deletion scenarios.
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components-after-deleting-references/App/ui/component2/layouts/Side1.json (1)
1-56
: LGTM! Test data file for post-deletion state.This file represents the expected state after deleting referenced components, serving as test data for verification.
backend/tests/Designer.Tests/_TestData/Repositories/testUser/ttd/app-with-summary2-components/App/ui/component2/layouts/Side2.json (1)
1-64
: LGTM! Test data file with similar structure.This file follows the same pattern as Side1.json but includes additional overrides configuration, serving as test data for Summary2 component deletion scenarios.
.../app-with-summary2-components-after-deleting-references/App/ui/component2/layouts/Side2.json
Show resolved
Hide resolved
...a/Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet/layouts/Side2.json
Show resolved
Hide resolved
.../app-with-summary2-components-after-deleting-references/App/ui/layoutSet2/layouts/Side1.json
Show resolved
Hide resolved
.../Repositories/testUser/ttd/app-with-summary2-components/App/ui/layoutSet2/layouts/Side1.json
Show resolved
Hide resolved
backend/src/Designer/Services/Implementation/AppDevelopmentService.cs
Outdated
Show resolved
Hide resolved
backend/src/Designer/EventHandlers/ComponentIdChanged/ComponentIdChangedLayoutsHandler.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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 (7)
backend/tests/Designer.Tests/Controllers/ResourceAdminController/ResourceAdminControllerTestsBaseClass.cs (1)
39-39
: Consider validating empty references in tests.The empty string for
Reference
property might not cover all test scenarios. Consider adding test cases with both empty and non-empty references to ensure proper handling of component deletions.protected static List<ResourceReference> GetTestResourceReferences() { List<ResourceReference> resourceReferences = new List<ResourceReference> { - new ResourceReference { Reference = string.Empty, ReferenceSource = ResourceReferenceSource.Default, ReferenceType = ResourceReferenceType.Default } + new ResourceReference { Reference = string.Empty, ReferenceSource = ResourceReferenceSource.Default, ReferenceType = ResourceReferenceType.Default }, + new ResourceReference { Reference = "deleted-component-id", ReferenceSource = ResourceReferenceSource.Default, ReferenceType = ResourceReferenceType.Default } }; return resourceReferences; }backend/src/Designer/Services/Implementation/AppDevelopmentService.cs (5)
612-612
: Use C# 8.0+ list initialization syntax.The empty list initialization can be simplified using C# 8.0+ syntax.
- List<Reference> referencesToDelete = []; + List<Reference> referencesToDelete = new();
621-621
: Avoid using array initializer with null coalescing operator.The use of array initializer with null coalescing operator is not idiomatic C# code.
- foreach (LayoutSetConfig layoutSet in layoutSets ?? [new() { Id = null }]) + foreach (LayoutSetConfig layoutSet in layoutSets ?? new List<LayoutSetConfig> { new() { Id = null } })
633-637
: Consider adding null check for layout.Value.The code checks if
layout.Value["data"]
is aJsonObject
, but it might be worth adding a null check forlayout.Value
itself first.- if (layout.Value["data"] is not JsonObject data) + if (layout.Value is null || layout.Value["data"] is not JsonObject data)
651-655
: Consider using pattern matching for null check.The null check can be simplified using pattern matching.
- string componentId = component["id"]?.GetValue<string>(); - if (string.IsNullOrEmpty(componentId)) - { - continue; - } + if (component["id"]?.GetValue<string>() is not string componentId || string.IsNullOrEmpty(componentId)) + { + continue; + }
688-724
: Consider extracting Summary2 component processing into a separate method.The Summary2 component processing logic is complex and would benefit from being extracted into a separate method for better readability and maintainability.
+ private bool ProcessSummary2Component( + JsonObject component, + JsonArray componentList, + int index, + string layoutSetId, + List<LayoutSetConfig> layoutSets, + List<string> deletedLayoutsSetIds, + List<Reference> deletedLayouts, + List<Reference> deletedComponents, + List<Reference> referencesToDelete) + { + if (component["target"] is not JsonObject target) + { + return false; + } + + bool hasChanges = false; + string type = target["type"]?.GetValue<string>(); + string id = target["id"]?.GetValue<string>(); + string taskId = target["taskId"]?.GetValue<string>(); + string targetLayoutSetId = string.IsNullOrEmpty(taskId) + ? layoutSetId + : layoutSets?.FirstOrDefault(item => item.Tasks?.Contains(taskId) ?? false)?.Id; + + if ((type == "page" && deletedLayouts.Exists(item => item.LayoutSetName == targetLayoutSetId && item.Id == id)) + || (type == "component" && deletedComponents.Exists(item => item.LayoutSetName == targetLayoutSetId && item.Id == id)) + || deletedLayoutsSetIds.Contains(targetLayoutSetId)) + { + string componentId = component["id"].GetValue<string>(); + referencesToDelete.Add(new Reference(ReferenceType.Component, layoutSetId, componentId)); + componentList.RemoveAt(index); + return true; + } + + if (component["overrides"] is JsonArray overrideList) + { + hasChanges |= ProcessOverrides(component, overrideList, targetLayoutSetId, deletedComponents); + } + + return hasChanges; + }Then use it in the switch statement:
case "Summary2": - if (component["target"] is JsonObject target) - { - // ... existing Summary2 processing code ... - } + hasLayoutChanges |= ProcessSummary2Component( + component, + componentList, + i, + layoutSet.Id, + layoutSets, + deletedLayoutsSetIds, + deletedLayouts, + deletedComponents, + referencesToDelete); break;backend/src/Designer/Controllers/ResourceAdminController.cs (1)
Line range hint
554-567
: Consider extracting validation logic for better maintainability.The validation logic for Maskinporten schema resources could be extracted into a separate method to improve readability and maintainability.
+ private void ValidateMaskinportenSchemaResource(ServiceResource resource) + { + if (resource.ResourceReferences == null || !resource.ResourceReferences.Any((x) => x.ReferenceType == ResourceReferenceType.MaskinportenScope)) + { + ModelState.AddModelError($"{resource.Identifier}.resourceReferences", "resourceerror.missingmaskinportenscope"); + } + for (int i = 0; i < resource.ResourceReferences?.Count; i++) + { + bool referenceError = string.IsNullOrEmpty(resource.ResourceReferences[i].Reference); + bool referenceSourceError = resource.ResourceReferences[i].ReferenceSource == null; + bool referenceTypeError = resource.ResourceReferences[i].ReferenceType == null; + + if (referenceError || referenceSourceError || referenceTypeError) + { + ModelState.AddModelError($"{resource.Identifier}.resourceReferences[{i}]", "resourceerror.missingresourcereferences."); + } + } + } private ValidationProblemDetails ValidateResource(ServiceResource resource) { // ... existing validation code ... if (resource.ResourceType == ResourceType.MaskinportenSchema) { - if (resource.ResourceReferences == null || !resource.ResourceReferences.Any((x) => x.ReferenceType == ResourceReferenceType.MaskinportenScope)) - { - ModelState.AddModelError($"{resource.Identifier}.resourceReferences", "resourceerror.missingmaskinportenscope"); - } - for (int i = 0; i < resource.ResourceReferences?.Count; i++) - { - bool referenceError = string.IsNullOrEmpty(resource.ResourceReferences[i].Reference); - bool referenceSourceError = resource.ResourceReferences[i].ReferenceSource == null; - bool referenceTypeError = resource.ResourceReferences[i].ReferenceType == null; - - if (referenceError || referenceSourceError || referenceTypeError) - { - ModelState.AddModelError($"{resource.Identifier}.resourceReferences[{i}]", "resourceerror.missingresourcereferences."); - } - } + ValidateMaskinportenSchemaResource(resource); } // ... rest of the validation code ... }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
backend/src/Designer/Controllers/ResourceAdminController.cs
(3 hunks)backend/src/Designer/Enums/ReferenceType.cs
(1 hunks)backend/src/Designer/Enums/ResourceReferenceSource.cs
(1 hunks)backend/src/Designer/Enums/ResourceReferenceType.cs
(1 hunks)backend/src/Designer/EventHandlers/ComponentDeleted/ComponentDeletedLayoutsHandler.cs
(1 hunks)backend/src/Designer/EventHandlers/LayoutPageDeleted/LayoutPageDeletedLayoutsHandler.cs
(1 hunks)backend/src/Designer/EventHandlers/LayoutSetDeleted/LayoutSetDeletedLayoutsHandler.cs
(1 hunks)backend/src/Designer/Models/Reference.cs
(1 hunks)backend/src/Designer/Models/ResourceReference.cs
(2 hunks)backend/src/Designer/Services/Implementation/AppDevelopmentService.cs
(2 hunks)backend/tests/Designer.Tests/Controllers/ResourceAdminController/ResourceAdminControllerTestsBaseClass.cs
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- backend/src/Designer/Models/Reference.cs
- backend/src/Designer/EventHandlers/LayoutSetDeleted/LayoutSetDeletedLayoutsHandler.cs
- backend/src/Designer/EventHandlers/LayoutPageDeleted/LayoutPageDeletedLayoutsHandler.cs
- backend/src/Designer/EventHandlers/ComponentDeleted/ComponentDeletedLayoutsHandler.cs
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Build environment and run e2e test
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Run integration tests against actual gitea and db
- GitHub Check: Analyze
🔇 Additional comments (8)
backend/tests/Designer.Tests/Controllers/ResourceAdminController/ResourceAdminControllerTestsBaseClass.cs (1)
39-39
: LGTM! Enum type updates align with the new reference tracking system.The change correctly updates the enum types to
ResourceReferenceSource
andResourceReferenceType
, supporting the enhanced reference tracking system.backend/src/Designer/Enums/ReferenceType.cs (1)
5-7
: LGTM! Clean and well-structured enum.The enum members are logically ordered from highest level (LayoutSet) to lowest level (Component), making it intuitive to understand the hierarchy of references in the layout system.
backend/src/Designer/Services/Implementation/AppDevelopmentService.cs (2)
598-608
: LGTM! Well-structured public method.The method provides a clean public interface for updating layout references, properly handling the repository initialization and layout sets retrieval.
748-751
: LGTM! Proper recursive cleanup.The code correctly handles recursive cleanup of references by calling
UpdateLayoutReferences
again with the newly discovered references that need to be deleted.backend/src/Designer/Enums/ResourceReferenceSource.cs (1)
8-8
: LGTM! Improved naming clarity.The rename from
ReferenceSource
toResourceReferenceSource
better reflects its purpose in the resource registry context.Let's verify all usages have been updated:
✅ Verification successful
All usages of the renamed enum have been updated correctly
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for any remaining references to the old enum name rg "ReferenceSource[^T]" --type csLength of output: 590
backend/src/Designer/Enums/ResourceReferenceType.cs (1)
8-30
: LGTM! Well-structured enum definition.The enum is well-documented, follows a logical order, and uses proper serialization attributes.
backend/src/Designer/Models/ResourceReference.cs (1)
16-16
: LGTM! Consistent type updates.Properties correctly updated to use the renamed enums while maintaining JSON serialization configuration.
Also applies to: 27-27
backend/src/Designer/Controllers/ResourceAdminController.cs (1)
Line range hint
490-500
: LGTM! Proper enum usage in resource filtering.The code correctly uses the new
ResourceReferenceType
enum for filtering services based on their reference types.
…mponents-that-has-a-reference-to-deleted-element-component-page-or-layout-set
There was a problem hiding this 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 (3)
backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteFormLayoutTests.cs (3)
60-62
: Consider adding more test scenarios.The test only covers one scenario with fixed values. Consider parameterizing the test with more scenarios using
[InlineData]
to test different layouts and components.
74-81
: Extract layout paths to a constant or configuration.The hardcoded array of layout paths could be moved to a constant or configuration file to improve maintainability and reusability. Also, consider using a more flexible collection type instead of an array.
- string[] layoutPaths = [ - "layout/layouts/Side1.json", - "layout/layouts/Side2.json", - "layout2/layouts/Side1.json", - "layout2/layouts/Side2.json", - ]; + private static readonly IReadOnlyList<string> LayoutPaths = new[] + { + "layout/layouts/Side1.json", + "layout/layouts/Side2.json", + "layout2/layouts/Side1.json", + "layout2/layouts/Side2.json" + };
64-66
: Document test data dependencies.Add XML documentation to describe the required structure and content of the test data repositories (
app-with-summary2-components
andapp-with-summary2-components-after-deleting-references
).+ // Test data requirements: + // app-with-summary2-components: Contains layouts with Summary 2.0 components + // app-with-summary2-components-after-deleting-references: Expected state after deletion
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteFormLayoutTests.cs
(2 hunks)backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteLayoutSetTests.cs
(1 hunks)backend/tests/Designer.Tests/Controllers/AppDevelopmentController/SaveFormLayoutTests.cs
(2 hunks)frontend/language/src/nb.json
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteLayoutSetTests.cs
- backend/tests/Designer.Tests/Controllers/AppDevelopmentController/SaveFormLayoutTests.cs
- frontend/language/src/nb.json
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Build environment and run e2e test
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Analyze
- GitHub Check: Run integration tests against actual gitea and db
- GitHub Check: Run dotnet build and test (ubuntu-latest)
🔇 Additional comments (2)
backend/tests/Designer.Tests/Controllers/AppDevelopmentController/DeleteFormLayoutTests.cs (2)
2-2
: LGTM!The addition of the
System.Linq
namespace is appropriate as it's required for theToList()
extension method used in the test.
71-72
: Verify async operation handling.Consider adding a timeout to the HTTP request and ensure proper resource cleanup:
- using var response = await HttpClient.SendAsync(httpRequestMessage); + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); + using var response = await HttpClient.SendAsync(httpRequestMessage, cts.Token);Also, verify that no other async operations are running that could affect the test:
layoutPaths.ToList().ForEach(file => | ||
{ | ||
string actual = TestDataHelper.GetFileFromRepo(org, app, developer, $"App/ui/{file}"); | ||
string expected = TestDataHelper.GetFileFromRepo(org, expectedApp, developer, $"App/ui/{file}"); | ||
Assert.True(JsonUtils.DeepEquals(actual, expected)); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance test assertions and error messages.
The current implementation could be improved by:
- Adding explicit verification that Summary 2.0 components are deleted
- Providing more descriptive error messages in assertions
- Adding null checks for file content
- layoutPaths.ToList().ForEach(file =>
- {
- string actual = TestDataHelper.GetFileFromRepo(org, app, developer, $"App/ui/{file}");
- string expected = TestDataHelper.GetFileFromRepo(org, expectedApp, developer, $"App/ui/{file}");
- Assert.True(JsonUtils.DeepEquals(actual, expected));
- });
+ foreach (var file in layoutPaths)
+ {
+ string actual = TestDataHelper.GetFileFromRepo(org, app, developer, $"App/ui/{file}");
+ string expected = TestDataHelper.GetFileFromRepo(org, expectedApp, developer, $"App/ui/{file}");
+
+ Assert.NotNull(actual, $"Layout file {file} not found in actual repository");
+ Assert.NotNull(expected, $"Layout file {file} not found in expected repository");
+ Assert.True(JsonUtils.DeepEquals(actual, expected),
+ $"Layout file {file} content does not match expected content");
+
+ // Verify Summary 2.0 components are deleted
+ Assert.DoesNotContain("\"type\": \"Summary2\"", actual);
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
layoutPaths.ToList().ForEach(file => | |
{ | |
string actual = TestDataHelper.GetFileFromRepo(org, app, developer, $"App/ui/{file}"); | |
string expected = TestDataHelper.GetFileFromRepo(org, expectedApp, developer, $"App/ui/{file}"); | |
Assert.True(JsonUtils.DeepEquals(actual, expected)); | |
}); | |
foreach (var file in layoutPaths) | |
{ | |
string actual = TestDataHelper.GetFileFromRepo(org, app, developer, $"App/ui/{file}"); | |
string expected = TestDataHelper.GetFileFromRepo(org, expectedApp, developer, $"App/ui/{file}"); | |
Assert.NotNull(actual, $"Layout file {file} not found in actual repository"); | |
Assert.NotNull(expected, $"Layout file {file} not found in expected repository"); | |
Assert.True(JsonUtils.DeepEquals(actual, expected), | |
$"Layout file {file} content does not match expected content"); | |
// Verify Summary 2.0 components are deleted | |
Assert.DoesNotContain("\"type\": \"Summary2\"", actual); | |
} |
Description
Delete all Summary 2.0 components that has a reference to a deleted component
Related Issue(s)
Verification
Summary by CodeRabbit
Based on the comprehensive summary, here are the updated release notes:
New Features
Bug Fixes
Documentation
Refactor
Style