Tests

We use pytest to validate that the functionality of the cms works as expected.

In addition, we use the following plugins:

For more information, see Testing in Django and Writing and running tests.

Conftest

This module contains shared fixtures for pytest

tests.conftest.QUICK_ROLE_SET: Final = ['ROOT', 'MANAGEMENT', 'AUTHOR', 'ANONYMOUS'][source]

Representative subset covering all permission boundaries (for faster local runs)

['ROOT', 'MANAGEMENT', 'AUTHOR', 'ANONYMOUS']
tests.conftest.TEST_ROLES: Final = ['MANAGEMENT', 'EDITOR', 'AUTHOR', 'EVENT_MANAGER', 'OBSERVER', 'ROOT', 'SERVICE_TEAM', 'CMS_TEAM', 'MARKETING_TEAM', 'ANONYMOUS'][source]

The roles used for parametrized tests — set QUICK_ROLES=1 to use the subset

[
    'MANAGEMENT',
    'EDITOR',
    'AUTHOR',
    'EVENT_MANAGER',
    'OBSERVER',
    'ROOT',
    'SERVICE_TEAM',
    'CMS_TEAM',
    'MARKETING_TEAM',
    'ANONYMOUS',
]
tests.conftest.clean_news_cache(load_test_data: None) Generator[None][source]

Clear external news-source cache entries before and after a test.

Language slugs are read from the DB so adding or removing a language is automatically reflected.

Parameters:

load_test_data (None)

Return type:

Generator[None]

tests.conftest.clear_cache() None[source]

Reset the cache before every test so cache state cannot leak between tests.

The cache backend used in tests (LocMemCache) lives for the lifetime of the worker process, and Django only rolls back the database between tests — not the cache. Without this, process-level cache state (most notably the API rate-limit counters in rate_limited()) accumulates across tests and makes assertions depend on test execution order.

Return type:

None

tests.conftest.clear_leaked_messages(request: SubRequest) Generator[None][source]

Discard unread messages from the shared client after every test.

login_role_user() is session-scoped, so one client — and one cookie jar — is reused for the whole run, while MESSAGE_STORAGE keeps messages in a cookie. A test that triggers a view emitting a message without ever rendering the redirect target leaves that message queued in the cookie, where an arbitrary later test renders it into its own response and trips content assertions.

Parameters:

request (SubRequest)

Return type:

Generator[None]

tests.conftest.create_event() Callable[..., Event][source]

Factory fixture to create an Event with sensible defaults for all required fields.

Returns:

A callable that creates an event

Return type:

Callable[…, Event]

tests.conftest.create_event_translation() Callable[..., EventTranslation][source]

Factory fixture to create an EventTranslation with sensible defaults for all required fields.

Returns:

A callable that creates an event translation

Return type:

Callable[…, EventTranslation]

tests.conftest.create_language() Callable[..., Language][source]

Factory fixture to create a Language with sensible defaults for all required fields, so tests only need to pass the values they care about.

Returns:

A callable that creates a language

Return type:

Callable[…, Language]

tests.conftest.create_page() Callable[..., Page][source]

Factory fixture to create a Page via treebeard’s add_root / add_child API.

Returns:

A callable that creates a page

Return type:

Callable[…, Page]

tests.conftest.create_page_translation() Callable[..., PageTranslation][source]

Factory fixture to create a PageTranslation with sensible defaults for all required fields.

Returns:

A callable that creates a page translation

Return type:

Callable[…, PageTranslation]

tests.conftest.create_recurrence_rule() Callable[..., RecurrenceRule][source]

Factory fixture to create a RecurrenceRule.

Returns:

A callable that creates a recurrence rule

Return type:

Callable[…, RecurrenceRule]

tests.conftest.create_region(create_language: Callable[..., Language]) Callable[..., Region][source]

Factory fixture to create a Region with sensible defaults for all required fields. If no language tree exists for the region after creation, a default language is created and attached automatically.

Returns:

A callable that creates a region

Parameters:

create_language (Callable[..., Language])

Return type:

Callable[…, Region]

tests.conftest.create_user() Callable[..., User][source]

Factory fixture to create a User.

Returns:

A callable that creates a user

Return type:

Callable[…, User]

tests.conftest.disable_auto_news_reimport(settings: SettingsWrapper) None[source]

Disable re-import of external news on demand to avoid hitting the real APIs and getting real news posts

Parameters:

settings (SettingsWrapper)

Return type:

None

tests.conftest.load_test_data(django_db_setup: None, django_db_blocker: _DatabaseBlocker) None[source]

Load the test data initially for all test cases.

Parameters:
  • django_db_setup (None) – The fixture providing the database availability

  • django_db_blocker (_DatabaseBlocker) – The fixture providing the database blocker

Return type:

None

tests.conftest.load_test_data_transactional(transactional_db: None, django_db_blocker: _DatabaseBlocker) None[source]

Load test data for transactional test cases. Transactional tests flush the database after each test, so fixtures must be reloaded per function. pytest-django ensures these run after all non-transactional tests within the same worker.

Parameters:
  • transactional_db (None) – The fixture providing transaction support for the database

  • django_db_blocker (_DatabaseBlocker) – The fixture providing the database blocker

Return type:

None

tests.conftest.login_role_user(request: SubRequest, load_test_data: None, django_db_blocker: _DatabaseBlocker) tuple[Client, str][source]

Get the test user of the current role and force a login. Gets executed only once per user.

Parameters:
  • request (SubRequest) – The request object providing the parametrized role variable through request.param

  • load_test_data (None) – The fixture providing the test data (see load_test_data())

  • django_db_blocker (_DatabaseBlocker) – The fixture providing the database blocker

