""" Test Film Transparency logic layer. The data fixtures in this file are all related to each other. """ from datetime import date from decimal import Decimal from unittest.mock import Mock from unittest.mock import patch from pytest import fixture from api.constants import MAN_ADJ_BONUS_CATEGORY from api.constants import MAN_ADJ_ORCHARD_PROFIT_SHARE_CATEGORY from api.logic import film_transparency from tests_unit.conftest import patch_transaction_types @fixture def advances_model_data(): """Data fixture for advances model.""" return { date(2016, 1, 2): Decimal(2), date(2016, 1, 3): Decimal(3), date(2016, 1, 5): Decimal(5)} @fixture def raw_advances_model_data(): """Raw data fixture for advances model.""" data = { date(2016, 1, 2): Decimal(2), date(2016, 1, 3): Decimal(3), date(2016, 1, 5): Decimal(5)} return (data, False) @fixture def advances_model_data_reversed(): """Data fixture for advances model after reverse logic application.""" return { date(2016, 1, 2): Decimal(-2), date(2016, 1, 3): Decimal(-3), date(2016, 1, 5): Decimal(-5)} @fixture def expense_model_data(): """Expense model return data fixture.""" return { 'this': { date(2016, 1, 1): Decimal(-11), date(2016, 1, 3): Decimal(-22) }, 'that': { date(2016, 1, 2): Decimal(-4), date(2016, 1, 3): Decimal(-5)} } @fixture def labels_model_data(): """Expense model return data fixture.""" return { 'this': 'This', 'that': 'That', 'another_vendor_level': 'Another Vendor Level' } @fixture def expense_model_data_reversed(): """Expense model data fixture after reverse logic application. Raw manual adjustments come in as negative even though it shows as positive. This fixture is just like the expense_model_data fixture but after the reverse_manual_adjustments business logic applied. """ return { 'this': { date(2016, 1, 1): Decimal(11), date(2016, 1, 3): Decimal(22)}, 'that': { date(2016, 1, 2): Decimal(4), date(2016, 1, 3): Decimal(5)}} @fixture def bonuses_model_data(): """Fixture of "bonuses" in payments breakdown.""" return { MAN_ADJ_BONUS_CATEGORY: { date(2016, 1, 1): Decimal(45), date(2016, 1, 2): Decimal(65)} } @fixture def profit_share_model_data(): """Fixture of "profit_share" in payments breakdown.""" return { MAN_ADJ_ORCHARD_PROFIT_SHARE_CATEGORY: { date(2016, 1, 2): Decimal(-25), date(2016, 1, 3): Decimal(-35)} } @fixture def man_adjustments_model_data(): """Manual adjustments model return data fixture.""" return { 'release': { 'this': { date(2016, 1, 1): Decimal(-11), date(2016, 1, 3): Decimal(-22)}, 'that': { date(2016, 1, 2): Decimal(-4), date(2016, 1, 3): Decimal(-5)}, MAN_ADJ_BONUS_CATEGORY: { date(2016, 1, 1): Decimal(45), date(2016, 1, 2): Decimal(65)}, MAN_ADJ_ORCHARD_PROFIT_SHARE_CATEGORY: { date(2016, 1, 2): Decimal(-25), date(2016, 1, 3): Decimal(-35)}}, 'vendor': { MAN_ADJ_BONUS_CATEGORY: { date(2016, 1, 1): Decimal(40), date(2016, 1, 2): Decimal(60)}, MAN_ADJ_ORCHARD_PROFIT_SHARE_CATEGORY: { date(2016, 1, 2): Decimal(-22), date(2016, 1, 3): Decimal(-33)}, 'another_vendor_level': { date(2016, 1, 1): Decimal(40), date(2016, 1, 2): Decimal(60)}}, 'labels': { 'this': 'This', 'that': 'That', 'another_vendor_level': 'Another Vendor Level' } } @fixture def classified_man_adjustments_model_data(): """Manual adjustments that are classified for breakdowns.""" return { 'bonuses': { MAN_ADJ_BONUS_CATEGORY: { date(2016, 1, 1): Decimal(45), date(2016, 1, 2): Decimal(65)}}, 'expenses': { 'this': { date(2016, 1, 1): Decimal(-11), date(2016, 1, 3): Decimal(-22)}, 'that': { date(2016, 1, 2): Decimal(-4), date(2016, 1, 3): Decimal(-5)}}, 'profit_share': { MAN_ADJ_ORCHARD_PROFIT_SHARE_CATEGORY: { date(2016, 1, 2): Decimal(-25), date(2016, 1, 3): Decimal(-35)}}} @fixture def revenue_model_data(): """Revenue model return data fixture.""" return { 'raw': [ { 'transaction_type_id': 1, 'data_point': date(2016, 1, 1), 'amount': Decimal(1)}, { 'transaction_type_id': 1, 'data_point': date(2016, 1, 3), 'amount': Decimal(2)}, { 'transaction_type_id': 2, 'data_point': date(2016, 1, 2), 'amount': Decimal(4)}, { 'transaction_type_id': 2, 'data_point': date(2016, 1, 3), 'amount': Decimal(5)}, { 'transaction_type_id': 3, 'data_point': date(2016, 1, 4), 'amount': Decimal(5)}, { 'transaction_type_id': 14, 'data_point': date(2016, 1, 1), 'store_id': 11, 'amount': Decimal(10)}, { 'transaction_type_id': 14, 'data_point': date(2016, 1, 3), 'store_id': 11, 'amount': Decimal(50)}, { 'transaction_type_id': 3, 'data_point': date(2016, 1, 5), 'amount': Decimal(6)}], 'bucket': { 'transactional': { date(2016, 1, 1): Decimal(1), date(2016, 1, 2): Decimal(4), date(2016, 1, 3): Decimal(7), date(2016, 1, 4): Decimal(5), date(2016, 1, 5): Decimal(6)}, 'term_license': { date(2016, 1, 1): Decimal(10), date(2016, 1, 3): Decimal(50)}}} @fixture def term_license_model_data(term_licenses_converted_sorted): """Term License model return data fixture.""" return { 'actuals': { date(2016, 1, 1): Decimal(10), date(2016, 1, 3): Decimal(50)}, 'projections': { date(2016, 1, 2): Decimal(20), date(2016, 1, 3): Decimal(30)}, 'raw': term_licenses_converted_sorted} @fixture def projections_model_data(): """Data fixture for projections data.""" return { 'raw': [ { 'transaction_type_id': 1, 'date': date(2016, 1, 4), 'amount': Decimal(10)}, { 'transaction_type_id': 1, 'date': date(2016, 1, 5), 'amount': Decimal(21)}, { 'transaction_type_id': 2, 'date': date(2016, 1, 3), 'amount': Decimal(43)}, { 'transaction_type_id': 3, 'date': date(2016, 1, 5), 'amount': Decimal(52)}], 'series': { 'transactional': { date(2016, 1, 4): Decimal(10), date(2016, 1, 3): Decimal(43), date(2016, 1, 5): Decimal(73)}}} @fixture def original_projections_model_data(): """Data fixture for original projections data.""" return { 'raw': [ { 'transaction_type_id': 1, 'date': date(2016, 1, 4), 'amount': Decimal(100)}, { 'transaction_type_id': 1, 'date': date(2016, 1, 5), 'amount': Decimal(110)}, { 'transaction_type_id': 2, 'date': date(2016, 1, 3), 'amount': Decimal(100)}, { 'transaction_type_id': 3, 'date': date(2016, 1, 5), 'amount': Decimal(110)}], 'series': { 'transactional': { date(2016, 1, 3): Decimal(100), date(2016, 1, 4): Decimal(100), date(2016, 1, 5): Decimal(220)}}} @fixture def unrefined_raw( term_licenses_converted_sorted, window_model_raw, revenue_model_data, projections_model_data, original_projections_model_data): """Fixture of a film's unrefined data.""" return { 'revenue': revenue_model_data['raw'], 'regular_projections': projections_model_data['raw'], 'original_projections': original_projections_model_data['raw'], 'term_license': term_licenses_converted_sorted, 'windows': window_model_raw, 'inaccurate_advances': False} @fixture def series_data_raw(): """Raw series data fixture of all model data combined.""" return [ { 'date': date(2016, 1, 1), 'expenses': { 'advances': Decimal(0), 'this': Decimal(-11), 'that': Decimal(0), 'total': Decimal(-11)}, 'revenue': { 'transactional': Decimal(1), 'term_license': Decimal(10), 'total': Decimal(11)}, 'projection': { 'transactional': Decimal(0), 'term_license': Decimal(0), 'total': Decimal(0)}, 'original_projection': { 'total': Decimal('0'), 'transactional': Decimal('0')}}, { 'date': date(2016, 1, 2), 'expenses': { 'advances': Decimal(-2), 'this': Decimal(-11), 'that': Decimal(-4), 'total': Decimal(-17)}, 'revenue': { 'transactional': Decimal(5), 'term_license': Decimal(10), 'total': Decimal(15)}, 'projection': { 'transactional': Decimal(0), 'term_license': Decimal(20), 'total': Decimal(20)}, 'original_projection': { 'total': Decimal('0'), 'transactional': Decimal('0')}}, { 'date': date(2016, 1, 3), 'expenses': { 'advances': Decimal(-5), 'this': Decimal(-33), 'that': Decimal(-9), 'total': Decimal(-47)}, 'revenue': { 'transactional': Decimal(12), 'term_license': Decimal(60), 'total': Decimal(72)}, 'projection': { 'transactional': Decimal(43), 'term_license': Decimal(50), 'total': Decimal(93)}, 'original_projection': { 'total': Decimal('100'), 'transactional': Decimal('100')}}, { 'date': date(2016, 1, 4), 'expenses': { 'advances': Decimal(-5), 'this': Decimal(-33), 'that': Decimal(-9), 'total': Decimal(-47)}, 'revenue': { 'transactional': Decimal(17), 'term_license': Decimal(60), 'total': Decimal(77)}, 'projection': { 'transactional': Decimal(53), 'term_license': Decimal(50), 'total': Decimal(103)}, 'original_projection': { 'total': Decimal('200'), 'transactional': Decimal('200')}}, { 'date': date(2016, 1, 5), 'expenses': { 'advances': Decimal(-10), 'this': Decimal(-33), 'that': Decimal(-9), 'total': Decimal(-52)}, 'revenue': { 'transactional': Decimal(23), 'term_license': Decimal(60), 'total': Decimal(83)}, 'projection': { 'transactional': Decimal(126), 'term_license': Decimal(50), 'total': Decimal(176)}, 'original_projection': { 'total': Decimal('420'), 'transactional': Decimal('420')}}] @fixture def series_data_formatted(series_data_raw): """Formatted series data fixture of all model data combined. The difference between this and raw is the projection data is a sum. """ raw_data = series_data_raw for data in raw_data: data['projection'] = ( data['projection']['total'] + data['revenue']['total']) return raw_data @fixture def breakdown_data(): """Aggregation fixture of all model data combined.""" return { 'actuals': { 'foo': Decimal(3), 'bar': Decimal(9), 'baz': Decimal(11), 'term_license_over_there(broadcast,est)': Decimal(0), 'term_license_that_thing(est)': Decimal(0), 'term_license_this_thing(tvod)': Decimal(0), 'term_license_netflix(svod)': Decimal(60), 'total': Decimal(83)}, 'expenses': { 'advances': Decimal(-10), 'this': Decimal(-33), 'that': Decimal(-9), 'total': Decimal(-52)}, 'projected': { 'foo': Decimal(34), 'bar': Decimal(52), 'baz': Decimal(63), 'term_license_over_there(broadcast,est)': Decimal(640), 'term_license_that_thing(est)': Decimal(400), 'term_license_this_thing(tvod)': Decimal(1000), 'term_license_netflix(svod)': Decimal(2000), 'total': Decimal(4189)}, 'payments_from_orchard': { 'actual_and_contracted_profit': Decimal(31), 'projected_remaining_profit': Decimal(4106), 'profit_share': Decimal(-60), 'bonuses': Decimal(110), 'total': Decimal(4187)}, 'labels': { 'this': 'This', 'that': 'That', 'another_vendor_level': 'Another Vendor Level'}, 'term_licenses_labels': { 'term_license_over_there(broadcast,est)': 'Term License - over there (Broadcast, EST)', 'term_license_that_thing(est)': 'Term License - that thing (EST)', 'term_license_this_thing(tvod)': 'Term License - this thing (TVOD)', 'term_license_netflix(svod)': 'Term License - Netflix (SVOD)'}, 'inaccurate_advances': False} @patch('api.logic.film_transparency.cms') @patch('api.logic.film_transparency.cable_revenue') @patch('api.logic.film_transparency.advances') @patch('api.logic.film_transparency.manual_adjustments') @patch('api.logic.film_transparency.projections') @patch('api.logic.film_transparency.revenue') @patch('api.logic.film_transparency.term_license') @patch('api.logic.film_transparency.window') def test_get_unrefined_data( window, term_license, revenue, projections, man_adjustments, advances, cable_revenue, cms, term_license_model_data, unrefined_raw, man_adjustments_model_data, revenue_model_data, projections_model_data, original_projections_model_data, advances_model_data, raw_advances_model_data, cable_revenue_buckets, window_model_data): """Test get_revenue_and_projection_raw function.""" vendor_id = 12321 release_id = 12341234 upc = 888812345678 advances.fetch_advances.return_value = raw_advances_model_data man_adjustments.fetch_manual_adjustments.return_value = \ man_adjustments_model_data revenue.fetch_all_time_buckets.return_value = revenue_model_data cable_revenue.fetch_all_time_buckets.return_value = \ cable_revenue_buckets term_license.fetch_term_licenses.return_value = term_license_model_data window.fetch_windows.return_value = window_model_data projections.fetch_all_time_buckets.side_effect = [ projections_model_data, original_projections_model_data] series, raw = film_transparency.get_unrefined_data( vendor_id, release_id, upc) assert series == { 'advances': advances_model_data, 'manual_adjustments': man_adjustments_model_data, 'revenue': revenue_model_data['bucket'], 'regular_projections': projections_model_data['series'], 'original_projections': original_projections_model_data['series'], 'term_license': { 'actuals': term_license_model_data['actuals'], 'projections': term_license_model_data['projections']}} assert raw == unrefined_raw revenue.fetch_all_time_buckets.assert_called_with(upc) def test_format_series_data( advances_model_data_reversed, expense_model_data, revenue_model_data, projections_model_data, original_projections_model_data, term_license_model_data, series_data_raw): """Test get_revenue_and_projection_raw function. The fixtures in this test contain both raw and series data, but only series data is used for this function in the business logic, so we pick it out. """ term_license_model_data.pop('raw', None) data = { 'advances': advances_model_data_reversed, 'expenses': expense_model_data, 'revenue': revenue_model_data['bucket'], 'regular_projections': projections_model_data['series'], 'original_projections': original_projections_model_data['series'], 'term_license': term_license_model_data} result = film_transparency.format_series_data(data) assert result == series_data_raw def test_format_series_data_none( advances_model_data_reversed, expense_model_data, revenue_model_data, projections_model_data, original_projections_model_data, term_license_model_data, series_data_raw): """Test format_series_data function when a value is none.""" term_license_model_data.pop('raw', None) data = { 'advances': advances_model_data_reversed, 'expenses': expense_model_data, 'revenue': revenue_model_data['bucket'], 'regular_projections': projections_model_data['series'], 'original_projections': {}, 'term_license': term_license_model_data} result = film_transparency.format_series_data(data) sdr_copy = series_data_raw[:] for i in sdr_copy: i.pop('original_projection') assert result == sdr_copy def test_classify_manual_adjustments( man_adjustments_model_data, labels_model_data, expense_model_data, bonuses_model_data, profit_share_model_data): """Test classify_manual_adjustments function.""" expected = { 'bonuses': bonuses_model_data, 'expenses': expense_model_data, 'profit_share': profit_share_model_data, 'labels': labels_model_data} results = film_transparency.classify_manual_adjustments( man_adjustments_model_data) assert results == expected @patch('api.logic.film_transparency.release') def test_get_releases(release): """Test get_releases.""" vendor_id = '12345' releases = [ {'upc': 842914078023, 'name': 'Ultimate Predator (censored)'}, {'upc': 842914078030, 'name': 'Ultimate Predator'}, {'upc': 884385048839, 'name': 'Mysteries of the Apocalypse'}, ] release.get_releases_by_vendor_id.return_value = releases response = film_transparency.get_releases(vendor_id) assert response.message == {'releases': releases} assert response.status == 200 def test_get_revenue_and_projection_authorized(monkeypatch): """Test get_all_time function when authorized.""" # Fixture upc = 888812345678 # film_transparency.get_revenue_and_projection_formatted_mock function get_revenue_and_projection_formatted_mock = Mock(return_value='foo') monkeypatch.setattr( film_transparency, 'get_revenue_and_projection_formatted', get_revenue_and_projection_formatted_mock) expected = film_transparency.get_revenue_and_projection(upc) # Asserts get_revenue_and_projection_formatted_mock.assert_called_once_with(upc) assert expected is 'foo' @patch('api.logic.film_transparency.cms') @patch('api.logic.film_transparency.cable_revenue') @patch('api.logic.film_transparency.advances') @patch('api.logic.film_transparency.manual_adjustments') @patch('api.logic.film_transparency.projections') @patch('api.logic.film_transparency.release') @patch('api.logic.film_transparency.revenue') @patch('api.logic.film_transparency.term_license') @patch('api.logic.film_transparency.window') @patch('api.utils.revenue.get_store_id_by_name') @patch('api.utils.revenue.get_store_name_by_id') @patch.dict( 'api.utils.revenue.BREAKDOWN_TRANSACTION_TYPES', patch_transaction_types(), clear=True) def test_get_revenue_and_projection_formatted( get_store_name_by_id, get_store_id_by_name, window, term_license, revenue, release, projections, man_adjustments, advances, cable_revenue, cms, revenue_model_data, man_adjustments_model_data, term_license_model_data, raw_advances_model_data, series_data_formatted, breakdown_data, original_projections_model_data, window_model_data, term_license_and_window_model_sorted, term_license_windows_data, projections_model_data): """Test get_revenue_and_projection_formatted.""" vendor_id = '123' release_id = '12341234' upc = '456' advances.fetch_advances.return_value = raw_advances_model_data man_adjustments.fetch_manual_adjustments.return_value = \ man_adjustments_model_data release.get_vendor_and_release.return_value = (vendor_id, release_id) revenue.fetch_all_time_buckets.return_value = revenue_model_data cable_revenue.fetch_all_time_buckets.return_value = \ {'raw': (), 'bucket': {'transactional': {}}} cms_client_mock = Mock() cms.get_client.return_value = cms_client_mock term_license.fetch_term_licenses.return_value = term_license_model_data get_store_id_by_name.return_value = (11,) get_store_name_by_id.return_value = ('Netflix',) window.fetch_windows.return_value = window_model_data projections.fetch_all_time_buckets.side_effect = [ projections_model_data, original_projections_model_data] response = film_transparency.get_revenue_and_projection_formatted(upc) # broken up for easier test diff output assert response.message['breakdown'] == breakdown_data assert response.message['series'] == series_data_formatted assert response.message['windows'] == term_license_and_window_model_sorted assert response.status == 200 advances.fetch_advances.assert_called_with(vendor_id, upc) man_adjustments.fetch_manual_adjustments.assert_called_with( vendor_id, release_id) projections.fetch_all_time_buckets.assert_any_call(upc, 'regular') projections.fetch_all_time_buckets.assert_any_call(upc, 'original') term_license.fetch_term_licenses.assert_called_with(upc, cms_client_mock) @patch('api.logic.film_transparency.release') @patch('api.logic.film_transparency.get_unrefined_data') def test_get_revenue_and_projection_formatted_with_no_data( get_unrefined_data, release): """ Test get_revenue_and_projection_formatted with empty response. For case when there are no data in CMS. """ vendor_id = '123' release_id = '12341234' upc = '456' release.get_vendor_and_release.return_value = (vendor_id, release_id) raw = { 'original_projections': (), 'regular_projections': (), 'revenue': ( { 'transaction_type_id': 18, 'amount': Decimal('0.016077'), 'data_point': date(2016, 10, 1)}, { 'transaction_type_id': 18, 'amount': Decimal('0.016077'), 'data_point': date(2016, 10, 2)}), 'term_license': [], 'windows': [], 'inaccurate_advances': False} series = { 'advances': {}, 'manual_adjustments': { 'release': {}, 'vendor': {}, 'labels': {} }, 'revenue': {}, 'regular_projections': {}, 'original_projections': {}, 'term_license': { 'actuals': {}, 'projections': {} } } get_unrefined_data.return_value = series, raw response = film_transparency.get_revenue_and_projection_formatted(upc) # broken up for easier test diff output assert response.message['breakdown'] == { 'actuals': { 'total': 0 }, 'expenses': { 'total': 0 }, 'projected': { 'total': 0 }, 'labels': { }, 'term_licenses_labels': { }, 'inaccurate_advances': False} assert response.message['series'] == [] assert response.message['windows'] == [] assert response.status == 200 @patch('api.logic.film_transparency.release') @patch('api.logic.film_transparency.get_unrefined_data') def test_get_revenue_and_projection_formatted_if_not_film( get_unrefined_data, release): """ Test get_revenue_and_projection_formatted with empty response. For case when there are no data in CMS. """ upc = '456' release.get_vendor_and_release.return_value = None response = film_transparency.get_revenue_and_projection_formatted(upc) # broken up for easier test diff output assert response.message['breakdown'] == {} assert response.message['series'] == [] assert response.message['windows'] == [] assert response.status == 200 def test_calculate_payments_from_orchard( classified_man_adjustments_model_data): """Test calculate_payments_from_orchard.""" params = { 'actuals': {'total': Decimal(22)}, 'expenses': {'total': Decimal(-5)}, 'projected': {'total': Decimal(30)}} expected = { 'actuals': {'total': Decimal(22)}, 'expenses': {'total': Decimal(-5)}, 'projected': {'total': Decimal(30)}, 'payments_from_orchard': { 'actual_and_contracted_profit': Decimal(17), 'bonuses': Decimal(110), 'profit_share': Decimal(-60), 'projected_remaining_profit': Decimal(8)}} results = film_transparency.calculate_payments_from_orchard( params, manual_adjustments=classified_man_adjustments_model_data) assert results == expected def test_calculate_payments_from_orchard_no_share( classified_man_adjustments_model_data): """Test calculate_payments_from_orchard without profit share.""" classified_man_adjustments_model_data['profit_share'] = {} params = { 'actuals': {'total': Decimal(22)}, 'expenses': {'total': Decimal(-5)}, 'projected': {'total': Decimal(30)}} expected = { 'actuals': {'total': Decimal(22)}, 'expenses': {'total': Decimal(-5)}, 'projected': {'total': Decimal(30)}, 'payments_from_orchard': { 'actual_and_contracted_profit': Decimal(17), 'bonuses': Decimal(110), 'profit_share': Decimal(0), 'projected_remaining_profit': Decimal(8)}} results = film_transparency.calculate_payments_from_orchard( params, manual_adjustments=classified_man_adjustments_model_data) assert results == expected def test_calculate_payments_from_orchard_no_bonuses( classified_man_adjustments_model_data): """Test calculate_payments_from_orchard without bonuses.""" classified_man_adjustments_model_data['bonuses'] = {} params = { 'actuals': {'total': Decimal(22)}, 'expenses': {'total': Decimal(-5)}, 'projected': {'total': Decimal(30)}} expected = { 'actuals': {'total': Decimal(22)}, 'expenses': {'total': Decimal(-5)}, 'projected': {'total': Decimal(30)}, 'payments_from_orchard': { 'actual_and_contracted_profit': Decimal(17), 'bonuses': Decimal(0), 'profit_share': Decimal(-60), 'projected_remaining_profit': Decimal(8)}} results = film_transparency.calculate_payments_from_orchard( params, manual_adjustments=classified_man_adjustments_model_data) assert results == expected def test_mask_breakdown_payments(): """Test mask_breakdown_payments with no masking.""" params = { 'payments_from_orchard': { 'bonuses': Decimal(100), 'actual_and_contracted_profit': Decimal(80), 'projected_remaining_profit': Decimal(50), 'profit_share': Decimal(-10)}} expected = { 'payments_from_orchard': { 'bonuses': Decimal(100), 'actual_and_contracted_profit': Decimal(80), 'projected_remaining_profit': Decimal(50), 'profit_share': Decimal(-10), 'total': Decimal(220)}} results = film_transparency.mask_breakdown_payments(params) assert results == expected def test_mask_breakdown_payments_table_mask(): """Test mask_breakdown_payments table masking.""" params = { 'payments_from_orchard': { 'bonuses': Decimal(-4), 'actual_and_contracted_profit': Decimal(0), 'projected_remaining_profit': Decimal(50), 'profit_share': Decimal(-10)}} expected = { 'payments_from_orchard': { 'bonuses': Decimal(-4), 'profit_share': Decimal(-10), 'total': Decimal(-14)}} results = film_transparency.mask_breakdown_payments(params) assert results == expected def test_mask_breakdown_payments_table_mask_bonuses(): """Test mask_breakdown_payments table masking with bonuses. As a side effect this also tests no actual profits masks actual and projected profit lines as well. """ params = { 'payments_from_orchard': { 'bonuses': Decimal(1), 'actual_and_contracted_profit': Decimal(0), 'projected_remaining_profit': Decimal(50), 'profit_share': Decimal(-10)}} expected = { 'payments_from_orchard': { 'bonuses': Decimal(1), 'profit_share': Decimal(-10), 'total': Decimal(-9)}} results = film_transparency.mask_breakdown_payments(params) assert results == expected def test_mask_breakdown_payments_table_mask_actuals(): """Test mask_breakdown_payments table masking with actuals.""" params = { 'payments_from_orchard': { 'bonuses': Decimal(0), 'actual_and_contracted_profit': Decimal(1), 'projected_remaining_profit': Decimal(50), 'profit_share': Decimal(-10)}} expected = { 'payments_from_orchard': { 'actual_and_contracted_profit': Decimal(1), 'projected_remaining_profit': Decimal(50), 'profit_share': Decimal(-10), 'total': Decimal(41)}} results = film_transparency.mask_breakdown_payments(params) assert results == expected def test_mask_breakdown_payments_line_mask_profit_share(): """Test mask_breakdown_payments line masking without profit share.""" params = { 'payments_from_orchard': { 'bonuses': Decimal(5), 'actual_and_contracted_profit': Decimal(1), 'projected_remaining_profit': Decimal(50), 'profit_share': Decimal(0)}} expected = { 'payments_from_orchard': { 'bonuses': Decimal(5), 'actual_and_contracted_profit': Decimal(1), 'projected_remaining_profit': Decimal(50), 'total': Decimal(56)}} results = film_transparency.mask_breakdown_payments(params) assert results == expected def test_mask_breakdown_payments_line_mask_multiple(): """Test mask_breakdown_payments line masking mix. Not a full permutation test, but enough to know multiple lines can get masked together. """ params = { 'payments_from_orchard': { 'bonuses': Decimal(0), 'actual_and_contracted_profit': Decimal(1), 'projected_remaining_profit': Decimal(50), 'profit_share': Decimal(0)}} expected = { 'payments_from_orchard': { 'actual_and_contracted_profit': Decimal(1), 'projected_remaining_profit': Decimal(50), 'total': Decimal(51)}} results = film_transparency.mask_breakdown_payments(params) assert results == expected def test_reverse_manual_adjustments( classified_man_adjustments_model_data, expense_model_data_reversed): """Test reverse_manual_adjustments logic function.""" expected = classified_man_adjustments_model_data.copy() expected['expenses'] = expense_model_data_reversed assert film_transparency.reverse_manual_adjustments( classified_man_adjustments_model_data) == expected def test_extract_windows_from_term_licenses( unrefined_raw, term_license_windows_data): """Test transformation of raw data to windowing records.""" results = film_transparency.extract_windows_from_term_licenses( unrefined_raw) assert results == term_license_windows_data def test_sort_windows( term_license_and_window_model_sorted, term_license_windows_data, window_model_raw): """Test transformation of raw data to windowing records.""" results = film_transparency.sort_windows( term_license_windows_data, window_model_raw) assert results == term_license_and_window_model_sorted