Skip to content

Commit 4880880

Browse files
committed
Fix multiple failing tests
Signed-off-by: tdruez <[email protected]>
1 parent 4914e3b commit 4880880

File tree

4 files changed

+30
-141
lines changed

4 files changed

+30
-141
lines changed

scanpipe/templates/scanpipe/panels/project_codebase.html

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,17 @@
22
<div class="panel-heading is-flex is-justify-content-space-between is-align-items-center">
33
<div>
44
<span>Codebase</span>
5-
{% if current_dir and current_dir != "." %}
6-
<span class="tag ml-2">
7-
{% for dir_name, full_path in codebase_breadcrumbs.items %}
8-
{% if not forloop.last %}
9-
<a
10-
href="#"
11-
hx-get="{{ project_details_url }}codebase/?current_dir={{ full_path }}"
12-
hx-target="#codebase-navigation"
13-
hx-swap="outerHTML">
14-
{{ dir_name }}
15-
</a>
16-
<span class="mr-1">/</span>
17-
{% else %}
18-
{{ dir_name }}/
19-
{% endif %}
20-
{% endfor %}
21-
</span>
22-
{% endif %}
235
</div>
246
<a href="{% url 'project_resource_tree' project.slug %}" class="ml-2 has-text-white has-text-decoration-none">
257
<i class="fa-solid fa-folder-tree mr-1"></i>Tree view
268
</a>
279
</div>
28-
{% for node in codebase_tree %}
29-
{% if node.is_dir %}
30-
<a class="panel-block" href="#" hx-target="#codebase-navigation" hx-swap="outerHTML" hx-get="{{ project_details_url }}codebase/?current_dir={{ node.location }}">
31-
<span class="panel-icon"><i class="fa-solid fa-folder"></i></span>
32-
{{ node.name }}
33-
</a>
34-
{% else %}
35-
<a class="panel-block" href="{% url "resource_detail" project.slug node.location %}" target="_blank">
36-
<span class="panel-icon"><i class="fa-regular fa-file"></i></span>
37-
{{ node.name }}
38-
</a>
39-
{% endif %}
10+
{% for node in codebase_root_tree %}
11+
<a class="panel-block" href="{% url 'project_resource_tree' project.slug %}?path={{ node.name }}">
12+
<span class="panel-icon">
13+
<i class="{% if node.is_dir %}fa-solid fa-folder{% else %}fa-regular fa-file{% endif %}"></i>
14+
</span>
15+
{{ node.name }}
16+
</a>
4017
{% endfor %}
4118
</nav>

scanpipe/tests/test_views.py

Lines changed: 16 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
from unittest import mock
2929

3030
from django.apps import apps
31-
from django.core.exceptions import SuspiciousFileOperation
3231
from django.http import FileResponse
3332
from django.http.response import Http404
3433
from django.test import TestCase
@@ -60,7 +59,7 @@
6059
from scanpipe.tests import package_data2
6160
from scanpipe.views import CodebaseResourceDetailsView
6261
from scanpipe.views import ProjectActionView
63-
from scanpipe.views import ProjectCodebaseView
62+
from scanpipe.views import ProjectCodebasePanelView
6463
from scanpipe.views import ProjectDetailView
6564

6665
scanpipe_app = apps.get_app_config("scanpipe")
@@ -676,22 +675,9 @@ def test_scanpipe_views_project_codebase_view(self):
676675
(self.project1.codebase_path / "file.txt").touch()
677676

678677
response = self.client.get(url)
679-
self.assertContains(response, "/codebase/?current_dir=./dir1")
680-
self.assertContains(response, "/resources/./file.txt/")
681-
682-
data = {"current_dir": "dir1"}
683-
response = self.client.get(url, data=data)
684-
self.assertContains(response, "..")
685-
self.assertContains(response, "/codebase/?current_dir=.")
686-
self.assertContains(response, "/codebase/?current_dir=dir1/dir2")
687-
688-
data = {"current_dir": "not_existing"}
689-
response = self.client.get(url, data=data)
690-
self.assertEqual(404, response.status_code)
691-
692-
data = {"current_dir": "../"}
693-
response = self.client.get(url, data=data)
694-
self.assertEqual(404, response.status_code)
678+
resource_tree_url = reverse("project_resource_tree", args=[self.project1.slug])
679+
self.assertContains(response, f"{resource_tree_url}?path=dir1")
680+
self.assertContains(response, f"{resource_tree_url}?path=file.txt")
695681

696682
def test_scanpipe_views_project_codebase_view_ordering(self):
697683
url = reverse("project_codebase", args=[self.project1.slug])
@@ -703,47 +689,33 @@ def test_scanpipe_views_project_codebase_view_ordering(self):
703689
(self.project1.codebase_path / "Dir").mkdir()
704690

