1
0
This commit is contained in:
2024-01-15 20:20:10 +00:00
parent c75ea4ea9d
commit 38cd64ea9a
87 changed files with 3946 additions and 2040 deletions

View File

@@ -1,46 +1,25 @@
# -*- coding: utf-8 -*-
# type: ignore
from __future__ import annotations
import json
from unittest import mock
import pytest
from bthlabs_jsonrpc_core import exceptions, executor
from bthlabs_jsonrpc_core.codecs import JSONCodec
from bthlabs_jsonrpc_core.registry import MethodRegistry
from bthlabs_jsonrpc_core.serializer import JSONRPCSerializer
@pytest.fixture
def single_call():
return {
'jsonrpc': '2.0',
'id': 'test',
'method': 'test',
}
@pytest.fixture
def batch_calls():
return [
{
'jsonrpc': '2.0',
'id': 'test',
'method': 'test',
},
{
'jsonrpc': '2.0',
'id': 'test2',
'method': 'test',
},
]
@pytest.fixture
def jsonrpc_error():
def jsonrpc_error() -> exceptions.BaseJSONRPCError:
return exceptions.BaseJSONRPCError('I HAZ FIAL')
@pytest.fixture
def execute_context():
def execute_context() -> executor.Executor.ExecuteContext:
return executor.Executor.ExecuteContext([])
@@ -55,7 +34,7 @@ def test_CallContext_invalid_context():
assert result.kwargs is None
def test_CallContext_is_valid_method_none(fake_handler):
def test_CallContext_is_valid_method_none(fake_handler: mock.Mock):
# When
call_context = executor.Executor.CallContext(None, fake_handler, [], {})
@@ -71,7 +50,7 @@ def test_CallContext_is_valid_handler_none():
assert call_context.is_valid is False
def test_CallContext_is_valid_args_none(fake_handler):
def test_CallContext_is_valid_args_none(fake_handler: mock.Mock):
# When
call_context = executor.Executor.CallContext(
'test', fake_handler, None, {},
@@ -81,7 +60,7 @@ def test_CallContext_is_valid_args_none(fake_handler):
assert call_context.is_valid is False
def test_CallContext_is_valid_kwargs_none(fake_handler):
def test_CallContext_is_valid_kwargs_none(fake_handler: mock.Mock):
# When
call_context = executor.Executor.CallContext(
'test', fake_handler, [], None,
@@ -91,7 +70,7 @@ def test_CallContext_is_valid_kwargs_none(fake_handler):
assert call_context.is_valid is False
def test_CallContext_is_valid(fake_handler):
def test_CallContext_is_valid(fake_handler: mock.Mock):
# When
call_context = executor.Executor.CallContext('test', fake_handler, [], {})
@@ -99,12 +78,13 @@ def test_CallContext_is_valid(fake_handler):
assert call_context.is_valid is True
def test_init_default_namespace():
def test_init():
# When
result = executor.Executor()
# Then
assert result.namespace == MethodRegistry.DEFAULT_NAMESPACE
assert isinstance(result.codec, JSONCodec) is True
def test_init_custom_namespace():
@@ -115,8 +95,17 @@ def test_init_custom_namespace():
assert result.namespace == 'testing'
def test_init_custom_codec(fake_custom_codec: mock.Mock):
# When
result = executor.Executor(codec=fake_custom_codec)
# Then
assert result.codec == fake_custom_codec
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_list_methods(mock_shared_registry, fake_method_registry):
def test_list_methods(mock_shared_registry: mock.Mock,
fake_method_registry: mock.Mock):
# Given
fake_method_registry.get_methods.return_value = ['test']
mock_shared_registry.return_value = fake_method_registry
@@ -170,6 +159,21 @@ def test_deserialize_data():
assert result == 'spam'
def test_deserialize_data_custom_codec(fake_custom_codec: mock.Mock):
# Given
fake_custom_codec.decode.return_value = 'spam'
the_executor = executor.Executor(codec=fake_custom_codec)
# When
result = the_executor.deserialize_data('"spam"')
# Then
assert result == 'spam'
fake_custom_codec.decode.assert_called_once_with('"spam"')
def test_deserialize_data_error():
# Given
the_executor = executor.Executor()
@@ -184,7 +188,25 @@ def test_deserialize_data_error():
assert False, 'No exception raised?'
def test_get_calls_batch(batch_calls):
def test_deserialize_data_custom_codec_error(fake_custom_codec: mock.Mock):
# Given
error = RuntimeError('I HAZ FAIL')
fake_custom_codec.decode.side_effect = error
the_executor = executor.Executor(codec=fake_custom_codec)
# When
try:
_ = the_executor.deserialize_data(None)
except Exception as exception:
# Then
assert isinstance(exception, exceptions.JSONRPCParseError)
assert exception.__cause__ == error
else:
assert False, 'No exception raised?'
def test_get_calls_batch(batch_calls: list):
# Given
the_executor = executor.Executor()
@@ -195,7 +217,7 @@ def test_get_calls_batch(batch_calls):
assert result == batch_calls
def test_get_calls_single(single_call):
def test_get_calls_single(single_call: dict):
# Given
the_executor = executor.Executor()
@@ -234,7 +256,7 @@ def test_get_call_spec_not_dict():
assert False, 'No exception raised?'
def test_get_call_spec_wihtout_jsonrpc(single_call):
def test_get_call_spec_wihtout_jsonrpc(single_call: dict):
# Given
single_call.pop('jsonrpc')
@@ -250,7 +272,7 @@ def test_get_call_spec_wihtout_jsonrpc(single_call):
assert False, 'No exception raised?'
def test_get_call_spec_invalid_jsonrpc(single_call):
def test_get_call_spec_invalid_jsonrpc(single_call: dict):
# Given
single_call['jsonrpc'] = 'test'
@@ -266,7 +288,7 @@ def test_get_call_spec_invalid_jsonrpc(single_call):
assert False, 'No exception raised?'
def test_get_call_spec_wihtout_method(single_call):
def test_get_call_spec_wihtout_method(single_call: dict):
# Given
single_call.pop('method')
@@ -283,9 +305,9 @@ def test_get_call_spec_wihtout_method(single_call):
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_internal_method(mock_shared_registry,
single_call,
fake_handler):
def test_get_call_spec_internal_method(mock_shared_registry: mock.Mock,
single_call: dict,
fake_handler: mock.Mock):
# Given
single_call['method'] = 'system.list_methods'
@@ -307,11 +329,13 @@ def test_get_call_spec_internal_method(mock_shared_registry,
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_registry_method(mock_shared_registry,
single_call,
fake_method_registry,
fake_handler):
def test_get_call_spec_registry_method(mock_shared_registry: mock.Mock,
single_call: dict,
fake_method_registry: mock.Mock,
fake_handler: mock.Mock):
# Given
single_call['method'] = 'test'
fake_method_registry.get_handler.return_value = fake_handler
mock_shared_registry.return_value = fake_method_registry
@@ -333,10 +357,12 @@ def test_get_call_spec_registry_method(mock_shared_registry,
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_method_not_found(mock_shared_registry,
single_call,
fake_method_registry):
def test_get_call_spec_method_not_found(mock_shared_registry: mock.Mock,
single_call: dict,
fake_method_registry: mock.Mock):
# Given
single_call['method'] = 'test'
fake_method_registry.get_handler.return_value = None
mock_shared_registry.return_value = fake_method_registry
@@ -353,10 +379,10 @@ def test_get_call_spec_method_not_found(mock_shared_registry,
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_invalid_params(mock_shared_registry,
single_call,
fake_method_registry,
fake_handler):
def test_get_call_spec_invalid_params(mock_shared_registry: mock.Mock,
single_call: dict,
fake_method_registry: mock.Mock,
fake_handler: mock.Mock):
# Given
single_call['params'] = 'spam'
@@ -376,10 +402,10 @@ def test_get_call_spec_invalid_params(mock_shared_registry,
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_with_args(mock_shared_registry,
single_call,
fake_method_registry,
fake_handler):
def test_get_call_spec_with_args(mock_shared_registry: mock.Mock,
single_call: dict,
fake_method_registry: mock.Mock,
fake_handler: mock.Mock):
# Given
single_call['params'] = ['spam']
@@ -402,10 +428,10 @@ def test_get_call_spec_with_args(mock_shared_registry,
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_with_kwargs(mock_shared_registry,
single_call,
fake_method_registry,
fake_handler):
def test_get_call_spec_with_kwargs(mock_shared_registry: mock.Mock,
single_call: dict,
fake_method_registry: mock.Mock,
fake_handler: mock.Mock):
# Given
single_call['params'] = {'spam': True}
@@ -427,7 +453,9 @@ def test_get_call_spec_with_kwargs(mock_shared_registry,
mock_enrich_kwargs.assert_called_with({'spam': True})
def test_process_results(batch_calls, single_call, jsonrpc_error):
def test_process_results(batch_calls: list,
single_call: dict,
jsonrpc_error: exceptions.BaseJSONRPCError):
# Given
call_without_id = {**single_call}
call_without_id.pop('id')
@@ -465,7 +493,7 @@ def test_process_results(batch_calls, single_call, jsonrpc_error):
assert second_response == expected_second_response
def test_process_results_single_call(single_call):
def test_process_results_single_call(single_call: dict):
# Given
call_results = [
(single_call, 'OK'),
@@ -485,7 +513,7 @@ def test_process_results_single_call(single_call):
assert result == expected_result
def test_process_results_top_level_error(jsonrpc_error):
def test_process_results_top_level_error(jsonrpc_error: exceptions.BaseJSONRPCError):
# Given
call_results = [
(None, jsonrpc_error),
@@ -505,7 +533,7 @@ def test_process_results_top_level_error(jsonrpc_error):
assert result == expected_result
def test_process_results_empty(single_call):
def test_process_results_empty(single_call: dict):
# Given
single_call.pop('id')
@@ -522,9 +550,9 @@ def test_process_results_empty(single_call):
assert result is None
def test_call_context_invalid_context(jsonrpc_error,
execute_context,
single_call):
def test_call_context_invalid_context(jsonrpc_error: exceptions.BaseJSONRPCError,
execute_context: executor.Executor.ExecuteContext,
single_call: dict):
# Given
the_executor = executor.Executor()
@@ -539,10 +567,10 @@ def test_call_context_invalid_context(jsonrpc_error,
assert result.is_valid is False
def test_call_context_handle_jsonrpc_error(fake_handler,
jsonrpc_error,
execute_context,
single_call):
def test_call_context_handle_jsonrpc_error(fake_handler: mock.Mock,
jsonrpc_error: exceptions.BaseJSONRPCError,
execute_context: executor.Executor.ExecuteContext,
single_call: dict):
# Given
the_executor = executor.Executor()
@@ -562,9 +590,9 @@ def test_call_context_handle_jsonrpc_error(fake_handler,
assert call_result[1] == jsonrpc_error
def test_call_context_handle_exception(fake_handler,
execute_context,
single_call):
def test_call_context_handle_exception(fake_handler: mock.Mock,
execute_context: executor.Executor.ExecuteContext,
single_call: dict):
# Given
the_executor = executor.Executor()
@@ -585,7 +613,9 @@ def test_call_context_handle_exception(fake_handler,
assert call_result[1].data == 'I HAZ FIAL'
def test_call_context(fake_handler, execute_context, single_call):
def test_call_context(fake_handler: mock.Mock,
execute_context: executor.Executor.ExecuteContext,
single_call: dict):
# Given
the_executor = executor.Executor()
@@ -610,7 +640,7 @@ def test_call_context(fake_handler, execute_context, single_call):
assert execute_context.results[0] == expected_call_result
def test_execute_context_handle_jsonrpc_error(jsonrpc_error):
def test_execute_context_handle_jsonrpc_error(jsonrpc_error: exceptions.BaseJSONRPCError):
# Given
the_executor = executor.Executor()
@@ -638,7 +668,7 @@ def test_execute_context_handle_exception():
assert result.serializer is None
def test_execute_context_handle_empty_results(single_call):
def test_execute_context_handle_empty_results(single_call: dict):
# Given
the_executor = executor.Executor()
@@ -656,7 +686,7 @@ def test_execute_context_handle_empty_results(single_call):
assert mock_serializer.called is False
def test_execute_context(fake_rpc_serializer, single_call):
def test_execute_context(fake_rpc_serializer: mock.Mock, single_call: dict):
# Given
fake_responses = {
'jsonrpc': '2.0',
@@ -712,7 +742,7 @@ def test_before_call():
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_execute(mock_shared_registry, fake_method_registry):
def test_execute(mock_shared_registry: mock.Mock, fake_method_registry: mock.Mock):
# Given
fake_method_registry.get_handler.return_value = None
fake_method_registry.get_methods.return_value = []