Returns:

The http client and the current role

Return type:

tuple[Client, str]

tests.conftest.pytest_addoption(parser: Parser) None[source]

Register custom CLI options.

Parameters:

parser (Parser)

Return type:

None

tests.conftest.reset_linkcheck_listeners() Generator[None][source]

Restore the configured linkcheck listener state around every test.

linkcheck.listeners.disable_listeners() re-registers the listeners when its context manager exits instead of restoring whatever state was active before, so production code paths that use it — the region form, region_actions and language_tree_actions — leave the listeners connected for the remainder of the worker process, even though LINKCHECK_DISABLE_LISTENERS is enabled in test_settings. Any later test that saves content then silently gets Url/Link rows it never asked for, which makes linkcheck assertions depend on which tests happened to share the worker.

Return type:

Generator[None]

tests.conftest.update_snapshots(request: FixtureRequest) bool[source]

Whether --update-snapshots was passed on the CLI.

Parameters:

request (FixtureRequest)

Return type:

bool

Constants

Shared test constants.

Role identifiers and role groups used across test parametrization. Extracted from conftest.py so they can be imported without triggering fixture registration.

tests.constants.ALL_ROLES: Final = ['MANAGEMENT', 'EDITOR', 'AUTHOR', 'EVENT_MANAGER', 'OBSERVER', 'ROOT', 'SERVICE_TEAM', 'CMS_TEAM', 'MARKETING_TEAM', 'ANONYMOUS'][source]

All region and staff roles and anonymous users

[
    'MANAGEMENT',
    'EDITOR',
    'AUTHOR',
    'EVENT_MANAGER',
    'OBSERVER',
    'ROOT',
    'SERVICE_TEAM',
    'CMS_TEAM',
    'MARKETING_TEAM',
    'ANONYMOUS',
]
tests.constants.ANONYMOUS: Final = 'ANONYMOUS'[source]

A role identifier for anonymous users

tests.constants.HIGH_PRIV_STAFF_ROLES: Final = ['ROOT', 'SERVICE_TEAM', 'CMS_TEAM'][source]

All roles of staff users that don’t just have read-only permissions

['ROOT', 'SERVICE_TEAM', 'CMS_TEAM']
tests.constants.PRIV_STAFF_ROLES: Final = ['ROOT', 'SERVICE_TEAM', 'CMS_TEAM'][source]

All roles of staff users that don’t just have read-only permissions

['ROOT', 'SERVICE_TEAM', 'CMS_TEAM']
tests.constants.REGION_ROLES: Final = ['MANAGEMENT', 'EDITOR', 'AUTHOR', 'EVENT_MANAGER', 'OBSERVER'][source]

All roles of region users

['MANAGEMENT', 'EDITOR', 'AUTHOR', 'EVENT_MANAGER', 'OBSERVER']
tests.constants.ROLES: Final = ['MANAGEMENT', 'EDITOR', 'AUTHOR', 'EVENT_MANAGER', 'OBSERVER', 'ROOT', 'SERVICE_TEAM', 'CMS_TEAM', 'MARKETING_TEAM'][source]

All region and staff roles

[
    'MANAGEMENT',
    'EDITOR',
    'AUTHOR',
    'EVENT_MANAGER',
    'OBSERVER',
    'ROOT',
    'SERVICE_TEAM',
    'CMS_TEAM',
    'MARKETING_TEAM',
]
tests.constants.ROOT: Final = 'ROOT'[source]

A role identifier for superusers

tests.constants.STAFF_ROLES: Final = ['ROOT', 'SERVICE_TEAM', 'CMS_TEAM', 'MARKETING_TEAM'][source]

All roles of staff users

['ROOT', 'SERVICE_TEAM', 'CMS_TEAM', 'MARKETING_TEAM']
tests.constants.WRITE_ROLES: Final = ['MANAGEMENT', 'EDITOR', 'AUTHOR', 'EVENT_MANAGER'][source]

All roles with editing permissions

['MANAGEMENT', 'EDITOR', 'AUTHOR', 'EVENT_MANAGER']

Mock

class tests.mock.MockServer(http_server: HTTPServer)[source]

Bases: object

Http server instance that allowes to configure mock responses

Parameters:

http_server (HTTPServer)

__init__(http_server: HTTPServer) None[source]
Parameters:

http_server (HTTPServer)

Return type:

None

Utils

This file contains helper functions for tests.

tests.utils.assert_message_in_log(message: str, caplog: LogCaptureFixture) None[source]

Check whether a given message is in the messages div

Parameters:
  • message (str) – The expected message

  • caplog (LogCaptureFixture) – The caplog fixture

Raises:

AssertionError – When the expected message was not found in the logs

Return type:

None

tests.utils.assert_no_error_messages(caplog: LogCaptureFixture) None[source]

Assert that no error messages were shown to the user

Parameters:

caplog (LogCaptureFixture) – The caplog fixture

Raises:

AssertionError – When the the logs contains error messages

Return type:

None

tests.utils.get_error_messages(caplog: LogCaptureFixture) list[str][source]

Get all errors from the messages framework

Parameters:

caplog (LogCaptureFixture) – The caplog fixture

Returns:

The list of error messages that were shown to the user

Return type:

list[str]

tests.utils.get_messages(caplog: LogCaptureFixture) list[str][source]

Get all logs from the messages framework

Parameters:

caplog (LogCaptureFixture) – The caplog fixture

Returns:

The list of messages that were shown to the user

Return type:

list[str]