import pytest from requests.models import Response from unittest.mock import Mock from labelaudit.connectors import api_client as api_connector from labelaudit.lib.vapi.api_client import ApiClient from labelaudit.logic import audit_persistence from labelaudit.logic.result import Result from labelaudit.models.label_audit import LabelAudit audit_id = 123 vendor_id = 456 user_id = 789 audit_status = 'hunkydory' report_location = 'somewhere...' created_timestamp = '1901-10-04 11:04:22' updated_timestamp = '1904-04-29 00:01:37' @pytest.fixture def json_to_vapi(): return { 'auditStatus': audit_status, 'initiatedById': user_id, 'reportLocation': report_location, 'vendorId': vendor_id } @pytest.fixture def json_from_vapi(overrides={}): audit_data = { 'auditStatus': audit_status, 'createdTimestamp': created_timestamp, 'initiatedById': user_id, 'reportLocation': report_location, 'updatedTimestamp': updated_timestamp, 'vendorId': vendor_id, 'youtubeAuditId': audit_id} audit_data.update(overrides) return audit_data @pytest.fixture def label_audit(): audit = LabelAudit() audit.audit_status = audit_status audit.initiated_by_id = user_id audit.report_location = report_location audit.vendor_id = vendor_id return audit @pytest.fixture def vapi_client(monkeypatch): base_url = 'https://api.notreal.com' access_token = 'not-a-real-token-either' api_client = ApiClient(base_url, access_token) monkeypatch.setattr( api_connector, 'get_client', Mock(return_value=api_client)) return api_client @pytest.fixture def ok_result(monkeypatch, vapi_client, json_from_vapi): vapi_data = {'youtubeAudit': json_from_vapi} return fake_result(monkeypatch, vapi_client, 200, vapi_data) @pytest.fixture def ok_multi_results(): return { 'pagination': {'limit': 100, 'offset': 0, 'totalRecords': 2}, 'sort': {'sortBy': None, 'sortOrder': None}, 'youtubeAudits': [ {'auditStatus': 'sample', 'initiatedById': None, 'reportLocation': None, 'updatedTimestamp': '2015-06-03 14:19:33', 'vendorId': '2222222222', 'youtubeAuditId': '2'}, {'auditStatus': 'another_sample', 'initiatedById': None, 'reportLocation': None, 'updatedTimestamp': '2015-06-03 14:19:34', 'vendorId': '9999999', 'youtubeAuditId': '3'}]} @pytest.fixture def vapi_fault(): return {'fault': {'foo': 'is invalid', 'bar': 'is invalid too'}} @pytest.fixture def ok_update_params(): return { 'auditStatus': 'generating', 'initiatedById': 888, 'vendorId': 5} @pytest.fixture def bad_update_params(): return { 'auditStatus': 'generating', 'initiatedById': 888, 'randomWrongness': 'some string', 'vendorId': 5, 'anotherFake': 'fake'} def fake_result(monkeypatch, vapi_client, vapi_status, vapi_json={}): vapi_response = Response() vapi_response.status_code = vapi_status monkeypatch.setattr(vapi_response, 'json', Mock(return_value=vapi_json)) monkeypatch.setattr(vapi_client, 'get', Mock(return_value=vapi_response)) return audit_persistence.fetch(audit_id) def test_fetch_data_on_success(ok_result, json_from_vapi): audit = ok_result.message assert audit.get('auditStatus') == audit_status assert audit.get('createdTimestamp') == created_timestamp assert audit.get('initiatedById') == user_id assert audit.get('reportLocation') == report_location assert audit.get('updatedTimestamp') == updated_timestamp assert audit.get('vendorId') == vendor_id assert audit.get('youtubeAuditId') == audit_id assert len(audit) == 7 def test_fetch_status_on_failure(monkeypatch, vapi_client): result = fake_result(monkeypatch, vapi_client, 500) assert result.status == 500 def test_fetch_error_on_failure(monkeypatch, vapi_client): error = 'something blew up' vapi_data = {'fault': error} result = fake_result(monkeypatch, vapi_client, 500, vapi_data) assert result.errors == error def test_persist_posts_new_audit(monkeypatch, vapi_client, label_audit, json_to_vapi): label_audit.youtube_audit_id = None response = Response() response.status_code = 201 monkeypatch.setattr(response, 'json', Mock(return_value={})) monkeypatch.setattr(vapi_client, 'request', Mock(return_value=response)) audit_persistence.persist(label_audit) vapi_client.request.assert_called_with( 'post', 'youtubeaudit', json=json_to_vapi) def test_persist_puts_updated_audit(monkeypatch, vapi_client, label_audit, json_to_vapi): label_audit.youtube_audit_id = audit_id response = Response() response.status_code = 200 monkeypatch.setattr(response, 'json', Mock(return_value={})) monkeypatch.setattr(vapi_client, 'request', Mock(return_value=response)) audit_persistence.persist(label_audit) vapi_client.request.assert_called_with( 'put', 'youtubeaudit/' + str(audit_id), json=json_to_vapi) def test_persist_status_on_failure(monkeypatch, vapi_client, label_audit): response = Response() response.status_code = 400 monkeypatch.setattr(response, 'json', Mock(return_value={})) monkeypatch.setattr(vapi_client, 'request', Mock(return_value=response)) result = audit_persistence.persist(label_audit) assert result.status == 400 def test_persist_error_on_failure(monkeypatch, vapi_client, label_audit): response = Response() response.status_code = 400 response_body = {'fault': {'foo': 'is invalid', 'bar': 'is invalid too'}} monkeypatch.setattr(response, 'json', Mock(return_value=response_body)) monkeypatch.setattr(vapi_client, 'request', Mock(return_value=response)) result = audit_persistence.persist(label_audit) assert result.errors == response_body['fault'] def test_success_response_format_on_fetch_all( monkeypatch, vapi_client, ok_multi_results): response = Response() response.status_code = 200 monkeypatch.setattr(vapi_client, 'request', Mock(return_value=response)) monkeypatch.setattr(Response, 'json', Mock(return_value=ok_multi_results)) fake_params = {'a': 'a', 'b': 'b'} results = audit_persistence.fetch_all(**fake_params) assert results.message['total_reports'] == 2 assert results.message['reports'] == ok_multi_results['youtubeAudits'] def test_error_response_format_on_fetch_all( monkeypatch, vapi_client, vapi_fault): response = Response() response.status_code = 400 monkeypatch.setattr(vapi_client, 'request', Mock(return_value=response)) monkeypatch.setattr(Response, 'json', Mock(return_value=vapi_fault)) fake_params = {'a': 'a', 'b': 'b'} results = audit_persistence.fetch_all(**fake_params) assert results.message is None assert results.errors == vapi_fault['fault'] def test_fetch_all_exception_on_500(monkeypatch, vapi_client): response = Response() response.status_code = 500 fake_vapi_body = '{"foo": "bar"}' monkeypatch.setattr(vapi_client, 'request', Mock(return_value=response)) monkeypatch.setattr(Response, 'text', fake_vapi_body) with pytest.raises(AssertionError): audit_persistence.fetch_all() def test_validate_good_update_fields(json_to_vapi): res = audit_persistence.validate_fields(json_to_vapi) assert res is None def test_validate_bad_update_fields(bad_update_params): res = audit_persistence.validate_fields(bad_update_params) assert res == { 'anotherFake': 'Invalid Field Name', 'randomWrongness': 'Invalid Field Name'} @pytest.mark.parametrize('json_from_vapi', [('ok_update_params')], indirect=['json_from_vapi']) def test_success_response_format_on_update( monkeypatch, vapi_client, ok_update_params, json_from_vapi): """Mocked success response from vapi will return proper Result obj. Mock vapi raw return value and make sure it is processed properly and put into the correct result format (Result obj) """ response = Response() response.status_code = 200 monkeypatch.setattr(vapi_client, 'request', Mock(return_value=response)) vapi_audit = json_from_vapi vapi_body = {'youtubeAudit': vapi_audit} monkeypatch.setattr(Response, 'json', Mock(return_value=vapi_body)) results = audit_persistence.update(3, ok_update_params) assert results.status == 200 assert results.message == vapi_audit assert results.errors == {} def test_error_response_from_vapi_on_update( monkeypatch, vapi_client, vapi_fault, ok_update_params): """Mocked error response from vapi will return proper Result obj.""" response = Response() response.status_code = 400 monkeypatch.setattr(vapi_client, 'request', Mock(return_value=response)) monkeypatch.setattr(Response, 'json', Mock(return_value=vapi_fault)) results = audit_persistence.update(3, ok_update_params) assert results.status == 400 assert results.errors == vapi_fault['fault'] assert results.message is None def test_error_response_from_validation_on_update( monkeypatch, vapi_client, bad_update_params): """Test validation fails method before vapi is called.""" monkeypatch.setattr(vapi_client, 'request', Mock(return_value={})) audit_persistence.update(3, bad_update_params) assert not vapi_client.request.called def test_update_report_status_false_on_vapi_error(monkeypatch): result = Result(errors={'some': 'error'}) monkeypatch.setattr(audit_persistence, 'update', Mock(return_value=result)) res = audit_persistence.update_report_status(5, 'generating') assert res is False def test_update_report_status_true_on_vapi_success(monkeypatch): result = Result(errors={}) monkeypatch.setattr(audit_persistence, 'update', Mock(return_value=result)) res = audit_persistence.update_report_status(5, 'generating') assert res is True