"""Tests for Handlers.""" import json from unittest.mock import MagicMock from unittest.mock import Mock from unittest.mock import patch import flask from oto import response import pytest from content_review import api from content_review import handlers from content_review.constants import error from content_review.constants import field_const from content_review.validation import validation from content_review.validation.schema import post_mena_products from content_review.validation.schema import put_mena_products @pytest.fixture def fixture_client(): """Create an api test client fixture.""" return api.app.test_client() @pytest.fixture def fixture_ok_response(): """Create a response.Response fixture for generic ok.""" return response.Response(error.SUCCESS_CODE) @pytest.fixture def fixture_error_response(): """Create a response.Response fixture for generic error.""" return response.create_error_response( code='error_code', message='error_message') @pytest.fixture def fixture_error_not_found_response(): """Create a response.Response fixture for generic error.""" return response.create_not_found_response(message='error_message') @pytest.fixture def get_status_success(): """Create a response.Response fixture for get_status success.""" payload = [{ 'product_id': 1, 'review_status': 'Pending', 'review_timestamp': '2017-09-27 22:47:23', 'created_timestamp': '2017-09-27 22:47:23' }] return response.Response(payload) @patch( 'content_review.logic.product.create_default_status', return_value=fixture_ok_response()) def test_handler_create_product_review_status_success( mock_prod, fixture_client): """Test POST /mena/products handler success state on insert.""" mock_data = {'product_ids': [1, 2, 3, 4, 5]} result = fixture_client.post('/mena/products', data=json.dumps(mock_data)) assert result.status_code == 200 mock_prod.assert_called_with('mena', mock_data['product_ids']) def test_handler_create_product_review_status_failure(fixture_client): """Test POST /mena/products handler failure state on insert.""" request = Mock() mock_data = {'product_ids': [1, 2, 1]} request.get_json = MagicMock(return_value=mock_data) @validation.validate_body(request, post_mena_products.schema) def fn(): pass resp = fn() assert flask.Response == type(resp) response_json = json.loads(resp.data.decode()) assert 400 == resp.status_code assert error.BODY_VALIDATION_ERROR == response_json[field_const.CODE] assert 'has non-unique elements' in response_json[field_const.MESSAGE] @patch( 'content_review.logic.product.update_status', return_value=fixture_ok_response()) def test_handler_update_product_review_status_success( mock_prod, fixture_client): """Test PUT /mena/products handler success state on upsert.""" mock_data = [{ 'product_id': 1, 'review_timestamp': '2017-08-15 11:26:19', 'review_status': 'Approved' }] result = fixture_client.put('/mena/products', data=json.dumps(mock_data)) assert result.status_code == 200 mock_prod.assert_called_with('mena', mock_data) def test_handler_update_product_review_status_failure(fixture_client): """Test PUT /mena/products handler failure state on upsert.""" request = Mock() bad_date = '201-08-15 11:26:19' mock_data = [{ 'product_id': 1, 'review_timestamp': bad_date, 'review_status': 'Approved' }] request.get_json = MagicMock(return_value=mock_data) @validation.validate_body(request, put_mena_products.schema) def fn(): pass resp = fn() assert flask.Response == type(resp) response_json = json.loads(resp.data.decode()) assert 400 == resp.status_code assert error.BODY_VALIDATION_ERROR == response_json[field_const.CODE] assert "'{}' does not match".format( bad_date ) in response_json[field_const.MESSAGE] @patch( 'content_review.logic.product.get_status', return_value=get_status_success()) def test_handler_get_product_review_status_success( mock_get_status_success, fixture_client): """Test GET /mena/products/{product_id} handler success state.""" mock_response_payload = [{ 'product_id': 1, 'review_status': 'Pending', 'review_timestamp': '2017-09-27 22:47:23', 'created_timestamp': '2017-09-27 22:47:23' }] result = fixture_client.get('/mena/products/1?page_offset=0&page_limit=10') response_message = json.loads(result.data.decode()) assert result.status_code == 200 assert response_message == mock_response_payload mock_get_status_success.assert_called_with( 'mena', 1, '0', '10') @patch( 'content_review.logic.product.get_status', return_value=get_status_success()) def test_handler_get_product_review_status_success_no_pages( mock_get_status_success, fixture_client): """Test GET /mena/products/{product_id} handler success state no pages.""" mock_response_payload = [{ 'product_id': 1, 'review_status': 'Pending', 'review_timestamp': '2017-09-27 22:47:23', 'created_timestamp': '2017-09-27 22:47:23' }] result = fixture_client.get('/mena/products/1') response_message = json.loads(result.data.decode()) assert result.status_code == 200 assert response_message == mock_response_payload mock_get_status_success.assert_called_with( 'mena', 1, None, None) @patch( 'content_review.logic.product.get_status', return_value=fixture_error_not_found_response()) def test_handler_get_product_review_status_using_string( mock_get_status_not_found, fixture_client): """Test GET /mena/products/{product_id} handler with bad request.""" result = fixture_client.get('/mena/products/something') assert result.status_code == 404 @patch( 'content_review.logic.product.get_status', return_value=fixture_error_not_found_response()) def test_handler_get_product_review_status_using_bad_product_id( mock_get_status_not_found, fixture_client): """Test GET /mena/products/{product_id} handler with no found product.""" result = fixture_client.get('/mena/products/9090') assert result.status_code == 404 @patch('content_review.handlers.g') def test_exception_handler(mock_g): """Verify exception_Handler returns 500 status code and json payload.""" message = ( 'The server encountered an internal error ' 'and was unable to complete your request.') mock_error = MagicMock() server_response = handlers.exception_handler(mock_error) mock_g.log.exception.assert_called_with(mock_error) # assert status code is 500 assert server_response.status_code == 500 # assert json payload response_message = json.loads(server_response.data.decode()) assert response_message['message'] == message assert response_message['code'] == response.error.ERROR_CODE_INTERNAL_ERROR