"""Functional tests for accounting periods.""" from abacus_common_logic.test_utils.helpers import get_json_body from abacus_common_logic.utils.dates import safe_format_date from royalties.constants.constants import ( ACCOUNTING_PERIOD_STATUSES, CONTRACT_TYPES, STATEMENT_PERIOD_STATUSES, ) from royalties.constants.error import ERROR_NO_CURRENT_STATEMENT_PERIOD from royalties.schemas.accounting_period import AccountingPeriodDetailSchema from royalties.tests.utils.factories import ( AccountingPeriodFactory, AccountingRunFactory, StatementPeriodFactory, ) def test_create_accounting_period(fixture_client, test_app): """Create an accounting period and get response from database.""" statement_period = StatementPeriodFactory.create( statement_period_status=STATEMENT_PERIOD_STATUSES.CURRENT ) default_is_visible = True default_status = ACCOUNTING_PERIOD_STATUSES.OPEN accounting_period_name = 'Test Accounting Period 2021' json_request = { 'accounting_period_name': accounting_period_name, 'statement_period_id': statement_period.statement_period_id, 'contract_type': CONTRACT_TYPES.LEGACY_DISTRIBUTION, } response = fixture_client.post('/accounting-period', json=json_request) json_response = get_json_body(response) assert response.status_code == 201 assert 'accounting_period_id' in json_response assert json_response['accounting_period_name'] == accounting_period_name assert json_response['accounting_period_status'] == default_status assert json_response['closed_date'] is None assert json_response['is_visible'] == default_is_visible def test_create_accounting_period_for_invalid_statement_period( fixture_client, test_app ): """Create an accounting period for an invalid statement period.""" statement_period = StatementPeriodFactory.create( statement_period_status=STATEMENT_PERIOD_STATUSES.CLOSED ) json_request = { 'accounting_period_name': 'Test Accounting Period 2021', 'statement_period_id': statement_period.statement_period_id, 'contract_type': CONTRACT_TYPES.LEGACY_DISTRIBUTION, } response = fixture_client.post('/accounting-period', json=json_request) assert response.status_code == 400 assert response.json['message'] == ERROR_NO_CURRENT_STATEMENT_PERIOD def test_get_accounting_period_by_accounting_run_id(fixture_client): """Test getting an accounting period by accounting_run_id. Success case. """ accounting_run = AccountingRunFactory.create() accounting_run_id = accounting_run.accounting_run_id response = fixture_client.get( f'/accounting-run/{accounting_run_id}/accounting-period' ) assert response.status_code == 200 assert response.json == AccountingPeriodDetailSchema().dump( accounting_run.accounting_period ) def test_get_accounting_period_by_accounting_run_id_failure(fixture_client): """Test getting an accounting period by accounting_run_id. Case where accounting_run_id is not found. """ response = fixture_client.get('/accounting-run/8000/accounting-period') assert response.status_code == 404 def test_list_accounting_periods(fixture_client): """List accounting periods. They should be sorted by created_at, most recent last. """ accounting_periods = [ AccountingPeriodFactory.create(created_at=date) for date in ('2019-06-01', '2019-02-15', '2019-01-01') ] response = fixture_client.get('/accounting-periods') response_body = get_json_body(response) accounting_period_ids = [ period['accounting_period_id'] for period in response_body['items'] ] accounting_period_ids.sort(reverse=True) assert response.status_code == 200 assert response_body['total_count'] == len(accounting_periods) assert accounting_period_ids == [ accounting_periods[2].accounting_period_id, accounting_periods[1].accounting_period_id, accounting_periods[0].accounting_period_id, ] def test_get_accounting_period(fixture_client): """Get specified accounting_period.""" accounting_period = AccountingPeriodFactory.create() response = fixture_client.get( f'/accounting-period/{accounting_period.accounting_period_id}' ) assert response.status_code == 200 # Accounting periods are mutable and out of scope for reference caching, so they # carry the hardening layer's default no-cache (never public,max-age). assert response.headers['Cache-Control'] == 'no-cache' response_body = get_json_body(response) assert ( response_body['accounting_period_name'] == accounting_period.accounting_period_name ) assert ( response_body['accounting_period_id'] == accounting_period.accounting_period_id ) assert response_body['statement_period_id'] == accounting_period.statement_period_id assert ( response_body['accounting_period_status'] == accounting_period.accounting_period_status ) assert response_body['closed_date'] == safe_format_date( accounting_period.closed_date ) def test_update_accounting_period_name_success(fixture_client): """Test updating an accounting period name successfully.""" accounting_period = AccountingPeriodFactory.create() json_request = {'accounting_period_name': 'new name'} response = fixture_client.put( f'/accounting-period/{accounting_period.accounting_period_id}', json=json_request, ) assert response.status_code == 201 assert accounting_period.accounting_period_name == 'new name' def test_update_accounting_period_name_failure(fixture_client): """Test updating an accounting period name failure.""" accounting_period = AccountingPeriodFactory.create( accounting_period_name='period name' ) other_period = AccountingPeriodFactory.create(accounting_period_name='other_period') json_request = {'accounting_period_name': other_period.accounting_period_name} response = fixture_client.put( f'/accounting-period/{accounting_period.accounting_period_id}', json=json_request, ) assert response.status_code == 400 def test_update_accounting_period_status_success(fixture_client): """Test updating an accounting period status successfully.""" accounting_period = AccountingPeriodFactory.create( accounting_period_status=ACCOUNTING_PERIOD_STATUSES.OPEN ) closed = ACCOUNTING_PERIOD_STATUSES.CLOSED json_request = {'accounting_period_status': closed} response = fixture_client.put( f'/accounting-period/{accounting_period.accounting_period_id}', json=json_request, ) assert response.status_code == 201 assert accounting_period.accounting_period_status == closed assert accounting_period.closed_date def test_update_period_fails_for_invalid_status_change(fixture_client): """Test updating an accounting period fails with invalid new status.""" closed = ACCOUNTING_PERIOD_STATUSES.CLOSED open_status = ACCOUNTING_PERIOD_STATUSES.OPEN accounting_period = AccountingPeriodFactory.create(accounting_period_status=closed) json_request = {'accounting_period_status': open_status} response = fixture_client.put( f'/accounting-period/{accounting_period.accounting_period_id}', json=json_request, ) assert response.status_code == 400 def test_update_accounting_period_status_success_legacy(fixture_client): """Test updating an accounting period status successfully.""" accounting_period = AccountingPeriodFactory.create( accounting_period_status=ACCOUNTING_PERIOD_STATUSES.OPEN ) new_status = ACCOUNTING_PERIOD_STATUSES.LOCKED json_request = {'accounting_period_status': new_status} response = fixture_client.put( f'/accounting-period/{accounting_period.accounting_period_id}', json=json_request, ) assert response.status_code == 201 assert accounting_period.accounting_period_status == new_status