Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2322,7 +2322,7 @@ def overall_compliance(self):
return round(count * 100 / total)

def __str__(self):
return self.folder.name + "/" + self.name
return f"{self.folder}/{self.name}"


class SecurityException(NameDescriptionMixin, FolderMixin, PublishInRootFolderMixin):
Expand Down
2 changes: 2 additions & 0 deletions backend/core/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ class PerimeterReadSerializer(BaseModelSerializer):
folder = FieldsRelatedField()
lc_status = serializers.CharField(source="get_lc_status_display")
default_assignee = FieldsRelatedField(many=True)
str = serializers.CharField(source="__str__", read_only=True)

class Meta:
model = Perimeter
Expand Down Expand Up @@ -1415,6 +1416,7 @@ class FolderReadSerializer(BaseModelSerializer):
filtering_labels = FieldsRelatedField(many=True)

content_type = serializers.CharField(source="get_content_type_display")
str = serializers.CharField(source="__str__", read_only=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's verify the FolderReadSerializer change and context
cat -n backend/core/serializers.py | sed -n '1410,1430p'

Repository: intuitem/ciso-assistant-community

Length of output: 809


🏁 Script executed:

# Check the Folder model and its __str__ method
rg -A 15 "class Folder" backend/core/models.py | head -40

Repository: intuitem/ciso-assistant-community

Length of output: 59


🏁 Script executed:

# Check the FolderViewSet implementation
rg -A 30 "class FolderViewSet" backend/core/views.py

Repository: intuitem/ciso-assistant-community

Length of output: 1080


🏁 Script executed:

# Also check PerimeterReadSerializer for comparison
rg -B 5 -A 10 "class PerimeterReadSerializer" backend/core/serializers.py

Repository: intuitem/ciso-assistant-community

Length of output: 536


🏁 Script executed:

# Check Folder model __str__ method
rg -A 10 "class Folder" backend/core/models.py | grep -A 20 "def __str__"

Repository: intuitem/ciso-assistant-community

Length of output: 59


🏁 Script executed:

# Check FolderViewSet.get_queryset() for query optimization
rg -A 40 "class FolderViewSet" backend/core/views.py | grep -A 20 "get_queryset"

Repository: intuitem/ciso-assistant-community

Length of output: 59


🏁 Script executed:

# Check PathAwareOrderingFilter implementation
rg -B 5 -A 30 "class PathAwareOrderingFilter" backend/core/

Repository: intuitem/ciso-assistant-community

Length of output: 2298


🏁 Script executed:

# Also check if there's any prefetch_related in the base viewset
rg -A 20 "class BaseModelViewSet" backend/core/views.py | head -40

Repository: intuitem/ciso-assistant-community

Length of output: 714


🏁 Script executed:

# Find the Folder model file location
find backend -name "*.py" -type f | xargs grep -l "^class Folder"

Repository: intuitem/ciso-assistant-community

Length of output: 148


🏁 Script executed:

# Get Folder model definition with __str__
rg "class Folder\(" backend/core/models.py -A 100 | head -120

Repository: intuitem/ciso-assistant-community

Length of output: 59


🏁 Script executed:

# Check if FolderViewSet overrides get_queryset
rg "class FolderViewSet" backend/core/views.py -A 100 | grep -A 15 "def get_queryset"

Repository: intuitem/ciso-assistant-community

Length of output: 59


🏁 Script executed:

# Search for Folder model definition more broadly
rg "^class Folder" backend/

Repository: intuitem/ciso-assistant-community

Length of output: 550


🏁 Script executed:

# Check what's in backend/core/models.py for Folder
rg "class Folder" backend/core/models.py -A 80

Repository: intuitem/ciso-assistant-community

Length of output: 59


🏁 Script executed:

# Check the import structure
head -50 backend/core/models.py

Repository: intuitem/ciso-assistant-community

Length of output: 1640


🏁 Script executed:

# Get the Folder model from iam/models.py
rg "class Folder\(" backend/iam/models.py -A 50

Repository: intuitem/ciso-assistant-community

Length of output: 1456


🏁 Script executed:

# Check if Folder has __str__ method
rg "class Folder\(" backend/iam/models.py -A 100 | grep -A 5 "def __str__"

Repository: intuitem/ciso-assistant-community

Length of output: 388


🏁 Script executed:

# Also check NameDescriptionMixin to see if __str__ is there
rg "class NameDescriptionMixin" backend/ -A 20

Repository: intuitem/ciso-assistant-community

Length of output: 1191


🏁 Script executed:

# Check the get_folder_full_path method
rg "def get_folder_full_path" backend/iam/models.py -A 20

Repository: intuitem/ciso-assistant-community

Length of output: 1671


🏁 Script executed:

# Check if there's a property or method that might be caching the path
rg "get_folder_full_path\|folder_path\|get_path" backend/iam/models.py

Repository: intuitem/ciso-assistant-community

Length of output: 59


🏁 Script executed:

# Check what the full Folder model looks like, especially any properties
rg "class Folder\(" backend/iam/models.py -A 150 | tail -100

Repository: intuitem/ciso-assistant-community

Length of output: 4107


🏁 Script executed:

# Let's check if FolderViewSet has a custom get_queryset method
rg "class FolderViewSet" backend/core/views.py -A 200 | grep -B 5 -A 20 "def get_queryset"

Repository: intuitem/ciso-assistant-community

Length of output: 59


🏁 Script executed:

# Check if there's any prefetch_related or select_related in the base class or viewset
rg "class FolderViewSet" backend/core/views.py -A 200 | grep -E "prefetch|select_related"

Repository: intuitem/ciso-assistant-community

Length of output: 59


🏁 Script executed:

# Verify the exact attribute name used in PathAwareOrderingFilter
rg "path_related_field" backend/core/views.py

Repository: intuitem/ciso-assistant-community

Length of output: 188


🏁 Script executed:

# Let's check the full FolderViewSet implementation to see if there's any queryset optimization we missed
cat -n backend/core/views.py | grep -A 80 "class FolderViewSet"

Repository: intuitem/ciso-assistant-community

Length of output: 3472


🏁 Script executed:

# Check if BaseModelViewSet has any get_queryset override
cat -n backend/core/views.py | grep -B 5 -A 30 "class BaseModelViewSet"

Repository: intuitem/ciso-assistant-community

Length of output: 1354


🏁 Script executed:

# Get the full get_queryset method from BaseModelViewSet
cat -n backend/core/views.py | sed -n '631,700p'

Repository: intuitem/ciso-assistant-community

Length of output: 3951


🏁 Script executed:

# Check if there's any queryset optimization specific to the Folder model
rg "Folder.objects" backend/core/views.py | head -20

Repository: intuitem/ciso-assistant-community

Length of output: 1398


🏁 Script executed:

# Let me verify the attribute name discrepancy more carefully
rg "path_related_field" backend/core/views.py -B 2 -A 2

Repository: intuitem/ciso-assistant-community

Length of output: 483


🏁 Script executed:

# Check if the FolderViewSet's attribute name matches what PathAwareOrderingFilter expects
rg "path_related_field\|path_related_fields" backend/core/views.py

Repository: intuitem/ciso-assistant-community

Length of output: 59


🏁 Script executed:

# Let's also check if there are any other viewsets that use this pattern correctly
rg "path_related_field" backend/core/views.py -B 10 | grep -E "class \w+ViewSet|path_related"

Repository: intuitem/ciso-assistant-community

Length of output: 188


🏁 Script executed:

# Check the Folder model fields to see if it has a "folder" field
rg "class Folder\(" backend/iam/models.py -A 80 | grep -E "^\s+(parent_folder|folder)\s*="

Repository: intuitem/ciso-assistant-community

Length of output: 115


🏁 Script executed:

# Verify that Folder model doesn't have a "folder" field
rg "^\s+folder\s*=" backend/iam/models.py

Repository: intuitem/ciso-assistant-community

Length of output: 573


🏁 Script executed:

# Let me look at the complete PathAwareOrderingFilter implementation
cat -n backend/core/views.py | sed -n '555,600p'

Repository: intuitem/ciso-assistant-community

Length of output: 1936


🏁 Script executed:

# Find the complete PathAwareOrderingFilter implementation
rg "class PathAwareOrderingFilter" backend/core/views.py -A 50

Repository: intuitem/ciso-assistant-community

Length of output: 2245


LGTM! Verify and fix query optimization for folder list views.

The addition of the str field to expose the Folder's string representation is consistent with the codebase. However, there is a genuine N+1 query concern:

The Folder.__str__() method traverses parent_folder relationships to build a hierarchical path. When serializing folder lists, each folder will trigger separate queries to fetch its parent folders. Additionally, there's an attribute name mismatch: FolderViewSet declares path_related_fields = "parent_folder" (plural), but PathAwareOrderingFilter looks for path_related_field (singular), preventing the filter's select_related() optimization from being applied.

To fix this, either:

  1. Rename path_related_fields to path_related_field in FolderViewSet, or
  2. Add explicit prefetch_related("parent_folder") to FolderViewSet.get_queryset()
🤖 Prompt for AI Agents
In backend/core/serializers.py around line 1419, adding the str field exposes
Folder.__str__ which walks parent_folder and causes N+1 queries when serializing
lists; fix FolderViewSet so the controller-side query optimization applies by
either renaming the attribute path_related_fields to path_related_field
(singular) to match PathAwareOrderingFilter so it can call select_related(...),
or explicitly add prefetch_related("parent_folder") (or select_related if single
FK) inside FolderViewSet.get_queryset() to eagerly load parents and avoid
per-object DB hits.


class Meta:
model = Folder
Expand Down
149 changes: 89 additions & 60 deletions backend/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1120,9 +1120,6 @@ def get(self, request, format=None):
return Response(content_types)


# Risk Assessment


class PerimeterFilter(GenericFilterSet):
folder = df.ModelMultipleChoiceFilter(
queryset=Folder.objects.all(),
Expand All @@ -1136,15 +1133,91 @@ class Meta:
fields = ["name", "folder", "lc_status", "campaigns"]


class PathAwareOrderingFilter(filters.OrderingFilter):
"""
Ordering filter that supports Python-side ordering for configured path fields.

- path_fields: fields that require Python-side ordering
- related_field: the related FK to follow for path-aware sorting (optional)
"""

path_fields: set[str] = set()
related_field: str | None = None # override per view if needed

def filter_queryset(self, request, queryset, view):
ordering = self.get_ordering(request, queryset, view)
if not ordering:
return queryset

# Use view-defined path_fields if not explicitly set in the filter
path_fields = self.path_fields or getattr(view, "path_ordering_fields", set())
if not path_fields:
return super().filter_queryset(request, queryset, view)

# Normalize ordering fields
normalized_ordering = [f.lstrip("-") for f in ordering]
if not any(f in path_fields for f in normalized_ordering):
return super().filter_queryset(request, queryset, view)

# Optional related field for path-aware sorting
related_field = getattr(view, "path_related_field", "folder")
if related_field and hasattr(queryset.model, related_field):
queryset = queryset.select_related(related_field)

data = list(queryset)

# Build full path string
def full_path(obj):
if isinstance(obj, Folder):
return str(obj)
folder = getattr(obj, related_field, None) if related_field else None
if folder is None:
return ""
# Use get_folder_full_path if available
if hasattr(folder, "get_folder_full_path"):
items = folder.get_folder_full_path(include_root=False)
names = [getattr(f, "name", "") or "" for f in items]
return " / ".join(names) if names else (folder.name or "")
return getattr(folder, "name", "") or ""

# Key function for sorting
def key_for_field(obj, field):
if field not in path_fields:
value = getattr(obj, field, "")
return value.casefold() if isinstance(value, str) else value
# Path-aware field
path_key = full_path(obj).casefold()
name_key = (getattr(obj, "name", "") or "").casefold()
return (path_key, name_key)

# Apply multi-field stable sort in reverse order
for field in reversed(ordering):
reverse = field.startswith("-")
field_name = field.lstrip("-")
data.sort(
key=lambda obj, f=field_name: key_for_field(obj, f), reverse=reverse
)

return data


class PerimeterViewSet(BaseModelViewSet):
"""
API endpoint that allows perimeters to be viewed or edited.
"""

model = Perimeter
filterset_class = PerimeterFilter
search_fields = ["name", "ref_id", "description"]
search_fields = ["name", "folder__name", "ref_id", "description"]
filterset_fields = ["name", "folder", "campaigns"]
filter_backends = [
DjangoFilterBackend,
PathAwareOrderingFilter,
filters.SearchFilter,
]
ordering_fields = ["name", "folder", "str", "description", "default_assignee"]
path_ordering_fields = {"str"}
path_fields = {"str"}

@method_decorator(cache_page(60 * LONG_CACHE_TTL))
@action(detail=False, name="Get status choices")
Expand Down Expand Up @@ -5456,66 +5529,13 @@ def destroy(self, request, *args, **kwargs):
return super().destroy(request, *args, **kwargs)


class UserGroupOrderingFilter(filters.OrderingFilter):
class UserGroupOrderingFilter(PathAwareOrderingFilter):
"""
Custom ordering filter:
- Performs in-memory (Python) sorting only for `localization_dict`.
- The sort key is a tuple: (folder full_path OR folder.name, object.name).
- Supports `-localization_dict` for descending order.
- For all other fields, it falls back to standard SQL ordering.
- Supports `localization_dict` via PathAwareOrderingFilter
"""

def filter_queryset(self, request, queryset, view):
ordering = self.get_ordering(request, queryset, view)
if not ordering:
return queryset

# Special case: in-memory sorting for `localization_dict`
if len(ordering) == 1 and ordering[0].lstrip("-") == "localization_dict":
desc = ordering[0].startswith("-")

# Optimize DB access: fetch the related folder in one query
queryset = queryset.select_related("folder")

# Materialize queryset into a list to sort in Python
data = list(queryset)

def full_path_or_name(folder):
"""
Build a string key from the folder:
- Prefer the full path (names of all parent folders + current).
- Fall back to the folder's name if no path is available.
"""
if folder is None:
return ""

path_list = getattr(folder, "get_folder_full_path", None)
if callable(path_list):
items = folder.get_folder_full_path(include_root=False)
names = [getattr(f, "name", "") or "" for f in items]
if names:
return "/".join(names)

# Fallback: just the folder name
return getattr(folder, "name", "") or ""

def key_func(obj):
# Get the folder from the object
folder = getattr(obj, "folder", None)
# If you want to be more robust, you could use:
# from yourapp.models import Folder
# folder = Folder.get_folder(obj)

path_key = full_path_or_name(folder).casefold()
name_key = (getattr(obj, "name", "") or "").casefold()
return (path_key, name_key)

# Perform stable sort, reverse if `-localization_dict`
data.sort(key=key_func, reverse=desc)
return data

# Default case: fall back to SQL ordering
return super().filter_queryset(request, queryset, view)
path_fields = {"localization_dict"}


class UserGroupViewSet(BaseModelViewSet):
Expand Down Expand Up @@ -5583,7 +5603,16 @@ class FolderViewSet(BaseModelViewSet):
model = Folder
filterset_class = FolderFilter
search_fields = ["name"]
filter_backends = [
DjangoFilterBackend,
PathAwareOrderingFilter,
filters.SearchFilter,
]
ordering_fields = ["name", "str", "parent_folder", "description", "content_type"]
batch_size = 100 # Configurable batch size for processing domain import
path_ordering_fields = {"str"}
path_fields = {"str"}
path_related_fields = "parent_folder"

def perform_create(self, serializer):
"""
Expand Down
12 changes: 8 additions & 4 deletions backend/iam/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@ class Meta:
verbose_name_plural = _("Folders")

def __str__(self) -> str:
return self.name.__str__()
path = self.get_folder_full_path(include_root=False)
names = [getattr(folder, "name", "") or "" for folder in path]
cleaned = [name for name in names if name]
display = "/".join(cleaned) if cleaned else (self.name or "")
return display or ""

def get_sub_folders(self) -> Generator[Self, None, None]:
"""Return the list of subfolders"""
Expand Down Expand Up @@ -381,15 +385,15 @@ class Meta:

def __str__(self) -> str:
if self.builtin:
return f"{self.folder.name} - {BUILTIN_USERGROUP_CODENAMES.get(self.name)}"
return f"{self.folder.name} - {self.name}"
return f"{self.folder} - {BUILTIN_USERGROUP_CODENAMES.get(self.name)}"
return f"{self.folder} - {self.name}"

def get_name_display(self) -> str:
return self.name

def get_localization_dict(self) -> dict:
return {
"folder": self.folder.name,
"folder": str(self.folder),
"role": BUILTIN_USERGROUP_CODENAMES.get(self.name)
if self.builtin
else self.name,
Expand Down
21 changes: 21 additions & 0 deletions enterprise/backend/enterprise_core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,34 @@ def get(self, request):
return Response({"status": "expired", "days_expired": days_expired})


class RoleOrderingFilter(filters.OrderingFilter):
"""
Order roles by their display name (sensitive to builtin translations).
"""

def filter_queryset(self, request, queryset, view):
ordering = self.get_ordering(request, queryset, view)
if not ordering:
return queryset

if len(ordering) == 1 and ordering[0].lstrip("-") == "name":
reverse = ordering[0].startswith("-")
data = list(queryset)
data.sort(key=lambda role: str(role).casefold(), reverse=reverse)
return data

return super().filter_queryset(request, queryset, view)


class RoleViewSet(BaseModelViewSet):
"""
API endpoint that allows roles to be viewed or edited
"""

model = Role
ordering = ["builtin", "name"]
ordering_fields = ["name"]
filter_backends = [DjangoFilterBackend, RoleOrderingFilter, filters.SearchFilter]

def perform_create(self, serializer):
"""
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/lib/components/DetailView/DetailView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,9 @@
? key.replace('_', '-') + '-field-value'
: null}
>
{#if value !== null && value !== undefined && value !== ''}
{#if key === 'name' && (data.model?.name === 'folder' || data.urlModel === 'folders') && data.data?.str}
{data.data.str}
{:else if value !== null && value !== undefined && value !== ''}
{#if key === 'asset_class'}
<!-- Special case for asset_class - Always translate the value -->
{#if typeof value === 'object' && (value.str || value.name)}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/utils/crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ export const URL_MODEL_MAP: ModelMap = {
{ field: 'ebios_rm_study', urlModel: 'ebios-rm' }
],
reverseForeignKeyFields: [{ field: 'risk_assessment', urlModel: 'risk-scenarios' }],
selectFields: [{ field: 'status' }, { field: 'risk_tolerance', valueType: 'number' }],
selectFields: [{ field: 'status' }],
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the actual file and the selectFields definition for risk-assessments
cat -n frontend/src/lib/utils/crud.ts | sed -n '220,240p'

Repository: intuitem/ciso-assistant-community

Length of output: 1191


🏁 Script executed:

# Search for all references to risk_tolerance in the entire codebase
echo "=== All risk_tolerance references ==="
rg -n 'risk_tolerance' --type=ts --type=js --type=svelte

Repository: intuitem/ciso-assistant-community

Length of output: 162


🏁 Script executed:

# Search for risk-assessments model definition to understand context
echo "=== Risk assessments model definition ==="
rg -B5 -A10 "'risk-assessments'" frontend/src/lib/utils/crud.ts

Repository: intuitem/ciso-assistant-community

Length of output: 5671


🏁 Script executed:

# Check if risk_tolerance is used in any components or forms
echo "=== Searching for risk_tolerance in component code ==="
fd -e svelte -e ts -e js . frontend/src -x grep -l 'risk_tolerance' {} \;

Repository: intuitem/ciso-assistant-community

Length of output: 432


🏁 Script executed:

# Check how risk_tolerance is used in RiskAssessmentForm.svelte
echo "=== RiskAssessmentForm.svelte usage ==="
grep -n 'risk_tolerance' frontend/src/lib/components/Forms/ModelForm/RiskAssessmentForm.svelte -C3

Repository: intuitem/ciso-assistant-community

Length of output: 433


🏁 Script executed:

# Check how risk_tolerance is defined in schemas.ts
echo "=== risk_tolerance in schemas.ts ==="
grep -n 'risk_tolerance' frontend/src/lib/utils/schemas.ts -C3

Repository: intuitem/ciso-assistant-community

Length of output: 763


🏁 Script executed:

# Check the crud.ts file to see if there are other selectFields definitions or if this was previously set
echo "=== Check if risk_tolerance appears elsewhere in crud.ts ==="
grep -n 'risk_tolerance' frontend/src/lib/utils/crud.ts -C3

Repository: intuitem/ciso-assistant-community

Length of output: 444


🏁 Script executed:

# Check QuantitativeRiskStudyForm for context
echo "=== QuantitativeRiskStudyForm.svelte usage ==="
grep -n 'risk_tolerance' frontend/src/lib/components/Forms/ModelForm/QuantitativeRiskStudyForm.svelte -C3

Repository: intuitem/ciso-assistant-community

Length of output: 2536


Restore risk_tolerance to selectFields for risk-assessments—this removal breaks the form.

The risk_tolerance field has been removed from the selectFields array at line 231, but it is actively used in RiskAssessmentForm.svelte (line 125) to display and edit risk tolerance data. The selectFields array controls which fields are included in API SELECT queries; removing it means the field will not be fetched, leaving the form with undefined data and breaking risk assessment edits.

The field is defined in the schema as risk_tolerance: z.number().optional().default(-1) and is essential for the risk assessment form. Restore it to:

selectFields: [{ field: 'status' }, { field: 'risk_tolerance' }],
🤖 Prompt for AI Agents
In frontend/src/lib/utils/crud.ts around line 231, the selectFields array no
longer includes risk_tolerance which causes RiskAssessmentForm.svelte (line 125)
to receive undefined for that field; restore risk_tolerance to the SELECT list
so the API returns it. Update the selectFields entry to include both status and
risk_tolerance (i.e., ensure the array contains { field: 'status' } and { field:
'risk_tolerance' }) so the form can read and edit the value.

filters: [{ field: 'perimeter' }, { field: 'auditor' }, { field: 'status' }]
},
'risk-assessment_duplicate': {
Expand Down
19 changes: 15 additions & 4 deletions frontend/src/lib/utils/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ export const DOMAIN_FILTER: ListViewFilterConfig = {
}
};

export const PARENT_DOMAIN_FILTER: ListViewFilterConfig = {
component: AutocompleteSelect,
props: {
optionsEndpoint: 'folders?content_type=DO&content_type=GL',
optionsLabelField: 'str',
label: 'parent_domain',
multiple: true
}
};

export const LABELS_FILTER: ListViewFilterConfig = {
component: AutocompleteSelect,
props: {
Expand Down Expand Up @@ -1194,16 +1204,17 @@ export const VULNERABILITY_SEVERITY_FILTER: ListViewFilterConfig = {

export const listViewFields = {
folders: {
head: ['name', 'description', 'contentType', 'parentDomain', 'labels'],
body: ['name', 'description', 'content_type', 'parent_folder', 'filtering_labels'],
head: ['name', 'description', 'contentType', 'labels'],
body: ['str', 'description', 'content_type', 'filtering_labels'],
filters: {
parent_folder: PARENT_DOMAIN_FILTER,
content_type: CONTENT_TYPE_FILTER,
filtering_labels: LABELS_FILTER
}
},
perimeters: {
head: ['ref_id', 'name', 'description', 'defaultAssignee', 'domain'],
body: ['ref_id', 'name', 'description', 'default_assignee', 'folder'],
head: ['ref_id', 'name', 'description', 'defaultAssignee'],
body: ['ref_id', 'str', 'description', 'default_assignee'],
filters: {
folder: DOMAIN_FILTER,
lc_status: PERIMETER_STATUS_FILTER
Expand Down
1 change: 1 addition & 0 deletions frontend/tests/functional/detailed/ebios-rm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ test('ebios rm study', async ({

await test.step('workshop 5', async () => {
await page.getByRole('button', { name: ' Step 1 Generate the risk' }).click();
await page.waitForTimeout(3000);
await riskAssessmentsPage.form.fill({
name: 'test-risk-assessment-ebios-rm',
perimeter: `${vars.folderName}/${vars.perimeterName}`
Expand Down
1 change: 1 addition & 0 deletions frontend/tests/utils/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@ export class TestContent {
displayName: 'Perimeters',
modelName: 'perimeter',
build: {
str: `${vars.folderName}/${vars.perimeterName}`,
name: vars.perimeterName,
description: vars.description,
folder: vars.folderName,
Expand Down
Loading