-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from edx/kkim/milestones_service
Milestones Service
- Loading branch information
Showing
3 changed files
with
84 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
""" | ||
A wrapper class around requested methods exposed in api.py | ||
""" | ||
|
||
import types | ||
|
||
from milestones import api as milestones_api | ||
|
||
|
||
class MilestonesService(object): # pylint: disable=too-few-public-methods | ||
""" | ||
An xBlock service for xBlocks to talk to the Milestones subsystem. | ||
NOTE: This is a Singleton class. We should only have one instance of it! | ||
""" | ||
|
||
_instance = None | ||
|
||
REQUESTED_FUNCTIONS = [ | ||
'get_course_content_milestones', | ||
] | ||
|
||
def __new__(cls, *args, **kwargs): | ||
""" | ||
This is the class factory to make sure this is a Singleton | ||
""" | ||
if not cls._instance: | ||
cls._instance = super(MilestonesService, cls).__new__(cls, *args, **kwargs) | ||
return cls._instance | ||
|
||
def __init__(self): | ||
""" | ||
Class initializer, which just inspects the libraries and exposes the same functions | ||
listed in REQUESTED_FUNCTIONS | ||
""" | ||
self._bind_to_requested_functions() | ||
|
||
def _bind_to_requested_functions(self): | ||
""" | ||
bind module functions. Since we use underscores to mean private methods, let's exclude those. | ||
""" | ||
for attr_name in self.REQUESTED_FUNCTIONS: | ||
attr = getattr(milestones_api, attr_name, None) | ||
if isinstance(attr, types.FunctionType) and not attr_name.startswith('_'): | ||
if not hasattr(self, attr_name): | ||
setattr(self, attr_name, attr) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
""" | ||
Test for the xBlock service | ||
""" | ||
|
||
import unittest | ||
import types | ||
|
||
from milestones.services import MilestonesService | ||
from milestones import api as milestones_api | ||
|
||
|
||
class TestMilestonesService(unittest.TestCase): # pylint: disable=too-many-public-methods | ||
""" | ||
Tests for MilestonesService | ||
""" | ||
def test_basic(self): | ||
""" | ||
See if the MilestonesService exposes the expected methods | ||
""" | ||
|
||
service = MilestonesService() | ||
|
||
for attr_name in dir(milestones_api): | ||
attr = getattr(milestones_api, attr_name, None) | ||
if isinstance(attr, types.FunctionType) and not attr_name.startswith('_'): | ||
if attr_name in MilestonesService.REQUESTED_FUNCTIONS: | ||
self.assertTrue(hasattr(service, attr_name)) | ||
else: | ||
self.assertFalse(hasattr(service, attr_name)) | ||
|
||
def test_singleton(self): | ||
""" | ||
Test to make sure the MilestonesService is a singleton. | ||
""" | ||
service1 = MilestonesService() | ||
service2 = MilestonesService() | ||
self.assertIs(service1, service2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters