Skip to content

Commit

Permalink
starting with pytest
Browse files Browse the repository at this point in the history
  • Loading branch information
jrief committed Jan 7, 2025
1 parent 1df26fb commit f71c5e3
Show file tree
Hide file tree
Showing 15 changed files with 255 additions and 97 deletions.
21 changes: 0 additions & 21 deletions .github/workflows/frontend.yml

This file was deleted.

44 changes: 0 additions & 44 deletions .github/workflows/test.yml

This file was deleted.

51 changes: 51 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Test django-filer

on:
push:
branches:
- finder
paths-ignore:
- '**.md'
- '**.rst'
- '/docs/**'
pull_request:
branches:
- develop
paths-ignore:
- '**.md'
- '**.rst'
- '/docs/**'

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12"]
django-version: ["5.2.*"]
node-version: ["18.x"]

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
npm install --include=dev
python -m pip install --upgrade pip
python -m pip install https://github.com/django/django/archive/refs/heads/main.zip
python -m pip install django-cte django-entangled ffmpeg-python pillow reportlab svglib
python -m pip install beautifulsoup4 coverage Faker lxml pytest pytest-django pytest-cov
- name: Build Client
run: |
npm run compilescss
npm run esbuild
- name: Test with pytest
run: |
python -m pytest -v demoapp/unittests
1 change: 0 additions & 1 deletion client/scss/finder-admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -695,4 +695,3 @@ ul.messagelist {
}

@import 'node_modules/react-image-crop/src/ReactCrop.scss';
@import 'node_modules/react-h5-audio-player/src/styles.scss';
4 changes: 4 additions & 0 deletions demoapp/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pytest]
DJANGO_SETTINGS_MODULE = demoapp.settings
django_find_project = false
addopts = --tb=native
38 changes: 19 additions & 19 deletions demoapp/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
'django.contrib.messages',
'django.contrib.sites',
'django.contrib.staticfiles',
'easy_thumbnails',
'filer',
'finder',
'finder.contrib.archive',
Expand Down Expand Up @@ -75,24 +74,25 @@
WSGI_APPLICATION = 'wsgi.application'


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

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'workdir/db.sqlite3',
},
'default_': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'finder',
'USER': 'finder',
'PASSWORD': '',
'HOST': 'localhost',
'PORT': 5432,
# 'CONN_MAX_AGE': 900,
},
}
if os.getenv('USE_POSTGRES', False) in ['1', 'True', 'true']:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'finder',
'USER': 'finder',
'PASSWORD': '',
'HOST': 'localhost',
'PORT': 5432,
# 'CONN_MAX_AGE': 900,
},
}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'workdir/db.sqlite3',
},
}


DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
Expand Down
Empty file added demoapp/unittests/__init__.py
Empty file.
111 changes: 111 additions & 0 deletions demoapp/unittests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import os
import pytest

from playwright.sync_api import sync_playwright

from django.conf import settings
from django.contrib.admin.sites import site as admin_site

Check failure on line 7 in demoapp/unittests/conftest.py

View workflow job for this annotation

GitHub Actions / flake8

'django.contrib.admin.sites.site as admin_site' imported but unused
from django.core.management import call_command
from django.urls import reverse

from finder.models.folder import FolderModel

Check failure on line 11 in demoapp/unittests/conftest.py

View workflow job for this annotation

GitHub Actions / flake8

'finder.models.folder.FolderModel' imported but unused
from finder.models.realm import RealmModel

from .utils import create_random_image

os.environ.setdefault('DJANGO_ALLOW_ASYNC_UNSAFE', 'true')


@pytest.fixture(autouse=True, scope='session')
def create_assets():
os.makedirs(settings.BASE_DIR / 'workdir/assets', exist_ok=True)
for counter in range(10):
image = create_random_image()
image.save(settings.BASE_DIR / 'workdir/assets' / f'image_{counter:01d}.png')


@pytest.fixture(scope='session')
def django_db_setup(django_db_blocker):
database_file = settings.BASE_DIR / 'workdir/test_db.sqlite3'
settings.DATABASES['default']['NAME'] = database_file
with django_db_blocker.unblock():
call_command('migrate', verbosity=0)
yield
os.remove(database_file)


@pytest.fixture
def realm(admin_client):
if realm := RealmModel.objects.first():
return realm
response = admin_client.get(reverse('admin:finder_foldermodel_changelist'))
assert response.status_code == 302
realm = RealmModel.objects.first()
assert realm is not None
redirected = reverse('admin:finder_inodemodel_change', kwargs={'inode_id': realm.root_folder.id})
assert response.url == redirected
assert realm.root_folder.is_folder is True
assert realm.root_folder.is_trash is False
assert realm.root_folder.owner == response.wsgi_request.user
assert realm.root_folder.name == '__root__'
assert realm.root_folder.parent is None
assert realm.root_folder.is_root
assert realm.trash_folders.count() == 0
return realm


