"""Functional test for POST /admin/products endpoint.""" from datetime import datetime from datetime import timedelta import itertools import json from availability.connectors import sql from availability.constants import models from availability.constants import stores from availability.models import product from availability.models import product_in_store from availability.models import task UPC = 'UPC-string' ORCHARD_PRODUCT_ID = 1 PRODUCT_ID = 1 STORE_ID = stores.STORE_ID_ITUNES PROVIDER = models.ORCHARD ITUNES_VENDOR_ID = '1' DELIVERY_DATE = datetime.utcnow().strftime(models.ISO8601_DATE_FORMAT) FORCE_POLLING = False SALES_START_DATE = ( (datetime.utcnow() + timedelta(days=1)).strftime( models.ISO8601_DATE_FORMAT)) def _get_product_sample(**update): product_sample = { 'upc': UPC, 'orchard_product_id': ORCHARD_PRODUCT_ID, 'product_id': PRODUCT_ID, 'store_id': STORE_ID, 'provider': PROVIDER, 'itunes_vendor_id': ITUNES_VENDOR_ID, 'delivery_date': DELIVERY_DATE, 'force_polling': FORCE_POLLING, 'sales_start_date': SALES_START_DATE, } product_sample.update(update) return product_sample def test_product_created(test_database, client): """Test that product all product related records are created in DB.""" product_ids = {1, 2} store_ids = set(stores.STORE_IDS) orchard_product_id_offset = 42 products = [] for product_id, store_id in itertools.product(product_ids, store_ids): products.append(_get_product_sample( product_id=product_id, store_id=store_id, orchard_product_id=product_id + orchard_product_id_offset, itunes_vendor_id=ITUNES_VENDOR_ID + str(product_id))) data = { 'products': products } response = client.post( '/admin/products', data=json.dumps(data), content_type='application/json') assert response.status_code == 204 with sql.session_scope() as session: res_products = session.query(product.Product).all() res_store_products = session.query( product_in_store.ProductInStore).all() res_tasks = session.query(task.Task).all() assert len(res_products) == len(product_ids) assert len(res_store_products) == len(product_ids) * len(store_ids) assert len(res_tasks) == len(product_ids) * len(store_ids) for res_product in res_products: current_id = res_product.product_id assert current_id in product_ids assert ( res_product.orchard_product_id == current_id + orchard_product_id_offset) assert res_product.upc == UPC assert ( res_product.itunes_vendor_id == ITUNES_VENDOR_ID + str(current_id)) assert res_product.provider == PROVIDER for res_store_product in res_store_products: assert res_store_product.store_id in store_ids assert res_store_product.product_id in product_ids assert res_store_product.store_internal_id == '' assert res_store_product.force_polling is FORCE_POLLING assert res_store_product.status == models.RELEASE_STATUS_DELIVERED assert res_store_product.store_internal_status == '' assert ( res_store_product.delivery_date == datetime.strptime(DELIVERY_DATE, models.ISO8601_DATE_FORMAT)) assert ( res_store_product.sales_start_date == datetime.strptime(SALES_START_DATE, models.ISO8601_DATE_FORMAT)) assert res_store_product.countries == [] assert res_store_product.go_live_date is None def test_second_submission_is_ignored(test_database, client): """Test that second submission of product is ignored.""" store_ids = set(stores.STORE_IDS) products = [_get_product_sample(store_id=s_id) for s_id in store_ids] data = { 'products': products } response = client.post( '/admin/products', data=json.dumps(data), content_type='application/json') assert response.status_code == 204 with sql.session_scope() as session: res_products = session.query(product.Product).all() res_store_products = session.query( product_in_store.ProductInStore).all() res_tasks = session.query(task.Task).all() assert len(res_products) == 1 assert len(res_store_products) == len(store_ids) assert len(res_tasks) == len(store_ids) the_same_products = [] for store_id in store_ids: now = datetime.utcnow() the_same_products.append(_get_product_sample( store_id=store_id, upc='not the same UPC', orchard_product_id=ORCHARD_PRODUCT_ID+42, provider=next(p for p in models.PROVIDERS_ENUM if p and p != PROVIDER), itunes_vendor_id='2', delivery_date=now.strftime(models.ISO8601_DATE_FORMAT), force_polling=FORCE_POLLING, sales_start_date=now.strftime(models.ISO8601_DATE_FORMAT))) data = { 'products': the_same_products } response = client.post( '/admin/products', data=json.dumps(data), content_type='application/json') assert response.status_code == 204 with sql.session_scope() as session: res_products = session.query(product.Product).all() res_store_products = session.query( product_in_store.ProductInStore).all() res_tasks = session.query(task.Task).all() assert len(res_products) == 1 assert len(res_store_products) == len(store_ids) assert len(res_tasks) == len(store_ids) for res_product in res_products: assert res_product.product_id == PRODUCT_ID assert res_product.orchard_product_id == ORCHARD_PRODUCT_ID assert res_product.upc == UPC assert res_product.itunes_vendor_id == ITUNES_VENDOR_ID assert res_product.provider == PROVIDER for res_store_product in res_store_products: assert res_store_product.store_id in store_ids assert res_store_product.product_id == PRODUCT_ID assert res_store_product.store_internal_id == '' assert res_store_product.force_polling is FORCE_POLLING assert res_store_product.status == models.RELEASE_STATUS_DELIVERED assert res_store_product.store_internal_status == '' assert ( res_store_product.delivery_date == datetime.strptime(DELIVERY_DATE, models.ISO8601_DATE_FORMAT)) assert ( res_store_product.sales_start_date == datetime.strptime(SALES_START_DATE, models.ISO8601_DATE_FORMAT)) assert res_store_product.countries == [] assert res_store_product.go_live_date is None def test_submission_of_duplicate_not_ignored_if_force_polling_set( test_database, client): """Assert can set force polling flag for duplicate product.""" data = {'products': [_get_product_sample()]} creation_response = client.post( '/admin/products', data=json.dumps(data), content_type='application/json') assert creation_response.status_code == 204, creation_response.data data['products'][0]['force_polling'] = True force_polling_response = client.post( '/admin/products', data=json.dumps(data), content_type='application/json') assert force_polling_response.status_code == 204 with sql.session_scope() as session: product = session.query(product_in_store.ProductInStore).first() assert product.force_polling is True