Skip to content

Commit

Permalink
add open edx api to be used for other packages
Browse files Browse the repository at this point in the history
  - prepare for deprecating `site_configuration` openedx/platform-roadmap#21
  - allow easier separation of `secret`, `admin` and other settings
  - packages can use these helpers instead of mocking Open edX
    configuration
  • Loading branch information
OmarIthawi committed Mar 28, 2022
1 parent eaee940 commit 0a6bff9
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 0 deletions.
76 changes: 76 additions & 0 deletions site_config_client/openedx/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""
External Open edX Python API helpers goes here.
### API Contract:
* Those APIs should be stable and abstract internal changes.
* Non-stable and internal APIs should be placed in other modules.
* The parameters of existing functions should change in a backward compatible way:
- No parameters should be removed from the function
- New parameters should have safe defaults
* For breaking changes, new functions should be created
"""

try:
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
except ImportError:
# Silence the initial import error, but runtime errors will occur in tests and non-Open edX environments.
# In tests, `configuration_helpers` can be mocked.
pass


def get_current_configuration():
"""
Gets current site configuration.
"""
return configuration_helpers.get_current_site_configuration()


def get_admin_value(name, default=None, site_configuration=None):
"""
Get `admin` setting from the site configuration service.
Proxy for `site_configuration.get_admin_setting` until site_configuration is deprecated.
"""
if not site_configuration:
site_configuration = get_current_configuration()

return site_configuration.get_admin_setting(name, default)


def get_secret_value(name, default=None, site_configuration=None):
"""
Get `secret` setting from the site configuration service.
Proxy for `site_configuration.get_secret_value` until site_configuration is deprecated.
"""

if not site_configuration:
site_configuration = get_current_configuration()

return site_configuration.get_secret_value(name, default)


def get_setting_value(name, default=None, site_configuration=None):
"""
Get `setting` setting from the site configuration service.
Proxy for `site_configuration.get_value` until site_configuration is deprecated.
"""
if not site_configuration:
site_configuration = get_current_configuration()

return site_configuration.get_value(name, default)


def get_page_value(name, default=None, site_configuration=None):
"""
Get `page` setting from the site configuration service.
Proxy for `site_configuration.get_page_content` until site_configuration is deprecated.
"""
if not site_configuration:
site_configuration = get_current_configuration()

return site_configuration.get_page_content(name, default)
18 changes: 18 additions & 0 deletions site_config_client/openedx/test_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
Test helpers for other packages to override testers.
"""

from unittest.mock import patch, Mock


def override_site_config(config_type, **config_overrides):
"""
Override site config settings for a specific type of configuration.
"""
def overrider_for_get_value_of_type(name, default=None, site_configuration=None):
return config_overrides.get(name, default)

return patch(
'site_config_client.openedx.api.get_{type}_value'.format(type=config_type),
Mock(side_effect=overrider_for_get_value_of_type),
)
77 changes: 77 additions & 0 deletions tests/test_openedx_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""
Tests for the openedx.api module.
"""
from unittest.mock import patch, Mock

import pytest

try:
from site_config_client.openedx import api as openedx_api
except ImportError:
# Silent import failures for non-Open edX environments.
pass


def with_current_configs(current_config):
"""
@patch `get_current_site_configuration()`
"""
configuration_helpers = Mock()
configuration_helpers.get_current_site_configuration.return_value = current_config
return patch(
'site_config_client.openedx.api.configuration_helpers',
configuration_helpers,
create=True,
)


@pytest.mark.openedx
def test_get_admin_value():
"""
Test `get_admin_value()` helper for `admin` type of configurations.
"""
current_config = Mock()
current_config.get_admin_setting.return_value = 'password'
with with_current_configs(current_config):
admin_value = openedx_api.get_admin_value('IDP_CLIENT', 'default-client')
assert admin_value == 'password'
current_config.get_admin_setting.assert_called_with('IDP_CLIENT', 'default-client')


@pytest.mark.openedx
def test_get_secret_value():
"""
Test `get_secret_value()` helper for `secret` type of configurations.
"""
current_config = Mock()
current_config.get_secret_value.return_value = 'password'
with with_current_configs(current_config):
secret_value = openedx_api.get_secret_value('EMAIL_PASSWORD', 'default-pass')
assert secret_value == 'password'
current_config.get_secret_value.assert_called_with('EMAIL_PASSWORD', 'default-pass')


@pytest.mark.openedx
def test_get_setting_value():
"""
Test `get_setting_value()` helper for `setting` type of configurations.
"""
current_config = Mock()
current_config.get_value.return_value = 'pre-defined-site.com'
with with_current_configs(current_config):
setting = openedx_api.get_setting_value('SITE_NAME', 'defaultsite.com')
assert setting == 'pre-defined-site.com'
current_config.get_value.assert_called_with('SITE_NAME', 'defaultsite.com')


@pytest.mark.openedx
def test_get_page_value():
"""
Test `get_page_value()` helper for `page` type of configurations.
"""
current_config = Mock()
current_config.get_page_content.return_value = '{"title": "About page"}'
with with_current_configs(current_config):
page_value = openedx_api.get_page_value('about', {})
assert page_value == '{"title": "About page"}'
current_config.get_page_content.assert_called_with('about', {})
30 changes: 30 additions & 0 deletions tests/test_openedx_test_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""
Tests for site_config_client.openedx.test_helpers
"""
import pytest

try:
from site_config_client.openedx.test_helpers import override_site_config
from site_config_client.openedx import api as openedx_api
except ImportError:
# Silent import failures for non-Open edX environments.
pass


@pytest.mark.openedx
def test_secret_override():
"""
Use `override_site_config` for a `secret` site configuration.
"""
with override_site_config('secret', EMAIL_PASSWORD='test'):
assert openedx_api.get_secret_value('EMAIL_PASSWORD') == 'test'


@pytest.mark.openedx
def test_without_overrides_fails():
"""
Test that api fails without overrides due to missing packages in test environment.
"""

with pytest.raises(NameError, match='name .configuration_helpers. is not defined'):
openedx_api.get_secret_value('EMAIL_PASSWORD')

0 comments on commit 0a6bff9

Please sign in to comment.