Skip to content

Commit

Permalink
Moved to Django's static files handler. (#1890)
Browse files Browse the repository at this point in the history
* Moved to Django's static files handler.
* Removed staticfiles.py file.
* Added entry in the changelog.
  • Loading branch information
carltongibson committed Aug 4, 2022
1 parent 868a468 commit 64b4346
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 143 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Next Release (will be 4.0)

* Drops support for Python 3.6.
* Minimum Django version is now Django 3.2.
* Added compatiblity with Django 4.1.
* Added compatibility with Django 4.1.
* Removed deprecated static files handling in favor of ``django.contrib.staticfiles``.

3.0.5 (2022-06-24)
------------------
Expand Down
5 changes: 2 additions & 3 deletions channels/management/commands/runserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
from daphne.server import Server
from django.apps import apps
from django.conf import settings
from django.contrib.staticfiles.handlers import ASGIStaticFilesHandler
from django.core.management import CommandError
from django.core.management.commands.runserver import Command as RunserverCommand

from channels import __version__
from channels.routing import get_default_application

from ...staticfiles import StaticFilesWrapper

logger = logging.getLogger("django.channels.server")


Expand Down Expand Up @@ -129,7 +128,7 @@ def get_application(self, options):
use_static_handler = options.get("use_static_handler", staticfiles_installed)
insecure_serving = options.get("insecure_serving", False)
if use_static_handler and (settings.DEBUG or insecure_serving):
return StaticFilesWrapper(get_default_application())
return ASGIStaticFilesHandler(get_default_application())
else:
return get_default_application()

Expand Down
82 changes: 0 additions & 82 deletions channels/staticfiles.py

This file was deleted.

4 changes: 2 additions & 2 deletions channels/testing/live.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from daphne.testing import DaphneProcess
from django.contrib.staticfiles.handlers import ASGIStaticFilesHandler
from django.core.exceptions import ImproperlyConfigured
from django.db import connections
from django.test.testcases import TransactionTestCase
from django.test.utils import modify_settings

from channels.routing import get_default_application
from channels.staticfiles import StaticFilesWrapper


class ChannelsLiveServerTestCase(TransactionTestCase):
Expand All @@ -18,7 +18,7 @@ class ChannelsLiveServerTestCase(TransactionTestCase):

host = "localhost"
ProtocolServerProcess = DaphneProcess
static_wrapper = StaticFilesWrapper
static_wrapper = ASGIStaticFilesHandler
serve_static = True

@property
Expand Down
60 changes: 5 additions & 55 deletions tests/test_staticfiles.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import os

import pytest

from channels.staticfiles import StaticFilesHandler, StaticFilesWrapper
from django.contrib.staticfiles.handlers import ASGIStaticFilesHandler


@pytest.fixture(autouse=True)
Expand All @@ -21,39 +18,16 @@ async def __call__(self, scope, receive, send):
return self.return_value


class MockStaticHandler:
async def __call__(self, scope, receive, send):
return scope["path"]


def request_for_path(path, type="http"):
return {
"type": type,
"path": path,
}


@pytest.mark.asyncio
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
async def test_staticfiles_wrapper_serves_static_http_requests(settings):
settings.STATIC_URL = "/mystatic/"

application = MockApplication("application")

wrapper = StaticFilesWrapper(application, staticfiles_handler=MockStaticHandler)

scope = request_for_path("/mystatic/image.png")
assert (
await wrapper(scope, None, None) == "/mystatic/image.png"
), "StaticFilesWrapper should serve paths under the STATIC_URL path"
assert (
not application.was_called
), "The inner application should not be called when serving static files"


@pytest.mark.asyncio
async def test_staticfiles_wrapper_calls_application_for_non_static_http_requests():
wrapper = StaticFilesWrapper(MockApplication("application"))
wrapper = ASGIStaticFilesHandler(MockApplication("application"))

non_static_path = request_for_path("/path/to/non/static/resource")
assert (
Expand All @@ -70,7 +44,7 @@ async def test_staticfiles_wrapper_calls_application_for_non_static_http_request
async def test_staticfiles_wrapper_calls_application_for_non_http_paths(settings):
settings.STATIC_URL = "/mystatic/"

wrapper = StaticFilesWrapper(MockApplication("application"))
wrapper = ASGIStaticFilesHandler(MockApplication("application"))

non_http_static_path = request_for_path("/mystatic/match", type="websocket")
assert await wrapper(non_http_static_path, None, None) == "application", (
Expand All @@ -83,7 +57,7 @@ async def test_staticfiles_wrapper_calls_application_for_non_http_paths(settings
async def test_staticfiles_wrapper_calls_application_if_static_url_has_host(settings):
settings.STATIC_URL = "http://hostname.com/mystatic/"

wrapper = StaticFilesWrapper(MockApplication("application"))
wrapper = ASGIStaticFilesHandler(MockApplication("application"))

scope = request_for_path("/mystatic/match")
assert await wrapper(scope, None, None) == "application", (
Expand All @@ -95,33 +69,9 @@ async def test_staticfiles_wrapper_calls_application_if_static_url_has_host(sett
def test_is_single_callable():
from asgiref.compatibility import is_double_callable

wrapper = StaticFilesWrapper(None)
wrapper = ASGIStaticFilesHandler(None)

assert not is_double_callable(wrapper), (
"StaticFilesWrapper should be recognized as a single callable by "
"asgiref compatibility tools"
)


@pytest.mark.asyncio
async def test_staticfiles_handler_can_generate_file_path():
"""
StaticFilesHandler.file_path must not rely on scope being assigned to self.
"""

class MockedHandler(StaticFilesHandler):
async def __call__(self, scope, receive, send):
# Equivalent setUp from real __call__.
request = self.request_class(scope, "")
self.static_base_url = scope["static_base_url"][2]
# Method under test.
return self.file_path(request.path)

wrapper = StaticFilesWrapper(
MockApplication("application"), staticfiles_handler=MockedHandler
)
scope = request_for_path("/static/image.png")
scope["method"] = "GET"
assert await wrapper(scope, None, None) == os.path.normpath(
"/image.png"
), "StaticFilesWrapper should serve paths under the STATIC_URL path"

0 comments on commit 64b4346

Please sign in to comment.