def on_get(self, request, response, sall=None, stag=None, sgrp=None): """Search resources. Args: request (obj): Falcon Request(). response (obj): Falcon Response(). sall (str): Search all ``sall`` path parameter. stag (str): Search tags ``stag`` path parameter. sgrp (str): Search groups ``sgrp`` path parameter. """ self._logger.debug('run: %s %s', request.method, request.uri) if sall: request.params['sall'] = sall if stag: request.params['stag'] = stag if sgrp: request.params['sgrp'] = sgrp api = Api(self._category, Api.SEARCH, request.params) Config.load(api) self._content.run() if not self._content.collection and Config.search_limit != 0: Cause.push(Cause.HTTP_NOT_FOUND, 'cannot find resources') if Cause.is_ok(): response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.collection(self._content.collection, request, response, pagination=True) response.status = Cause.http_status() else: response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.error(Cause.json_message()) response.status = Cause.http_status() Cause.reset() self._logger.debug('end: %s %s', request.method, request.uri)
def on_get(self, request, response): """Search unique resource attributes. Search is made from all content categories by default. Args: request (obj): Falcon Request(). response (obj): Falcon Response(). """ self._logger.debug('run: %s %s', request.method, request.uri) if 'scat' not in request.params: request.params['scat'] = Const.CATEGORIES api = Api(self._category, Api.UNIQUE, request.params) Config.load(api) self._content.run() if not self._content.uniques: Cause.push( Cause.HTTP_NOT_FOUND, 'cannot find unique fields for %s attribute' % self._category) if Cause.is_ok(): response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.fields(self._category, self._content.uniques, request, response) response.status = Cause.http_status() else: response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.error(Cause.json_message()) response.status = Cause.http_status() Cause.reset() self._logger.debug('end: %s %s', request.method, request.uri)
def on_post(self, request, response, **kwargs): # pylint: disable=unused-argument """Create new resource. Args: request (obj): Falcon Request(). response (obj): Falcon Response(). """ self._logger.debug('run: %s %s', request.method, request.uri) collection = Collection() data = Validate.json_object(request) for resource in data: api = Api(self._category, Api.CREATE, resource) Config.load(api) self._content.run(collection) if Cause.is_ok(): response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.collection(collection, request, response) response.status = Cause.http_status() else: response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.error(Cause.json_message()) response.status = Cause.http_status() Cause.reset() self._logger.debug('end: %s %s', request.method, request.uri)
def on_get(self, request, response, identity, field): """Get defined content field based on resource ID. If the given uuid matches to multiple resources or no resources at all, an error is returned. This conflicts against the JSON API v1.0 specifications. See the Snippy documentation for more information. Args: request (obj): Falcon Request(). response (obj): Falcon Response(). identity (str): Partial or full message digest or UUID. field (str): Resource attribute. """ self._logger.debug('run: %s %s', request.method, request.uri) local_params = {'identity': identity, 'fields': field} api = Api(self._category, Api.SEARCH, local_params) Config.load(api) self._content.run() if len(self._content.collection) != 1: Cause.push(Cause.HTTP_NOT_FOUND, 'content identity: %s was not unique and matched to: %d resources' % (identity, len(self._content.collection))) if Cause.is_ok(): response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.resource(self._content.collection, request, response, identity, field=field, pagination=False) response.status = Cause.http_status() else: response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.error(Cause.json_message()) response.status = Cause.http_status() Cause.reset() self._logger.debug('end: %s %s', request.method, request.uri)
def on_put(self, request, response, identity): """Update resource based on the resource ID. Args: request (obj): Falcon Request(). response (obj): Falcon Response(). identity (str): Partial or full message digest or UUID. """ self._logger.debug('run: %s %s', request.method, request.uri) collection = Validate.json_object(request, identity) for resource in collection: api = Api(self._category, Api.UPDATE, resource) Config.load(api) self._content.run() if Cause.is_ok(): response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.resource(self._content.collection, request, response, identity) response.status = Cause.http_status() else: response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.error(Cause.json_message()) response.status = Cause.http_status() Cause.reset() self._logger.debug('end: %s %s', request.method, request.uri)
def test_config_create_013(): """Test that multiple links can be added by separating them with bar.""" content = 'docker rm $(docker ps -a -q)' brief = 'Remove all docker containers' tags = ('cleanup', 'container', 'docker') links = ( 'https://askubuntu.com/questions/574163/how-to-stop-and-remove-a-docker-container', 'https://www.digitalocean.com/community/tutorials/how-to-remove-docker-images-containers-and-volumes' ) Config.init(None) Config.load( Cli([ 'snippy', 'create', '-c', content, '-b', brief, '-t', 'docker, container, cleanup', '-l', '|'.join(links) ])) assert isinstance(Config.content_data, tuple) assert isinstance(Config.content_brief, Const.TEXT_TYPE) assert isinstance(Config.content_tags, tuple) assert isinstance(Config.content_links, tuple) assert Config.content_data == tuple([content]) assert Config.content_brief == brief assert Config.content_tags == tags assert Config.content_links == links
def test_config_create_006(): """Test that tags can be added inside quotes separated by comma and space after comma.""" content = 'docker rm $(docker ps -a -q)' brief = 'Remove all docker containers' groups = ('docker', ) tags = ('cleanup', 'container', 'docker') links = ( 'https://askubuntu.com/questions/574163/how-to-stop-and-remove-a-docker-container', ) Config.init(None) Config.load( Cli([ 'snippy', 'create', '-c', content, '-b', brief, '-g', 'docker', '-t', 'docker, container, cleanup', '-l', links[0] ])) assert isinstance(Config.content_data, tuple) assert isinstance(Config.content_brief, Const.TEXT_TYPE) assert isinstance(Config.content_groups, tuple) assert isinstance(Config.content_tags, tuple) assert isinstance(Config.content_links, tuple) assert Config.content_data == tuple([content]) assert Config.content_brief == brief assert Config.content_groups == groups assert Config.content_tags == tags assert Config.content_links == links
def test_config_search_001(): """Test that search can be used with one keyword.""" search_kw = ('docker', ) Config.init(None) Config.load(Cli(['snippy', 'search', '--sall', 'docker'])) assert isinstance(Config.search_all_kws, tuple) assert Config.search_all_kws == search_kw
def test_config_search_003(): """Test that search keywords can be added inside quotes separated by comma and spaces after comma.""" search_kw = ('cleanup', 'container', 'docker') Config.init(None) Config.load( Cli(['snippy', 'search', '--sall', 'docker, container, cleanup'])) assert isinstance(Config.search_all_kws, tuple) assert Config.search_all_kws == search_kw
def test_config_search_004(): """Test that search keywords can be added so that they are separated by spaces before and after the words.""" search_kw = ('cleanup', 'container', 'docker') Config.init(None) Config.load( Cli(['snippy', 'search', '--sall', 'docker, container, cleanup'])) assert isinstance(Config.search_all_kws, tuple) assert Config.search_all_kws == search_kw
def test_config_create_002(): """Test that new snippet can be created without optional arguments.""" content = 'docker rm $(docker ps -a -q)' Config.init(None) Config.load(Cli(['snippy', 'create', '-c', content])) assert isinstance(Config.content_data, tuple) assert isinstance(Config.content_brief, Const.TEXT_TYPE) assert isinstance(Config.content_tags, tuple) assert Config.content_data == tuple([content]) assert not Config.content_brief assert not Config.content_tags
def test_config_create_004(): """Test that new snippet can be created with a single tag.""" content = 'docker rm $(docker ps -a -q)' tags = ('docker', ) Config.init(None) Config.load(Cli(['snippy', 'create', '-c', content, '-t', 'docker'])) assert isinstance(Config.content_data, tuple) assert isinstance(Config.content_brief, Const.TEXT_TYPE) assert isinstance(Config.content_tags, tuple) assert Config.content_data == tuple([content]) assert not Config.content_brief assert Config.content_tags == tags
def test_config_create_003(): """Test that new snippet can be created with brief description but no tags.""" content = 'docker rm $(docker ps -a -q)' brief = 'Remove all docker containers' Config.init(None) Config.load(Cli(['snippy', 'create', '-c', content, '-b', brief])) assert isinstance(Config.content_data, tuple) assert isinstance(Config.content_brief, Const.TEXT_TYPE) assert isinstance(Config.content_tags, tuple) assert Config.content_data == tuple([content]) assert Config.content_brief == brief assert not Config.content_tags
def test_config_search_007(): """Test that search keywords are accepted if they contain special characters.""" search_kw = (u'cleanup_testing', u'container-managemenet', u'docker–testing') Config.init(None) Config.load( Cli([ 'snippy', 'search', '--sall', 'docker–testing, ', 'container-managemenet, ', 'cleanup_testing' ])) assert isinstance(Config.search_all_kws, tuple) assert Config.search_all_kws == search_kw assert len(Config.search_all_kws) == 3
def test_config_create_009(): """Test that tags can be added so that they are separated by comma after the words like in '-t docker, container, cleanup'.""" content = 'docker rm $(docker ps -a -q)' tags = ('cleanup', 'container', 'docker') Config.init(None) Config.load( Cli([ 'snippy', 'create', '-c', content, '-t', 'docker,', 'container,', 'cleanup' ])) assert isinstance(Config.content_data, tuple) assert isinstance(Config.content_brief, Const.TEXT_TYPE) assert isinstance(Config.content_tags, tuple) assert Config.content_data == tuple([content]) assert Config.content_tags == tags
def test_config_create_005(): """Test that tags can be added inside quotes separated by comma and without spaces.""" content = 'docker rm $(docker ps -a -q)' tags = ('cleanup', 'container', 'docker') Config.init(None) Config.load( Cli([ 'snippy', 'create', '-c', content, '-t', 'docker,container,cleanup' ])) assert isinstance(Config.content_data, tuple) assert isinstance(Config.content_brief, Const.TEXT_TYPE) assert isinstance(Config.content_tags, tuple) assert Config.content_data == tuple([content]) assert not Config.content_brief assert Config.content_tags == tags
def test_config_create_011(): """Test that tags are accepted if the tags are elements in a list. This might not be realistic case since user might not be able to reproduce this?""" content = 'docker rm $(docker ps -a -q)' tags = ('cleanup', 'container', 'docker') Config.init(None) Config.load( Cli([ 'snippy', 'create', '-c', content, '-t', 'docker', 'container', 'cleanup' ])) assert isinstance(Config.content_data, tuple) assert isinstance(Config.content_brief, Const.TEXT_TYPE) assert isinstance(Config.content_tags, tuple) assert Config.content_data == tuple([content]) assert Config.content_tags == tags
def test_config_create_010(): """Test that tags are accepted if they contain special characters.""" content = 'docker rm $(docker ps -a -q)' tags = (u'cleanup_testing', u'container-managemenet', u'docker–testing') Config.init(None) Config.load( Cli([ 'snippy', 'create', '-c', content, '-t', 'docker–testing, ', 'container-managemenet, ', 'cleanup_testing' ])) assert isinstance(Config.content_data, tuple) assert isinstance(Config.content_brief, Const.TEXT_TYPE) assert isinstance(Config.content_tags, tuple) assert Config.content_data == tuple([content]) assert Config.content_tags == tags assert len(Config.content_tags) == 3
def on_get(self, request, response, scat=None, sall=None, stag=None, sgrp=None): """Search unique groups. By default the search is made from all content categories. Args: request (obj): Falcon Request(). response (obj): Falcon Response(). scat (str): Search categories ``scat`` path parameter. sall (str): Search all ``sall`` path parameter. stag (str): Search tags ``stag`` path parameter. sgrp (str): Search groups ``sgrp`` path parameter. """ self._logger.debug('run: %s %s', request.method, request.uri) if scat: request.params['scat'] = scat else: request.params['scat'] = Const.CATEGORIES if sall: request.params['sall'] = sall if stag: request.params['stag'] = stag if sgrp: request.params['sgrp'] = sgrp api = Api(self._category, Api.UNIQUE, request.params) Config.load(api) self._content.run() if not self._content.uniques: Cause.push(Cause.HTTP_NOT_FOUND, 'cannot find unique fields for groups attribute') if Cause.is_ok(): response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.fields('groups', self._content.uniques, request, response) response.status = Cause.http_status() else: response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.error(Cause.json_message()) response.status = Cause.http_status() Cause.reset() self._logger.debug('end: %s %s', request.method, request.uri)
def run(self, args=None): """Run service. Args: list: Command line arguments. """ if args: Config.load(Cli(args)) if Config.failure: Cause.print_failure() return Cause.reset() if Config.run_server: self._run_server() elif Config.run_healthcheck: self._run_healthcheck() else: self._run_cli() return Cause.reset()
def on_delete(self, request, response, identity): """Delete resource based on the resource ID. Args: request (obj): Falcon Request(). response (obj): Falcon Response(). identity (str): Partial or full message digest or UUID. """ self._logger.debug('run: %s %s', request.method, request.uri) local_params = {'identity': identity} api = Api(self._category, Api.DELETE, local_params) Config.load(api) self._content.run() if Cause.is_ok(): response.status = Cause.http_status() else: response.content_type = ApiResource.MEDIA_JSON_API response.body = Generate.error(Cause.json_message()) response.status = Cause.http_status() Cause.reset() self._logger.debug('end: %s %s', request.method, request.uri)
def test_config_create_001(mock_utcnow): """Create new snippet. Test default values when only mandatory arguments are used. """ mock_utcnow.return_value = '2018-02-17 13:23:43' Config.init(None) Config.load(Cli(['snippy', 'import'])) assert isinstance(Config.content_category, Const.TEXT_TYPE) assert isinstance(Config.content_data, tuple) assert isinstance(Config.content_brief, Const.TEXT_TYPE) assert isinstance(Config.content_description, Const.TEXT_TYPE) assert isinstance(Config.content_groups, tuple) assert isinstance(Config.content_tags, tuple) assert isinstance(Config.content_links, tuple) assert isinstance(Config.content_name, Const.TEXT_TYPE) assert isinstance(Config.content_filename, Const.TEXT_TYPE) assert isinstance(Config.content_versions, tuple) assert isinstance(Config.content_source, Const.TEXT_TYPE) assert isinstance(Config.operation_digest, type(None)) assert isinstance(Config.search_cat_kws, tuple) assert isinstance(Config.search_all_kws, tuple) assert isinstance(Config.search_tag_kws, tuple) assert isinstance(Config.search_grp_kws, tuple) assert Config.search_filter is None assert Config.search_limit == 99 assert Config.search_offset == 0 assert Config.remove_fields == () assert Config.sort_fields == OrderedDict([('brief', 'ASC')]) assert isinstance(Config.get_operation_file(), Const.TEXT_TYPE) assert not Config.get_resource(None) assert not Config.get_collection() assert not Config.is_operation_create assert not Config.is_operation_search assert not Config.is_operation_update assert not Config.is_operation_delete assert not Config.is_operation_export assert Config.is_operation_import assert Config.is_category_snippet assert not Config.is_category_solution assert not Config.is_category_reference assert not Config.is_multi_category assert Config.content_category == Const.SNIPPET assert not Config.content_data assert not Config.content_brief assert Config.content_groups == Const.DEFAULT_GROUPS assert not Config.content_tags assert not Config.content_links assert not Config.search_all_kws assert not Config.search_tag_kws assert not Config.search_grp_kws assert Config.operation_digest is None assert not Config.search_filter assert not Config.content_filename assert not Config.editor assert Config.get_operation_file() == './snippets.mkdn' assert Config.is_operation_file_mkdn assert not Config.is_operation_file_json assert not Config.is_operation_file_yaml assert not Config.is_operation_file_text assert Config.use_ansi