-
Notifications
You must be signed in to change notification settings - Fork 30
fix: Unit tests #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
fix: Unit tests #28
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
875c2f8
fix/unit-tests: Improve unit test coverage to ensure spec is followed
ajhelsby 6d9a044
fix/unit-tests: Add test coverage around hooks
ajhelsby 5da054e
fix/unit-tests: Parametrize test_should_use_no_op_provider_if_none_pr…
ajhelsby b91d636
fix/unit-tests: Parametrize all flag type methods in open feature client
ajhelsby 03b0412
fix/unit-tests: Parametrize all flag type methods in open feature client
ajhelsby 42aafc5
fix/unit-tests: Add fixture to clear global provider after each tests
ajhelsby d8245fd
fix/unit-tests: Mock hooks in tests
ajhelsby 27d2ad8
fix/unit-tests: Update docstring on clear_provider method
ajhelsby d12011c
fix/unit-tests: remove setup method in client tests
ajhelsby f61604c
fix/unit-tests: Remove invalid flag type check in private method _cre…
ajhelsby File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import pytest | ||
|
|
||
| from open_feature.exception.exceptions import GeneralError | ||
| from open_feature.flag_evaluation.error_code import ErrorCode | ||
| from open_feature.open_feature_api import get_client, get_provider, set_provider | ||
| from open_feature.provider.no_op_provider import NoOpProvider | ||
|
|
||
|
|
||
| def test_should_raise_exception_with_nop_client(): | ||
| # Given | ||
| # When | ||
| with pytest.raises(GeneralError) as ge: | ||
| get_client() | ||
| # Then | ||
| assert ge.value | ||
| assert ( | ||
| ge.value.error_message | ||
| == "Provider not set. Call set_provider before using get_client" | ||
| ) | ||
| assert ge.value.error_code == ErrorCode.GENERAL | ||
|
|
||
|
|
||
| def test_should_return_open_feature_client_when_configured_correctly(): | ||
| # Given | ||
| set_provider(NoOpProvider()) | ||
|
|
||
| # When | ||
| client = get_client(name="No-op Provider", version="1.0") | ||
|
|
||
| # Then | ||
| assert client.name == "No-op Provider" | ||
| assert client.version == "1.0" | ||
| assert isinstance(client.provider, NoOpProvider) | ||
|
|
||
|
|
||
| def test_should_try_set_provider_and_fail_if_none_provided(): | ||
| # Given | ||
| # When | ||
| with pytest.raises(GeneralError) as ge: | ||
| set_provider(provider=None) | ||
|
|
||
| # Then | ||
| assert ge.value.error_message == "No provider" | ||
| assert ge.value.error_code == ErrorCode.GENERAL | ||
|
|
||
|
|
||
| def test_should_return_a_provider_if_setup_correctly(): | ||
| # Given | ||
| set_provider(NoOpProvider()) | ||
|
|
||
| # When | ||
| provider = get_provider() | ||
|
|
||
| # Then | ||
| assert provider | ||
| assert isinstance(provider, NoOpProvider) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| from numbers import Number | ||
| from unittest.mock import MagicMock | ||
|
|
||
| import pytest | ||
|
|
||
| from open_feature.exception.exceptions import OpenFeatureError | ||
| from open_feature.flag_evaluation.error_code import ErrorCode | ||
| from open_feature.flag_evaluation.reason import Reason | ||
| from open_feature.hooks.hook import Hook | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "flag_type, default_value, get_method", | ||
| ( | ||
| (bool, True, "get_boolean_value"), | ||
| (str, "String", "get_string_value"), | ||
| (Number, 100, "get_number_value"), | ||
| ( | ||
| dict, | ||
| { | ||
| "String": "string", | ||
| "Number": 2, | ||
| "Boolean": True, | ||
| }, | ||
| "get_object_value", | ||
| ), | ||
| ), | ||
| ) | ||
| def test_should_get_flag_value_based_on_method_type( | ||
| flag_type, default_value, get_method, no_op_provider_client | ||
| ): | ||
| # Given | ||
| # When | ||
| flag = getattr(no_op_provider_client, get_method)( | ||
| flag_key="Key", default_value=default_value | ||
| ) | ||
| # Then | ||
| assert flag is not None | ||
| assert flag == default_value | ||
| assert isinstance(flag, flag_type) | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "flag_type, default_value, get_method", | ||
| ( | ||
| (bool, True, "get_boolean_details"), | ||
| (str, "String", "get_string_details"), | ||
| (Number, 100, "get_number_details"), | ||
| ( | ||
| dict, | ||
| { | ||
| "String": "string", | ||
| "Number": 2, | ||
| "Boolean": True, | ||
| }, | ||
| "get_object_details", | ||
| ), | ||
| ), | ||
| ) | ||
| def test_should_get_flag_detail_based_on_method_type( | ||
| flag_type, default_value, get_method, no_op_provider_client | ||
| ): | ||
| # Given | ||
| # When | ||
| flag = getattr(no_op_provider_client, get_method)( | ||
| flag_key="Key", default_value=default_value | ||
| ) | ||
| # Then | ||
| assert flag is not None | ||
| assert flag.value == default_value | ||
| assert isinstance(flag.value, flag_type) | ||
|
|
||
|
|
||
| def test_should_raise_exception_when_invalid_flag_type_provided(no_op_provider_client): | ||
| # Given | ||
| # When | ||
| flag = no_op_provider_client.evaluate_flag_details( | ||
| flag_type=None, flag_key="Key", default_value=True | ||
| ) | ||
| # Then | ||
| assert flag.value | ||
| assert flag.error_message == "Unknown flag type" | ||
| assert flag.error_code == ErrorCode.GENERAL | ||
| assert flag.reason == Reason.ERROR | ||
|
|
||
|
|
||
| def test_should_handle_a_generic_exception_thrown_by_a_provider(no_op_provider_client): | ||
| # Given | ||
| exception_hook = MagicMock(spec=Hook) | ||
| exception_hook.after.side_effect = Exception("Generic exception raised") | ||
| no_op_provider_client.add_hooks([exception_hook]) | ||
| # When | ||
| flag_details = no_op_provider_client.get_boolean_details( | ||
| flag_key="Key", default_value=True | ||
| ) | ||
| # Then | ||
| assert flag_details is not None | ||
| assert flag_details.value | ||
| assert isinstance(flag_details.value, bool) | ||
| assert flag_details.reason == Reason.ERROR | ||
| assert flag_details.error_message == "Generic exception raised" | ||
|
|
||
|
|
||
| def test_should_handle_an_open_feature_exception_thrown_by_a_provider( | ||
| no_op_provider_client, | ||
| ): | ||
| # Given | ||
| exception_hook = MagicMock(spec=Hook) | ||
| exception_hook.after.side_effect = OpenFeatureError( | ||
| "error_message", ErrorCode.GENERAL | ||
| ) | ||
| no_op_provider_client.add_hooks([exception_hook]) | ||
|
|
||
| # When | ||
| flag_details = no_op_provider_client.get_boolean_details( | ||
| flag_key="Key", default_value=True | ||
| ) | ||
| # Then | ||
| assert flag_details is not None | ||
| assert flag_details.value | ||
| assert isinstance(flag_details.value, bool) | ||
| assert flag_details.reason == Reason.ERROR | ||
| assert flag_details.error_message == "error_message" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| import pytest | ||
|
|
||
| from open_feature.evaluation_context.evaluation_context import EvaluationContext | ||
| from open_feature.exception.exceptions import GeneralError | ||
| from open_feature.flag_evaluation.error_code import ErrorCode | ||
| from open_feature.open_feature_evaluation_context import ( | ||
| api_evaluation_context, | ||
| set_api_evaluation_context, | ||
| ) | ||
|
|
||
|
|
||
| def test_should_raise_an_exception_if_no_evaluation_context_set(): | ||
| # Given | ||
| with pytest.raises(GeneralError) as ge: | ||
| set_api_evaluation_context(evaluation_context=None) | ||
| # Then | ||
| assert ge.value | ||
| assert ge.value.error_message == "No api level evaluation context" | ||
| assert ge.value.error_code == ErrorCode.GENERAL | ||
|
|
||
|
|
||
| def test_should_successfully_set_evaluation_context_for_api(): | ||
| # Given | ||
| evaluation_context = EvaluationContext("targeting_key", {"attr1": "val1"}) | ||
|
|
||
| # When | ||
| set_api_evaluation_context(evaluation_context) | ||
| global_evaluation_context = api_evaluation_context() | ||
|
|
||
| # Then | ||
| assert global_evaluation_context | ||
| assert global_evaluation_context.targeting_key == evaluation_context.targeting_key | ||
| assert global_evaluation_context.attributes == evaluation_context.attributes |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.