Skip to content

Commit

Permalink
[#467] update django-setup-configuration site step
Browse files Browse the repository at this point in the history
  • Loading branch information
SonnyBA committed Dec 10, 2024
1 parent 09e092a commit 8f60c30
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 16 deletions.
33 changes: 17 additions & 16 deletions docs/installation/config_cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,29 @@ Objects API
Sites configuration
-------------------

..
_TODO:
Create or update a (single) YAML configuration file with your settings:

.. code-block:: yaml
...
sites_config_enable: true
sites:
items:
- domain: example.com
name: Example site
- domain: test.example.com
name: Test site
...
.. note:: The ``domain`` field will be used to lookup existing ``Site``'s.

Objecttypes configuration
-------------------------

Create a (single) YAML configuration file with your settings:
Create or update a (single) YAML configuration file with your settings:

.. code-block:: yaml
...
objecttypes_config_enable: true
objecttypes:
items:
Expand All @@ -55,6 +68,7 @@ Create a (single) YAML configuration file with your settings:
- uuid: b0e8553f-8b1a-4d55-ab90-6d02f1bcf2c2
name: Object Type 2
service_identifier: service-2
...
.. note:: The ``uuid`` field will be used to lookup existing ``ObjectType``'s.

Expand All @@ -65,12 +79,6 @@ Demo user configuration
_TODO:

Sites configuration
-------------------

..
_TODO:

Objects configuration
---------------------
Expand All @@ -79,13 +87,6 @@ Objects configuration
_TODO:

Demo user configuration
-----------------------

..
_TODO:

Execution
=========

Expand Down
1 change: 1 addition & 0 deletions src/objects/conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,6 @@
#
SETUP_CONFIGURATION_STEPS = (
"zgw_consumers.contrib.setup_configuration.steps.ServiceConfigurationStep",
"objects.setup_configuration.steps.sites.SitesConfigurationStep",
"objects.setup_configuration.steps.objecttypes.ObjectTypesConfigurationStep",
)
17 changes: 17 additions & 0 deletions src/objects/setup_configuration/models/sites.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django.contrib.sites.models import Site
from django_setup_configuration.models import ConfigurationModel
from pydantic import Field


class SiteConfigurationModel(ConfigurationModel):
class Meta:
django_model_refs = {
Site: (
"domain",
"name",
)
}


class SitesConfigurationModel(ConfigurationModel):
items: list[SiteConfigurationModel] = Field()
40 changes: 40 additions & 0 deletions src/objects/setup_configuration/steps/sites.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from django.contrib.sites.models import Site

from django.core.exceptions import ValidationError
from django.db import IntegrityError
from django_setup_configuration.configuration import BaseConfigurationStep
from django_setup_configuration.exceptions import ConfigurationRunFailed

from objects.setup_configuration.models.sites import SitesConfigurationModel


class SitesConfigurationStep(BaseConfigurationStep):
config_model = SitesConfigurationModel
verbose_name = "Sites configuration"

namespace = "sites"
enable_setting = "sites_config_enable"

def execute(self, model: SitesConfigurationModel) -> None:
for item in model.items:
site_kwargs = dict(domain=item.domain, name=item.name)
site_instance = Site(**site_kwargs)

try:
site_instance.full_clean(exclude=("id",), validate_unique=False)
except ValidationError as exception:
exception_message = (
f"Validation error(s) occured for site {item.domain}."
)
raise ConfigurationRunFailed(exception_message) from exception

try:
Site.objects.update_or_create(
domain=item.domain,
defaults=dict(name=item.name)
)
except IntegrityError as exception:
exception_message = (
f"Failed configuring site {item.domain}."
)
raise ConfigurationRunFailed(exception_message) from exception
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sites_config_enable: true
sites:
items:
- domain: example.com
name: Example site

- domain: alternative.example.com
name: Alternative example site
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sites_config_enable: true
sites:
items:
- domain: example.com
name: Example site (revised)

- domain: test.example.com
name: Test site
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sites_config_enable: true
sites:
items:
- domain: example.com
name: Example site

- domain: alternative.example.com
name: Alternative example site
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sites_config_enable: true
sites:
items:
- domain: example.com
name: Example site

- domain: foobar whitespace.com
name: Invalid site
101 changes: 101 additions & 0 deletions src/objects/setup_configuration/tests/test_site_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
from pathlib import Path

from django.contrib.sites.models import Site
from django.db.models import QuerySet
from django.test import TestCase

from django_setup_configuration.exceptions import ConfigurationRunFailed
from django_setup_configuration.test_utils import execute_single_step

from objects.setup_configuration.steps.sites import SitesConfigurationStep

TEST_FILES = (Path(__file__).parent / "files").resolve()


class SitesConfigurationStepTests(TestCase):
def test_empty_database(self):
test_file_path = str(TEST_FILES / "sites_empty_database.yaml")

execute_single_step(SitesConfigurationStep, yaml_source=test_file_path)

sites: QuerySet[Site] = Site.objects.all()

self.assertEqual(sites.count(), 2)

example_site: Site = sites.get(name="Example site")
self.assertEqual(example_site.domain, "example.com")

alternative_site: Site = sites.get(name="Alternative example site")
self.assertEqual(alternative_site.domain, "alternative.example.com")

def test_existing_sites(self):
test_file_path = str(TEST_FILES / "sites_existing_sites.yaml")

example_site, _ = Site.objects.get_or_create(
domain="example.com",
defaults=dict(name="Example site")
)

alternative_site = Site.objects.create(
domain="alternative.example.com",
name="Alternative example site",
)

execute_single_step(SitesConfigurationStep, yaml_source=test_file_path)

sites: QuerySet[Site] = Site.objects.order_by("name")

self.assertEqual(sites.count(), 3)

example_site: Site = sites.get(name="Example site (revised)")
self.assertEqual(example_site.domain, "example.com")

alternative_site: Site = sites.get(name="Alternative example site")
self.assertEqual(alternative_site.domain, "alternative.example.com")

test_site: Site = sites.get(name="Test site")
self.assertEqual(test_site.domain, "test.example.com")

def test_invalid_domain(self):
test_file_path = str(TEST_FILES / "sites_invalid_domain.yaml")

with self.assertRaises(ConfigurationRunFailed):
execute_single_step(SitesConfigurationStep, yaml_source=test_file_path)

sites: QuerySet[Site] = Site.objects.all()

# the default test site created during test runs
self.assertEqual(sites.count(), 1)

site: Site = sites.get()

self.assertEqual(site.domain, "example.com")

def test_idempotent_step(self):
test_file_path = str(TEST_FILES / "sites_idempotent_step.yaml")

execute_single_step(SitesConfigurationStep, yaml_source=test_file_path)

sites: QuerySet[Site] = Site.objects.all()

self.assertEqual(sites.count(), 2)

example_site: Site = sites.get(name="Example site")
self.assertEqual(example_site.domain, "example.com")

alternative_site: Site = sites.get(name="Alternative example site")
self.assertEqual(alternative_site.domain, "alternative.example.com")

execute_single_step(SitesConfigurationStep, yaml_source=test_file_path)

self.assertEqual(Site.objects.count(), 2)

example_site.refresh_from_db()

self.assertEqual(example_site.name, "Example site")
self.assertEqual(example_site.domain, "example.com")

alternative_site.refresh_from_db()

self.assertEqual(alternative_site.name, "Alternative example site")
self.assertEqual(alternative_site.domain, "alternative.example.com")

0 comments on commit 8f60c30

Please sign in to comment.