Skip to content
This repository has been archived by the owner on May 28, 2022. It is now read-only.

Commit

Permalink
Adds json schemas to responses for view requests
Browse files Browse the repository at this point in the history
  • Loading branch information
FranciscoCanas committed Nov 20, 2014
1 parent 8616d92 commit fe443ce
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 89 deletions.
76 changes: 55 additions & 21 deletions src/freeseer/frontend/controller/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ def update_config(config, data):
Raises:
HTTPError: If given data changes don't conform to config's schema.
"""

for key, value in data.items():
# TODO: Add json-schema validation when pr #646 is merged.
try:
opt_instance = config.options[key]
value = opt_instance.decode(value)
Expand All @@ -126,6 +126,37 @@ def update_config(config, data):
config.save()


def pack_configuration(config, include=[]):
"""
Returns a response for the given config.
Args:
config: A Config instance.
include: An optional list of Config options to include in response.
Returns:
A dict containing the given configuration, and its schema. If an
'include' list is given, only the options listed are returned in
the configuration.
"""
conf = {}
schema = {}

if include:
for key in include:
option = config.options[key]
conf[key] = option.presentation(config.values[key])
schema[key] = option.schema()
else:
conf = config.values
schema = config.schema()

return {
'configuration': conf,
'schema': schema,
}


@configuration.before_app_first_request
def configure_configuration():
"""
Expand All @@ -142,7 +173,8 @@ def load_profile_configuration(profile):
HTTPError: If profile does not exist.
"""
profile_instance = load_profile(profile)
return profile_instance.get_config('freeseer.conf', settings.FreeseerConfig, storage_args=['Global'], read_only=False)
return profile_instance.get_config('freeseer.conf', settings.FreeseerConfig, storage_args=['Global'],
read_only=False)


def load_profile(profile):
Expand Down Expand Up @@ -216,7 +248,7 @@ def view_profile(profile):
HTTPError: If profile doesn't exist.
"""
profile_configuration = load_profile_configuration(profile)
return {'profile_configuration': profile_configuration.values}
return pack_configuration(profile_configuration)


@configuration.route('/profiles', methods=['POST'])
Expand Down Expand Up @@ -291,10 +323,7 @@ def view_general_configuration(profile):
HTTPError: If profile does not exist.
"""
profile_configuration = load_profile_configuration(profile)
return {
'default_language': profile_configuration.default_language,
'auto_hide': profile_configuration.auto_hide,
}
return pack_configuration(profile_configuration, include=['default_language', 'auto_hide'])


@configuration.route('/profiles/<string:profile>/general', methods=['PATCH'])
Expand All @@ -311,6 +340,8 @@ def modify_general_configuration(profile):
changes = request.form
update_config(profile_configuration, changes)
return ''


#
# General Configuration Endpoints
#
Expand All @@ -330,17 +361,17 @@ def view_recording_configuration(profile):
HTTPError: If profile does not exist.
"""
profile_configuration = load_profile_configuration(profile)
return {
'record_to_file': profile_configuration.record_to_file,
'videodir': profile_configuration.videodir,
'record_to_file_plugin': profile_configuration.record_to_file_plugin,
'record_to_stream': profile_configuration.record_to_stream,
'record_to_stream_plugin': profile_configuration.record_to_stream_plugin,
'enable_audio_recording': profile_configuration.enable_audio_recording,
'audiomixer': profile_configuration.audiomixer,
'enable_video_recording': profile_configuration.enable_video_recording,
'videomixer': profile_configuration.videomixer,
}
return pack_configuration(profile_configuration, include=[
'record_to_file',
'videodir',
'record_to_file_plugin',
'record_to_stream',
'record_to_stream_plugin',
'enable_audio_recording',
'audiomixer',
'enable_video_recording',
'videomixer',
])


@configuration.route('/profiles/<string:profile>/recording', methods=['PATCH'])
Expand All @@ -357,6 +388,8 @@ def modify_recording_configuration(profile):
changes = request.form
update_config(profile_configuration, changes)
return ''


#
# End recording configuration endpoints.
#
Expand All @@ -380,6 +413,8 @@ def list_plugin_category(profile, category):
return {
'plugins': [plugin.name for plugin in plugin_infos]
}


