"""Integration tests for abacus state dataloader. POST /abacus-state/dataloader. """ from typing import Any import pytest from abacus_common_logic.connectors.database import db from tests.integration.conftest import ows_abacus_state_api_client @pytest.fixture def seed_accounting_period_abacus_state(basic_headers: dict[str, Any]) -> None: """Use API to seed accounting period.""" abacus_state_client = ows_abacus_state_api_client(basic_headers) post_data = [ { 'parent_table_id': 1, 'action_name': 'deliver_sales_files', 'parent_table_name': 'accounting_period', } ] abacus_state_client.post_states(post_data) @pytest.mark.parametrize( 'header_fixture_name, expected_status_code', [ pytest.param( 'no_authorization_headers', 403, id='orchard-requestor-service forces profile checks', ), pytest.param( 'some_other_app_profile_headers', 403, id='other apps are not authorized', ), pytest.param('abacus_headers', 200, id='abacus is authorized'), pytest.param( 'a360_headers', 403, id='Account360Profile is not authorized, should be based on PP', ), ], ) def test_authorization_accounting_period_abacus_state( seed_accounting_period_abacus_state: Any, header_fixture_name: str, expected_status_code: int, request: pytest.FixtureRequest, ) -> None: """Test authorization based on headers.""" headers = request.getfixturevalue(header_fixture_name) abacus_state_client = ows_abacus_state_api_client(headers) result = abacus_state_client.get_state('accounting-period', 1) assert result.status_code == expected_status_code if expected_status_code == 200: item = result.json()[0] assert item['action_name'] == 'deliver_sales_files' assert item['action_status'] == 'init' assert 'abacus_state_id' in item else: assert result.json() == { 'code': 'authorization_error', 'message': 'Unauthorized', } @pytest.fixture def seed_account_payee_abacus_state( drop_fks: Any, basic_headers: dict[str, Any], ) -> None: """Use db engine and API to fixture account_payee state.""" account_query = """ INSERT INTO royalty_accounting.account ( account_id, account_name, created_by, created_at, last_modified_by, last_modified ) VALUES ( 25153, 'TEST ACCOUNT', 1472, '2021-04-12 02:38:45.000000', 1472, '2021-04-12 02:38:45.000000' ) """ db.engine.execute(account_query) account_payee_query = """ INSERT INTO royalty_accounting.account_payee (account_id, payoneer_payee_id, payoneer_payee_name, payoneer_iframe_url, payoneer_iframe_url_date, payoneer_session_id, created_by, created_at, last_modified_by, last_modified) VALUES (25153, 1, 'test', 'test', '2022-03-24', 'test', 'vz', '2022-03-24 07:27:26', 'vz', '2022-03-24 07:27:30')""" db.engine.execute(account_payee_query) abacus_state_client = ows_abacus_state_api_client(basic_headers) post_data = [ { 'parent_table_id': 1, 'action_name': 'tax_eligibility', 'parent_table_name': 'account_payee', }, { 'parent_table_id': 1, 'action_name': 'payment_eligibility', 'parent_table_name': 'account_payee', }, ] abacus_state_client.post_states(post_data) @pytest.mark.parametrize( 'header_fixture_name, expected_status_code', [ pytest.param( 'no_authorization_headers', 403, id='orchard-requestor-service forces profile checks', ), pytest.param( 'some_other_app_profile_headers', 403, id='other apps are not authorized', ), pytest.param('abacus_headers', 200, id='abacus is authorized'), pytest.param( 'a360_headers', 403, id="""Account360Profile is not authorized, should be based on PP""", ), ], ) def test_authorization_get_abacus_states_dataloader( seed_account_payee_abacus_state: Any, seed_accounting_period_abacus_state: Any, header_fixture_name: str, expected_status_code: int, request: pytest.FixtureRequest, ) -> None: """Test authorization based on headers.""" headers = request.getfixturevalue(header_fixture_name) abacus_state_client = ows_abacus_state_api_client(headers) result = abacus_state_client.get_states_dataloader([1, 2, 4, 3]) assert result.status_code == expected_status_code if expected_status_code == 200: json_result = result.json() assert 'items' in json_result items = json_result['items'] assert len(items) == 4 assert items[0]['data']['action_name'] == 'tax_eligibility' assert items[1]['data']['action_name'] == 'payment_eligibility' assert not items[2]['data'] assert items[3]['data']['action_name'] == 'deliver_sales_files' else: assert result.json() == { 'code': 'authorization_error', 'message': 'Unauthorized', } @pytest.mark.parametrize( 'state_ids, expected_status_code', [ pytest.param( [], 400, id='Empty list is not supported', ), pytest.param( [1, 2], 200, id='account payee (ids 1, 2) states are authorized', ), pytest.param( [4], 200, id='null (id 4) state is authorized', ), pytest.param( [4, 99], 200, id='null (ids 4, 99) states are authorized', ), pytest.param( [1, 2, 4], 200, id='account payee (ids 1, 2) and null (id 4) states are authorized', ), pytest.param( [3], 403, id='accounting period (id 3) state is not authorized', ), pytest.param( [1, 2, 4, 3], 403, id="""when one state (id 3) is unauthorized, the entire request is considered unauthorized, even though there are authorized account payee (ids 1, 2) and null (id 4) states""", ), ], ) def test_authorization_read_only_user( seed_account_payee_abacus_state: Any, # creates account payee state ids 1, 2 seed_accounting_period_abacus_state: Any, # creates statement period state id 3 state_ids: str, bearer_token_read_only_user: dict[str, Any], expected_status_code: int, ) -> None: """Test authorization based on JWT.""" headers = { 'Content-Type': 'application/json', 'orchard-requestor-service': 'graphql-abacus', 'Authorization': f'Bearer {bearer_token_read_only_user}', } abacus_state_client = ows_abacus_state_api_client(headers) result = abacus_state_client.get_states_dataloader(state_ids) assert result.status_code == expected_status_code if expected_status_code == 200: json_result = result.json() assert 'items' in json_result items = json_result['items'] assert len(items) == len(state_ids) elif expected_status_code == 400: assert result.json() == { 'code': 'error', 'message': 'AbacusState IDs must be integers', } else: assert result.json() == { 'code': 'authorization_error', 'message': 'Unauthorized', }