"""Mode Service Tests.""" import base64 import pytest from reporting import config from reporting.utils import mode def test__generate_md5_hash(): """Test generation of md5 hash.""" content_a = 'Hash me!' content_test = 'Hash me!' content_hash_a = mode._generate_md5_hash(content_a) content_hash_test = mode._generate_md5_hash(content_test) assert content_hash_a assert content_hash_a == content_hash_test def test__generate_md5_hash_is_unique(): """Test generated hash is unique.""" content_a = 'Hash me!' content_b = 'Hash me too!' content_hash_a = mode._generate_md5_hash(content_a) content_hash_b = mode._generate_md5_hash(content_b) assert content_hash_a != content_hash_b test_collection = [ {'name': 'apples', 'id': 1}, {'name': 'celery', 'id': 2}, {'name': 'chocolate', 'id': 30001}, ] @pytest.mark.parametrize( 'collection, new_key, old_key, expected', [ ( test_collection, 'celery', 'name', {'name': 'celery', 'id': 2, 'index': 1}, ), ( test_collection, 'chocolate', 'name', {'name': 'chocolate', 'id': 30001, 'index': 2}, ), ( test_collection, 'apples', 'name', {'name': 'apples', 'id': 1, 'index': 0}, ), (test_collection, 'apples', 'foo', None), ([], 'apples', 'name', None), ([], None, None, None), ], ) def test_dict_from_collection(collection, new_key, old_key, expected): """Test `dict_from_collection` returns expected shape of data.""" assert mode.dict_from_collection(collection, new_key, old_key) == expected def test__generate_content_digest(): """Test generation of a base64 encoded content digest.""" content_hash = mode._generate_md5_hash() expected_digest = base64.encodebytes(content_hash).decode('utf-8').strip() actual_digest = mode._generate_content_digest() assert actual_digest == expected_digest def test__build_encoded_request_string(): """Test concatenation of parameters into a valid request string.""" request_type = 'GET' content_type = 'content/type' content_digest = 'S0M3H@SH' url = 'http://foo.bar' timestamp = 9001 expected_request_string = '{},{},{},{},{}'.format( request_type, content_type, content_digest, url, timestamp ) actual_request_string = mode._build_encoded_request_string( content_digest, url, timestamp, request_type, content_type ) assert actual_request_string == expected_request_string.encode('utf-8') def test_generate_signed_url(): """Test generating a signed url.""" input_url = 'http://foo.bar' access_secret = 'accessSecret' timestamp = 9001 signed_url = mode.generate_signed_url(input_url, access_secret, timestamp) assert signed_url assert input_url in signed_url assert '&signature=' in signed_url def test_sort_params_by_key(): """Test alphabetical sorting of dictionary by key.""" test_dict = {'a': 12, 'd': 1, 'c': 0, 'b': 21} expected_dict = {'a': 12, 'b': 21, 'c': 0, 'd': 1} sorted_dict = mode.sort_params_by_key(test_dict) assert sorted_dict == expected_dict test_sort_and_encode_params_data = [ ( { 'param_zzz': 'str001', 'param_bbb': ['c', 'b', 'a'], 'param_aaa': ['e', 'f', 'g'], }, ('param_aaa=e%2Cf%2Cg¶m_bbb=c%2Cb%2Ca¶m_zzz=str001'), ), ( {'param_zzz': 'str001', 'param_bbb': ['c', 'b', 'a'], 'param_aaa': []}, ('param_aaa=¶m_bbb=c%2Cb%2Ca¶m_zzz=str001'), ), ( { 'param_zzz': 'str001', 'param_bbb': ['c', 'b', 'a'], 'param_aaa': False, }, ('param_aaa=¶m_bbb=c%2Cb%2Ca¶m_zzz=str001'), ), ( {'param_zzz': 'str001', 'param_bbb': ['c', 'b', 'a'], 'param_aaa': ''}, ('param_aaa=¶m_bbb=c%2Cb%2Ca¶m_zzz=str001'), ), ( { 'param_zzz': 'str001', 'param_bbb': ['c', 'b', 'a'], 'param_aaa': None, }, ('param_aaa=¶m_bbb=c%2Cb%2Ca¶m_zzz=str001'), ), ( {'param_zzz': 'str001', 'param_bbb': ['c', 'b', 'a'], 'param_aaa': 0}, ('param_aaa=¶m_bbb=c%2Cb%2Ca¶m_zzz=str001'), ), # params None (None, ''), # params empty string ('', ''), # params False ('', ''), # testing with single quote in value ( { 'param_zzz': 'str001', 'param_bbb': ["dog's", "d'oh"], 'param_aaa': 0, }, ('param_aaa=¶m_bbb=dog%27s%2Cd%27oh¶m_zzz=str001'), ), # testing with comma in array value ( { 'param_zzz': 'str001', 'param_bbb': ['FERREL, PERRY', 'MORANIS, RICK'], 'param_aaa': 0, }, ( 'param_aaa=¶m_bbb=FERREL%28_COMMA_%29%20PERRY%2CMORANIS' '%28_COMMA_%29%20RICK¶m_zzz=str001' ), ), ] @pytest.mark.parametrize( ('payload,expected_response'), test_sort_and_encode_params_data ) def test_sort_and_encode_params(payload, expected_response): """Test sorting and encoding of url parameters.""" sorted_and_encoded_str = mode.sort_and_encode_params(payload) assert sorted_and_encoded_str == expected_response def test_api_url_with_params(): """Test mode api url helper.""" test_params = { 'path': 'reports/0916aeab9453/runs/2428701e9a74', 'query': { 'param_subaccount_id': 30, 'param_limit': 100, 'param_vendor_id': 7123, }, } expected_url = ( 'https://modeanalytics.com/api/theorchard/reports/0916aeab9453/' + 'runs/2428701e9a74?param_limit=100¶m_subaccount_id=30' + '¶m_vendor_id=7123' ) mode_api_url_with_params = mode.api_url(**test_params) assert mode_api_url_with_params == expected_url def test_api_url_without_params(): """Test api url without passing parameter arguments.""" test_params = {'path': 'reports/0916aeab9453/runs/2428701e9a74'} expected_url = ( 'https://modeanalytics.com/api/theorchard/' + 'reports/0916aeab9453/runs/2428701e9a74' ) mode_api_url_without_params = mode.api_url(**test_params) assert mode_api_url_without_params == expected_url @pytest.mark.parametrize( 'string, expected_output', [ ( 'workstation_analytics', '{}_workstation_analytics'.format(config.ENVIRONMENT), ), ('', ''), (None, ''), ], ) def test_prefix_with_environment(string, expected_output): """Test string with prefixed with current environment.""" prefixed_string = mode.prefix_with_environment(string) assert expected_output == prefixed_string test_query_url_from_query_run_data = [ ( {'_links': {'query': {'href': '/query/1234'}}}, 'https://modeanalytics.com/query/1234', ), ({'_links': {'query': {'href': None}}}, None), ({'_links': {'query': None}}, None), ({'_links': None}, None), ] @pytest.mark.parametrize( ('query_run,expected_response'), test_query_url_from_query_run_data ) def test_query_url_from_query_run(query_run, expected_response): """Test getting query url from query run object.""" query_url = mode.query_url_from_query_run(query_run) assert query_url == expected_response test_query_run_result_url_from_query_run_data = [ ( {'_links': {'result': {'href': '/query/1234'}}}, 'https://modeanalytics.com/query/1234', ), ({'_links': {'result': {'href': None}}}, None), ({'_links': {'result': None}}, None), ({'_links': None}, None), ] @pytest.mark.parametrize( ('query_run,expected_response'), test_query_run_result_url_from_query_run_data, ) def test_query_run_result_url_from_query_run(query_run, expected_response): """Test getting query result url from query run object.""" query_url = mode.query_run_result_url_from_query_run(query_run) assert query_url == expected_response test_json_url_from_query_result_data = [ ( {'_links': {'json': {'href': 'https://api.com/json'}}}, 'https://api.com/json', ), ({'_links': {'json': {'href': None}}}, None), ({'_links': {'json': None}}, None), ({'_links': None}, None), ] @pytest.mark.parametrize( ('query_result,expected_response'), test_json_url_from_query_result_data ) def test_json_url_from_query_result(query_result, expected_response): """Test getting json url from query result object.""" json_url = mode.json_url_from_query_result(query_result) assert json_url == expected_response test_is_report_query_data = [ ({'name': 'filter_artist_name'}, False), ({'name': 'Product View'}, True), ({'name': 'Retailer View'}, True), ({'name': 'filter_ ksjdfiubpiurb n ??? '}, False), ({}, False), ] @pytest.mark.parametrize( ('query,expected_response'), test_is_report_query_data ) def test_is_report_query(query, expected_response): """Test check for is_report_query.""" test = mode.is_report_query(query) assert test == expected_response