💚 ci: Switch test suite to SQLite, remove service container deps
All checks were successful
CI / lint (pull_request) Successful in 22s
CI / test (pull_request) Successful in 50s
CI / lint (push) Successful in 16s
CI / test (push) Successful in 40s

The Forgejo Actions CI `test` job has never passed — all 24 runs show
failure. Two root causes: the Forgejo `podman` runner's service
container networking doesn't reliably expose the PostgreSQL hostname,
and the CI pipeline doesn't provision RabbitMQ, causing
`fedora_messaging.api.publish()` to raise `ConnectionException`.

Since the codebase uses zero PostgreSQL-specific features, the test
database backend can safely be switched to SQLite in-memory. This
eliminates all external service dependencies for tests.

Changes to test infrastructure:
- Override `DATABASES` in `tsting.py` to use SQLite in-memory
- Add Celery memory broker settings to prevent Redis connections
- Add `CRISPY_ALLOWED_TEMPLATE_PACKS` for `bootstrap5` compatibility
- Set dummy `ADMIN_USERNAME`/`ADMIN_PASSWORD` for FAS `AccountSystem`
- Create `conftest.py` with autouse fixtures to mock `publish()`,
  `AccountSystem.people_query()`, and provide a stub `STATIC_ROOT`

Changes to CI pipeline:
- Remove `postgres:15` and `redis:7` service containers
- Remove `gcc`/`libpq-dev` system dependency step

Bug fixes surfaced by the new test environment:
- Replace stale `import ckeditor.fields` in migration 0007 with
  `models.TextField` (old `django-ckeditor` removed in Phase 5)
- Pass `link_rel=None` to `nh3.clean()` to fix `ValueError` when `'rel'`
  is in `allowed_attributes` (nh3 >= 0.2.18 API change)

Closes #281.

Assisted-by: Claude Opus 4.6 (1M context)
Signed-off-by: Justin Wheeler <jwheel@fedoraproject.org>
This commit is contained in:
Justin Wheeler 2026-06-20 16:57:57 -04:00
commit 51d6014997
Signed by: jflory7
GPG key ID: 6BD803B36BF8F62E
5 changed files with 56 additions and 14 deletions

View file

@ -20,23 +20,12 @@ jobs:
runs-on: podman
container:
image: python:3.13-slim
services:
db:
image: postgres:15
env:
POSTGRES_PASSWORD: example
POSTGRES_DB: postgres
redis:
image: redis:7
steps:
- name: Install Node.js for checkout action
run: apt-get update && apt-get install -y --no-install-recommends nodejs
- uses: https://code.forgejo.org/actions/checkout@v4
- name: Install system dependencies
run: apt-get install -y --no-install-recommends gcc libpq-dev
- name: Install Poetry and project dependencies
run: |
pip install poetry

36
conftest.py Normal file
View file

@ -0,0 +1,36 @@
import tempfile
from pathlib import Path
from unittest.mock import patch
import pytest
from django.test import override_settings
MINIMAL_PNG = (
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01'
b'\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00'
b'\x00\x00\x0cIDATx\x9cc\xf8\x0f\x00\x00\x01\x01\x00'
b'\x05\x18\xd8N\x00\x00\x00\x00IEND\xaeB`\x82'
)
@pytest.fixture(autouse=True)
def _mock_fedora_messaging_publish():
with patch('happinesspackets.messaging.views.publish'):
yield
@pytest.fixture(autouse=True)
def _mock_fas_people_query():
from fedora.client.fas2 import AccountSystem
with patch.object(AccountSystem, 'people_query', return_value=[]):
yield
@pytest.fixture(autouse=True)
def _mock_static_root_for_email():
with tempfile.TemporaryDirectory() as tmpdir:
images_dir = Path(tmpdir) / 'images'
images_dir.mkdir()
(images_dir / 'logo.svg').write_bytes(MINIMAL_PNG)
with override_settings(STATIC_ROOT=Path(tmpdir)):
yield

View file

@ -86,6 +86,7 @@ class MessageSendForm(forms.ModelForm):
html,
tags=allowed_tags,
attributes=allowed_attributes,
link_rel=None,
)
def clean(self):

View file

@ -1,7 +1,6 @@
# Generated by Django 2.0 on 2019-05-08 11:53
import ckeditor.fields
from django.db import migrations
from django.db import migrations, models
class Migration(migrations.Migration):
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='message',
name='message',
field=ckeditor.fields.RichTextField(),
field=models.TextField(),
),
]

View file

@ -18,3 +18,20 @@ AUTHENTICATION_BACKENDS = (
DEBUG_TOOLBAR_CONFIG = {
"SHOW_TOOLBAR_CALLBACK" : lambda request: False,
}
CRISPY_ALLOWED_TEMPLATE_PACKS = ('bootstrap5',)
ADMIN_USERNAME = 'test'
ADMIN_PASSWORD = 'test'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:',
}
}
CELERY_TASK_ALWAYS_EAGER = True
CELERY_TASK_EAGER_PROPAGATES = True
CELERY_BROKER_URL = 'memory://'
CELERY_RESULT_BACKEND = 'cache+memory://'