#
# End of plugin category endpoints.
#
Expand Down Expand Up @@ -410,9 +445,7 @@ def view_plugin_instance(profile, category, plugin, id):
HTTPError: If profile, category, or plugin do not exist.
"""
plugin_config = get_plugin_config(profile, category, plugin, id)
return {
'configuration': plugin_config.values
}
return pack_configuration(plugin_config)


@configuration.route('/profiles/<string:profile>/recording/<string:category>/<string:plugin>', methods=['POST'])
Expand Down Expand Up @@ -441,6 +474,7 @@ def modify_plugin_instance(profile, category, plugin, id):
changes = request.form
update_config(plugin_config, changes)
return ''

#
# End of plugin endpoints.
#
173 changes: 105 additions & 68 deletions src/freeseer/tests/frontend/controller/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@
from freeseer.frontend.controller import server


def pack_schema(config, include):
"""Returns a partial schema from the options in 'include'."""
schema = {}
for key in include:
schema[key] = config.options[key].schema()
print schema
return schema


class TestConfigurationApp:
@pytest.fixture(scope='module')
def test_client(self):
Expand Down Expand Up @@ -63,8 +72,18 @@ def test_list_profiles(self, test_client):
assert response.status_code == 200
assert expected == data

def test_view_profile(self, test_client):
def test_view_profile(self, test_client, configuration):
response = test_client.get('/profiles/testing')
configuration.config = configuration.profile.get_config('freeseer.conf',
settings.FreeseerConfig,
['Global'],
read_only=True)
expected = {
'configuration': configuration.config.values,
'schema': configuration.config.schema(),
}
data = json.loads(response.data)
assert expected == data
assert response.status_code == 200

def test_view_profile_nonexistant_id(self, test_client):
Expand Down Expand Up @@ -136,8 +155,11 @@ def test_view_general_configuration(self, test_client, configuration):
['Global'],
read_only=True)
assert response_data == {
'default_language': general.default_language,
'auto_hide': general.auto_hide,
'configuration': {
'default_language': general.default_language,
'auto_hide': general.auto_hide,
},
'schema': pack_schema(general, ['default_language', 'auto_hide']),
}

assert response.status_code == 200
Expand All @@ -158,72 +180,87 @@ def test_modify_general_configuration(self, test_client, configuration):

def test_view_recording_configuration(self, test_client, configuration):
response = test_client.get('/profiles/testing/recording')
response_data = json.loads(response.data)
config = configuration.config
assert response.status_code == 200
assert response_data == {
'record_to_file': config.record_to_file,
'videodir': config.videodir,
'record_to_file_plugin': config.record_to_file_plugin,
'record_to_stream': config.record_to_stream,
'record_to_stream_plugin': config.record_to_stream_plugin,
'enable_audio_recording': config.enable_audio_recording,
'audiomixer': config.audiomixer,
'enable_video_recording': config.enable_video_recording,
'videomixer': config.videomixer,
}

def test_list_plugin_category(self, test_client, configuration):
response = test_client.get('/profiles/testing/recording/audioinput')
plugin_infos = configuration.plugin_manager.get_plugins_of_category('AudioInput')
expected = {'plugins': [plugin.name for plugin in plugin_infos]}
data = json.loads(response.data)
assert data == expected
assert response.status_code == 200

def test_list_plugin_instances(self, test_client, configuration):
response = test_client.get('/profiles/testing/recording/audioinput/jackaudiosource')
assert response.status_code == 501

def test_view_plugin_instance(self, test_client, configuration):
response = test_client.get('/profiles/testing/recording/audioinput/jackaudiosource/0')
plugin = configuration.plugin_manager.get_plugin_by_name('Jack Audio Source', 'AudioInput')
plugin_object = plugin.plugin_object
plugin_object.set_instance(0)
plugin_object.load_config(configuration.plugin_manager)
config = configuration.config
expected = {
'configuration': plugin_object.config.values
'configuration': {
'record_to_file': config.record_to_file,
'videodir': config.videodir,
'record_to_file_plugin': config.record_to_file_plugin,
'record_to_stream': config.record_to_stream,
'record_to_stream_plugin': config.record_to_stream_plugin,
'enable_audio_recording': config.enable_audio_recording,
'audiomixer': config.audiomixer,
'enable_video_recording': config.enable_video_recording,
'videomixer': config.videomixer,
},
'schema': pack_schema(config, [
'record_to_file',
'videodir',
'record_to_file_plugin',
'record_to_stream',
'record_to_stream_plugin',
'enable_audio_recording',
'audiomixer',
'enable_video_recording',
'videomixer',
]),
}
data = json.loads(response.data)
assert response.status_code == 200
assert expected == data

def test_view_invalid_plugin_name(self, test_client, configuration):
response = test_client.get('/profiles/testing/recording/audioinput/fakeaudiosource/0')
data = json.loads(response.data)
assert data['error_message'] == 'Invalid Plugin Name: fakeaudiosource'
assert response.status_code == 400

def test_view_invalid_plugin_category(self, test_client, configuration):
response = test_client.get('/profiles/testing/recording/fakeinput/jackaudiosource/0')
data = json.loads(response.data)
assert data['error_message'] == 'Invalid Plugin Category: fakeinput'
assert response.status_code == 400

def test_create_plugin_instance(self, test_client, configuration):
response = test_client.post('/profiles/testing/recording/audioinput/jackaudiosource')
assert response.status_code == 501

def test_modify_plugin_instance(profile, test_client, configuration):
response = test_client.patch('/profiles/testing/recording/audioinput/jackaudiosource/0',
data={
'client': 'testclient',
'connect': 'testconnect',
})
plugin = configuration.plugin_manager.get_plugin_by_name('Jack Audio Source', 'AudioInput')
plugin_object = plugin.plugin_object
plugin_object.set_instance(0)

assert plugin_object.config.client == 'testclient'
assert plugin_object.config.connect == 'testconnect'
assert response.status_code == 200
assert expected['configuration'] == data['configuration']

def test_list_plugin_category(self, test_client, configuration):
response = test_client.get('/profiles/testing/recording/audioinput')
plugin_infos = configuration.plugin_manager.get_plugins_of_category('AudioInput')
expected = {'plugins': [plugin.name for plugin in plugin_infos]}
data = json.loads(response.data)
assert data == expected
assert response.status_code == 200

def test_list_plugin_instances(self, test_client, configuration):
response = test_client.get('/profiles/testing/recording/audioinput/jackaudiosource')
assert response.status_code == 501

def test_view_plugin_instance(self, test_client, configuration):
response = test_client.get('/profiles/testing/recording/audioinput/jackaudiosource/0')
plugin = configuration.plugin_manager.get_plugin_by_name('Jack Audio Source', 'AudioInput')
plugin_object = plugin.plugin_object
plugin_object.set_instance(0)
plugin_object.load_config(configuration.plugin_manager)
expected = {
'configuration': plugin_object.config.values,
'schema': plugin_object.config.schema(),
}
data = json.loads(response.data)
assert response.status_code == 200
assert expected == data

def test_view_invalid_plugin_name(self, test_client, configuration):
response = test_client.get('/profiles/testing/recording/audioinput/fakeaudiosource/0')
data = json.loads(response.data)
assert data['error_message'] == 'Invalid Plugin Name: fakeaudiosource'
assert response.status_code == 400

def test_view_invalid_plugin_category(self, test_client, configuration):
response = test_client.get('/profiles/testing/recording/fakeinput/jackaudiosource/0')
data = json.loads(response.data)
assert data['error_message'] == 'Invalid Plugin Category: fakeinput'
assert response.status_code == 400

def test_create_plugin_instance(self, test_client, configuration):
response = test_client.post('/profiles/testing/recording/audioinput/jackaudiosource')
assert response.status_code == 501

def test_modify_plugin_instance(profile, test_client, configuration):
response = test_client.patch('/profiles/testing/recording/audioinput/jackaudiosource/0',
data={
'client': 'testclient',
'connect': 'testconnect',
})
plugin = configuration.plugin_manager.get_plugin_by_name('Jack Audio Source', 'AudioInput')
plugin_object = plugin.plugin_object
plugin_object.set_instance(0)

assert plugin_object.config.client == 'testclient'
assert plugin_object.config.connect == 'testconnect'
assert response.status_code == 200

0 comments on commit fe443ce

Please sign in to comment.