def test_parse_query__event__query_did_not_validate(self): class QueryParser(parsers.Parser): title = parsers.CharField() prices = parsers.ListField(child=parsers.IntegerField()) input = Input(query_parser=QueryParser) request = Mock(GET=RequestGet(title=['hi there'], prices=['what']), origin=None, log_authorizer={ 'user_id': 902, }) with pytest.raises(EventFactory.BrokenRequest) as e: input.parse_query(request) assert e.value.data == { '@type': 'error', '@event': 'QUERY_DID_NOT_VALIDATE', '@authorizer': { 'user_id': 902, }, 'errors': { 'prices': { 0: ['A valid integer is required.'] }, }, }
def test_parse_query__multiple_parsers(self): class AParser(parsers.Parser): title = parsers.CharField() prices = parsers.ListField(child=parsers.IntegerField()) class BParser(parsers.Parser): title = parsers.CharField() quantity = parsers.IntegerField() class CParser(AParser, BParser): pass input = Input(query_parser=CParser) request = Mock(GET=RequestGet(title=['hi there'], prices=[67, 89, 11], quantity=[190]), user_id=902) data = input.parse_query(request) assert data == { 'title': 'hi there', 'prices': [67, 89, 11], 'quantity': 190, }
def test_parse_query__all_ok(self): class QueryParser(parsers.Parser): title = parsers.CharField() prices = parsers.ListField(child=parsers.IntegerField()) input = Input(query_parser=QueryParser) request = Mock(GET=RequestGet(title=['hi there'], prices=[67, 89, 11]), user_id=902) data = input.parse_query(request) assert data == {'title': 'hi there', 'prices': [67, 89, 11]}
def test_parse__makes_the_right_calls(self): parse_body = self.mocker.patch.object(Input, 'parse_body') parse_body.return_value = [{}, {}] parse_query = self.mocker.patch.object(Input, 'parse_query') query_parser, body_parser = Mock(), Mock() request = Mock() # -- both query and body parsers i = Input(query_parser=query_parser, body_parser=body_parser) i.parse(request, command_name='MAKE_IT') assert parse_body.call_count == 1 assert parse_query.call_count == 1
def test_conf__is_saved_on_function(self): source = TestCommands.post.command_conf.pop('source') assert TestCommands.post.command_conf == { 'name': 'MAKE_IT', 'method': 'post', 'meta': Meta(title='hi there', description='it is made for all', domain=Domain(id='test', name='test management')), 'access': Access(access_list=['PREMIUM', 'SUPER_PREMIUM']), 'input': Input(body_parser=TestCommands.BodyParser), 'output': Output(serializer=TestCommands.ClientSerializer), 'is_atomic': False, 'fn': TestCommands.post.command_conf['fn'], } assert source.filepath == '/tests/test_base/test_command.py' assert source.start_line == 117 assert source.end_line == 131
def test_parse_query__all_missing(self): class QueryParser(parsers.Parser): title = parsers.CharField() prices = parsers.ListField(child=parsers.IntegerField()) input = Input(query_parser=QueryParser) request = Mock(GET=RequestGet(), origin=None, log_authorizer={ 'user_id': 902, }) with pytest.raises(EventFactory.BrokenRequest) as e: input.parse_query(request) assert e.value.event == 'QUERY_DID_NOT_VALIDATE'
def _prepare_body_parser(self): class BodyParser(parsers.Parser): title = parsers.CharField() amount = parsers.IntegerField(max_value=19) input = Input(body_parser=BodyParser) return input
class EntryPointCommands(HTTPCommands): class EntryPointSerializer(serializers.Serializer): class VersionInfoSerializer(serializers.Serializer): _type = 'version_info' deployed = serializers.CharField() displayed = serializers.CharField() available = serializers.ListField(child=serializers.CharField()) _type = 'entrypoint' version_info = VersionInfoSerializer() name = serializers.CharField() commands = serializers.DictField(child=CommandSerializer()) enums = serializers.ListField(child=serializers.DictField()) class QueryParser(parsers.Parser): commands = parsers.ListField(child=parsers.CharField(), default=None) with_schemas = parsers.BooleanField(default=True) is_private = parsers.BooleanField(default=None) domain_id = parsers.CharField(default=None) version = parsers.CharField(default=None) @command( name=name.Read('ENTRY_POINT'), meta=Meta(title='Read Entry Point', description=''' Serve Service Entry Point data: - current or chosen version of the service - list of all available commands together with their configurations - examples collected for a given service. ''', domain=Domain(id='docs', name='Docs Management')), access=Access( is_private=True, access_list=settings.LILY_ENTRYPOINT_COMMANDS_ACCESS_LIST), input=Input(query_parser=QueryParser), output=Output(serializer=EntryPointSerializer), ) def get(self, request): command_names = request.input.query['commands'] is_private = request.input.query['is_private'] domain_id = request.input.query['domain_id'] version = request.input.query['version'] config = Config() commands = self.get_commands(version) enums = commands.pop('enums') if command_names: commands = { command_name: commands[command_name] for command_name in command_names } if is_private is not None: commands = { name: command for name, command in commands.items() if command['access']['is_private'] == is_private } if domain_id: commands = { name: command for name, command in commands.items() if command['meta'] ['domain']['id'].lower() == domain_id.lower() } raise self.event.Read({ 'name': config.name, 'version_info': { 'deployed': config.version, 'displayed': version or config.version, 'available': self.get_available_versions(), }, 'commands': commands, 'enums': enums, }) def get_available_versions(self): commands_dir_path = os.path.join(Config.get_lily_path(), 'commands') return sorted([ commands_file.replace('.json', '') for commands_file in os.listdir(commands_dir_path) ], key=lambda x: [int(e) for e in x.split('.')], reverse=True) def get_commands(self, version=None): config = Config() version = version or config.version commands_dir_path = os.path.join(Config.get_lily_path(), 'commands') commands_path = os.path.join(commands_dir_path, f'{version}.json') with open(commands_path, 'r') as f: return json.loads(f.read())
class TestCommands(HTTPCommands): class BodyParser(parsers.Parser): name = parsers.CharField() age = parsers.IntegerField() class ClientSerializer(serializers.ModelSerializer): _type = 'client' card_id = serializers.SerializerMethodField() def get_access(self, instance): return [(TestCommands.put, True)] class Meta: model = FakeClient fields = ('name', 'card_id') def get_card_id(self, instance): return 190 class SimpleSerializer(serializers.Serializer): _type = 'simple' amount = serializers.IntegerField() @command(name='MAKE_IT', meta=Meta(title='hi there', description='it is made for all', domain=Domain(id='test', name='test management')), input=Input(body_parser=BodyParser), output=Output(serializer=ClientSerializer), access=Access(access_list=['PREMIUM', 'SUPER_PREMIUM'])) def post(self, request, user_id): raise self.event.Executed(event='MADE_IT', instance=FakeClient(name="Jake")) @command(name='GET_IT', meta=Meta(title='get', description='get it...', domain=Domain(id='get', name='get')), output=Output(serializer=ClientSerializer)) def get(self, request): raise self.event.Executed(event='GET_IT', instance=FakeClient(name="Jake")) @command(name='BREAK', meta=Meta(title='break', description='break it...', domain=Domain(id='break', name='break')), output=Output(serializer=SimpleSerializer)) def put(self, request): raise self.event.Executed(event='BROKEN', context=request, data=json.loads(request.body.decode('utf8'))) @command(name='ATOMIC', meta=Meta(title='atomic', description='atomic it...', domain=Domain(id='atomic', name='atomic')), is_atomic='default') def delete(self, request): self.some_stuff() raise self.event.Executed(event='ATOMIC', context=request, data={}) def some_stuff(self): pass