Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 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
6 changes: 6 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Set up Chrome
uses: browser-actions/setup-chrome@v1

- name: Set up ChromeDriver
uses: nanasess/setup-chromedriver@v2

- name: Install dependencies
run: |
python -m pip install --upgrade pip wheel setuptools
Expand Down
12 changes: 11 additions & 1 deletion channels/testing/live.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from functools import partial

from daphne.testing import DaphneProcess
from django import VERSION
from django.contrib.staticfiles.handlers import ASGIStaticFilesHandler
from django.core.exceptions import ImproperlyConfigured
from django.db import connections
Expand Down Expand Up @@ -68,9 +69,18 @@ def _post_teardown(self):
self._live_server_modified_settings.disable()
super(ChannelsLiveServerTestCase, self)._post_teardown()

def _is_in_memory_db(self, connection):
@staticmethod
def _is_in_memory_db(connection):
"""
Check if DatabaseWrapper holds in memory database.
"""
if connection.vendor == "sqlite":
return connection.is_in_memory_db()


# Workaround for Django 5.2: _pre_setup became a classmethod.
# TODO: Remove this workaround once support for Django <5.2 is dropped.
if VERSION >= (5, 2):
ChannelsLiveServerTestCase._pre_setup = classmethod(
ChannelsLiveServerTestCase._pre_setup
)
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ tests =
pytest
pytest-django
pytest-asyncio
selenium
daphne =
daphne>=4.0.0

Expand Down
27 changes: 27 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,39 @@ def pytest_configure():
}
},
INSTALLED_APPS=[
"daphne",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.admin",
"django.contrib.staticfiles",
"tests.sample_project.sampleapp",
"channels",
],
STATIC_URL="static/",
ASGI_APPLICATION="tests.sample_project.config.asgi.application",
MIDDLEWARE=[
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
],
ROOT_URLCONF="tests.sample_project.config.urls",
CHANNEL_LAYERS={
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer",
},
},
TEMPLATES=[
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
],
},
},
],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might would be cleaner to just load the tests.sample_project.settings instead.
e.g.

os.environ["DJANGO_SETTINGS_MODULE"] = "tests.sample_project.settings"
settings._setup()

SECRET_KEY="Not_a_secret_key",
)

Expand Down
Empty file.
Empty file.
35 changes: 35 additions & 0 deletions tests/sample_project/config/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""
ASGI config for sample_project project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/5.2/howto/deployment/asgi/
"""

from django.core.asgi import get_asgi_application
from django.urls import path

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from tests.sample_project.sampleapp.consumers import LiveMessageConsumer

application = ProtocolTypeRouter(
{
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
[
path(
"ws/message/",
LiveMessageConsumer.as_asgi(),
name="live_message_counter",
),
]
)
)
),
"http": get_asgi_application(),
}
)
138 changes: 138 additions & 0 deletions tests/sample_project/config/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
"""
Django settings for sample_project project.

Generated by 'django-admin startproject' using Django 5.2.

For more information on this file, see
https://docs.djangoproject.com/en/5.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.2/ref/settings/
"""

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-w%kkd-b39(9uvz68x!-9+xt=&9q&^j@#uc_&=g%-s@bcsz*qbu"

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
"daphne",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"sampleapp",
"channels",
]

MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "config.urls"

TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.csrf",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]

WSGI_APPLICATION = "config.wsgi.application"
ASGI_APPLICATION = "config.asgi.application"

CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer",
},
}

# Database
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases

DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "sampleapp/sampleapp.sqlite3",
"TEST": {
"NAME": BASE_DIR / "sampleapp/test_sampleapp.sqlite3",
},
}
}


# Password validation
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
{
"NAME": (
"django.contrib.auth.password_validation."
"UserAttributeSimilarityValidator"
),
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]


# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/

LANGUAGE_CODE = "en-us"

TIME_ZONE = "UTC"

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.2/howto/static-files/

STATIC_URL = "static/"

# Default primary key field type
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
31 changes: 31 additions & 0 deletions tests/sample_project/config/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
URL configuration for sample_project project.

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""

from django.conf import settings
from django.contrib import admin
from django.urls import path
from django.views.generic import RedirectView

urlpatterns = [
path("admin/", admin.site.urls),
path(
"favicon.ico",
RedirectView.as_view(
url=settings.STATIC_URL + "sampleapp/images/django.svg", permanent=True
),
),
]
16 changes: 16 additions & 0 deletions tests/sample_project/config/wsgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
WSGI config for sample_project project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")

application = get_wsgi_application()
22 changes: 22 additions & 0 deletions tests/sample_project/manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)


if __name__ == "__main__":
main()
Empty file.
9 changes: 9 additions & 0 deletions tests/sample_project/sampleapp/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.contrib import admin

from .models import Message


@admin.register(Message)
class MessageAdmin(admin.ModelAdmin):
list_display = ("title", "created")
change_list_template = "admin/sampleapp/message/change_list.html"
6 changes: 6 additions & 0 deletions tests/sample_project/sampleapp/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class SampleappConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "tests.sample_project.sampleapp"
Loading
Loading