"""Integration test configuration.""" import os import pytest from abacus_common_logic.connectors.database import db from ledger.api import create_app from ledger.config import Config from tests.integration.consts.headers import ( ADMIN_HEADERS, BASIC_HEADERS, ) from tests.integration.utils import auth from tests.integration.utils.generic_helper import ( create_account as create_account_fn, generate_random_string, ) from tests.integration.utils.ows_abacus_account_api_client import AbacusAccountAPIClient from tests.integration.utils.ows_abacus_event_api_client import AbacusEventAPIClient from tests.integration.utils.ows_ledger_api_client import LedgerAPIClient from tests.integration.utils.ows_royalties_api_client import RoyaltiesAPIClient LEDGER_API_BASE_URL = os.environ.get('LEDGER_API_BASE_URL', 'http://localhost:6200') print(f'Using ledger URL {LEDGER_API_BASE_URL}') ROYALTIES_API_BASE_URL = os.environ.get( 'ROYALTIES_API_BASE_URL', 'http://ledger-ows-royalties:8080' ) print(f'Using royalties URL {ROYALTIES_API_BASE_URL}') ABACUS_EVENT_API_BASE_URL = os.environ.get( 'ABACUS_EVENT_API_BASE_URL', 'http://ledger-ows-abacus-event:8080' ) print(f'Using abacus-event URL {ABACUS_EVENT_API_BASE_URL}') ACCOUNT_API_BASE_URL = os.environ.get( 'ACCOUNT_API_BASE_URL', 'http://ledger-ows-abacus-account:8080' ) print(f'Using abacus-account URL {ACCOUNT_API_BASE_URL}') 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.""" return create_app(TestConfig) @pytest.fixture(scope='session', autouse=True) def test_app_in_context(test_app): """Push the test app onto the context.""" with test_app.app_context(): yield test_app def ows_ledger_api_client(headers): """Create ows-ledger APIClient object.""" return LedgerAPIClient(LEDGER_API_BASE_URL, headers) def ows_royalties_api_client(headers): """Create ows-royalties APIClient object.""" return RoyaltiesAPIClient(ROYALTIES_API_BASE_URL, headers) def ows_abacus_event_api_client(headers): """Create ows-abacus-event APIClient object.""" return AbacusEventAPIClient(ABACUS_EVENT_API_BASE_URL, headers) def ows_abacus_account_api_client(headers): """Create ows-abacus-account APIClient object.""" return AbacusAccountAPIClient(ACCOUNT_API_BASE_URL, headers) @pytest.fixture(scope='session') def basic_headers(): """Return basic headers.""" return BASIC_HEADERS @pytest.fixture(autouse=True) def clean_db(): """Clean tables between runs.""" tables = [ 'abacus_event', 'account', 'accounting_period', 'accounting_run', 'account_tax_info', 'account_payment_term', 'account_contract', 'contract', 'contract_exclusion', 'contract_reserve', 'statement_period', 'ledger_account', 'ledger_account_contract', 'ledger_account_contract_current_balance', 'ledger_account_current_balance', 'ledger_adjustment_applied', 'ledger_adjustment', 'ledger_reserve_release', 'ledger_contract_advance_applied', 'ledger_reserve_taken', 'ledger_reserve_release_schedule', 'reference_vat_rate', 'run_controller', 'ledger_accounting_run_balance', 'ledger_accounting_run_vat', 'ledger_adjustment_adjustment_detail_applied', 'ledger_adjustment_applied', 'ledger_adjustment_detail', 'ledger_adjustment_adjustment_detail', 'ledger_adjustment_detail_applied', 'ledger_correction', 'payment_hold', 'payment_hold_history', 'reference_adjustment_type', 'worksheet_adjustment_detail', 'worksheet_adjustment', 'statement_period_adjustment_file', 'worksheet_correction', ] db.engine.execute('SET FOREIGN_KEY_CHECKS = 0;') for table_name in tables: db.engine.execute(f'TRUNCATE TABLE `{table_name}`') db.engine.execute('SET FOREIGN_KEY_CHECKS = 1;') def generate_payee(payee_type='Artist', agreement_type='Finetunes', currency='USD'): """Return POST /payee body.""" return { 'payee_name': 'orcd_autotest_{}'.format(generate_random_string(16)), 'payee_type': payee_type, 'currency_code': currency, 'payment_agreement_type': agreement_type, 'payment_minimum': '500.00', 'payment_schedule': '30 days after month end', } @pytest.fixture() def create_account(account_id=1): """Insert account data.""" create_account_fn(account_id) @pytest.fixture def create_accounting_period(): """Insert accounting period data.""" ACCOUNTING_PERIOD_INSERT = """ INSERT INTO accounting_period ( `accounting_period_id`, `statement_period_id`, `accounting_period_name`, `accounting_period_status`, `contract_type`, `closed_date`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 300, 'test_period', 'open', 'distribution', null, 'vz', '2021-11-30 07:58:34', 'vz', '2021-11-30 07:58:40') """ db.engine.execute(ACCOUNTING_PERIOD_INSERT) @pytest.fixture def create_statement_period(create_accounting_period): """Statement period db fixture.""" STATEMENT_PERIOD_INSERT = """ INSERT INTO statement_period( statement_period_id, statement_period_name, statement_period_status ) VALUES(300, 'Jan 20', 'current'), (2, 'Feb 20', 'open'); """ db.engine.execute(STATEMENT_PERIOD_INSERT) @pytest.fixture def create_run_controller(): """Mock run controller insert.""" SQL_QUERY = """ INSERT INTO run_controller ( `run_controller_id`, `run_controller_name`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 'foo', 'dana', NOW(), 'dana', NOW()), (2, 'bar', 'dana', NOW(), 'dana', NOW()), (3, 'baz', 'dana', NOW(), 'dana', NOW()); """ db.engine.execute(SQL_QUERY) @pytest.fixture def create_accounting_run(create_accounting_period, create_statement_period): """Insert accounting run data.""" SQL_QUERY = """ INSERT INTO accounting_run ( `accounting_run_id`, `accounting_period_id`, `run_controller_id`, `run_status`, `start_date`, `summary_export_url`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 1, 1, 'Committed', '2020-02-24 20:09:35', 's3://qa-royalties-sales-files/21-january-2020/1337-jen-priority/ summary/january-2020_jen-priority_monthly-summary.tsv', 'VZ', '2021-08-06 03:34:24', 'VZ', '2021-08-06 03:34:27'), (2, 1, 2, 'No Action Taken', null, null, 'VZ', '2021-08-06 03:37:37', 'VZ', '2021-08-06 03:37:40'), (3, 1, 3, 'Committed', '2021-08-06 03:38:52', 's3://qa-royalties-sales-files/21-january-2020/1341-priority-1/ summary/january-2020_priority-1_monthly-summary.tsv', 'VZ', '2021-08-06 03:39:06', 'VZ', '2021-08-06 03:39:10'); """ db.engine.execute(SQL_QUERY) def create_contract(contract_id=1, account_id=1): """Mock contract insert.""" SQL_QUERY = """ INSERT INTO contract ( `contract_id`, `reference_signing_entity_id`, `contract_name`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES ( {contract_id}, 1, 'foo-{contract_id}-{account_id}', '', NOW(), '', NOW() ); """ db.engine.execute('SET FOREIGN_KEY_CHECKS=0') db.engine.execute(SQL_QUERY.format(contract_id=contract_id, account_id=account_id)) db.engine.execute('SET FOREIGN_KEY_CHECKS=1') def create_account_tax_info(): """Mock account_tax_info insert.""" SQL_QUERY = """ INSERT INTO account_tax_info( `account_tax_info_id`, `account_id`, `country_of_tax_residence`, `is_sba_signed`, `is_vat_exempt`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 1,'USA',0,0,'test','2021-10-29 13:22:52','test','2021-10-29 13:22:58'), (2, 50,'GBR',0,0,'test','2021-10-29 13:25:36','test','2021-10-29 13:25:43'); """ db.engine.execute(SQL_QUERY) def create_account_payment_term(): """Mock account_payment_term insert.""" SQL_QUERY = """ INSERT INTO account_payment_term( `account_payment_term_id`, `account_id`, `currency_code`, `payment_minimum`, `payment_entity_id`, `payment_schedule`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 1, 'USD', 42.00, 1, null, 'Test', NOW(), 'Test', NOW()), (2, 50, 'USD', 43.00, 1, null, 'Test', NOW(), 'Test', NOW()); """ db.engine.execute(SQL_QUERY) def create_account_contract(): """Mock account_contract insert.""" SQL_QUERY = """ INSERT INTO account_contract(account_contract_id, account_id, contract_id) VALUES (1, 1, 1), (2, 50, 2); """ db.engine.execute(SQL_QUERY) def create_contract_reserve(): """Mock contract_reserve insert.""" SQL_QUERY = """ INSERT INTO contract_reserve( contract_reserve_id, contract_id, reserve_rate, reserve_release_offset_in_months, installments_in_months, release_schedule, created_by, created_at, last_modified_by, last_modified ) VALUES (1, 1, 1.90, 1, 2, '["0.50", "0.50"]', 'Test', NOW(), 'Test', NOW()) """ db.engine.execute('SET FOREIGN_KEY_CHECKS=0') db.engine.execute(SQL_QUERY) db.engine.execute('SET FOREIGN_KEY_CHECKS=1') @pytest.fixture def create_event_fixtures(create_account, create_accounting_run): """Create the records required to add ledger entries.""" create_contract() create_account_tax_info() create_account_payment_term() create_account_contract() create_contract_reserve() SQL_QUERY = """ INSERT INTO abacus_event ( `abacus_event_id`, `statement_period_id`, `event_date`, `event_name`, `target_type`, `target_id`, `created_by` ) VALUES ( 1, 300, '2020-01-01', 'commit_royalties', 'accounting_period', 1, 'Test' ), ( 2, 265, '2020-01-02', 'commit_royalties', 'accounting_period', 1, 'Test' ), ( 3, 265, '2020-01-03', 'commit_adjustment', 'accounting_period', 1, 'Test' ), ( 4, 265, '2020-01-03', 'commit_adjustment', 'accounting_period', 1, 'Test' ), ( 5, 265, '2020-01-04', 'accounting_period_close', 'accounting_period', 1, 'Test' ); """ db.engine.execute(SQL_QUERY) @pytest.fixture def create_ledger_adjustment(): """Mock ledger_adjustment insert.""" SQL_QUERY = """ INSERT INTO ledger_adjustment ( ledger_adjustment_id, abacus_event_id, account_id, contract_id, activity_statement_period_id, apply_to_statement_period_id, reference_adjustment_type_id, adjustment_amount, adjustment_currency_code, note, created_by, created_at, last_modified_by, last_modified ) VALUES ( 1, 1, 1, 1, 300, 300, 1, 12.00, 'GBP', 'vz', 'vz', '2022-08-24 03:56:29', 'vz', '2022-08-24 03:56:31' ) """ db.engine.execute(SQL_QUERY) @pytest.fixture def create_ledger_adjustment_detail_fixture(): """Mock ledger_adjustment_detail insert.""" SQL_QUERY = """ INSERT INTO ledger_adjustment_detail ( account_id, contract_id, activity_statement_period_id, apply_to_statement_period_id, reference_adjustment_type_id, currency_code, amount, upc, distribution_type, note, created_by, created_at, last_modified_by, last_modified ) VALUES ( 1, 1, 300, 300, 1, 'USD', 123.00, '13', DEFAULT, null, 'vz', '2023-08-30 16:26:20', 'vz', '2023-08-30 16:26:22' ) """ db.engine.execute(SQL_QUERY) @pytest.fixture def create_ledger_adjustment_adjustment_detail_fixture(): """Mock ledger_adjustment_adjustment_detail insert.""" SQL_QUERY = """ INSERT INTO ledger_adjustment_adjustment_detail ( ledger_adjustment_id, ledger_adjustment_detail_id, detail_count ) VALUES ( 1, 1, 2 ) """ db.engine.execute(SQL_QUERY) @pytest.fixture def create_reference_adjustment_type_fixture(): """Create reference_adjustment_type fixture.""" query = """ INSERT INTO reference_adjustment_type ( reference_adjustment_type_id, type_name, oa_category_name ) VALUES ( 1, 'Label Earnings', 'tst' ) """ db.engine.execute(query) @pytest.fixture def create_worksheet_correction(): """Mock worksheet_correction insert.""" SQL_QUERY = """ INSERT INTO worksheet_correction( `worksheet_correction_id`, `account_id`, `contract_id`, `statement_period_id`, `correction_statement_period_id`, `correction_type`, `currency_code`, `gross_revenue`, `distribution_fee`, `net_revenue`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES ( 1, 1, 1, 300, 2, 'royalty_reversal', 'USD', -150.00, 30.00, -120.00, 'test', '2021-10-29 13:22:52', 'test', '2021-10-29 13:22:58' ); """ db.engine.execute(SQL_QUERY) @pytest.fixture def create_statement_period_adjustment_file(): """Mock statement_period_adjustment_file insert.""" SQL_QUERY = """ INSERT INTO statement_period_adjustment_file( `statement_period_adjustment_file_id`, `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, 300, 'Test Adjustment File', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'test', '2021-10-29 13:22:52', 'test', '2021-10-29 13:22:58' ); """ db.engine.execute(SQL_QUERY) @pytest.fixture def create_worksheet_adjustment( create_event_fixtures, create_statement_period_adjustment_file, create_reference_adjustment_type_fixture, ): """Mock worksheet_adjustment insert.""" SQL_QUERY = """ INSERT INTO worksheet_adjustment( `worksheet_adjustment_id`, `statement_period_adjustment_file_id`, `abacus_event_id`, `account_id`, `contract_id`, `activity_statement_period_id`, `apply_to_statement_period_id`, `reference_adjustment_type_id`, `adjustment_amount`, `adjustment_currency_code`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES ( 1, 1, 1, 1, 1, 300, 300, 1, '1500.00', 'USD', 'test', '2021-10-29 13:22:52', 'test', '2021-10-29 13:22:58' ), ( 2, 1, 1, 1, 1, 300, 300, 1, '2000.00', 'USD', 'test', '2021-10-29 13:22:52', 'test', '2021-10-29 13:22:58' ); """ db.engine.execute(SQL_QUERY) @pytest.fixture def create_worksheet_adjustment_detail(create_worksheet_adjustment): """Mock worksheet_adjustment_detail insert.""" SQL_QUERY = """ INSERT INTO worksheet_adjustment_detail( `worksheet_adjustment_detail_id`, `statement_period_adjustment_file_id`, `worksheet_adjustment_id`, `account_id`, `contract_id`, `activity_statement_period_id`, `apply_to_statement_period_id`, `reference_adjustment_type_id`, `currency_code`, `amount`, `upc`, `distribution_type`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES( 1, 1, 1, 1, 1, 300, 300, 1, 'USD', '1500.00', '123456789111', 'digital', 'test', '2021-10-29 13:22:52', 'test', '2021-10-29 13:22:58' ); """ db.engine.execute(SQL_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 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 unauthorized_headers(bearer_token_read_only_user_unauthorized): """Return headers for unauthorized user.""" return { 'Authorization': f'Bearer {bearer_token_read_only_user_unauthorized}', 'Orchard-Requestor-Service': 'graphql-abacus', } @pytest.fixture(params=['read_only', 'admin', 'basic']) def auth_headers(request, bearer_token_read_only_user, basic_headers): """Return appropriate headers based on the parameter.""" if request.param == 'read_only': return { 'Authorization': f'Bearer {bearer_token_read_only_user}', 'Orchard-Requestor-Service': 'graphql-abacus', } elif request.param == 'admin': return ADMIN_HEADERS else: return basic_headers