"""Test consumer works with Spotify store correctly.""" from datetime import datetime import json import os import pytest from availability.connectors import sql from availability.constants import models from availability.constants import stores from availability.logic.queue import consumer from availability.models import product_in_store from availability.models import store from availability.models import task from availability.models import task_log FIXTURES_DIR = 'tests/files/spotify' FIXTURE_LIVE = 'spotify_available_markets.json' FIXTURE_MARKETS_ABSENT = 'spotify_available_markets_absent.json' FIXTURE_MARKETS_EMPTY = 'spotify_available_markets_empty.json' FIXTURE_NO_RELEASE = 'spotify_no_match.json' UPC = 'UPC string' TASK_ID = 1 PRODUCT_IN_STORE_ID = 1 PRODUCT_ID = 1 STORE_ID = stores.STORE_ID_SPOTIFY SQS_MESSAGE = { 'upc': UPC, 'task_id': TASK_ID, 'product_in_store_id': PRODUCT_IN_STORE_ID, 'orchard_product_id': 1, 'store_id': STORE_ID, 'countries': ['USA', 'UK'] } def _get_fixture_content(filename): with open(os.path.join(FIXTURES_DIR, filename)) as f: return json.load(f) def _create_records(): store_obj = store.Store( store_id=STORE_ID, name='spotify', polling_delay_days=0, poll_days_after_sales=7) product_in_store_obj = product_in_store.ProductInStore( product_in_store_id=PRODUCT_IN_STORE_ID, product_id=PRODUCT_ID, store_id=STORE_ID, status=models.RELEASE_STATUS_DELIVERED, sales_start_date=datetime.utcnow(), store_internal_id='', store_internal_status='') task_obj = task.Task( task_id=TASK_ID, product_in_store_id=PRODUCT_IN_STORE_ID, status=models.TASK_STATUS_IN_QUEUE) with sql.session_scope() as session: session.add(store_obj) session.add(product_in_store_obj) session.add(task_obj) def test_consumer_process_correct_response(mocker, test_database): """Test that correct response is processed.""" _create_records() fixture = _get_fixture_content(FIXTURE_LIVE) store_internal_id = fixture['albums']['items'][0]['id'] countries = fixture['albums']['items'][0]['available_markets'] spotipy_mock = mocker.patch( 'availability.logic.queue.consumer.polling.spotify.spotify.spotipy') spotipy_mock.Spotify().search.return_value = fixture consumer.process_single_message(SQS_MESSAGE) with sql.session_scope() as session: store_product = session.query(product_in_store.ProductInStore).first() assert store_product.status == models.RELEASE_STATUS_LIVE assert store_product.store_internal_id == store_internal_id assert store_product.countries == countries assert store_product.go_live_date <= datetime.utcnow() task_obj = session.query(task.Task).first() assert task_obj.last_change_date <= datetime.utcnow() assert task_obj.status == models.TASK_STATUS_OK logs = session.query(task_log.TaskLog).all() assert len(logs) == 0 @pytest.mark.parametrize( 'fixture', [FIXTURE_MARKETS_ABSENT, FIXTURE_MARKETS_EMPTY]) def test_consumer_process_correct_response_no_markets( fixture, mocker, test_database): """Test that correct response with missing empty countries is processed.""" _create_records() fixture = _get_fixture_content(fixture) store_internal_id = fixture['albums']['items'][0]['id'] spotipy_mock = mocker.patch( 'availability.logic.queue.consumer.polling.spotify.spotify.spotipy') spotipy_mock.Spotify().search.return_value = fixture consumer.process_single_message(SQS_MESSAGE) with sql.session_scope() as session: store_product = session.query(product_in_store.ProductInStore).first() assert store_product.status == models.RELEASE_STATUS_LIVE assert store_product.store_internal_id == store_internal_id assert store_product.countries == [] assert store_product.go_live_date <= datetime.utcnow() task_obj = session.query(task.Task).first() assert task_obj.last_change_date <= datetime.utcnow() assert task_obj.status == models.TASK_STATUS_OK logs = session.query(task_log.TaskLog).all() assert len(logs) == 0 def test_consumer_process_correct_response_not_released(mocker, test_database): """Test that non-existing release is processed.""" _create_records() spotipy_mock = mocker.patch( 'availability.logic.queue.consumer.polling.spotify.spotify.spotipy') spotipy_mock.Spotify().search.return_value = _get_fixture_content( FIXTURE_NO_RELEASE) consumer.process_single_message(SQS_MESSAGE) with sql.session_scope() as session: store_product = session.query(product_in_store.ProductInStore).first() assert store_product.status == models.RELEASE_STATUS_DELIVERED assert store_product.store_internal_id == '' assert store_product.countries == [] assert store_product.go_live_date is None task_obj = session.query(task.Task).first() assert task_obj.last_change_date <= datetime.utcnow() assert task_obj.status == models.TASK_STATUS_OK logs = session.query(task_log.TaskLog).all() assert len(logs) == 0 def test_consumer_process_spotipy_exception(mocker, test_database): """Test that spotify error is handled.""" _create_records() spotipy_mock = mocker.patch( 'availability.logic.queue.consumer.polling.spotify.spotify.spotipy') spotipy_mock.Spotify().search.side_effect = Exception('Boom!') consumer.process_single_message(SQS_MESSAGE) with sql.session_scope() as session: store_product = session.query(product_in_store.ProductInStore).first() assert store_product.status == models.RELEASE_STATUS_DELIVERED assert store_product.store_internal_id == '' assert store_product.countries == [] assert store_product.go_live_date is None task_obj = session.query(task.Task).first() assert task_obj.last_change_date <= datetime.utcnow() assert task_obj.status == models.TASK_STATUS_FAILED logs = session.query(task_log.TaskLog).all() assert len(logs) == 1