Repository: joshuadavidthomas/django-bird (python)

Issue:
Static file urls not correct
When rendering the asset url, it appears as

```html
<script src="/static/bird/button.js"></script>
```

But the location on the filesystem is actually `/static/django_bird/bird/button.js`. There's a disconnect here between the storage prefix (`django_bird`) and the url provided by the `Asset`.

Pull request:
Fix static URLs to include django_bird prefix
The BirdAssetStorage class wasn't applying the 'django_bird' prefix to generated static URLs, causing a mismatch between collection paths and URL paths. Added an override to the URL method that ensures the prefix is applied.

closes #218 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 118d28f..ff1e0fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,10 @@ and this project attempts to adhere to [Semantic Versioning](https://semver.org/
 
 ## [Unreleased]
 
+### Fixed
+
+- Fixed static asset URLs to properly include the 'django_bird' prefix, ensuring URLs match the actual file paths during collection
+
 ## [0.17.0]
 
 🚨 This release contains some breaking changes. See the Removed section for more information. 🚨
diff --git a/src/django_bird/staticfiles.py b/src/django_bird/staticfiles.py
index 7b7030b..8765a8f 100644
--- a/src/django_bird/staticfiles.py
+++ b/src/django_bird/staticfiles.py
@@ -174,6 +174,14 @@ class BirdAssetStorage(StaticFilesStorage):
         super().__init__(*args, **kwargs)
         self.prefix = prefix
 
+    @override
+    def url(self, name: str | None) -> str:
+        if name is None:
+            return super().url(name)
+        if not name.startswith(f"{self.prefix}/"):
+            name = f"{self.prefix}/{name}"
+        return super().url(name)
+
 
 @final
 class BirdAssetFinder(BaseFinder):


Test patch:
diff --git a/tests/templatetags/test_asset.py b/tests/templatetags/test_asset.py
index ab165db..6aaa40d 100644
--- a/tests/templatetags/test_asset.py
+++ b/tests/templatetags/test_asset.py
@@ -103,15 +103,21 @@ class TestTemplateTag:
         rendered = template.render({})
 
         assert (
-            f'<link rel="stylesheet" href="/static/bird/{alert_css.file.name}">'
+            f'<link rel="stylesheet" href="/static/django_bird/bird/{alert_css.file.name}">'
             in rendered
         )
         assert (
-            f'<link rel="stylesheet" href="/static/bird/{button_css.file.name}">'
+            f'<link rel="stylesheet" href="/static/django_bird/bird/{button_css.file.name}">'
+            in rendered
+        )
+        assert (
+            f'<script src="/static/django_bird/bird/{alert_js.file.name}"></script>'
+            in rendered
+        )
+        assert (
+            f'<script src="/static/django_bird/bird/{button_js.file.name}"></script>'
             in rendered
         )
