diff --git a/switcher_client/lib/remote.py b/switcher_client/lib/remote.py index 5ded0c1..25cd563 100644 --- a/switcher_client/lib/remote.py +++ b/switcher_client/lib/remote.py @@ -33,8 +33,9 @@ def check_criteria( token: Optional[str], context: Context, switcher: SwitcherData) -> ResultDetail: """ Check criteria """ - url = f'{context.url}/criteria?showReason={str(switcher.show_details).lower()}&key={switcher.key}' - response = Remote.do_post(url, switcher.input, Remote.get_header(token)) + url = f'{context.url}/criteria?showReason={str(switcher._show_details).lower()}&key={switcher._key}' + entry = Remote.__get_entry(switcher._input) + response = Remote.do_post(url, entry, Remote.get_header(token)) if response.status_code == 200: json_response = response.json() @@ -48,6 +49,7 @@ def check_criteria( @staticmethod def do_post(url, data, headers) -> requests.Response: """ Perform a POST request """ + print(data) return requests.post(url, json=data, headers=headers) @staticmethod @@ -55,4 +57,18 @@ def get_header(token: Optional[str]): return { 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json', - } \ No newline at end of file + } + + @staticmethod + def __get_entry(input: list): + entry = [] + for strategy_type, input_value in input: + entry.append({ + 'strategy': strategy_type, + 'input': input_value + }) + + if not entry: + return None + + return {'entry': entry} \ No newline at end of file diff --git a/switcher_client/switcher.py b/switcher_client/switcher.py index 6e61f9d..5922709 100644 --- a/switcher_client/switcher.py +++ b/switcher_client/switcher.py @@ -9,24 +9,35 @@ class Switcher(SwitcherData): def __init__(self, context: Context, key: Optional[str] = None): super().__init__(key) - self.context = context + self._context = context def is_on(self, key: Optional[str] = None) -> bool: """ Execute criteria """ - result = False - self.__validate_args(key) + return self.__submit() + + def __submit(self) -> bool: + """ Submit criteria for execution (local or remote) """ + + self.__validate() self.__execute_api_checks() - result = self.__execute_remote_criteria() + return self.__execute_remote_criteria() + + def __validate(self) -> 'Switcher': + """ Validates client settings for remote API calls """ + errors = [] - return result + if not self._key: + errors.append('Missing key field') - def __validate_args(self, key: Optional[str] = None): - if self.key is None: - self.key = key + if errors: + raise ValueError(f"Something went wrong: {', '.join(errors)}") + + return self - if self.key is None: - raise ValueError('Key is required') + def __validate_args(self, key: Optional[str] = None): + if key is not None: + self._key = key def __execute_api_checks(self): """ Assure API is available and token is valid """ @@ -37,5 +48,5 @@ def __execute_remote_criteria(self): token = GlobalAuth.get_token() GlobalAuth.get_exp() - response_criteria = Remote.check_criteria(token, self.context, self) + response_criteria = Remote.check_criteria(token, self._context, self) return response_criteria.result \ No newline at end of file diff --git a/switcher_client/switcher_data.py b/switcher_client/switcher_data.py index 4b17fd2..ae28c79 100644 --- a/switcher_client/switcher_data.py +++ b/switcher_client/switcher_data.py @@ -1,7 +1,21 @@ -from typing import Optional +from abc import ABCMeta +from typing import Optional, Self -class SwitcherData: +# Strategy types +VALUE_VALIDATION = 'VALUE_VALIDATION' + +class SwitcherData(metaclass=ABCMeta): def __init__(self, key: Optional[str] = None): - self.key = key - self.input = {} - self.show_details = False \ No newline at end of file + self._key = key + self._input = [] + self._show_details = False + + def check(self, strategy_type: str, input: str)-> Self: + """ Adds a strategy for validation """ + self._input = [item for item in self._input if item[0] != strategy_type] + self._input.append([strategy_type, input]) + return self + + def check_value(self, input: str) -> Self: + """ Adds VALUE_VALIDATION input for strategy validation """ + return self.check(VALUE_VALIDATION, input) \ No newline at end of file diff --git a/tests/test_switcher_remote.py b/tests/test_switcher_remote.py index 5c2bbec..235e9e6 100644 --- a/tests/test_switcher_remote.py +++ b/tests/test_switcher_remote.py @@ -19,6 +19,29 @@ def test_remote(): # test assert switcher.is_on('MY_SWITCHER') +@responses.activate +def test_remote_with_input(): + """ Should call the remote API with success using input parameters """ + + # given + given_auth() + given_check_criteria(response={'result': True}, match=[ + responses.matchers.json_params_matcher({ + 'entry': [{ + 'strategy': 'VALUE_VALIDATION', + 'input': 'user_id' + }] + }) + ]) + given_context() + + switcher = Client.get_switcher() + + # test + assert switcher \ + .check_value('user_id') \ + .is_on('MY_SWITCHER') + def test_remote_err_no_key(): """ Should raise an exception when no key is provided """ @@ -82,10 +105,11 @@ def given_auth(status=200, token='[token]', exp=int(round(time.time() * 1000))): status=status ) -def given_check_criteria(status=200, key='MY_SWITCHER', response={}, show_details=False): +def given_check_criteria(status=200, key='MY_SWITCHER', response={}, show_details=False, match=[]): responses.add( responses.POST, f'https://api.switcherapi.com/criteria?showReason={str(show_details).lower()}&key={key}', json=response, - status=status - ) \ No newline at end of file + status=status, + match=match + )