Skip to content

Commit

Permalink
Update how we load settings from database.
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathangreen committed Nov 3, 2023
1 parent 500064b commit e77b5a7
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
8 changes: 4 additions & 4 deletions core/integration/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ def integration_settings_load(
"""
Load the settings object for an integration from the database.
These settings ARE NOT validated when loaded from the database. It is assumed that
the settings have already been validated when they were saved to the database. This
speeds up the loading of the settings from the database.
The settings are validated when loaded from the database, this is done rather
than using construct() because there are some types that need to get type converted
when round tripping from the database (such as enum) and construct() doesn't do that.
:param settings_cls: The settings class that the settings should be loaded into.
:param integration: The integration to load the settings from. This should be a
Expand All @@ -37,7 +37,7 @@ def integration_settings_load(
:return: An instance of the settings class loaded with the settings from the database.
"""
settings_dict = integration.settings_dict
return settings_cls.construct(**settings_dict)
return settings_cls(**settings_dict)

Check warning on line 40 in core/integration/base.py

View check run for this annotation

Codecov / codecov/patch

core/integration/base.py#L40

Added line #L40 was not covered by tests


def integration_settings_update(
Expand Down
40 changes: 37 additions & 3 deletions tests/core/integration/test_base.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import datetime
from enum import Enum
from functools import partial
from unittest.mock import MagicMock, Mock, patch

import pytest

from core.integration.base import integration_settings_load, integration_settings_update
from core.integration.goals import Goals
from core.integration.settings import BaseSettings
from core.model import IntegrationConfiguration
from tests.fixtures.database import DatabaseTransactionFixture


class BaseFixture:
Expand All @@ -31,10 +35,40 @@ def base_fixture():

def test_integration_settings_load(base_fixture: BaseFixture) -> None:
return_value: BaseSettings = base_fixture.load()
base_fixture.mock_settings_cls.construct.assert_called_once_with(
test="test", number=123
base_fixture.mock_settings_cls.assert_called_once_with(test="test", number=123)
assert return_value is base_fixture.mock_settings_cls.return_value


def test_integration_settings_roundtrip(db: DatabaseTransactionFixture) -> None:
class TestEnum(Enum):
FOO = "foo"
BAR = "bar"

class TestSettings(BaseSettings):
test: str
number: int
enum: TestEnum
date: datetime.date

# Create a settings object and save it to the database
settings = TestSettings(
test="test", number=123, enum=TestEnum.FOO, date=datetime.date.today()
)
assert return_value is base_fixture.mock_settings_cls.construct.return_value
integration = db.integration_configuration(protocol="test", goal=Goals.LICENSE_GOAL)
integration_settings_update(TestSettings, integration, settings)
settings_dict = integration.settings_dict.copy()

# Expire this object in the session, so that we can be sure that the integration data
# gets round-tripped from the database, which includes a JSON serialization step.
db.session.flush()
db.session.expire(integration)

# Load the settings from the database and check that the settings_dict is different
# due to the JSON serialization, but that once we load the settings object, it is
# equal to the original settings object.
assert integration.settings_dict != settings_dict
settings_roundtripped = integration_settings_load(TestSettings, integration)
assert settings_roundtripped == settings


def test_integration_settings_update_no_merge(base_fixture: BaseFixture) -> None:
Expand Down

0 comments on commit e77b5a7

Please sign in to comment.