"""Tests for ows-account model.""" import json from unittest.mock import MagicMock from owsrequest import request import pytest import requests import sentry_sdk from artist import api from artist import response from artist.connectors import sentry from artist.models import account TEAPOT_STATUS = 418 TEAPOT_BODY = '{"height": "short", "width": "stout"}' @pytest.fixture def subaccount_id(): """Test subaccount id.""" return 48 def test_vendor_id_success(subaccount_id, mocker, context, headers): """Test successfully getting a subaccount vendor id from ows-account.""" with context, api.app.test_request_context(headers=headers): mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value={'vendor_id': 7123}) mocker.patch.object(request, 'get', return_value=mock_response) result = account.get_vendor_id_for_subaccount_id(subaccount_id) assert result.status == 200 assert result.message == 7123 def test_vendor_id_subaccount_not_found( subaccount_id, mocker, context, headers): """Test getting a 404 from ows-account for the given subaccount.""" with context, api.app.test_request_context(headers=headers): mock_response = MagicMock(status_code=404) mocker.patch.object(request, 'get', return_value=mock_response) result = account.get_vendor_id_for_subaccount_id(subaccount_id) assert result.status == 404 assert result.message is None assert result.errors == { 'code': response.ERROR_CODE_NOT_FOUND, 'message': 'subaccount not found'} def test_vendor_id_error(context, subaccount_id, headers, mocker): """Test handling an unsuccessful call for vendor id from ows-account.""" with context, api.app.test_request_context(headers=headers): mock_response = MagicMock(status_code=500) mock_response.text = 'some error' mocker.patch.object(request, 'get', return_value=mock_response) result = account.get_vendor_id_for_subaccount_id(subaccount_id) assert result.status == 500 assert result.message is None assert result.errors == { 'code': response.ERROR_CODE_INTERNAL_ERROR, 'message': 'ows-account returned 500 status with body some error'} def test_vendor_id_error_logging(context, mocker, monkeypatch, subaccount_id, headers): """Test that account model logs unexpected response from ows-account.""" with context, api.app.test_request_context(headers=headers): mock_response = MagicMock(status_code=TEAPOT_STATUS) mock_response.text = TEAPOT_BODY mocker.patch.object(request, 'get', return_value=mock_response) mocker.spy(context.g.ows.log, 'error') monkeypatch.setattr(account, 'capture_message', MagicMock()) account.get_vendor_id_for_subaccount_id(subaccount_id) expected_message = 'ows-account returned {} status with body {}'.format( TEAPOT_STATUS, TEAPOT_BODY) context.g.ows.log.error.assert_called_with(expected_message) account.capture_message.assert_called_with(expected_message) def test_vendor_id_missing_status(context, subaccount_id, mocker, headers): """Test that the account model returns an error. Should happen if ows-account returns a successful response with no vendor_id property in the body. """ with context, api.app.test_request_context(headers=headers): mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value={}) mocker.patch.object(request, 'get', return_value=mock_response) result = account.get_vendor_id_for_subaccount_id(subaccount_id) assert result.status == 500 assert result.message is None assert result.errors == { 'code': response.ERROR_CODE_INTERNAL_ERROR, 'message': account.VENDOR_ID_MISSING_MESSAGE } def test_vendor_id_missing_logging(context, mocker, monkeypatch, subaccount_id, headers): """Test logging for missing vendor. Test that the account model logs when it receives a successful response from ows-account with no vendor_id property in the body. """ with context, api.app.test_request_context(headers=headers): mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value={}) mocker.patch.object(request, 'get', return_value=mock_response) mocker.spy(context.g.ows.log, 'error') monkeypatch.setattr(account, 'capture_message', MagicMock()) account.get_vendor_id_for_subaccount_id(subaccount_id) context.g.ows.log.error.assert_called_with( account.VENDOR_ID_MISSING_MESSAGE) account.capture_message.assert_called_with( account.VENDOR_ID_MISSING_MESSAGE) def test_get_subaccount_success(mocker, subaccount_id): """Test get_subaccount success.""" expected_response = { 'vendor_id': 100, 'subaccount_id': subaccount_id, 'subaccount_name': 'Columbia Records', 'description': 'Yeee Haw!', 'country_id': '889', } ows_account_response = requests.Response() ows_account_response.status_code = 200 ows_account_response._content = json.dumps(expected_response).encode() mocker.patch.object( request, 'get', return_value=ows_account_response, autospec=True) subaccount = account.get_subaccount(subaccount_id) assert subaccount.status == 200 assert subaccount.message['vendor_id'] == expected_response['vendor_id'] assert subaccount.message['subaccount_id'] == ( expected_response['subaccount_id']) def test_get_subaccount_error_logging(context, mocker, monkeypatch, subaccount_id, headers): """Test that account model logs unexpected response from ows-account.""" with context, api.app.test_request_context(headers=headers): mock_response = MagicMock(status_code=TEAPOT_STATUS) mock_response.text = TEAPOT_BODY mocker.patch.object(request, 'get', return_value=mock_response) mocker.spy(context.g.ows.log, 'error') monkeypatch.setattr(account, 'capture_message', MagicMock()) account.get_subaccount(subaccount_id) expected_message = 'ows-account returned {} status with body {}'.format( TEAPOT_STATUS, TEAPOT_BODY) context.g.ows.log.error.assert_called_with(expected_message) account.capture_message.assert_called_with(expected_message)