"""Integration test configuration.""" import os from typing import Any import pytest from abacus_common_logic.connectors.database import db from abacus_contract.tests.utils.factories import ( AccountContractFactory, ContractFactory, ReferenceSapProfitCenterFactory, ReferenceSigningEntityFactory, ) from core.config import Config from royalties.tests.integration.consts import headers from royalties.tests.integration.utils import auth from royalties.tests.integration.utils.ows_royalties_api_client import ( RoyaltiesAPIClient, ) ROYALTIES_API_BASE_URL = os.environ.get( 'ROYALTIES_API_BASE_URL', 'http://localhost:6052' ) print(f'Using royalties URL {ROYALTIES_API_BASE_URL}') def ows_royalties_api_client(headers): """Create ows-royalties APIClient object.""" return RoyaltiesAPIClient(ROYALTIES_API_BASE_URL, headers) @pytest.fixture(scope='session') def basic_headers(): """Return basic headers.""" return {'Content-Type': 'application/json'} @pytest.fixture def currency_usd(): """Return USD currency object.""" return {'currency_id': 1, 'currency_code': 'USD', 'currency_name': 'US Dollar'} @pytest.fixture def test_label_id(): """Return label id for testing.""" return 7123 def cleanup_runcontrollers(basic_headers): """Clean up runcontrollers before test scenario.""" ows_royalties_client = ows_royalties_api_client(basic_headers) runcontrollers = ows_royalties_client.get_runcontrollers().json()['items'] runcontrollers_to_delete = [ runcontroller for runcontroller in runcontrollers if runcontroller['name'].startswith('orcd_autotest') ] for runcontroller in runcontrollers_to_delete: ows_royalties_client.delete_runcontroller( str(runcontroller['run_controller_id']) ) # TODO: uncomment this once we're able to delete accounting period # assert response.status_code == 204, \ # 'failed to cleanup runcontrollers' def create_accounting_period_if_not_exist(basic_headers, statement_period_fixtures): """Create a new accounting period if there's none.""" ows_royalties_client = ows_royalties_api_client(basic_headers) response = ows_royalties_client.get_accounting_periods() assert response.status_code == 200 response_body = response.json() items = response_body['items'] open_period = next((item for item in items if item['closed_date'] is None), None) if open_period is None: accounting_period_name = 'March 2020' params = { 'accounting_period_name': accounting_period_name, 'statement_period_id': 11, 'contract_type': 'distribution', } response_post_period = ows_royalties_client.post_accounting_period(params) assert response_post_period.status_code == 201 response = ows_royalties_client.get_accounting_periods() assert response.status_code == 200 response_body = response.json() return { 'statement_period_id': response_body['items'][0]['statement_period_id'], 'accounting_period_id': response_body['items'][0]['accounting_period_id'], 'accounting_period': response_body['items'][0], } class TestConfig(Config): """Test configuration.""" MYSQL_DB_NAME = os.environ.get('MYSQL_DB_NAME', Config.MYSQL_DB_NAME) MYSQL_DB_USER = os.environ.get('MYSQL_DB_USER', 'royalties') MYSQL_DB_HOST = os.environ.get('MYSQL_DB_HOST', 'mysql-royalties-container') MYSQL_DB_PORT = os.environ.get('MYSQL_DB_PORT', '3306') MYSQL_DB_PASS = os.environ.get('MYSQL_DB_PASS', '1234') @pytest.fixture(scope='session', autouse=True) def test_app(): """Create a test application.""" from core.app_factory import create_app return create_app(TestConfig) @pytest.mark.fixture @pytest.fixture(autouse=True) def test_app_in_context(test_app): """Push the test app onto the context.""" with test_app.app_context(): yield test_app @pytest.fixture(autouse=True) def clear_db(): """Refresh the test database.""" top_level_tables = ( 'abacus_state', 'run_controller', 'contract', 'accounting_period', 'accounting_period_report', 'exchange_rate', 'earnings_transfer', 'project_transfer_term', 'project_transfer_term_condition', 'sales_file', 'accounting_run', 'run_controller_contract', 'account', 'account_payment_term', 'account_contract', 'accounting_period_report', 'statement_period', 'statement_period_payment_entity', 'statement_period_adjustment_file', 'statement_period_adjustment_batch_criteria', 'worksheet_adjustment', 'reference_sap_profit_center', 'reference_payment_entity', ) with db.engine.connect() as conn: conn.exec_driver_sql('SET FOREIGN_KEY_CHECKS=0') for table in top_level_tables: conn.exec_driver_sql(f'TRUNCATE TABLE {table}') conn.exec_driver_sql('SET FOREIGN_KEY_CHECKS=1') @pytest.fixture def statement_period_adjustments_file_error_fixture(): """Create an entry in statement_period_adjustment_file with error file.""" query = """ INSERT INTO statement_period_adjustment_file ( statement_period_id, file_name, valid_file_location, invalid_file_location, valid_row_count, invalid_row_count, total_file_amount_multicurrency, total_rounded_amount_multicurrency, md5sum, error_type, created_by, created_at, last_modified_by, last_modified ) VALUES ( 1, 'Test7.xlsx', null, 's3://qa-abacus-adjustments/errors/Test7.xlsx', null, null, null, null, null, null, 'integration_tests', '2023-11-22 11:12:59', 'integration_tests', '2023-11-22 11:13:03' )""" db.engine.execute(query) @pytest.fixture def statement_period_adjustments_file_report_fixture(): """Create an entry in statement_period_adjustment_file with no error.""" query = """ INSERT INTO statement_period_adjustment_file ( statement_period_id, file_name, valid_file_location, invalid_file_location, valid_row_count, invalid_row_count, total_file_amount_multicurrency, total_rounded_amount_multicurrency, md5sum, error_type, created_by, created_at, last_modified_by, last_modified ) VALUES ( 1, 'test_adjustment.xlsx', 's3://qa-abacus-adjustments/test_fixtures/test_adjustment.xlsx', null, null, null, null, null, null, null, 'integration_tests', '2023-11-22 11:12:59', 'integration_tests', '2023-11-22 11:13:03' )""" db.engine.execute(query) @pytest.fixture def runcontroller_deleted_fixture(): """Create 2 runcontroller entries, one is soft-deleted, the other is not.""" query = """ INSERT INTO run_controller ( run_controller_name, contract_type, created_by, created_at, last_modified_by, last_modified, deleted_by, deleted_at ) VALUES ( 'integration_test_1', 'distribution', 'integration_tests', '2023-09-26 13:46:06', 'integration_tests', '2023-09-26 13:46:11', 'integration_tests', '2023-09-26 13:46:15' ), ( 'integration_test_2', 'distribution', 'integration_tests', '2023-09-26 13:46:06', 'integration_tests', '2023-09-26 13:46:11', NULL, NULL ) """ db.engine.execute(query) @pytest.fixture def statement_period_payment_entity_fixture(): """Create statement_period_payment_entity fixture.""" query = """ INSERT INTO statement_period_payment_entity ( statement_period_payment_entity_id, statement_period_id, reference_payment_entity_id, is_visible_to_customer ) VALUES ( 1, 11, 1, 1 ) """ db.engine.execute(query) @pytest.fixture(scope='session') def bearer_token_read_only_user() -> str: """Fetch Auth0 secrets from AWS Secret Manager.""" login_secrets = auth.login_from_secrets_manager( password_secret_name=auth.READONLY_USER_PASSWORD_SECRET_NAME, auth_client_id_secret_name=auth.AUTH0_CLIENT_ID_SECRET_NAME, auth_client_secret_secret_name=auth.AUTH0_CLIENT_SECRET_SECRET_NAME, ) token = auth.generate_auth_token( auth.LoginInfo( auth_client_id=login_secrets.auth_client_id, auth_client_secret=login_secrets.auth_client_secret, password=login_secrets.password, username=auth.READONLY_USER, ) ) return token @pytest.fixture(scope='session') def admin_headers() -> dict[str, str]: """Return profile headers.""" return headers.ADMIN_HEADERS @pytest.fixture(params=['read_only', 'admin'], scope='session') def auth_headers( request: Any, bearer_token_read_only_user: str, admin_headers: dict[str, str] ) -> dict[str, str]: """Return appropriate headers based on the parameter.""" if request.param == 'read_only': return { 'Authorization': f'Bearer {bearer_token_read_only_user}', 'Content-Type': 'application/json', 'Orchard-Identity-Id': 'ff3737b4-7734-4339-9798-5ddd1c9998b0', 'Orchard-Profile-Id': '1005', 'Orchard-Profile-Type': 'Account360Profile', 'Orchard-Requestor-Service': 'graphql-abacus', 'Orchard-Roles': 'account360', } else: return admin_headers @pytest.fixture() def unauthorized_headers(bearer_token_read_only_user_unauthorized) -> dict[str, str]: """Return headers for unauthorized user.""" return { 'Authorization': f'Bearer {bearer_token_read_only_user_unauthorized}', 'Orchard-Requestor-Service': 'graphql-abacus', } @pytest.fixture(scope='session') def bearer_token_read_only_user_unauthorized() -> str: """Fetch Auth0 secrets from AWS Secret Manager.""" login_secrets = auth.login_from_secrets_manager( password_secret_name=auth.READONLY_USER_PASSWORD_SECRET_NAME, auth_client_id_secret_name=auth.AUTH0_CLIENT_ID_SECRET_NAME, auth_client_secret_secret_name=auth.AUTH0_CLIENT_SECRET_SECRET_NAME, ) token = auth.generate_auth_token( auth.LoginInfo( auth_client_id=login_secrets.auth_client_id, auth_client_secret=login_secrets.auth_client_secret, password=login_secrets.password, username=auth.READONLY_USER_UNAUTHORIZED, ) ) return token @pytest.fixture def account_contract_fixtures(reference_payment_entity_fixtures): """Create account, contract, and account_contract records.""" account_insert = """ INSERT INTO account( account_id, account_name, created_by, created_at, last_modified_by, last_modified ) VALUES (1, 'Test Account', 'dana', CURRENT_TIMESTAMP, 'dana', CURRENT_TIMESTAMP), (2, 'Test Account 2', 'Test User', CURRENT_TIMESTAMP, 'Test User', CURRENT_TIMESTAMP); """ db.engine.execute(account_insert) account_payment_term_insert = """ INSERT INTO account_payment_term( account_id, currency_code, payment_minimum, payment_entity_id, agreement_type_id, payment_schedule, created_by, created_at, last_modified_by, last_modified ) VALUES (1, 'USD', '12.90', 1, NULL, '30_days_after_month_end', 'Test User' , CURRENT_TIMESTAMP, 'Test User' , CURRENT_TIMESTAMP), (2, 'USD', '1.22', 2, NULL, '60_days_after_month_end', 'Test User' , CURRENT_TIMESTAMP, 'Test User' , CURRENT_TIMESTAMP); """ db.engine.execute(account_payment_term_insert) reference_sap_profit_center = ReferenceSapProfitCenterFactory.create( reference_sap_profit_center_id=1, profit_center='UK4914', company_code='4914' ) reference_signing_entity = ReferenceSigningEntityFactory.create( reference_sap_profit_center=reference_sap_profit_center ) contract_1 = ContractFactory.create( reference_signing_entity=reference_signing_entity, contract_name='Test Contract 1', contract_type='distribution', term_start='2020-01-01', ) contract_2 = ContractFactory.create( reference_signing_entity=reference_signing_entity, contract_name='Test Contract 2', contract_type='distribution', term_start='2020-02-02', ) contract_3 = ContractFactory.create( reference_signing_entity=reference_signing_entity, contract_name='Test Contract 3', contract_type='distribution', term_start='2020-03-03', ) AccountContractFactory.create(account_id=1, contract=contract_1) AccountContractFactory.create(account_id=1, contract=contract_2) AccountContractFactory.create(account_id=2, contract=contract_3)