"""Tests for helper functions for model module.""" import datetime from oto import response as oto_response import pytest from sqlalchemy import exc from availability.connectors import sql from availability.constants import field_const from availability.models import helpers from availability.models import product from availability.models import product_in_store from availability.models import task from availability.validation import product_submission def test_attributes_to_datetime(): """Assert can convert product date attributes to datetime.""" product_dict = { 'something': '2017-01-01T12:12:12+00:32', 'delivery_date': '2017-01-01T12:12:12+00:32', 'not_date': 'some value' } attrs_to_convert = ['something', 'delivery_date'] converted_product = helpers.attributes_to_datetime( product_dict, attrs_to_convert) assert converted_product != product_dict assert all(attr in converted_product for attr in attrs_to_convert) for attr_name in attrs_to_convert: assert isinstance(converted_product[attr_name], datetime.datetime) def test_create_submitted_products_handle_sql_errors(mocker, product_data): """Assert that function return error Response or SQL errors.""" sql_mock = mocker.patch('availability.models.helpers.sql') sql_mock.session_scope.side_effect = exc.SQLAlchemyError('Boom!') result = helpers.create_submitted_products(product_data) assert isinstance(result, oto_response.Response) assert result.errors def test_create_submitted_products_creates_records( test_database, products_data): """Assert that function creates all 3 types of records.""" products = ( product_submission.filter_initial_product_fields(p) for p in products_data) products = ( helpers.attributes_to_datetime(p, field_const.DATE_FIELDS) for p in products) results = helpers.create_submitted_products(products) assert isinstance(results, oto_response.Response) assert results product_ids = {p['product_id'] for p in products_data} store_ids = {p['store_id'] for p in products_data} with sql.session_scope() as session: products_count = session.query(product.Product).count() products_in_store_count = session.query( product_in_store.ProductInStore).count() tasks_count = session.query(task.Task).count() assert products_count == len(product_ids) assert products_in_store_count == len(product_ids) * len(store_ids) assert tasks_count == len(product_ids) * len(store_ids) @pytest.mark.parametrize( ['days_delta', 'force_polling', 'expected_force_polling'], [ (+1, False, False), (-1, False, True), (+1, True, True), (-1, True, True), ] ) def test_create_submitted_products_sets_force_polling( days_delta, force_polling, expected_force_polling, test_database, products_data): """Assert that function automatically sets force_polling when needed. It should set this flag to True automatically if sales_start_date is in the past (VC-1477). """ products = ( product_submission.filter_initial_product_fields(p) for p in products_data) products = ( helpers.attributes_to_datetime(p, field_const.DATE_FIELDS) for p in products) delta = datetime.datetime.utcnow() + datetime.timedelta(days=days_delta) products = ( dict(p, sales_start_date=delta, force_polling=force_polling) for p in products) results = helpers.create_submitted_products(products) assert isinstance(results, oto_response.Response) assert results with sql.session_scope() as session: products_in_store = session.query(product_in_store.ProductInStore) assert all( p.force_polling == expected_force_polling for p in products_in_store) def test_create_submitted_products_no_records_on_fail( test_database, products_data): """Assert that function does not create anything if one record fails.""" products_data[-1]['store_id'] = None # breaks not-null constraint products = ( product_submission.filter_initial_product_fields(p) for p in products_data) products = ( helpers.attributes_to_datetime(p, field_const.DATE_FIELDS) for p in products) results = helpers.create_submitted_products(products) assert isinstance(results, oto_response.Response) assert results.errors with sql.session_scope() as session: products_count = session.query(product.Product).count() products_in_store_count = session.query( product_in_store.ProductInStore).count() tasks_count = session.query(task.Task).count() assert products_count == 0 assert products_in_store_count == 0 assert tasks_count == 0