diff --git a/.woodpecker.yaml b/.woodpecker.yaml index 340f9fc..5eda517 100644 --- a/.woodpecker.yaml +++ b/.woodpecker.yaml @@ -1,6 +1,16 @@ +services: + - name: postgres + image: postgres:16 + environment: + POSTGRES_DB: python_tdd_test + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + steps: - - name: test-UTs + - name: test-UTs-n-ITs image: python:3.13-slim + environment: + DATABASE_URL: postgresql://postgres:postgres@postgres/python_tdd_test commands: - pip install -r requirements.txt - cd ./src diff --git a/requirements.dev.txt b/requirements.dev.txt index 4d42320..6f57054 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -3,7 +3,9 @@ attrs==25.4.0 certifi==2025.11.12 cffi==2.0.0 charset-normalizer==3.4.4 +coverage cssselect==1.3.0 +dj-database-url Django==6.0 django-stubs==5.2.8 django-stubs-ext==5.2.8 diff --git a/requirements.txt b/requirements.txt index 4c0c532..2575734 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,10 @@ cssselect==1.3.0 Django==6.0 +dj-database-url django-stubs==5.2.8 django-stubs-ext==5.2.8 gunicorn==23.0.0 lxml==6.0.2 +psycopg2-binary requests==2.31.0 whitenoise==6.11.0 diff --git a/src/.coveragerc b/src/.coveragerc new file mode 100644 index 0000000..78d398c --- /dev/null +++ b/src/.coveragerc @@ -0,0 +1,8 @@ +[run] +source = apps +omit = + */migrations/* + */tests/* + +[report] +show_missing = true \ No newline at end of file diff --git a/src/apps/lyric/tests/unit/test_authentication.py b/src/apps/lyric/tests/unit/test_authentication.py index 75f47f6..6cdfcfb 100644 --- a/src/apps/lyric/tests/unit/test_authentication.py +++ b/src/apps/lyric/tests/unit/test_authentication.py @@ -10,3 +10,8 @@ class SimpleAuthenticateTest(SimpleTestCase): HttpRequest(), "no-such-token" ) self.assertIsNone(result) + + def test_returns_None_if_no_uuid(self): + result = PasswordlessAuthenticationBackend().authenticate(HttpRequest()) + self.assertIsNone(result) + diff --git a/src/core/settings.py b/src/core/settings.py index 031de84..04b6935 100644 --- a/src/core/settings.py +++ b/src/core/settings.py @@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/6.0/ref/settings/ from pathlib import Path import os +import dj_database_url # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -26,13 +27,11 @@ if 'DJANGO_DEBUG_FALSE' in os.environ: DEBUG = False SECRET_KEY = os.environ['DJANGO_SECRET_KEY'] ALLOWED_HOSTS = [host.strip() for host in os.environ['DJANGO_ALLOWED_HOST'].split(',')] - db_path = os.environ['DJANGO_DB_PATH'] else: DEBUG = True # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'django-insecure-&9b_h=qpjy=sshhnsyg98&jp7(t6*v78__y%h2l$b#_@6z$-9r' ALLOWED_HOSTS = [] - db_path = BASE_DIR / 'db.sqlite3' # Application definition @@ -90,12 +89,16 @@ ASGI_APPLICATION = 'core.asgi.application' # Database # https://docs.djangoproject.com/en/6.0/ref/settings/#databases -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': db_path, +DATABASE_URL = os.environ.get('DATABASE_URL') +if DATABASE_URL: + DATABASES = {'default': dj_database_url.config(conn_max_age=600)} +else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } } -} # Password validation