"""Tests for produce_job_messages API endpoint.""" import datetime import json from unittest import mock from oto import response from oto import status as oto_status import pytest from availability import utils as avail_utils from availability.connectors import sql from availability.constants import models from availability.models import product_in_store from availability.models import store from tests import utils @pytest.fixture def itunes_product(): """Create iTunes product suitable for polling.""" received_date = datetime.datetime.today() - datetime.timedelta(days=10) sales_start_date = datetime.datetime.today() + datetime.timedelta(days=10) product = { 'product_id': 1, 'orchard_product_id': 1, 'upc': '123456789012', 'itunes_vendor_id': '01', 'provider': 'orchard', 'store_id': 1, 'status': 'delivered', 'store_internal_status': 'test', 'store_internal_id': 'test', 'received_for_polling_date': received_date.strftime( models.ISO8601_DATE_FORMAT), 'sales_start_date': sales_start_date.strftime( models.ISO8601_DATE_FORMAT), } return {'products': [product]} @pytest.mark.parametrize( 'store_exist_response, put_product_to_queue_response, ' 'reset_stuck_tasks_response, current_date_override_str, expected_status', [ ( response.Response(), response.Response(), response.Response(), None, 200, ), ( response.Response(), response.Response(), response.Response(), '1985-04-12T23:20:50.52Z', 200, ), ( response.create_not_found_response('foo'), response.Response(), response.Response(), None, 404, ), ( response.Response(), response.create_fatal_response('foo'), response.Response(), None, 500, ), ( response.Response(), response.Response(), response.create_fatal_response('foo'), None, 500, ), ] ) def test_produce_job_messages( store_exist_response, put_product_to_queue_response, reset_stuck_tasks_response, client, mocker, expected_status, current_date_override_str): """Test endpoint that produces polling job messages.""" uuid4 = 'd1296fc7-719c-4b5e-9794-795d922f8086' store_id = '1' if current_date_override_str is not None: current_date_override = avail_utils.to_datetime( current_date_override_str) else: current_date_override = None mock_model = mocker.patch('availability.handlers.store') mock_model.get_store_by_id.return_value = store_exist_response mock_logic = mocker.patch('availability.handlers.producer') mock_logic.put_products_to_poll_messages_to_queue.return_value = ( put_product_to_queue_response) mock_task_logic = mocker.patch('availability.handlers.task') mock_task_logic.reset_stuck_tasks.return_value = reset_stuck_tasks_response mock_uuid = mocker.patch('availability.handlers.uuid') mock_uuid.uuid4.return_value = uuid4 server_response = client.post( '/admin/produce-job-messages/{}'.format(store_id), data=dict(current_date_override=current_date_override_str)) assert server_response assert server_response.status_code == expected_status if server_response.status_code < 400: mock_logic.put_products_to_poll_messages_to_queue.assert_called_with( store_id=store_id, correlation_id=uuid4, current_date_override=current_date_override, ) mock_task_logic.reset_stuck_tasks.assert_called_with( store_id, current_date_override=current_date_override, ) def test_product_job_messages_generates_correlation_id( test_database, mocker, client, itunes_product): """Assert Correlation-Id will be generated when not provided.""" with sql.session_scope() as session: itunes_store = store.Store( store_id=1, name='itunes', polling_delay_days=1, poll_days_after_sales=1) session.add(itunes_store) creation_response = client.post( '/admin/products', data=json.dumps(itunes_product), content_type='application/json') assert creation_response.status_code == oto_status.NO_CONTENT # Set the field we are not allowed to pass via API. received_for_polling_date = datetime.datetime.strptime( itunes_product['products'][0]['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}) mocker.patch( 'availability.handlers.ownership.check_products_ownership', return_value=True) carveouts_response = mock.MagicMock( status_code=oto_status.OK, content=json.dumps({})) mocker.patch( 'availability.logic.countries.request.get', return_value=carveouts_response) with utils.mock_availability_queue() as queue: mocker.patch( 'availability.logic.queue.producer.utils.get_availability_queue', return_value=queue) messages_response = client.post('/admin/produce-job-messages/1') assert messages_response.status_code == oto_status.OK received_messages = queue.receive_messages() assert len(received_messages) == 1 message = received_messages[0] assert message.queue_url == 'https://sqs.us-east-1.amazonaws.com/123456789012/test-queue' @pytest.mark.parametrize( 'invalid_id', [2, 'test', {}, (), [], '', '/']) def test_produce_job_messages_with_invalid_store_id(client, invalid_id): """Assert can determine invalid store id.""" response = client.post('/admin/produce-job-messages/{}'.format(invalid_id)) assert response.status_code == oto_status.NOT_FOUND