Skip to content
Merged
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 scanpipe/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ def filter_run_status(self, queryset, name, value):
"""Filter by Run status using the `RunQuerySet` methods."""
run_queryset_method = value
run_queryset = getattr(Run.objects, run_queryset_method)()
return queryset.filter(runs__in=run_queryset)
return queryset.filter(runs__in=run_queryset).distinct()


class JSONContainsFilter(django_filters.CharFilter):
Expand Down
2 changes: 1 addition & 1 deletion scanpipe/templates/scanpipe/forms/project_clone_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</div>
<div class="field">
<label class="checkbox" for="{{ form.execute_now.id_for_label }}-clone">
<input type="checkbox" name="{{ form.execute_now.name }}" id="{{ form.execute_now.id_for_label }}-clone">
<input type="checkbox" name="{{ form.execute_now.html_name }}" id="{{ form.execute_now.id_for_label }}-clone">
{{ form.execute_now.label }}
</label>
<p class="help">{{ form.execute_now.help_text }}</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</div>
</div>
<div class="field">
<label class="label" for="{{ form.name.id_for_label }}">
<label class="label" for="{{ form.purl.id_for_label }}">
PURL
</label>
<div class="control">
Expand Down
2 changes: 1 addition & 1 deletion scanpipe/templates/scanpipe/includes/search_field.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{% endif %}
<form method="get">
<p class="control has-icons-left">
<input class="input {{ extra_class }}" type="search" placeholder="{% if placeholder %}{{ placeholder }}{% else %}Search {{ filter.verbose_name_plural }}{% endif %}" name="{{ filter.form.search.name }}" value="{{ filter.form.search.value|default_if_none:'' }}">
<input class="input {{ extra_class }}" type="search" placeholder="{% if placeholder %}{{ placeholder }}{% else %}Search {{ filter.verbose_name_plural }}{% endif %}" name="{{ filter.form.search.html_name }}" value="{{ filter.form.search.value|default_if_none:'' }}">
<span class="icon is-small is-left">
<i class="fa-solid fa-search"></i>
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@
<hr>
<div class="field include-all-field">
<label class="checkbox" for="{{ archive_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ archive_form.select_across.name }}" id="{{ archive_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ archive_form.select_across.html_name }}" id="{{ archive_form.select_across.id_for_label }}">
Include all {{ paginator.count|intcomma }} projects
</label>
<p class="help">{{ outputs_download_form.select_across.help_text }}</p>
</div>
</div>
{% endif %}
</section>
<input type="hidden" name="{{ archive_form.url_query.name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="{{ archive_form.url_query.html_name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="action" value="archive">
<footer class="modal-card-foot is-justify-content-flex-end">
<div class="buttons">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</p>
</section>
<form action="{% url 'project_action' %}" method="post" id="delete-projects-form">{% csrf_token %}
<input type="hidden" name="{{ action_form.url_query.name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="{{ action_form.url_query.html_name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="action" value="delete">
<footer class="modal-card-foot is-justify-content-flex-end">
<div class="buttons">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@
<hr>
<div class="field">
<label class="checkbox" for="{{ outputs_download_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ outputs_download_form.select_across.name }}" id="{{ outputs_download_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ outputs_download_form.select_across.html_name }}" id="{{ outputs_download_form.select_across.id_for_label }}">
Include all {{ paginator.count|intcomma }} projects
</label>
<p class="help">{{ outputs_download_form.select_across.help_text }}</p>
</div>
</div>
{% endif %}
</section>
<input type="hidden" name="{{ outputs_download_form.url_query.name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="{{ outputs_download_form.url_query.html_name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="action" value="download">
<footer class="modal-card-foot is-justify-content-flex-end">
<div class="buttons">
Expand Down
4 changes: 2 additions & 2 deletions scanpipe/templates/scanpipe/modals/projects_report_modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@
<hr>
<div class="field include-all-field">
<label class="checkbox" for="{{ report_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ report_form.select_across.name }}" id="{{ report_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ report_form.select_across.html_name }}" id="{{ report_form.select_across.id_for_label }}">
Include all {{ paginator.count|intcomma }} projects
</label>
<p class="help">{{ report_form.select_across.help_text }}</p>
</div>
</div>
{% endif %}
</section>
<input type="hidden" name="{{ report_form.url_query.name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="{{ report_form.url_query.html_name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="action" value="report">
<footer class="modal-card-foot is-justify-content-flex-end">
<div class="buttons">
Expand Down
4 changes: 2 additions & 2 deletions scanpipe/templates/scanpipe/modals/projects_reset_modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@
<hr>
<div class="field include-all-field">
<label class="checkbox" for="{{ reset_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ reset_form.select_across.name }}" id="{{ reset_form.select_across.id_for_label }}">
<input type="checkbox" name="{{ reset_form.select_across.html_name }}" id="{{ reset_form.select_across.id_for_label }}">
Include all {{ paginator.count|intcomma }} projects
</label>
<p class="help">{{ outputs_download_form.select_across.help_text }}</p>
</div>
</div>
{% endif %}
</section>
<input type="hidden" name="{{ action_form.url_query.name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="{{ reset_form.url_query.html_name }}" value="{{ request.GET.urlencode }}">
<input type="hidden" name="action" value="reset">
<footer class="modal-card-foot is-justify-content-flex-end">
<div class="buttons">
Expand Down
28 changes: 24 additions & 4 deletions scanpipe/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,17 @@ def test_scanpipe_views_project_list_state_of_filters_in_search_form(self):
expected = '<input type="hidden" name="status" value="failed">'
self.assertContains(response, expected, html=True)

def test_scanpipe_views_project_list_filter_by_status_distinct_results(self):
url = reverse("project_list")
pipeline1 = self.project1.add_pipeline(pipeline_name="scan_codebase")
pipeline1.set_task_stopped()
pipeline2 = self.project1.add_pipeline(pipeline_name="scan_codebase")
pipeline2.set_task_stopped()

data = {"status": "failed"}
response = self.client.get(url, data=data)
self.assertEqual(1, len(response.context["object_list"]))

@mock.patch("scanpipe.views.ProjectListView.get_paginate_by")
def test_scanpipe_views_project_list_filters_exclude_page(self, mock_paginate_by):
url = reverse("project_list")
Expand All @@ -174,13 +185,22 @@ def test_scanpipe_views_project_list_modal_forms_include_url_query(self):
url = reverse("project_list")
response = self.client.get(url)

expected = '<input type="hidden" name="url_query" value="">'
self.assertContains(response, expected, html=True)
expected_html_names = [
"url_query",
"download-url_query",
"report-url_query",
"archive-url_query",
"reset-url_query",
]
for html_name in expected_html_names:
expected = f'<input type="hidden" name="{html_name}" value="">'
self.assertContains(response, expected, html=True)

url_query = "name=search_value"
response = self.client.get(url + "?" + url_query)
expected = f'<input type="hidden" name="url_query" value="{url_query}">'
self.assertContains(response, expected, html=True)
for html_name in expected_html_names:
expected = f'<input type="hidden" name="{html_name}" value="{url_query}">'
self.assertContains(response, expected, html=True)

@mock.patch("scanpipe.views.ProjectListView.get_paginate_by")
def test_scanpipe_views_project_list_modal_forms_include_show_on_all_checked(
Expand Down
10 changes: 4 additions & 6 deletions scanpipe/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1351,14 +1351,12 @@ def get_project_queryset(selected_project_ids=None, action_form=None):
An instance of BaseProjectActionForm can be provided as the ``action_form``
argument for the support of ``select_across``.
"""
if action_form:
select_across = action_form.cleaned_data.get("select_across")
if action_form and action_form.cleaned_data.get("select_across"):
# url_query may be empty for a "select everything"
url_query = action_form.cleaned_data.get("url_query", "")
if select_across:
project_filterset = ProjectFilterSet(data=QueryDict(url_query))
if project_filterset.is_valid():
return project_filterset.qs
project_filterset = ProjectFilterSet(data=QueryDict(url_query))
if project_filterset.is_valid():
return project_filterset.qs

if selected_project_ids:
return Project.objects.filter(uuid__in=selected_project_ids)
Expand Down