"""Tests for Handlers.""" import json from unittest.mock import Mock import pydantic import pytest from flask.testing import FlaskClient from owsresponse import status as http_status from pytest_mock import MockerFixture from vectororder import ( exceptions, handlers, # noqa (imported for test client only) ) from vectororder.constants import header, jobs as jobs_constants from vectororder.logic.schemas import ( JobDeliveryXmlPayload, JobEligibility, JobIneligibilityReason, ) from vectororder.models.schemas import DeliveryType, EncodingOrderType from vectororder.schemas import jobs_status_schema pydantic_minor_version = ".".join(pydantic.__version__.split(".")[0:2]) def test_jobs_status_action_validation_error( fixture_client: FlaskClient, mocker: Mock ) -> None: """Test jobs status action endpoint validation error is propagated.""" message = "msg" headers = { header.CONTENT_TYPE: header.CONTENT_TYPE_JSON_VAL, "Orchard-User-Id": "oa:123", } handlers_utils_mock = mocker.patch("vectororder.handlers.jobs.handlers") parse_request_json_mock = mocker.Mock( side_effect=exceptions.RequestError(message=message) ) handlers_utils_mock.parse_request_json = parse_request_json_mock action_mock = mocker.patch("vectororder.logic.jobs.perform_status_action") result = fixture_client.put( "/jobs/status", headers=headers, data=json.dumps({"foo": 42}) ) res_data = json.loads(result.data.decode()) parse_request_json_mock.assert_called_with( schema=jobs_status_schema.JobsStatusPUTSchema ) assert action_mock.call_count == 0 assert result.status_code == 400 assert res_data["message"] == message def test_jobs_status_action_success(fixture_client: FlaskClient, mocker: Mock) -> None: """Test jobs status action endpoint successfully handles request.""" action = jobs_constants.JOBS_ACTIONS[0] job_ids = [1, 2] payload = { jobs_constants.FIELD_ACTION: action, jobs_constants.FIELD_JOB_IDS: job_ids, } headers = { header.CONTENT_TYPE: header.CONTENT_TYPE_JSON_VAL, "Orchard-User-Id": "oa:123", } handlers_utils_mock = mocker.patch("vectororder.handlers.jobs.handlers") parse_request_json_mock = mocker.Mock(return_value=payload) handlers_utils_mock.parse_request_json = parse_request_json_mock action_mock = mocker.patch("vectororder.logic.jobs.perform_status_action") action_mock.return_value = {} result = fixture_client.put( "/jobs/status", headers=headers, data=json.dumps(payload) ) parse_request_json_mock.assert_called_with( schema=jobs_status_schema.JobsStatusPUTSchema ) assert action_mock.call_count == 1 action_mock.assert_called_with(action=action, job_ids=job_ids) assert result.status_code == http_status.NO_CONTENT @pytest.mark.parametrize( "headers, status_code", ( ({}, 400), ({"Orchard-User-Id": ""}, 400), ({"Orchard-User-Id": "alw:123"}, 400), ), ) def test_jobs_status_action_for_non_oa_users( headers: dict[str, str], status_code: int, fixture_client: FlaskClient, ) -> None: """Test search endpoint for Non-OA users.""" result = fixture_client.put("/jobs/status", headers=headers) assert result.status_code == status_code def test_get_job_eligibility( fixture_client: FlaskClient, mocker: MockerFixture ) -> None: """Test get job eligibility endpoint success with eligible response.""" job_id = 123 get_job_eligibility_mock = mocker.patch( "vectororder.logic.jobs.get_job_eligibility", return_value=JobEligibility( is_eligible=True, reason=None, ), ) result = fixture_client.get(f"/jobs/{job_id}/eligibility") assert get_job_eligibility_mock.mock_calls == [ mocker.call(job_id), ] assert result.status_code == 200 assert result.get_json() == { "is_eligible": True, "reason": None, } def test_get_job_ineligible(fixture_client: FlaskClient, mocker: MockerFixture) -> None: """Test get job eligibility endpoint success with ineligible response.""" job_id = 123 get_job_eligibility_mock = mocker.patch( "vectororder.logic.jobs.get_job_eligibility", return_value=JobEligibility( is_eligible=False, reason=JobIneligibilityReason.NOT_HD, ), ) result = fixture_client.get(f"/jobs/{job_id}/eligibility") assert get_job_eligibility_mock.mock_calls == [ mocker.call(job_id), ] assert result.status_code == 200 assert result.get_json() == { "is_eligible": False, "reason": JobIneligibilityReason.NOT_HD.value, } def test_get_product_eligibility( fixture_client: FlaskClient, mocker: MockerFixture ) -> None: """Test product eligibility endpoint success.""" upc = 123456 store_id = 42 delivery_type = "complete_album" mock_get_eligibility = mocker.patch( "vectororder.logic.jobs.get_product_eligibility", return_value=JobEligibility( is_eligible=True, reason=None, ), ) url = f"/products/{upc}/eligibility" response = fixture_client.get( url, query_string={"store_id": store_id, "delivery_type": delivery_type} ) # Verify function was called with correct arguments assert mock_get_eligibility.mock_calls == [ mocker.call( upc, store_id, DeliveryType.COMPLETE_ALBUM, EncodingOrderType.RELEASE ) ] assert response.status_code == 200 assert response.get_json() == { "is_eligible": True, "reason": None, } def test_get_job_delivery_xml( fixture_client: FlaskClient, mocker: MockerFixture ) -> None: """Test delivery XML payload endpoint success.""" job_id = 123 mock_get_payload = mocker.patch( "vectororder.logic.jobs.get_job_delivery_xml_payload", return_value=JobDeliveryXmlPayload( presigned_link="https://my-bucket.s3.amazonaws.com/test/file.jpg", ), ) url = f"/jobs/{job_id}/delivery-file-download" response = fixture_client.get(url) # Verify function was called with correct arguments mock_get_payload.assert_called_once_with(job_id) assert response.status_code == 200 assert response.get_json() == { "presigned_link": "https://my-bucket.s3.amazonaws.com/test/file.jpg", }