"""Test PATCH /v2/vendor/ (info).""" import time from typing import Any import pytest import requests from tests.integration import config @pytest.fixture() def theorchard_vendor_for_info() -> dict[str, Any]: return { 'is_distributor': False, 'name': f'ows-account integration-test info {time.time()}', 'owner': 'odd', 'company_brand': 'theorchard', 'service_tier_uuid': 'c069ab15-9370-4bd6-8ad1-895a64ae2ad8', 'payment_currency': 'USD', } @pytest.fixture() def created_vendor( bearer_token_contract_admin_theorchard: str, theorchard_vendor_for_info: dict[str, Any], ) -> dict[str, Any]: headers = {'Authorization': f'Bearer {bearer_token_contract_admin_theorchard}'} resp = requests.post( f'{config.QA_BASE_URL}/v2/vendors', json=theorchard_vendor_for_info, headers=headers, ) assert resp.status_code == 200, resp.text return resp.json() @pytest.fixture() def created_vendor_uuid(created_vendor: dict[str, Any]) -> str: return created_vendor['vendor_uuid'] def test_update_info_success( bearer_token_account_admin_theorchard: str, created_vendor: dict[str, Any], ) -> None: """PATCH every accepted field, then GET and verify each persisted.""" vendor_uuid = created_vendor['vendor_uuid'] vendor_id = created_vendor['vendor_id'] headers = {'Authorization': f'Bearer {bearer_token_account_admin_theorchard}'} payload: dict[str, Any] = { 'name': 'ows-account integration-test info Updated Name', 'owner': 'updated-owner', 'company': 'Updated Company LLC', 'support_contact_email': 'support@example.com', 'label_identifier': 'Frontline', 'contact_email': 'contact@example.com', 'label_summary': 'updated label summary', 'relationship_notes': 'updated relationship notes', 'newsletter': 'N', 'website': 'https://updated.example.com', 'priority': 7, 'primary_genre': 20, 'date_signed': '2026-01-15', 'status': 'signed', } resp = requests.patch( f'{config.QA_BASE_URL}/v2/vendor/{vendor_uuid}', json=payload, headers=headers, ) assert resp.status_code == 200, resp.text assert resp.json()['vendor_uuid'] == vendor_uuid # GET /vendor/ renames a few columns and omits some metadata fields # (newsletter, date_signed, relationship_notes are persisted but not # surfaced by VENDOR_LABEL_INFO_SQL). get_resp = requests.get( f'{config.QA_BASE_URL}/vendor/{vendor_id}', headers=headers, ) assert get_resp.status_code == 200, get_resp.text fetched = get_resp.json() field_to_response_key = { 'name': 'contact_name', 'company': 'account_name', } for field in ( 'name', 'owner', 'company', 'support_contact_email', 'label_identifier', 'contact_email', 'label_summary', 'website', 'priority', 'primary_genre', 'status', ): response_key = field_to_response_key.get(field, field) assert ( fetched[response_key] == payload[field] ), f'{field} not persisted: {fetched[response_key]!r}' def test_update_info_clears_nullable_fields( bearer_token_account_admin_theorchard: str, created_vendor: dict[str, Any], ) -> None: """Sending null clears the column for nullable text columns.""" vendor_uuid = created_vendor['vendor_uuid'] vendor_id = created_vendor['vendor_id'] headers = {'Authorization': f'Bearer {bearer_token_account_admin_theorchard}'} set_resp = requests.patch( f'{config.QA_BASE_URL}/v2/vendor/{vendor_uuid}', json={'support_contact_email': 'temp@example.com', 'label_summary': 'temp summary'}, headers=headers, ) assert set_resp.status_code == 200, set_resp.text clear_resp = requests.patch( f'{config.QA_BASE_URL}/v2/vendor/{vendor_uuid}', json={'support_contact_email': None, 'label_summary': None}, headers=headers, ) assert clear_resp.status_code == 200, clear_resp.text get_resp = requests.get( f'{config.QA_BASE_URL}/vendor/{vendor_id}', headers=headers, ) assert get_resp.status_code == 200, get_resp.text fetched = get_resp.json() assert fetched['support_contact_email'] is None assert fetched['label_summary'] is None @pytest.mark.parametrize( 'payload,expected_status', [ pytest.param({}, 400, id='no fields'), pytest.param({'newsletter': 'maybe'}, 400, id='bad newsletter enum'), pytest.param({'label_identifier': 'Bogus'}, 400, id='bad label_identifier enum'), pytest.param({'unknown_field': 'x'}, 400, id='unknown field'), ], ) def test_update_info_validation_errors( bearer_token_account_admin_theorchard: str, created_vendor_uuid: str, payload: dict[str, Any], expected_status: int, ) -> None: """Bad payloads return 400.""" headers = {'Authorization': f'Bearer {bearer_token_account_admin_theorchard}'} resp = requests.patch( f'{config.QA_BASE_URL}/v2/vendor/{created_vendor_uuid}', json=payload, headers=headers, ) assert resp.status_code == expected_status, resp.text def test_update_info_forbidden_other_brand( bearer_token_contract_admin_sme: str, created_vendor_uuid: str, ) -> None: """Contract admin for a different brand cannot update.""" headers = {'Authorization': f'Bearer {bearer_token_contract_admin_sme}'} resp = requests.patch( f'{config.QA_BASE_URL}/v2/vendor/{created_vendor_uuid}', json={'name': 'Hostile Takeover'}, headers=headers, ) assert resp.status_code == 403, resp.text def test_update_info_no_auth() -> None: """No auth header returns 401.""" resp = requests.patch( f'{config.QA_BASE_URL}/v2/vendor/fff741c2-6def-4493-bfdf-c2bcb1128e02', json={'name': 'Anonymous'}, ) assert resp.status_code == 401, resp.text