"""Functional test for POST /admin/produce-job-messages/{store-id} endpoint.""" import datetime import json import flask from oto import status as oto_status import pytest import requests from availability.connectors import redis from availability.connectors import sql from availability.connectors.sqs import JSONMessageExt from availability.constants import error from availability.constants import models from availability.constants import stores from availability.logic import product_submission from availability.models import product_in_store from availability.models import store as store_model from tests import utils ALL_COUNTRIES = ['foo', 'bar', 'baz'] LIVE_COUNTRIES = ['foo'] CARVEOUTS_COUNTRIES = ['bar'] def setup_function(): """Flush redis cache.""" redis.redis_client.flushall() def _get_product_data(store_id, force_polling=False): # pragma: no cover data = { 'product_id': 1, 'orchard_product_id': 1, 'upc': '123456789012', 'itunes_vendor_id': '01', 'provider': 'orchard', 'store_id': store_id, 'status': 'delivered', 'store_internal_status': 'test', 'store_internal_id': 'test', 'received_for_polling_date': '2017-01-01T19:52:22Z', 'delivery_date': '2017-01-01T19:52:22Z', 'sales_start_date': '2017-01-01T19:52:22Z', 'countries': ['USA', 'UK'], 'go_live_date': '2017-01-01T19:52:22Z' } if not force_polling: data['sales_start_date'] = datetime.datetime.now().strftime( models.ISO8601_DATE_FORMAT) data['force_polling'] = False else: data['received_for_polling_date'] = ( datetime.datetime.now() + datetime.timedelta(days=1)).strftime( models.ISO8601_DATE_FORMAT) data['force_polling'] = True return data def test_product_job_messages_validates_store_id(client): """Assert only existing store id is accepted.""" response = client.post( '/admin/produce-job-messages/1234567890', headers={'Correlation-Id': 'foo'} ) response_data = json.loads(response.data.decode()) assert response.status_code == oto_status.NOT_FOUND assert response_data['message'] == error.ERROR_MESSAGE_STORE_NOT_FOUND @pytest.mark.parametrize( 'store_id, force_polling', ( (stores.STORE_ID_ITUNES, False), (stores.STORE_ID_SPOTIFY, False), (stores.STORE_ID_ITUNES, True), (stores.STORE_ID_SPOTIFY, True), ) ) def test_produce_job_messages( test_database, client, mocker, store_id, force_polling): """Assert message created and put to queue.""" product = _get_product_data(store_id, force_polling=force_polling) # adjust date to fall into limits of # latest_valid_for_polling_after_sales_date # in product_in_store.get_products_to_poll_query with sql.session_scope() as session: store = store_model.Store( store_id=store_id, name='test', polling_delay_days=1, poll_days_after_sales=1) session.add(store) tomorrow = datetime.datetime.utcnow() + datetime.timedelta(days=1) product['sales_start_date'] = tomorrow.strftime(models.ISO8601_DATE_FORMAT) product_response = product_submission.submit_to_poll([product]) assert product_response.status == 204, 'Failed to create products' with sql.session_scope() as session: product_in_store_obj = session.query( product_in_store.ProductInStore).first() product_in_store_obj.countries = LIVE_COUNTRIES session.add(product_in_store_obj) # Set the field we are not allowed to pass via API. received_for_polling_date = datetime.datetime.strptime( product['received_for_polling_date'], models.ISO8601_DATE_FORMAT) with sql.session_scope() as session: session.query(product_in_store.ProductInStore).filter_by( product_in_store_id=1).update( {'received_for_polling_date': received_for_polling_date}) expected_message = { 'upc': product['upc'], 'task_id': 1, # the only task id we should have in test db 'product_in_store_id': 1, # the only id we should have in test db 'orchard_product_id': product['orchard_product_id'], 'store_id': product['store_id'], 'countries': utils.get_expected_countries( store_id=store_id, all_countries=ALL_COUNTRIES, carveouts_countries=CARVEOUTS_COUNTRIES, live_countries=LIVE_COUNTRIES, ) } carveouts_countries = {i: c for i, c in enumerate(CARVEOUTS_COUNTRIES)} carveouts_response = requests.Response() carveouts_response.status_code = oto_status.OK carveouts_response._content = json.dumps( carveouts_countries).encode('latin_1') mocker.patch( 'availability.logic.countries.request.get', return_value=carveouts_response) mocker.patch( 'availability.logic.countries.all_countries_ordered', ALL_COUNTRIES) with utils.mock_availability_queue() as queue: mocker.patch( 'availability.logic.queue.producer.utils.get_availability_queue', return_value=queue) response = client.post( '/admin/produce-job-messages/{}'.format(store_id), headers={'Correlation-Id': 'foo'}) assert isinstance(response, flask.Response) assert response.status_code == oto_status.OK received_messages = queue.receive_messages() assert len(received_messages) == 1 message = JSONMessageExt(received_messages[0]) assert message.get_body() == expected_message