"""conftest.py. Test fixtures and configurations. """ import json from datetime import datetime import pytest from owslogger import flask_logger import application from reporting import config, features from reporting.constants import header from tests.utils import setup_test_db, sqlite class MockLogAdaptor: """Mocking Class for Logger. This class replaces the ows logger class, so it's easier to use and test in our codebase. """ def error(self, message, *args, **kwargs): """Log errors. Args: message (str): the message to log. args (list): additional arguments. kwargs (dict): additional named arguments. """ pass def warning(self, message, *args, **kwargs): """Log Warnings. Args: message (str): the message to log. args (list): additional arguments. kwargs (dict): additional named arguments. """ pass def info(self, message, *args, **kwargs): """Log information. Args: message (str): the message to log. args (list): additional arguments. kwargs (dict): additional named arguments. """ pass @pytest.yield_fixture(scope='session', autouse=True) def create_and_populate_summary_sos_table(): """Set up and tear down test.""" setup_test_db.create_snowflake_test_setup() setup_test_db.create_and_populate_test_tables() yield setup_test_db.remove_snowflake_test_setup() @pytest.fixture def client(): """Return flask test client.""" return application.app.test_client() @pytest.fixture def valid_post_headers(): """Return valid POST request headers.""" return { header.CONTENT_TYPE: 'application/json', header.CORRELATION_ID: '1234567890', header.GRASS_ACCOUNT_TYPE: header.GRASS_ACCOUNT_TYPE_VENDOR, header.GRASS_ACCOUNT_ID: '7123', header.ORCHARD_USER_ID: '1', } @pytest.fixture def valid_get_headers(): """Return valid GET request headers.""" return { header.CONTENT_TYPE: 'application/json', header.GRASS_ACCOUNT_TYPE: header.GRASS_ACCOUNT_TYPE_VENDOR, header.GRASS_ACCOUNT_ID: '7123', } @pytest.fixture def mode_run_state_enqueuing(): """Mode report run status enqueuing response fixture.""" return { 'token': 'f335d980d5bc', 'state': 'enqueuing', } @pytest.fixture def mode_run_state_succeeded(): """Mode report run status succeeded response fixture.""" return { 'token': 'f335d980d5bc', 'state': 'succeeded', 'parameters': {'label_id': '7123', 'limit': '100'}, 'created_at': '2017-07-07T15:15:20.932Z', 'updated_at': '2017-07-07T15:15:28.995Z', 'completed_at': '2017-07-07T15:15:28.995Z', 'python_state': 'none', 'form_fields': [ { 'name': 'label_id', 'label': 'Label', 'type': 'text', 'default': 7123, 'description': None, 'input_type': 'string', 'human_name': 'Label', 'value': '7123', 'options': [], }, { 'name': 'limit', 'label': 'Limit', 'type': 'text', 'default': 50, 'description': None, 'input_type': 'string', 'human_name': 'Limit', 'value': '100', 'options': [], }, ], '_links': { 'self': { 'href': '/api/theorchard/reports/f4a80decd6e2/runs/' + 'f335d980d5bc?embed[result]=1' }, 'content': { 'href': '/api/theorchard/reports/f4a80decd6e2/runs/' + 'f335d980d5bc/results/content.csv' }, 'account': {'href': '/api/theorchard'}, 'executed_by': {'href': '/api/cnewsom'}, 'share': { 'href': '/theorchard/reports/f4a80decd6e2/runs/f335d980d5bc' }, 'report': {'href': '/api/theorchard/reports/f4a80decd6e2'}, 'clone': { 'href': '/theorchard/reports/f4a80decd6e2/runs/f335d980d5bc/' + 'clone' }, 'query_runs': { 'href': '/api/theorchard/reports/f4a80decd6e2/runs/' + 'f335d980d5bc/query_runs' }, 'python_cell_runs': { 'href': '/api/theorchard/reports/f4a80decd6e2/runs/' + 'f335d980d5bc/python_cell_runs' }, 'pdf_export': { 'href': '/api/theorchard/reports/f4a80decd6e2/exports/runs/' + 'f335d980d5bc/pdf' }, }, '_forms': { 'edit': { 'method': 'patch', 'action': '/api/theorchard/reports/f4a80decd6e2/runs/' + 'f335d980d5bc', 'input': { 'report_run': { 'dataset': { 'count': {'type': 'text'}, 'content': {'type': 'file'}, 'columns': {'type': 'text'}, }, 'error': { 'message': {'type': 'text'}, 'detail': {'type': 'text'}, }, } }, }, 'cancel': { 'method': 'put', 'action': '/api/theorchard/reports/f4a80decd6e2/runs/' + 'f335d980d5bc/cancel', }, }, } @pytest.fixture def mode_spaces(): """Mode spaces succeeded with json response.""" env = config.ENVIRONMENT return { '_links': {'self': {'href': '/api/theorchard/spaces'}}, '_embedded': { 'spaces': [ { 'token': 'c50aa7fb6d9c', 'id': 225628, 'space_type': 'private', 'name': 'Personal', 'description': 'null', 'state': 'active', 'restricted': 'false', '_links': { 'self': { 'href': '/api/theorchard/spaces/c50aa7fb6d9c' }, 'detail': { 'href': '/api/theorchard/spaces/c50aa7fb6d9c/detail' # noqa: E501 }, 'web': {'href': '/theorchard/spaces/c50aa7fb6d9c'}, 'reports': { 'href': '/api/theorchard/spaces/c50aa7fb6d9c/reports' # noqa: E501 }, 'creator': {'href': '/api/dethbird'}, }, '_forms': { 'create': { 'method': 'post', 'action': '/api/theorchard/spaces', 'input': { 'space': { 'space_type': { 'type': 'select', 'options': [ 'private', 'community', 'custom', ], 'value': 'custom', }, 'name': {'type': 'text'}, 'description': {'type': 'text'}, 'restricted': { 'type': 'select', 'options': ['true', 'false'], 'value': 'false', }, } }, }, 'edit': { 'method': 'patch', 'action': '/api/theorchard/spaces/c50aa7fb6d9c', 'input': { 'space': { 'name': {'type': 'text'}, 'description': {'type': 'text'}, } }, }, 'destroy': { 'method': 'delete', 'action': '/api/theorchard/spaces/c50aa7fb6d9c', }, }, }, { 'token': '5dd9f3426461', 'id': 228677, 'space_type': 'custom', 'name': '{}_workstation_digital_sales'.format(env), 'description': 'totally demo dude', 'state': 'active', 'restricted': 'false', '_links': { 'self': { 'href': '/api/theorchard/spaces/5dd9f3426461' }, 'detail': { 'href': '/api/theorchard/spaces/5dd9f3426461/detail' # noqa: E501 }, 'space_report_pins': { 'href': '/api/theorchard/spaces/5dd9f3426461/' + 'report_pins' }, 'web': {'href': '/theorchard/spaces/5dd9f3426461'}, 'reports': { 'href': '/api/theorchard/spaces/5dd9f3426461/reports' # noqa: E501 }, 'creator': {'href': '/api/dethbird'}, 'user_space_membership': { 'href': '/api/theorchard/spaces/5dd9f3426461/' + 'memberships/e856abecc6f8' }, 'space_memberships': { 'href': '/api/theorchard/spaces/5dd9f3426461/' + 'memberships' }, 'preview_space_memberships': { 'href': '/api/theorchard/spaces/5dd9f3426461/' + 'memberships/preview' }, }, '_forms': { 'create': { 'method': 'post', 'action': '/api/theorchard/spaces', 'input': { 'space': { 'space_type': { 'type': 'select', 'options': [ 'private', 'community', 'custom', ], 'value': 'custom', }, 'name': {'type': 'text'}, 'description': {'type': 'text'}, 'restricted': { 'type': 'select', 'options': ['true', 'false'], 'value': 'false', }, } }, }, 'edit': { 'method': 'patch', 'action': '/api/theorchard/spaces/5dd9f3426461', 'input': { 'space': { 'name': {'type': 'text'}, 'description': {'type': 'text'}, } }, }, 'destroy': { 'method': 'delete', 'action': '/api/theorchard/spaces/5dd9f3426461', }, }, }, { 'token': '3a17f1133a4b', 'id': 244667, 'space_type': 'custom', 'name': '{}_workstation_physical'.format(env), 'description': '', 'state': 'active', 'restricted': 'false', '_links': { 'self': { 'href': '/api/theorchard/spaces/3a17f1133a4b' }, 'detail': { 'href': '/api/theorchard/spaces/3a17f1133a4b/detail' # noqa: E501 }, 'space_report_pins': { 'href': '/api/theorchard/spaces/3a17f1133a4b/' + 'report_pins' }, 'web': {'href': '/theorchard/spaces/3a17f1133a4b'}, 'reports': { 'href': '/api/theorchard/spaces/3a17f1133a4b/reports' # noqa: E501 }, 'creator': {'href': '/api/dethbird'}, 'user_space_membership': { 'href': '/api/theorchard/spaces/3a17f1133a4b/' + 'memberships/26186a68cd4d' }, 'space_memberships': { 'href': '/api/theorchard/spaces/3a17f1133a4b/' + 'memberships' }, 'preview_space_memberships': { 'href': '/api/theorchard/spaces/3a17f1133a4b/' + 'memberships/preview' }, }, '_forms': { 'create': { 'method': 'post', 'action': '/api/theorchard/spaces', 'input': { 'space': { 'space_type': { 'type': 'select', 'options': [ 'private', 'community', 'custom', ], 'value': 'custom', }, 'name': {'type': 'text'}, 'description': {'type': 'text'}, 'restricted': { 'type': 'select', 'options': ['true', 'false'], 'value': 'false', }, } }, }, 'edit': { 'method': 'patch', 'action': '/api/theorchard/spaces/3a17f1133a4b', 'input': { 'space': { 'name': {'type': 'text'}, 'description': {'type': 'text'}, } }, }, 'destroy': { 'method': 'delete', 'action': '/api/theorchard/spaces/3a17f1133a4b', }, }, }, ] }, } @pytest.fixture def mode_reports(): """Mode reports succeeded with json response.""" env = config.ENVIRONMENT return { '_links': { 'self': {'href': '/api/theorchard/spaces/3a17f1133a4b/reports'} }, '_embedded': { 'reports': [ { 'token': '8d9af0be16ab', 'id': 551270, 'name': '{}_product_view_report'.format(env), 'description': '', 'created_at': '2017-07-25T18: 32: 24.871Z', 'updated_at': '2017-09-06T19: 49: 43.393Z', 'edited_at': '2017-09-06T19: 28: 33.748Z', 'theme_id': 3, 'archived': 'false', 'space_token': '3a17f1133a4b', 'account_id': 81953, 'account_username': 'theorchard', 'public': 'false', 'full_width': 'false', 'manual_run_disabled': 'false', 'run_privately': 'true', 'layout': '', 'is_embedded': 'false', 'is_signed': 'true', 'shared': 'false', 'last_successfully_run_at': '2017-09-06T19: 49: 43.343Z', 'last_run_at': '2017-09-06T19: 49: 41.256Z', 'web_preview_image': 'https: //s3-us-west-2.amazonaws.com/' + 'mode.production/' + 'report-run-previews/web/' + 'theorchard/8d9af0be16ab/' + '192ef3f455e0/' + '126a2889cf66?AWSAccessKeyId=' + 'AKIAJZYSJ2XHDM2CQN2Q\u0026Expires=' + '1504728537\u0026Signature=' + 'f6q9mfdVFso502ZmXZQlCZLe2ws%3D', 'last_successful_run_token': '192ef3f455e0', '_links': { 'self': { 'href': '/api/theorchard/reports/8d9af0be16ab' }, 'web': { 'href': 'https: //modeanalytics.com/theorchard/' + 'reports/8d9af0be16ab' }, 'web_edit': { 'href': '/editor/theorchard/reports/8d9af0be16ab' }, 'share': {'href': '/theorchard/reports/8d9af0be16ab'}, 'web_report_runs': { 'href': '/theorchard/reports/8d9af0be16ab/runs' }, 'account': {'href': '/api/theorchard'}, 'report_run': { 'templated': 'true', 'href': '/api/theorchard/reports/8d9af0be16ab/' + 'runs/{id}?embed[result]=1', }, 'space': { 'href': '/api/theorchard/spaces/3a17f1133a4b' }, 'space_links': { 'href': '/api/theorchard/reports/' + '8d9af0be16ab/space_links' }, 'queries': { 'href': '/api/theorchard/reports/' + '8d9af0be16ab/queries' }, 'report_runs': { 'href': '/api/theorchard/reports/8d9af0be16ab/runs' }, 'report_pins': { 'href': '/api/theorchard/reports/8d9af0be16ab/pins' }, 'report_filters': { 'href': '/api/theorchard/reports/' + '8d9af0be16ab/filters' }, 'report_schedules': { 'href': '/api/theorchard/reports/' + '8d9af0be16ab/schedules' }, 'report_subscriptions': { 'href': '/api/theorchard/reports/' + '8d9af0be16ab/subscriptions' }, 'python_visualizations': { 'href': '/api/theorchard/reports/' + '8d9af0be16ab/layout_cells' }, 'last_run': { 'href': '/api/theorchard/reports/8d9af0be16ab/' + 'runs/192ef3f455e0' }, 'last_successful_run': { 'href': '/api/theorchard/reports/8d9af0be16ab/' + 'runs/192ef3f455e0' }, 'python_notebook': { 'href': '/api/theorchard/reports/8d9af0be16ab/' + 'notebooks/1bf25485f839' }, 'perspective_email_subscription_memberships': { 'href': '/api/theorchard/reports/8d9af0be16ab/' + 'perspective_email_report_' + 'subscription_memberships' }, 'validate_email_subscriber': { 'templated': 'true', 'href': '/api/theorchard/reports/8d9af0be16ab/' + 'email_report_subscribers/validate' + '{?subscriber[email]}', }, 'creator': {'href': '/api/mscott'}, 'report_theme': { 'href': '/api/modeanalytics/' + 'report_themes/3818837139b7' }, }, '_forms': { 'edit': { 'method': 'patch', 'action': '/api/theorchard/reports/8d9af0be16ab', 'input': { 'report': { 'name': { 'type': 'text', 'value': '{}_product_view'.format(env) + '_report', }, 'layout': {'type': 'text', 'value': ''}, 'description': { 'type': 'text', 'value': '', }, 'account_id': { 'type': 'text', 'value': 81953, }, 'space_token': { 'type': 'text', 'value': '3a17f1133a4b', }, 'published': { 'type': 'text', 'value': 'false', }, } }, }, 'archive': { 'method': 'patch', 'action': '/api/theorchard/reports/' + '8d9af0be16ab/archive', }, 'unarchive': { 'method': 'patch', 'action': '/api/theorchard/reports/' + '8d9af0be16ab/unarchive', }, 'batch_edit_filters': { 'method': 'patch', 'action': '/api/theorchard/reports/' + '8d9af0be16ab/filters/update_batch', 'input': { 'report': { 'filters[]': { 'token': {'type': 'text'}, 'options': {'type': 'text'}, } } }, }, 'clone': { 'method': 'post', 'action': '/theorchard/reports/' + '8d9af0be16ab/runs/192ef3f455e0/clone', 'input': { 'owner_id': {'type': 'text', 'value': 81953} }, }, 'enable_signed_embeds': { 'method': 'patch', 'action': '/api/theorchard/reports/' + '8d9af0be16ab/signed_embeds/enable', }, 'disable_signed_embeds': { 'method': 'patch', 'action': '/api/theorchard/reports/' + '8d9af0be16ab/signed_embeds/disable', }, 'update_settings': { 'method': 'patch', 'action': '/api/theorchard/' + 'reports/8d9af0be16ab/update_settings', 'input': { 'report': { 'theme': { 'type': 'select', 'options': [ ['Mode Dark', 1], ['Mode Grey', 2], ['Mode Light', 3], ['Mode Subway', 5], ], 'value': 3, }, 'full_width': { 'type': 'select', 'options': ['true', 'false'], 'value': 'false', }, 'manual_run_disabled': { 'type': 'select', 'options': ['true', 'false'], 'value': 'false', }, } }, }, }, } ] }, } @pytest.fixture def valid_get_header(valid_grass_account_vendor_id): """Return valid GET request headers. Returns: (dict): header dict """ data = { header.CORRELATION_ID: '1234567890-1234567890', header.GRASS_ACCOUNT_TYPE: 'vendor', header.GRASS_ACCOUNT_ID: str(valid_grass_account_vendor_id), } return data @pytest.fixture def valid_grass_account_vendor_id(): """Vendor id for testing.""" return 25257 @pytest.fixture def context(): """Return flask app context, including a mock logger. Returns: AppContext: flask app context, including a mock logger. """ context = application.app.app_context() context.g.ows = flask_logger.Ows() context.g.ows.log = MockLogAdaptor() return context @pytest.fixture def feature_method(): """Configure mock_feature_util. Usage: @pytest.mark.parametrize('feature_method', ['is_overstock_enabled']) """ return 'define with @pytest.mark.parametrize' @pytest.fixture def is_enabled(): """Configure mock_feature_util. Usage: @pytest.mark.parametrize('is_enabled', [True]) """ return 'define with @pytest.mark.parametrize' @pytest.fixture def mock_feature_util(mocker, feature_method, is_enabled): """Mock reporting.features.feature_method. Usage: @pytest.mark.parametrize('feature_method, is_enabled', [ ('is_overstock_enabled', True)]) def test_get_column_names(mock_feature_util, is_enabled): pass Args: mocker (object): mocker patch object. feature_method (str): the method to call on reporting.features. is_enabled (bool): the state of the feature flag. """ mocker.patch.object(features, feature_method, return_value=is_enabled) @pytest.fixture def art_relations_report_presets(valid_grass_account_vendor_id): """Get report_presets table rows.""" return [ { 'id': 1, 'name': 'Nice Report', 'report_id': 'awesome_report', 'params': json.dumps({'applesauce': 'bananas'}), 'account_type': 'vendor', 'account_id': valid_grass_account_vendor_id, 'user_id': 'alw:12321', 'datetime_created': '2018-01-29 11:43:23', 'is_deleted': 0, }, { 'id': 2, 'name': 'Best Report', 'report_id': 'awesome_report', 'params': json.dumps({'applesauce': 'bananas'}), 'account_type': 'vendor', 'account_id': valid_grass_account_vendor_id, 'user_id': 'alw:12321', 'datetime_created': '2018-01-27 09:55:01', 'is_deleted': 0, }, { 'id': 3, 'name': 'Good Report', 'report_id': 'awesome_report', 'params': json.dumps({'applesauce': 'bananas'}), 'account_type': 'vendor', 'account_id': valid_grass_account_vendor_id, 'user_id': 'alw:12321', 'datetime_created': '2018-01-24 09:15:57', 'is_deleted': 1, }, { 'id': 4, 'name': 'Nice Report', 'report_id': 'awesome_report', 'params': json.dumps({'applesauce': 'bananas'}), 'account_type': 'vendor', 'account_id': valid_grass_account_vendor_id + 1, 'user_id': 'alw:22322', 'datetime_created': '2018-01-28 15:44:08', 'is_deleted': 0, }, { 'id': 5, 'name': 'Best Report', 'report_id': 'awesome_report', 'params': json.dumps({'applesauce': 'bananas'}), 'account_type': 'vendor', 'account_id': valid_grass_account_vendor_id + 1, 'user_id': 'alw:22322', 'datetime_created': '2018-01-29 12:10:11', 'is_deleted': 0, }, { 'id': 6, 'name': 'Good Report', 'report_id': 'awesome_report', 'params': json.dumps({'applesauce': 'bananas'}), 'account_type': 'vendor', 'account_id': valid_grass_account_vendor_id + 1, 'user_id': 'alw:22322', 'datetime_created': '2018-01-28 17:19:18', 'is_deleted': 1, }, ] @pytest.yield_fixture def art_relations_fixture(): """Set up tables in test database.""" sqlite.create_report_preset_table() yield sqlite.drop_report_preset_table() @pytest.fixture def art_relations_with_data( art_relations_fixture, art_relations_report_presets ): """Fixture that sets up art_relations database and injects test data.""" sqlite.populate_table('report_preset', art_relations_report_presets) @pytest.fixture def supply_chain_id(): """Mock supply chain id for single product overview tests..""" return 738 @pytest.fixture def local_product_cd(): """Mock local product code for single product overview tests.""" return '709422' @pytest.fixture def single_product_overview_rtd(): """Return expected row from monthly rtd_table.""" return { 'supply_chain_id': 738, 'local_product_cd': '709422', 'first_4week_qt': 1200, 'second_4week_qt': 16, 'day1_ship_qt': 0, 'day1_ship_am': 0, 'day1_ship_us_am': 0, 'day1_return_qt': 0, 'day1_return_am': 0, 'day1_return_us_am': 0, 'day2_ship_qt': 0, 'day2_ship_am': 0, 'day2_ship_us_am': 0, 'day2_return_qt': 0, 'day2_return_am': 0, 'day2_return_us_am': 0, 'day3_ship_qt': 2, 'day3_ship_am': 14.94, 'day3_ship_us_am': 14.94, 'day3_return_qt': 0, 'day3_return_am': 0, 'day3_return_us_am': 0, 'day4_ship_qt': 0, 'day4_ship_am': 0, 'day4_ship_us_am': 0, 'day4_return_qt': 0, 'day4_return_am': 0, 'day4_return_us_am': 0, 'day5_ship_qt': 0, 'day5_ship_am': 0, 'day5_ship_us_am': 0, 'day5_return_qt': 0, 'day5_return_am': 0, 'day5_return_us_am': 0, 'week1_ship_qt': 0, 'week1_ship_am': 0, 'week1_ship_us_am': 0, 'week1_return_qt': 0, 'week1_return_am': 0, 'week1_return_us_am': 0, 'week2_ship_qt': 5, 'week2_ship_am': 38.88, 'week2_ship_us_am': 38.88, 'week2_return_qt': 0, 'week2_return_am': 0, 'week2_return_us_am': 0, 'week3_ship_qt': 0, 'week3_ship_am': 0, 'week3_ship_us_am': 0, 'week3_return_qt': 0, 'week3_return_am': 0, 'week3_return_us_am': 0, 'week4_ship_qt': 3, 'week4_ship_am': 25.47, 'week4_ship_us_am': 25.47, 'week4_return_qt': -1, 'week4_return_am': -9, 'week4_return_us_am': -9, 'mtd_ship_qt': 2, 'mtd_ship_am': 14.94, 'mtd_ship_us_am': 14.94, 'mtd_return_qt': 0, 'mtd_return_am': 0, 'mtd_return_us_am': 0, 'ytd_ship_qt': 59, 'ytd_ship_am': 489.69, 'ytd_ship_us_am': 489.69, 'ytd_return_qt': -15, 'ytd_return_am': -133.47, 'ytd_return_us_am': -133.47, 'cytd_ship_qt': 10, 'cytd_ship_am': 79.29, 'cytd_ship_us_am': 79.29, 'cytd_return_qt': -1, 'cytd_return_am': -9, 'cytd_return_us_am': -9, 'last_12_mtd_ship_qt': 61, 'last_12_mtd_ship_am': 507.69, 'last_12_mtd_ship_us_am': 507.69, 'last_12_mtd_return_qt': -16, 'last_12_mtd_return_am': -142.47, 'last_12_mtd_return_us_am': -142.47, 'last_24_mtd_ship_qt': 172, 'last_24_mtd_ship_am': 1471.5, 'last_24_mtd_ship_us_am': 1471.5, 'last_24_mtd_return_qt': -87, 'last_24_mtd_return_am': -753.12, 'last_24_mtd_return_us_am': -753.12, 'last_3_mth_ship_qt': 68, 'last_3_mth_ship_am': 573.75, 'last_3_mth_ship_us_am': 573.75, 'last_3_mth_return_qt': -28, 'last_3_mth_return_am': -249.57, 'last_3_mth_return_us_am': -249.57, 'last_12_mth_ship_qt': 68, 'last_12_mth_ship_am': 573.75, 'last_12_mth_ship_us_am': 573.75, 'last_12_mth_return_qt': -28, 'last_12_mth_return_am': -249.57, 'last_12_mth_return_us_am': -249.57, 'last_24_mth_ship_qt': 202, 'last_24_mth_ship_am': 1706.94, 'last_24_mth_ship_us_am': 1706.94, 'last_24_mth_return_qt': -106, 'last_24_mth_return_am': -919.14, 'last_24_mth_return_us_am': -919.14, 'rtd_ship_qt': 1699, 'rtd_ship_am': 14475.06, 'rtd_ship_us_am': 14475.06, 'rtd_return_qt': -279, 'rtd_return_am': -2327.04, 'rtd_return_us_am': -2327.04, 'prior_yr_ship_qt': 112, 'prior_yr_ship_am': 972.81, 'prior_yr_ship_us_am': 972.81, 'prior_yr_return_qt': -69, 'prior_yr_return_am': -593.1, 'prior_yr_return_us_am': -593.1, 'prior_cyr_ship_qt': 66, 'prior_cyr_ship_am': 563.4, 'prior_cyr_ship_us_am': 563.4, 'prior_cyr_return_qt': -28, 'prior_cyr_return_am': -249.57, 'prior_cyr_return_us_am': -249.57, 'order_qt': 3, 'order_am': 0, 'order_us_am': 0, 'back_order_qt': 0, 'back_order_am': 0, 'back_order_us_am': 0, } @pytest.fixture def single_product_monthly(): """Single product overview monthly view.""" return [ { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2018-01-01', '%Y-%m-%d'), 'ship_qt': 17, 'ship_am': 139.54, 'return_qt': 0, 'return_am': 0, }, { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2017-12-01', '%Y-%m-%d'), 'ship_qt': 30, 'ship_am': 223.6, 'return_qt': 0, 'return_am': 0, }, { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2017-11-01', '%Y-%m-%d'), 'ship_qt': 24, 'ship_am': 170.47, 'return_qt': 0, 'return_am': 0, }, { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2017-10-01', '%Y-%m-%d'), 'ship_qt': 30, 'ship_am': 194.16, 'return_qt': -20, 'return_am': -185.08, }, { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2017-09-01', '%Y-%m-%d'), 'ship_qt': 10, 'ship_am': 78.67, 'return_qt': 0, 'return_am': 0, 'return_us_am': 0, }, { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2017-08-01', '%Y-%m-%d'), 'ship_qt': 27, 'ship_am': 204.86, 'return_qt': -1, 'return_am': -8.72, }, { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2017-07-01', '%Y-%m-%d'), 'ship_qt': 38, 'ship_am': 314.4, 'return_qt': 0, 'return_am': 0, }, { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2017-06-01', '%Y-%m-%d'), 'ship_qt': 26, 'ship_am': 214.02, 'return_qt': 0, 'return_am': 0, }, { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2017-05-01', '%Y-%m-%d'), 'ship_qt': 21, 'ship_am': 186.29, 'return_qt': -2, 'return_am': -18.41, }, { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2017-04-01', '%Y-%m-%d'), 'ship_qt': 33, 'ship_am': 255.15, 'return_qt': 0, 'return_am': 0, }, { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2017-03-01', '%Y-%m-%d'), 'ship_qt': 27, 'ship_am': 224.02, 'return_qt': -3, 'return_am': -28.1, }, { 'supply_chain_id': 738, 'local_product_cd': '709422', 'reporting_dt': datetime.strptime('2017-02-01', '%Y-%m-%d'), 'ship_qt': 27, 'ship_am': 195.03, 'return_qt': -1, 'return_am': -5.81, }, ] @pytest.fixture def single_product_inventory(): """Single product inventory fixture.""" return { 'supply_chain_id': 738, 'local_product_cd': '709422', 'on_hand_qt': 248, 'available_qt': 248, 'all_order_qt': 2, 'rdo_backorder_qt': 0, 'fut_dated_qt': 0, 'open_po_qt': 0, 'rework_qt': 0, 'whse_rework_qt': 0, 'rip_qt': 38, 'ip_xfr_due_in_qt': 0, 'ip_in_tran_qt': 0, 'ip_xfr_due_out_qt': 0, 'hold_qt': 0, 'returns_disp_cd': 'K', 'returns_disp_override_cd': 'N', 'open_scrap_qt': 1, 'overstock_12_mtd_qt': 20, 'overstock_24_mtd_qt': 11, } @pytest.fixture def single_product_metadata(): """Single product metadata fixture.""" return { 'supply_chain_id': 738, 'local_product_cd': '709422', 'artist_nm': 'good riddance', 'product_nm': 'peace in our time', 'label_nm': 'fat wreck chords', 'label_id': 21945, 'sublabel_nm': 'fat wreck chords', 'genre_nm': 'punk', 'subgenre_nm': 'punk', 'product_cd': 709422, 'upc_cd': 751097094228, 'release_dt': datetime.strptime('2015-04-21', '%Y-%m-%d'), 'product_type': 'cd', 'product_format': 'album', 'units_per_set': 1, 'display_configuration': '1 x cd album', 'boxlot': 30, 'status_cd': 31, 'status_nm': 'active catalog', 'cutout_dt': 'null', 'returns_allowed_in': 'y', 'exclusive_product_in': 'n', 'series_cd': 13.98, 'red_price_cd': 'cd13', 'wholesales_pr': 9, 'gras_prod_no': 75109709422, 'inventory_category_cd': 7, 'profit_code': 'null', 'article_no': 709422, 'fin_label_cd': 'd093', 'fin_label_profit_cd': 'd093', 'sap_profit_center_cd': 'us3443', 'sap_company_cd': 2963, 'exclusive_for': '', 'price_cd': 9, 'store_pricing_tier_nm': 'cd13', 'vendor_id': 21945, 'subacct_id': 7483, 'release_id': 2151331, } @pytest.fixture def single_product_overview( single_product_metadata, single_product_inventory, single_product_overview_rtd, ): """Combine views into a single fixture.""" overview = dict() overview.update(single_product_metadata) overview.update(single_product_inventory) overview.update(single_product_overview_rtd) return overview @pytest.fixture def account_by_product_response(): """Account by product fixture response.""" return {'vendor_id': 21945, 'subacct_id': 7483} @pytest.fixture def app_context(): """Create an api test app fixture.""" with application.app.app_context(): yield