-        assert f'<script src="/static/bird/{alert_js.file.name}"></script>' in rendered
-        assert f'<script src="/static/bird/{button_js.file.name}"></script>' in rendered
 
     def test_template_inheritence_no_bird_usage(
         self, create_template, templates_dir, registry
@@ -154,10 +160,13 @@ class TestTemplateTag:
         rendered = template.render({})
 
         assert (
-            f'<link rel="stylesheet" href="/static/bird/{alert_css.file.name}">'
+            f'<link rel="stylesheet" href="/static/django_bird/bird/{alert_css.file.name}">'
+            in rendered
+        )
+        assert (
+            f'<script src="/static/django_bird/bird/{alert_js.file.name}"></script>'
             in rendered
         )
-        assert f'<script src="/static/bird/{alert_js.file.name}"></script>' in rendered
 
     def test_with_no_assets(self, create_template, templates_dir):
         TestComponent(
@@ -232,21 +241,21 @@ class TestTemplateTag:
 
         head_end = rendered.find("</head>")
         assert (
-            f'<link rel="stylesheet" href="/static/bird/{first_css.file.name}">'
+            f'<link rel="stylesheet" href="/static/django_bird/bird/{first_css.file.name}">'
             in rendered[:head_end]
         )
         assert (
-            f'<link rel="stylesheet" href="/static/bird/{second_css.file.name}">'
+            f'<link rel="stylesheet" href="/static/django_bird/bird/{second_css.file.name}">'
             in rendered[:head_end]
         )
 
         body_start = rendered.find("<body")
         assert (
-            f'<script src="/static/bird/{first_js.file.name}"></script>'
+            f'<script src="/static/django_bird/bird/{first_js.file.name}"></script>'
             in rendered[body_start:]
         )
         assert (
-            f'<script src="/static/bird/{second_js.file.name}"></script>'
+            f'<script src="/static/django_bird/bird/{second_js.file.name}"></script>'
             in rendered[body_start:]
         )
 
@@ -294,12 +303,14 @@ class TestTemplateTag:
 
         assert (
             rendered.count(
-                f'<link rel="stylesheet" href="/static/bird/{alert_css.file.name}">'
+                f'<link rel="stylesheet" href="/static/django_bird/bird/{alert_css.file.name}">'
             )
             == 1
         )
         assert (
-            rendered.count(f'<script src="/static/bird/{alert_js.file.name}"></script>')
+            rendered.count(
+                f'<script src="/static/django_bird/bird/{alert_js.file.name}"></script>'
+            )
             == 1
         )
 
@@ -356,16 +367,19 @@ class TestTemplateTag:
         rendered = template.render({})
 
         assert (
-            f'<link rel="stylesheet" href="/static/bird/{alert_css.file.name}">'
+            f'<link rel="stylesheet" href="/static/django_bird/bird/{alert_css.file.name}">'
+            in rendered
+        )
+        assert (
+            f'<script src="/static/django_bird/bird/{alert_js.file.name}"></script>'
             in rendered
         )
-        assert f'<script src="/static/bird/{alert_js.file.name}"></script>' in rendered
         assert (
-            f'<link rel="stylesheet" href="/static/bird/{button_css.file.name}">'
+            f'<link rel="stylesheet" href="/static/django_bird/bird/{button_css.file.name}">'
             not in rendered
         )
         assert (
-            f'<script src="/static/bird/{button_js.file.name}"></script>'
+            f'<script src="/static/django_bird/bird/{button_js.file.name}"></script>'
             not in rendered
         )
 
@@ -425,7 +439,7 @@ class TestManifest:
             rendered = template.render({})
 
             assert (
-                f'<link rel="stylesheet" href="/static/bird/{button_css.file.name}">'
+                f'<link rel="stylesheet" href="/static/django_bird/bird/{button_css.file.name}">'
                 in rendered
             )
 
@@ -466,7 +480,7 @@ class TestManifest:
             rendered = template.render({})
 
             assert (
-                f'<link rel="stylesheet" href="/static/bird/{button_css.file.name}">'
+                f'<link rel="stylesheet" href="/static/django_bird/bird/{button_css.file.name}">'
                 in rendered
             )
 
@@ -513,7 +527,7 @@ class TestManifest:
             rendered = template.render({})
 
             assert (
-                f'<link rel="stylesheet" href="/static/bird/{button_css.file.name}">'
+                f'<link rel="stylesheet" href="/static/django_bird/bird/{button_css.file.name}">'
                 in rendered
             )
 
diff --git a/tests/test_staticfiles.py b/tests/test_staticfiles.py
index 5245f7b..2f569cf 100644
--- a/tests/test_staticfiles.py
+++ b/tests/test_staticfiles.py
@@ -213,7 +213,8 @@ class TestAssetClass:
         asset = component.get_asset(button_css.file.name)
 
         assert (
-            asset.url == f"/static/{button_css.file.parent.name}/{button_css.file.name}"
+            asset.url
+            == f"/static/django_bird/{button_css.file.parent.name}/{button_css.file.name}"
         )
 
     def test_url_nonexistent(self, templates_dir):