"""Tests for features logic.""" from unittest.mock import MagicMock from owsresponse import response import pytest from pythonfeatures.constants import context as context_constants from pythonfeatures.constants import split as split_constants from pythonfeatures.logic import features from pythonfeatures.models import split from pythonfeatures.models.context import AccountContext from pythonfeatures.models.context import ProfileContext @pytest.mark.parametrize(( 'user_context', 'expected_response'), [ # no context ( {}, split_constants.TRAFFIC_TYPE_ANONYMOUS ), # just orchard identity uuid ( { context_constants.ORCHARD_IDENTITY_UUID: '77f607ed-c303-4eb7-9c05-f8b19eb94757' # noqa }, '77f607ed-c303-4eb7-9c05-f8b19eb94757' ), # profile type and id takes precedence ( { context_constants.PROFILE_TYPE_AND_ID: 'OrchAdminProfile:456', context_constants.ORCHARD_USER_ID: 'oa:456' }, 'OrchAdminProfile:456' ), # profile type and id takes precedence ( { context_constants.PROFILE_TYPE_AND_ID: 'LabelProfile:786', context_constants.ORCHARD_USER_ID: 'alw:786', context_constants.VENDOR_ID: '16888' }, 'LabelProfile:786' ), # orchard identity id takes precedence ( { context_constants.IDENTITY_ID: 'auth0-user-id', context_constants.PROFILE_TYPE_AND_ID: 'LabelProfile:786', context_constants.ORCHARD_USER_ID: 'alw:786', context_constants.VENDOR_ID: '16888' }, 'auth0-user-id' ), # orchard identity uuid takes precedence ( { context_constants.ORCHARD_IDENTITY_UUID: '77f607ed-c303-4eb7-9c05-f8b19eb94757', # noqa context_constants.IDENTITY_ID: 'auth0-user-id', context_constants.PROFILE_TYPE_AND_ID: 'LabelProfile:786', context_constants.ORCHARD_USER_ID: 'alw:786', context_constants.VENDOR_ID: '16888' }, '77f607ed-c303-4eb7-9c05-f8b19eb94757' ), # just orchard user id ( { context_constants.ORCHARD_USER_ID: 'alw:789' }, 'alw:789' ), # just vendor id ( { context_constants.VENDOR_ID: 8888 }, '{}{}'.format( split_constants.TRAFFIC_TYPE_VENDOR_PREFIX, 8888) ), # just subaccount id ( { context_constants.SUBACCOUNT_ID: 9999 }, '{}{}'.format( split_constants.TRAFFIC_TYPE_SUBACCOUNT_PREFIX, 9999) ), # orchard user id takes precedence ( { context_constants.ORCHARD_USER_ID: 'alw:789', context_constants.VENDOR_ID: 8888, context_constants.SUBACCOUNT_ID: 9999 }, 'alw:789' ), # vendor id takes precedence ( { context_constants.VENDOR_ID: 8888, context_constants.SUBACCOUNT_ID: 9999 }, '{}{}'.format( split_constants.TRAFFIC_TYPE_VENDOR_PREFIX, 8888) ), ]) def test__get_traffic_type_identifier( user_context, expected_response ): """Test 'private' method _get_traffic_type_identifier.""" result = features._get_traffic_type_identifier(user_context) assert expected_response == result def test__get_all_features(monkeypatch): """Test 'private' method _get_all_features.""" monkeypatch.setattr( split, 'get_all_features', MagicMock(return_value={ 'pizza': split_constants.SPLIT_DISABLED, 'party': split_constants.SPLIT_ENABLED})) all_features_response = features._get_all_features({ context_constants.IDENTITY_ID: 'auth0-user-id' }) assert all_features_response.message == { 'pizza': split_constants.FEATURE_DISABLED, 'party': split_constants.FEATURE_ENABLED} assert split.get_all_features.called split.get_all_features.assert_called_with( traffic_type=features._get_traffic_type_identifier({ context_constants.IDENTITY_ID: 'auth0-user-id'}), attributes={ context_constants.IDENTITY_ID: 'auth0-user-id'}) def test__get_single_feature(monkeypatch): """Test 'private' method _get_single_feature.""" monkeypatch.setattr( split, 'get_single_feature', MagicMock( return_value=split_constants.SPLIT_ENABLED)) single_feature_response = features._get_single_feature( 'test_feature', {context_constants.IDENTITY_ID: 'auth0-user-id'}) assert single_feature_response.message == split_constants.FEATURE_ENABLED assert split.get_single_feature.called split.get_single_feature.assert_called_with( traffic_type=features._get_traffic_type_identifier({ context_constants.IDENTITY_ID: 'auth0-user-id'}), feature_name='test_feature', attributes={ context_constants.IDENTITY_ID: 'auth0-user-id'}) @pytest.mark.parametrize(( 'validation_response'), [ (response.Response()), (response.create_error_response( code='whetever', message='whatever')), ]) def test_get_all_features_with_profile_context( monkeypatch, validation_response ): """Test get_all_features_with_profile_context.""" monkeypatch.setattr( ProfileContext, 'validate', MagicMock( return_value=validation_response)) monkeypatch.setattr( ProfileContext, 'to_dict', MagicMock( return_value={ context_constants.PROFILE_TYPE: 'Whatever', context_constants.PROFILE_ID: '888', context_constants.PROFILE_TYPE_AND_ID: 'Whatever:888', context_constants.ORCHARD_IDENTITY_UUID: '77f607ed-c303-4eb7-9c05-f8b19eb94757' # noqa })) monkeypatch.setattr( features, '_get_all_features', MagicMock()) features.get_all_features_with_profile_context( profile_type='Whatever', profile_id='888', identity_id=None, orchard_identity_uuid='77f607ed-c303-4eb7-9c05-f8b19eb94757') if validation_response: assert features._get_all_features.called features._get_all_features.assert_called_with({ context_constants.PROFILE_TYPE: 'Whatever', context_constants.PROFILE_ID: '888', context_constants.PROFILE_TYPE_AND_ID: 'Whatever:888', context_constants.ORCHARD_IDENTITY_UUID: '77f607ed-c303-4eb7-9c05-f8b19eb94757' # noqa }) else: assert features._get_all_features.called is False @pytest.mark.parametrize(( 'validation_response'), [ (response.Response()), (response.create_error_response( code='whetever', message='whatever')), ]) def test_get_all_features_with_account_context( monkeypatch, validation_response ): """Test get_all_features_with_account_context.""" monkeypatch.setattr( AccountContext, 'validate', MagicMock( return_value=validation_response)) monkeypatch.setattr( AccountContext, 'to_dict', MagicMock( return_value={ context_constants.ORCHARD_USER_ID: 'oa:555', context_constants.ORCHARD_IDENTITY_UUID: '77f607ed-c303-4eb7-9c05-f8b19eb94757' # noqa })) monkeypatch.setattr( features, '_get_all_features', MagicMock()) features.get_all_features_with_account_context( orchard_user_id='oa:555', vendor_id=None, subaccount_id=None, orchard_identity_uuid='77f607ed-c303-4eb7-9c05-f8b19eb94757') if validation_response: assert features._get_all_features.called features._get_all_features.assert_called_with({ context_constants.ORCHARD_USER_ID: 'oa:555', context_constants.ORCHARD_IDENTITY_UUID: '77f607ed-c303-4eb7-9c05-f8b19eb94757' # noqa }) else: assert features._get_all_features.called is False @pytest.mark.parametrize(( 'validation_response'), [ (response.Response()), (response.create_error_response( code='whetever', message='whatever')), ]) def test_get_single_feature_with_profile_context( monkeypatch, validation_response ): """Test get_single_feature_with_profile_context.""" monkeypatch.setattr( ProfileContext, 'validate', MagicMock( return_value=validation_response)) monkeypatch.setattr( ProfileContext, 'to_dict', MagicMock( return_value={ context_constants.PROFILE_TYPE: 'Whatever', context_constants.PROFILE_ID: '888', context_constants.PROFILE_TYPE_AND_ID: 'Whatever:888', context_constants.ORCHARD_IDENTITY_UUID: '77f607ed-c303-4eb7-9c05-f8b19eb94757' # noqa })) monkeypatch.setattr( features, '_get_single_feature', MagicMock()) features.get_single_feature_with_profile_context( feature_name='test_feature', profile_type='Whatever', profile_id='888', identity_id=None, orchard_identity_uuid='77f607ed-c303-4eb7-9c05-f8b19eb94757') if validation_response: assert features._get_single_feature.called features._get_single_feature.assert_called_with( 'test_feature', { context_constants.PROFILE_TYPE: 'Whatever', context_constants.PROFILE_ID: '888', context_constants.PROFILE_TYPE_AND_ID: 'Whatever:888', context_constants.ORCHARD_IDENTITY_UUID: '77f607ed-c303-4eb7-9c05-f8b19eb94757' # noqa }) else: assert features._get_single_feature.called is False @pytest.mark.parametrize(( 'validation_response'), [ (response.Response()), (response.create_error_response( code='whetever', message='whatever')), ]) def test_get_single_feature_with_account_context( monkeypatch, validation_response ): """Test get_single_feature_with_account_context.""" monkeypatch.setattr( AccountContext, 'validate', MagicMock( return_value=validation_response)) monkeypatch.setattr( AccountContext, 'to_dict', MagicMock( return_value={ context_constants.ORCHARD_USER_ID: 'oa:555', context_constants.ORCHARD_IDENTITY_UUID: '77f607ed-c303-4eb7-9c05-f8b19eb94757' # noqa })) monkeypatch.setattr( features, '_get_single_feature', MagicMock()) features.get_single_feature_with_account_context( feature_name='test_feature', orchard_user_id='oa:555', vendor_id=None, subaccount_id=None, orchard_identity_uuid='77f607ed-c303-4eb7-9c05-f8b19eb94757') if validation_response: assert features._get_single_feature.called features._get_single_feature.assert_called_with( 'test_feature', { context_constants.ORCHARD_USER_ID: 'oa:555', context_constants.ORCHARD_IDENTITY_UUID: '77f607ed-c303-4eb7-9c05-f8b19eb94757' # noqa }) else: assert features._get_single_feature.called is False def test_get_single_feature_by_attributes(monkeypatch): """Test get_single_feature_by_attributes().""" monkeypatch.setattr( features, '_get_single_feature', MagicMock()) features.get_single_feature_by_attributes( 'whatever', {'user_id': 'alw:789'}) assert features._get_single_feature.called assert features._get_single_feature.call_args[ 0][0] == 'whatever' assert features._get_single_feature.call_args[ 0][1] == {'user_id': 'alw:789'}