From 79c64a4df74a9e394e41be3be7204a85b4616a67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= <joasoe@gmail.com>
Date: Tue, 20 Aug 2024 16:20:27 +0200
Subject: [PATCH] Add workaround for bad filenames (#3987)

---
 custom_components/hacs/repositories/plugin.py |  6 ++-
 tests/repositories/test_plugin_repository.py  | 41 ++++++++++++++++---
 ...board-resource-with-invalid-file-name.json | 16 ++++++++
 3 files changed, 56 insertions(+), 7 deletions(-)
 create mode 100644 tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-add-dashboard-resource-with-invalid-file-name.json

diff --git a/custom_components/hacs/repositories/plugin.py b/custom_components/hacs/repositories/plugin.py
index 9166ae995af..86e30f9994c 100644
--- a/custom_components/hacs/repositories/plugin.py
+++ b/custom_components/hacs/repositories/plugin.py
@@ -161,8 +161,12 @@ def generate_dashboard_resource_namespace(self) -> str:
 
     def generate_dashboard_resource_url(self) -> str:
         """Get the dashboard resource namespace."""
+        filename = self.data.file_name
+        if "/" in filename:
+            self.logger.warning("%s have defined an invalid file name %s", self.string, filename)
+            filename = filename.split("/")[-1]
         return (
-            f"{self.generate_dashboard_resource_namespace()}/{self.data.file_name}"
+            f"{self.generate_dashboard_resource_namespace()}/{filename}"
             f"?hacstag={self.generate_dashboard_resource_hacstag()}"
         )
 
diff --git a/tests/repositories/test_plugin_repository.py b/tests/repositories/test_plugin_repository.py
index 2d3931b658f..44b8973c1f8 100644
--- a/tests/repositories/test_plugin_repository.py
+++ b/tests/repositories/test_plugin_repository.py
@@ -17,7 +17,8 @@ async def downloaded_plugin_repository(
 ) -> HacsPluginRepository:
     """Return a HacsPluginRepository instance."""
     hacs = get_hacs(hass)
-    repository = hacs.repositories.get_by_full_name("hacs-test-org/plugin-basic")
+    repository = hacs.repositories.get_by_full_name(
+        "hacs-test-org/plugin-basic")
     await repository.async_install(version="1.0.0")
     return repository
 
@@ -182,7 +183,8 @@ async def test_remove_dashboard_resource(
     resource_handler = downloaded_plugin_repository._get_resource_handler()
     await resource_handler.async_load()
 
-    current_urls = [resource["url"] for resource in resource_handler.async_items()]
+    current_urls = [resource["url"]
+                    for resource in resource_handler.async_items()]
     assert len(current_urls) == 1
     assert downloaded_plugin_repository.generate_dashboard_resource_url() in current_urls
 
@@ -192,7 +194,8 @@ async def test_remove_dashboard_resource(
         in caplog.text
     )
 
-    current_urls = [resource["url"] for resource in resource_handler.async_items()]
+    current_urls = [resource["url"]
+                    for resource in resource_handler.async_items()]
     assert len(current_urls) == 0
 
 
@@ -205,7 +208,8 @@ async def test_add_dashboard_resource(
     resource_handler = downloaded_plugin_repository._get_resource_handler()
     resource_handler.data.clear()
 
-    current_urls = [resource["url"] for resource in resource_handler.async_items()]
+    current_urls = [resource["url"]
+                    for resource in resource_handler.async_items()]
     assert len(current_urls) == 0
 
     await downloaded_plugin_repository.update_dashboard_resources()
@@ -223,7 +227,8 @@ async def test_update_dashboard_resource(
     """Test adding a dashboard resource."""
     resource_handler = downloaded_plugin_repository._get_resource_handler()
     await resource_handler.async_load()
-    current_urls = [resource["url"] for resource in resource_handler.async_items()]
+    current_urls = [resource["url"]
+                    for resource in resource_handler.async_items()]
     assert len(current_urls) == 1
 
     prev_url = downloaded_plugin_repository.generate_dashboard_resource_url()
@@ -242,6 +247,30 @@ async def test_update_dashboard_resource(
     after_url = downloaded_plugin_repository.generate_dashboard_resource_url()
     assert after_url != prev_url
 
-    current_urls = [resource["url"] for resource in resource_handler.async_items()]
+    current_urls = [resource["url"]
+                    for resource in resource_handler.async_items()]
     assert len(current_urls) == 1
     assert current_urls[0] == after_url
+
+
+async def test_add_dashboard_resource_with_invalid_file_name(
+    hass: HomeAssistant,
+    downloaded_plugin_repository: HacsPluginRepository,
+    caplog: pytest.LogCaptureFixture,
+) -> None:
+    """Test adding a dashboard resource."""
+    resource_handler = downloaded_plugin_repository._get_resource_handler()
+    resource_handler.data.clear()
+
+    current_urls = [resource["url"]
+                    for resource in resource_handler.async_items()]
+    assert len(current_urls) == 0
+
+    downloaded_plugin_repository.data.file_name = "dist/plugin-basic.js"
+
+    await downloaded_plugin_repository.update_dashboard_resources()
+    assert "<Plugin hacs-test-org/plugin-basic> have defined an invalid file name dist/plugin-basic.js" in caplog.text
+    assert (
+        "Adding dashboard resource /hacsfiles/plugin-basic/plugin-basic.js?hacstag=1296267100"
+        in caplog.text
+    )
diff --git a/tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-add-dashboard-resource-with-invalid-file-name.json b/tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-add-dashboard-resource-with-invalid-file-name.json
new file mode 100644
index 00000000000..ae277f4364b
--- /dev/null
+++ b/tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-add-dashboard-resource-with-invalid-file-name.json
@@ -0,0 +1,16 @@
+{
+    "tests/repositories/test_plugin_repository.py::test_add_dashboard_resource_with_invalid_file_name": {
+        "https://api.github.com/repos/hacs-test-org/plugin-basic": 1,
+        "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1,
+        "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1,
+        "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1,
+        "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1,
+        "https://api.github.com/repos/hacs/integration": 1,
+        "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1,
+        "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1,
+        "https://api.github.com/repos/hacs/integration/git/trees/main": 1,
+        "https://api.github.com/repos/hacs/integration/releases": 1,
+        "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1,
+        "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1
+    }
+}
\ No newline at end of file