class Connector:
def __init__(self, live_server):
print(f"\nStarting end-to-end test server at {live_server}\n")
self.live_server = live_server

def __enter__(self):
def print_args(msg):
if msg.type in ['info', 'debug']:
return
for arg in msg.args:
print(arg.json_value())

self.playwright = sync_playwright().start()
self.browser = self.playwright.chromium.launch()
return self

def __exit__(self, exc_type, exc_val, exc_tb):
self.browser.close()
self.playwright.stop()


@pytest.fixture(scope='session')
def connector(live_server):
with Connector(live_server) as connector:
yield connector


@pytest.fixture
def locale():
return 'en-US'


@pytest.fixture
def language():
return 'en'


def print_args(msg):
"""
Print messages from the browser console.
"""
for arg in msg.args:
print(arg.json_value())


@pytest.fixture()
def page(connector, viewname, locale, language):
context = connector.browser.new_context(locale=locale)
context.add_cookies([{'name': 'django_language', 'value': language, 'domain': 'localhost', 'path': '/'}])
page = context.new_page()
# page.on('console', print_args)
page.goto(connector.live_server.url + reverse(viewname))
# django_formset = page.locator('django-formset:defined')
# django_formset.wait_for()
return page
33 changes: 33 additions & 0 deletions demoapp/unittests/test_folder_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import json
import pytest

from bs4 import BeautifulSoup

from django.urls import reverse


@pytest.mark.django_db
def test_access_root_folder(realm, admin_client):
admin_url = reverse('admin:finder_inodemodel_change', kwargs={'inode_id': realm.root_folder.id})
request = admin_client.get(admin_url)
assert request.status_code == 200
soup = BeautifulSoup(request.content, 'html.parser')
assert soup.title.string == "Root | Change Folder | Django site admin"
script_element = soup.find(id='finder-settings')
assert script_element.name == 'script'
finder_settings = json.loads(script_element.string)
finder_settings.pop('csrf_token')
finder_settings.pop('favorite_folders')
finder_settings.pop('menu_extensions')
assert finder_settings == {
'name': '__root__',
'is_folder': True,
'folder_id': str(realm.root_folder.id),
'parent_id': None,
'parent_url': None,
'is_root': True,
'is_trash': False,
'folder_url': admin_url,
'base_url': reverse('admin:finder_foldermodel_changelist'),
'ancestors': [str(realm.root_folder.id)],
}
29 changes: 29 additions & 0 deletions demoapp/unittests/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import colorsys
from faker import Faker
import random
from PIL import Image, ImageDraw
from typing import NewType


ColorRGBA = NewType('ColorRGBA', tuple[int, int, int, int])


def random_color() -> ColorRGBA:
return *(random.randint(0, 255) for _ in range(3)), 255


def rotate_hue(rgb: ColorRGBA, degrees: float) -> ColorRGBA:
h, l, s = colorsys.rgb_to_hls(rgb[0], rgb[1], rgb[2])
h = (h + degrees / 360.0) % 1.0
l = 255.0 - l

Check failure on line 18 in demoapp/unittests/utils.py

View workflow job for this annotation

GitHub Actions / flake8

ambiguous variable name 'l'
return *map(lambda c: int(c), colorsys.hls_to_rgb(h, l, s)), rgb[3]


def create_random_image() -> Image:
faker = Faker()
background_color = random_color()
image = Image.new('RGB', (100, 100), color=background_color)
drawing = ImageDraw.Draw(image)
foreground_color = rotate_hue(background_color, 180)
drawing.text((5, 40), faker.text(20), fill=foreground_color)
return image
8 changes: 0 additions & 8 deletions finder/admin/folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,6 @@
class FolderAdmin(InodeAdmin):
form_template = 'finder/admin/change_folder_form.html'
_model_admin_cache = {}
_legends = {
'name': _("Name"),
'owner_name': _("Owner"),
'details': _("Details"),
'created_at': _("Created at"),
'mime_type': _("Mime type"),
}

@property
def media(self):
Expand Down Expand Up @@ -146,7 +139,6 @@ def get_editor_settings(self, request, inode):
settings.update(
base_url=reverse('admin:finder_foldermodel_changelist', current_app=self.admin_site.name),
ancestors=ancestor_ids,
legends=self._legends,
menu_extensions=self.get_menu_extension_settings(request),
)
return settings
Expand Down
2 changes: 1 addition & 1 deletion finder/management/commands/filer_to_finder.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from pathlib import Path

from django.conf import settings
from django.contrib.admin import site as admin_site
from django.contrib.sites.models import Site
from django.core.management.base import BaseCommand
from easy_thumbnails.conf import settings

from filer.models.filemodels import Folder as FilerFolder
from filer.models.imagemodels import Image as FilerImage
Expand Down
Loading

0 comments on commit f71c5e3

Please sign in to comment.