705691
response = self.client.get(url)
706-
codebase_tree = response.context_data["codebase_tree"]
692+
codebase_tree = response.context_data["codebase_root_tree"]
707693
expected = ["Dir", "Zdir", "a", "z", "a.txt", "z.txt"]
708694
self.assertEqual(expected, [path.get("name") for path in codebase_tree])
709695

710-
def test_scanpipe_views_project_codebase_view_get_tree(self):
711-
get_tree = ProjectCodebaseView.get_tree
696+
def test_scanpipe_views_project_codebase_view_get_root_tree(self):
697+
get_root_tree = ProjectCodebasePanelView.get_root_tree
712698

713699
(self.project1.codebase_path / "dir1").mkdir()
714700
(self.project1.codebase_path / "dir1/dir2").mkdir()
715701
(self.project1.codebase_path / "file.txt").touch()
716702

717703
with mock.patch.object(scanpipe_app, "workspace_path", ""):
718704
self.assertEqual("", scanpipe_app.workspace_path)
719-
with self.assertRaises(ValueError) as e:
720-
get_tree(self.project1, current_dir="")
721-
722-
with self.assertRaises(FileNotFoundError):
723-
get_tree(self.project1, current_dir="not_existing")
724-
725-
with self.assertRaises(SuspiciousFileOperation) as e:
726-
get_tree(self.project1, current_dir="../../")
727-
self.assertIn("is located outside of the base path component", str(e.exception))
728-
729-
codebase_tree = get_tree(self.project1, current_dir="")
730-
expected = [
731-
{"name": "dir1", "is_dir": True, "location": "/dir1"},
732-
{"name": "file.txt", "is_dir": False, "location": "/file.txt"},
733-
]
734-
self.assertEqual(expected, codebase_tree)
705+
with self.assertRaises(ValueError):
706+
get_root_tree(self.project1)
735707

736-
codebase_tree = get_tree(self.project1, current_dir="dir1")
708+
codebase_tree = get_root_tree(self.project1)
737709
expected = [
738-
{"name": "..", "is_dir": True, "location": "."},
739-
{"name": "dir2", "is_dir": True, "location": "dir1/dir2"},
710+
{"name": "dir1", "is_dir": True},
711+
{"name": "file.txt", "is_dir": False},
740712
]
741713
self.assertEqual(expected, codebase_tree)
742714

743715
shutil.rmtree(self.project1.work_directory, ignore_errors=True)
744716
self.assertFalse(self.project1.codebase_path.exists())
745717
with self.assertRaises(Exception):
746-
get_tree(self.project1, current_dir="")
718+
get_root_tree(self.project1)
747719

748720
def test_scanpipe_views_project_archive_view(self):
749721
url = reverse("project_archive", args=[self.project1.slug])
@@ -1682,12 +1654,12 @@ def test_scanpipe_views_project_resource_tree_table_view_with_path_directory(sel
16821654
self.assertEqual(["parent/child1.txt", "parent/child2.py"], resource_paths)
16831655

16841656
def test_scanpipe_views_project_resource_tree_table_view_with_path_file(self):
1685-
make_resource_file(self.project1, path="specific_file.txt")
1657+
resource = make_resource_file(self.project1, path="specific_file.txt")
16861658

16871659
url = reverse(
16881660
"project_resource_tree_table", kwargs={"slug": self.project1.slug}
16891661
)
1690-
response = self.client.get(url + "?path=specific_file.txt")
1662+
response = self.client.get(url + f"?path={resource.path}")
16911663

16921664
self.assertEqual(200, response.status_code)
16931665
self.assertEqual("specific_file.txt", response.context["path"])
@@ -1708,23 +1680,6 @@ def test_scanpipe_views_project_resource_tree_table_view_empty_directory(self):
17081680
resources = list(response.context["resources"])
17091681
self.assertEqual(0, len(resources))
17101682

1711-
def test_scanpipe_views_project_resource_tree_table_view_with_packages(self):
1712-
resource1 = make_resource_file(self.project1, path="file_with_package.txt")
1713-
package1 = DiscoveredPackage.create_from_data(self.project1, package_data1)
1714-
package1.add_resources([resource1])
1715-
1716-
url = reverse(
1717-
"project_resource_tree_table", kwargs={"slug": self.project1.slug}
1718-
)
1719-
response = self.client.get(url + "?path=file_with_package.txt")
1720-
1721-
self.assertEqual(200, response.status_code)
1722-
resources = list(response.context["resources"])
1723-
self.assertEqual(1, len(resources))
1724-
1725-
resource = resources[0]
1726-
self.assertTrue(resource.discovered_packages.exists())
1727-
17281683
@mock.patch("scanpipe.views.ProjectResourceTreeTableView.paginate_by", 2)
17291684
def test_scanpipe_views_project_resource_tree_table_view_pagination(self):
17301685
make_resource_directory(self.project1, path="parent")
@@ -1761,7 +1716,7 @@ def test_scanpipe_views_project_resource_tree_table_view_field_selection(self):
17611716
url = reverse(
17621717
"project_resource_tree_table", kwargs={"slug": self.project1.slug}
17631718
)
1764-
response = self.client.get(url + "?path=test_file.py")
1719+
response = self.client.get(url + f"?path={resource.path}")
17651720

17661721
self.assertEqual(200, response.status_code)
17671722
resources = list(response.context["resources"])
@@ -1770,5 +1725,4 @@ def test_scanpipe_views_project_resource_tree_table_view_field_selection(self):
17701725
resource = resources[0]
17711726
self.assertEqual("test_file.py", resource.path)
17721727
self.assertEqual("Python", resource.programming_language)
1773-
self.assertEqual("text/x-python", resource.mime_type)
17741728
self.assertEqual("MIT", resource.detected_license_expression)

scanpipe/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
),
129129
path(
130130
"project/<slug:slug>/codebase/",
131-
views.ProjectCodebaseView.as_view(),
131+
views.ProjectCodebasePanelView.as_view(),
132132
name="project_codebase",
133133
),
134134
path(

scanpipe/views.py

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import operator
2727
from collections import Counter
2828
from contextlib import suppress
29-
from pathlib import Path
3029

3130
from django.apps import apps
3231
from django.conf import settings
@@ -1195,14 +1194,14 @@ def get_context_data(self, **kwargs):
11951194
return context
11961195

11971196

1198-
class ProjectCodebaseView(ConditionalLoginRequired, generic.DetailView):
1197+
class ProjectCodebasePanelView(ConditionalLoginRequired, generic.DetailView):
11991198
model = Project
12001199
template_name = "scanpipe/panels/project_codebase.html"
12011200

12021201
@staticmethod
1203-
def get_tree(project, current_dir):
1202+
def get_root_tree(project):
12041203
"""
1205-
Return the direct content of the ``current_dir`` as a flat tree.
1204+
Return the direct content of the project codebase root directory as a flat tree.
12061205
12071206
The lookups are scoped to the ``project`` codebase/ work directory.
12081207
The security is handled by the FileSystemStorage and will raise a
@@ -1215,60 +1214,20 @@ def get_tree(project, current_dir):
12151214
# Raises ValueError if the codebase_root is not within the workspace_path
12161215
codebase_root.relative_to(scanpipe_app.workspace_path)
12171216
fs_storage = FileSystemStorage(location=codebase_root)
1218-
directories, files = fs_storage.listdir(current_dir)
1219-
1220-
def get_node(name, is_dir, location):
1221-
return {
1222-
"name": name,
1223-
"is_dir": is_dir,
1224-
"location": location,
1225-
}
1217+
directories, files = fs_storage.listdir(".")
12261218

12271219
tree = []
1228-
root_directory = "."
1229-
include_parent = current_dir and current_dir != root_directory
1230-
if include_parent:
1231-
tree.append(
1232-
get_node(name="..", is_dir=True, location=str(Path(current_dir).parent))
1233-
)
1234-
12351220
for resources, is_dir in [(sorted(directories), True), (sorted(files), False)]:
1236-
tree.extend(
1237-
get_node(name=name, is_dir=is_dir, location=f"{current_dir}/{name}")
1238-
for name in resources
1239-
)
1221+
tree.extend({"name": name, "is_dir": is_dir} for name in resources)
12401222

12411223
return tree
12421224

1243-
@staticmethod
1244-
def get_breadcrumbs(current_dir):
1245-
breadcrumbs = {}
1246-
path_segments = current_dir.removeprefix("./").split("/")
1247-
last_path = ""
1248-
1249-
for segment in path_segments:
1250-
if segment:
1251-
last_path += f"{segment}/"
1252-
breadcrumbs[segment] = last_path
1253-
1254-
return breadcrumbs
1255-
12561225
def get_context_data(self, **kwargs):
12571226
context = super().get_context_data(**kwargs)
1258-
current_dir = self.request.GET.get("current_dir") or "."
1259-
12601227
try:
1261-
codebase_tree = self.get_tree(self.object, current_dir)
1262-
except FileNotFoundError:
1263-
raise Http404(f"{current_dir} not found")
1228+
context["codebase_root_tree"] = self.get_root_tree(self.object)
12641229
except (ValueError, SuspiciousFileOperation) as error:
12651230
raise Http404(error)
1266-
1267-
context["current_dir"] = current_dir
1268-
context["codebase_tree"] = codebase_tree
1269-
context["codebase_breadcrumbs"] = self.get_breadcrumbs(current_dir)
1270-
context["project_details_url"] = self.object.get_absolute_url()
1271-
12721231
return context
12731232

12741233

@@ -2822,7 +2781,6 @@ def get_queryset(self):
28222781
"detected_license_expression",
28232782
"compliance_alert",
28242783
)
2825-
.prefetch_related("discovered_packages")
28262784
.order_by("type", "path")
28272785
)
28282786

0 commit comments

Comments
 (0)