Skip to content
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

Open
wants to merge 32 commits into
base: main
Choose a base branch
from

Conversation

mlqn
Copy link
Contributor

@mlqn mlqn commented Nov 21, 2024

Description

Delete all Summary 2.0 components that has a reference to a deleted component

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)

Summary by CodeRabbit

Based on the comprehensive summary, here are the updated release notes:

  • New Features

    • Enhanced event handling for layout and component management
    • Improved deletion workflows for layouts, components, and layout sets
    • New classes and methods for handling component and layout deletion events
  • Bug Fixes

    • Updated reference management to handle component and layout deletions more robustly
  • Documentation

    • Added clearer user warnings about deletion of associated Summary2 components
    • Updated user interface messages to explain deletion consequences
  • Refactor

    • Restructured reference type enumerations
    • Improved event-driven architecture for layout and component management
  • Style

    • Updated confirmation messages for better user clarity

@github-actions github-actions bot added solution/studio/designer Issues related to the Altinn Studio Designer solution. backend labels Nov 21, 2024
mlqn added 4 commits November 27, 2024 13:42
…elete-all-summary-20-components-that-has-a-reference-to-deleted-element-component-page-or-layout-set
@github-actions github-actions bot added the quality/testing Tests that are missing, needs to be created or could be improved. label Nov 29, 2024
Copy link

codecov bot commented Nov 29, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 95.65%. Comparing base (5dda0fd) to head (9ada558).

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.
📢 Have feedback on the report? Share it here.

@mlqn mlqn force-pushed the 13525-automatically-delete-all-summary-20-components-that-has-a-reference-to-deleted-element-component-page-or-layout-set branch from d881911 to 160d666 Compare December 16, 2024 11:56
mlqn added 2 commits January 6, 2025 14:50
…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
Copy link

@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

🧹 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:

  1. Documenting which Summary2 components should remain vs. be deleted
  2. Adding test cases for various reference scenarios (deleted pages, components, etc.)
  3. 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:

  1. Consolidating summary views where possible
  2. Documenting the purpose of each Summary2 component
  3. Implementing a more hierarchical summary structure
backend/src/Designer/Services/Implementation/AppDevelopmentService.cs (1)

632-632: Address the TODO comment

There'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:

  1. Make properties immutable by removing setters
  2. Add a constructor to initialize properties
  3. 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:

  1. Make properties immutable
  2. Add constructor
  3. 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:

  1. Creating a base handler class
  2. 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

📥 Commits

Reviewing files that changed from the base of the PR and between 9f902c6 and d360473.

📒 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.json

Length 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.cs

Length 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.json

Length 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.json

Length 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:

  1. This is intentional (e.g., part of a test case verifying cleanup)
  2. The file should be moved to a different test directory
  3. 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)'
done

Length 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}'
done

Length 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")'
done

Length 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/_TestData

Length 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.json

Length 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.json

Length 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:

  1. Deletion when layoutSet reference is empty
  2. Deletion when referenced pages don't exist
  3. Deletion when referenced component exists
  4. 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 enum ReferenceType enhances code clarity

The introduction of the ReferenceType enum and the Reference record improves type safety and readability.

backend/src/Designer/Events/LayoutSetDeletedEvent.cs (1)

9-9: Verify impact of changing property from LayoutSetId to LayoutSetName

Ensure that all references to LayoutSetId have been updated to LayoutSetName 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 issue

Add 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:

  1. Adding cancellation support for better resource management
  2. 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 to LayoutSetName 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:

  1. Remove the binding if it's not needed
  2. 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:

  1. Empty layoutSet ID at line 8-9
  2. Page references to "Side1" and "Side2"
  3. 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:

  1. Removed Summary2 component targeting Page "Side2"
  2. Removed Summary2 component targeting Component "Input-AVRSNf"
  3. 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 and app-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 test

Length 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 where taskId 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 json

Length 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.json

Length 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.json

Length 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.

Copy link

@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 (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 a JsonObject, but it might be worth adding a null check for layout.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

📥 Commits

Reviewing files that changed from the base of the PR and between d360473 and 7ca7686.

📒 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 and ResourceReferenceType, 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 to ResourceReferenceSource 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 cs

Length 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
Copy link

@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 (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 and app-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

📥 Commits

Reviewing files that changed from the base of the PR and between 7ca7686 and 0db4933.

📒 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 the ToList() 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:

Comment on lines +83 to +88
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));
});
Copy link

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:

  1. Adding explicit verification that Summary 2.0 components are deleted
  2. Providing more descriptive error messages in assertions
  3. 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.

Suggested change
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);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/process Area: Related to app process (e.g. signing, receipt, fill inn, payment, etc). backend frontend quality/testing Tests that are missing, needs to be created or could be improved. solution/studio/designer Issues related to the Altinn Studio Designer solution.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants