diff --git a/app/main/views/add_service.py b/app/main/views/add_service.py index a6779fc38..6e816a409 100644 --- a/app/main/views/add_service.py +++ b/app/main/views/add_service.py @@ -40,17 +40,22 @@ def _add_invited_user_to_service(invited_user): def _create_service(service_name, organisation_type, email_from, form): + free_sms_fragment_limit = current_app.config['DEFAULT_FREE_SMS_FRAGMENT_LIMITS'].get(organisation_type) try: service_id = service_api_client.create_service( service_name=service_name, organisation_type=organisation_type, message_limit=current_app.config['DEFAULT_SERVICE_LIMIT'], - free_sms_fragment_limit=current_app.config['DEFAULT_FREE_SMS_FRAGMENT_LIMITS'].get(organisation_type), + free_sms_fragment_limit=free_sms_fragment_limit, restricted=True, user_id=session['user_id'], email_from=email_from, ) session['service_id'] = service_id + + # TODO: Comment out until data migration + # billing_api_client.create_or_update_free_sms_fragment_limit(service_id, free_sms_fragment_limit) + return service_id, None except HTTPError as e: if e.status_code == 400 and e.message['name']: diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index ce63fdc00..22a85e486 100644 --- a/app/main/views/dashboard.py +++ b/app/main/views/dashboard.py @@ -112,10 +112,13 @@ def template_history(service_id): def usage(service_id): year, current_financial_year = requested_and_current_financial_year(request) + free_sms_allowance = billing_api_client.get_free_sms_fragment_limit_for_year(service_id, year) return render_template( 'views/usage.html', months=list(get_free_paid_breakdown_for_billable_units( - year, billing_api_client.get_billable_units(service_id, year) + year, + free_sms_allowance, + billing_api_client.get_billable_units(service_id, year) )), selected_year=year, years=get_tuples_of_financial_years( @@ -123,7 +126,8 @@ def usage(service_id): start=current_financial_year - 1, end=current_financial_year + 1, ), - **calculate_usage(billing_api_client.get_service_usage(service_id, year)) + **calculate_usage(billing_api_client.get_service_usage(service_id, year), + free_sms_allowance) ) @@ -287,9 +291,8 @@ def get_dashboard_totals(statistics): return statistics -def calculate_usage(usage): - # TODO: Don't hardcode these - get em from the API - sms_free_allowance = 250000 +def calculate_usage(usage, free_sms_fragment_limit): + sms_free_allowance = free_sms_fragment_limit sms_rate = 0 if len(usage) == 0 else usage[0].get("rate", 0) sms_sent = get_sum_billing_units(breakdown for breakdown in usage if breakdown['notification_type'] == 'sms') @@ -355,14 +358,14 @@ def get_sum_billing_units(billing_units, month=None): return sum(b['billing_units'] * b.get('rate_multiplier', 1) for b in billing_units) -def get_free_paid_breakdown_for_billable_units(year, billing_units): +def get_free_paid_breakdown_for_billable_units(year, free_sms_fragment_limit, billing_units): cumulative = 0 for month in get_months_for_financial_year(year): previous_cumulative = cumulative monthly_usage = get_sum_billing_units(billing_units, month) cumulative += monthly_usage breakdown = get_free_paid_breakdown_for_month( - cumulative, previous_cumulative, + free_sms_fragment_limit, cumulative, previous_cumulative, [billing_month for billing_month in billing_units if billing_month['month'] == month] ) yield { @@ -373,11 +376,12 @@ def get_free_paid_breakdown_for_billable_units(year, billing_units): def get_free_paid_breakdown_for_month( + free_sms_fragment_limit, cumulative, previous_cumulative, monthly_usage ): - allowance = 250000 + allowance = free_sms_fragment_limit total_monthly_billing_units = get_sum_billing_units(monthly_usage) diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index 6da8ceded..ad5817fa1 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -40,7 +40,7 @@ from app.main.forms import ( ServiceEditInboundNumberForm, SMSPrefixForm, ) -from app import user_api_client, current_service, organisations_client, inbound_number_client +from app import user_api_client, current_service, organisations_client, inbound_number_client, billing_api_client from notifications_utils.formatters import formatted_list @@ -90,6 +90,9 @@ def service_settings(service_id): default_sms_sender = next( (Field(x['sms_sender'], html='escape') for x in sms_senders if x['is_default']), "None" ) + + free_sms_fragment_limit = billing_api_client.get_free_sms_fragment_limit_for_year(service_id) + return render_template( 'views/service-settings.html', organisation=organisation, @@ -105,7 +108,9 @@ def service_settings(service_id): letter_contact_details_count=letter_contact_details_count, default_sms_sender=default_sms_sender, sms_sender_count=sms_sender_count, + free_sms_fragment_limit=free_sms_fragment_limit, prefix_sms_with_service_name=current_service['prefix_sms_with_service_name'], + ) @@ -708,13 +713,18 @@ def set_organisation_type(service_id): @user_has_permissions(admin_override=True) def set_free_sms_allowance(service_id): - form = FreeSMSAllowance(free_sms_allowance=current_service['free_sms_fragment_limit']) + form = FreeSMSAllowance(free_sms_allowance=billing_api_client.get_free_sms_fragment_limit_for_year(service_id)) if form.validate_on_submit(): service_api_client.update_service( service_id, + # TODO: Retire this eventually after using annual_billing free_sms_fragment_limit=form.free_sms_allowance.data, ) + + # TODO: Comment out until data migration + # billing_api_client.create_or_update_free_sms_fragment_limit(service_id, form.free_sms_allowance.data) + return redirect(url_for('.service_settings', service_id=service_id)) return render_template( diff --git a/app/notify_client/billing_api_client.py b/app/notify_client/billing_api_client.py index 2041f74fe..ab6e76e13 100644 --- a/app/notify_client/billing_api_client.py +++ b/app/notify_client/billing_api_client.py @@ -23,3 +23,26 @@ class BillingAPIClient(NotifyAdminAPIClient): '/service/{0}/billing/yearly-usage-summary'.format(service_id), params=dict(year=year) ) + + def get_free_sms_fragment_limit_for_year(self, service_id, year=None): + result = self.get( + '/service/{0}/billing/free-sms-fragment-limit'.format(service_id), + params=dict(financial_year_start=year) + ) + return result['free_sms_fragment_limit'] + + def get_free_sms_fragment_limit_for_all_years(self, service_id, year=None): + return self.get( + '/service/{0}/billing/free-sms-fragment-limit'.format(service_id)) + + def create_or_update_free_sms_fragment_limit(self, service_id, free_sms_fragment_limit, year=None): + # year = None will update current and future year in the API + data = { + "financial_year_start": year, + "free_sms_fragment_limit": free_sms_fragment_limit + } + + return self.post( + url='/service/{0}/billing/free-sms-fragment-limit'.format(service_id), + data=data + ) diff --git a/app/templates/views/service-settings.html b/app/templates/views/service-settings.html index 1eb75ee21..528c6a56d 100644 --- a/app/templates/views/service-settings.html +++ b/app/templates/views/service-settings.html @@ -200,7 +200,7 @@ {% endcall %} {% call row() %} {{ text_field('Free text message allowance')}} - {{ text_field('{:,}'.format(current_service.free_sms_fragment_limit or 0)) }} + {{ text_field('{:,}'.format(free_sms_fragment_limit or 0)) }} {{ edit_field('Change', url_for('.set_free_sms_allowance', service_id=current_service.id)) }} {% endcall %} {% call row() %} diff --git a/tests/app/main/views/service_settings/test_service_setting_permissions.py b/tests/app/main/views/service_settings/test_service_setting_permissions.py index 0002e23bc..8996989a1 100644 --- a/tests/app/main/views/service_settings/test_service_setting_permissions.py +++ b/tests/app/main/views/service_settings/test_service_setting_permissions.py @@ -12,6 +12,7 @@ def get_service_settings_page( service_one, mock_get_inbound_number_for_service, mock_get_letter_organisations, + mock_get_free_sms_fragment_limit, no_reply_to_email_addresses, no_letter_contact_blocks, single_sms_sender, @@ -83,11 +84,12 @@ def test_service_setting_toggles_dont_show(get_service_settings_page, service_on def test_normal_user_doesnt_see_any_toggle_buttons( client_request, service_one, - mock_get_inbound_number_for_service, - mock_get_letter_organisations, no_reply_to_email_addresses, no_letter_contact_blocks, single_sms_sender, + mock_get_letter_organisations, + mock_get_inbound_number_for_service, + mock_get_free_sms_fragment_limit, ): page = client_request.get('main.service_settings', service_id=service_one['id']) toggles = page.find('a', {'class': 'button'}) diff --git a/tests/app/main/views/test_add_service.py b/tests/app/main/views/test_add_service.py index ee584a27a..0d4ead910 100644 --- a/tests/app/main/views/test_add_service.py +++ b/tests/app/main/views/test_add_service.py @@ -31,6 +31,7 @@ def test_should_add_service_and_redirect_to_tour_when_no_services( mock_create_service_template, mock_get_services_with_no_services, api_user_active, + mock_create_or_update_free_sms_fragment_limit, ): response = logged_in_client.post( url_for('main.add_service'), @@ -83,6 +84,7 @@ def test_should_add_service_and_redirect_to_dashboard_when_existing_service( api_user_active, organisation_type, free_allowance, + mock_create_or_update_free_sms_fragment_limit ): response = logged_in_client.post( url_for('main.add_service'), diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 35a68dea4..d8eb6c20e 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -502,6 +502,7 @@ def test_usage_page( logged_in_client, mock_get_usage, mock_get_billable_units, + mock_get_free_sms_fragment_limit ): response = logged_in_client.get(url_for('main.usage', service_id=SERVICE_ONE_ID)) @@ -509,6 +510,7 @@ def test_usage_page( mock_get_billable_units.assert_called_once_with(SERVICE_ONE_ID, 2011) mock_get_usage.assert_called_once_with(SERVICE_ONE_ID, 2011) + mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID, 2011) page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') @@ -540,11 +542,14 @@ def test_usage_page( def test_usage_page_with_year_argument( logged_in_client, mock_get_usage, - mock_get_billable_units + mock_get_billable_units, + mock_get_free_sms_fragment_limit, + mock_create_or_update_free_sms_fragment_limit ): assert logged_in_client.get(url_for('main.usage', service_id=SERVICE_ONE_ID, year=2000)).status_code == 200 mock_get_billable_units.assert_called_once_with(SERVICE_ONE_ID, 2000) mock_get_usage.assert_called_once_with(SERVICE_ONE_ID, 2000) + mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID, 2000) def test_usage_page_for_invalid_year( @@ -558,11 +563,13 @@ def test_future_usage_page( logged_in_client, mock_get_future_usage, mock_get_future_billable_units, + mock_get_free_sms_fragment_limit ): assert logged_in_client.get(url_for('main.usage', service_id=SERVICE_ONE_ID, year=2014)).status_code == 200 mock_get_future_billable_units.assert_called_once_with(SERVICE_ONE_ID, 2014) mock_get_future_usage.assert_called_once_with(SERVICE_ONE_ID, 2014) + mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID, 2014) def _test_dashboard_menu(mocker, app_, usr, service, permissions): @@ -588,7 +595,8 @@ def test_menu_send_messages( mock_get_template_statistics, mock_get_detailed_service, mock_get_usage, - mock_get_inbound_sms_summary + mock_get_inbound_sms_summary, + mock_get_free_sms_fragment_limit, ): with app_.test_request_context(): resp = _test_dashboard_menu( @@ -619,7 +627,8 @@ def test_menu_manage_service( mock_get_template_statistics, mock_get_detailed_service, mock_get_usage, - mock_get_inbound_sms_summary + mock_get_inbound_sms_summary, + mock_get_free_sms_fragment_limit, ): with app_.test_request_context(): resp = _test_dashboard_menu( @@ -649,7 +658,8 @@ def test_menu_manage_api_keys( mock_get_template_statistics, mock_get_detailed_service, mock_get_usage, - mock_get_inbound_sms_summary + mock_get_inbound_sms_summary, + mock_get_free_sms_fragment_limit, ): with app_.test_request_context(): resp = _test_dashboard_menu( @@ -679,7 +689,8 @@ def test_menu_all_services_for_platform_admin_user( mock_get_template_statistics, mock_get_detailed_service, mock_get_usage, - mock_get_inbound_sms_summary + mock_get_inbound_sms_summary, + mock_get_free_sms_fragment_limit, ): with app_.test_request_context(): resp = _test_dashboard_menu( @@ -866,9 +877,10 @@ def test_aggregate_status_types(dict_in, expected_failed, expected_requested): ] ) def test_get_free_paid_breakdown_for_billable_units(now, expected_number_of_months): + sms_allowance = 250000 with now: billing_units = get_free_paid_breakdown_for_billable_units( - 2016, [ + 2016, sms_allowance, [ { 'month': 'April', 'international': False, 'rate_multiplier': 1, 'notification_type': 'sms', 'rate': 1.65, 'billing_units': 100000 diff --git a/tests/app/main/views/test_service_settings.py b/tests/app/main/views/test_service_settings.py index 08d3d19fa..d2a9d45c8 100644 --- a/tests/app/main/views/test_service_settings.py +++ b/tests/app/main/views/test_service_settings.py @@ -29,6 +29,16 @@ from tests.conftest import ( get_inbound_number_sms_sender, SERVICE_ONE_ID ) +from freezegun import freeze_time + + +@pytest.fixture +def mock_get_service_settings_page_common( + mock_get_letter_organisations, + mock_get_inbound_number_for_service, + mock_get_free_sms_fragment_limit, +): + return @pytest.mark.parametrize('user, expected_rows', [ @@ -84,13 +94,12 @@ def test_should_show_overview( mocker, service_one, fake_uuid, - mock_get_letter_organisations, no_reply_to_email_addresses, no_letter_contact_blocks, single_sms_sender, user, expected_rows, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): service_one['permissions'] = ['sms', 'email'] @@ -159,8 +168,7 @@ def test_should_show_overview_for_service_with_more_things_set( single_letter_contact_block, single_sms_sender, mock_get_organisation, - mock_get_letter_organisations, - mock_get_inbound_number_for_service, + mock_get_service_settings_page_common, permissions, expected_rows ): @@ -182,7 +190,6 @@ def test_should_show_overview_for_service_with_more_things_set( def test_service_settings_show_elided_api_url_if_needed( logged_in_platform_admin_client, service_one, - mock_get_letter_organisations, single_reply_to_email_address, single_sms_sender, single_letter_contact_block, @@ -190,7 +197,7 @@ def test_service_settings_show_elided_api_url_if_needed( fake_uuid, url, elided_url, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): service_one['permissions'] = ['sms', 'email', 'inbound_sms'] service_one['inbound_api'] = [fake_uuid] @@ -219,8 +226,7 @@ def test_service_settings_show_elided_api_url_if_needed( def test_if_cant_send_letters_then_cant_see_letter_contact_block( logged_in_client, service_one, - mock_get_letter_organisations, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): response = logged_in_client.get(url_for( 'main.service_settings', service_id=service_one['id'] @@ -235,8 +241,7 @@ def test_letter_contact_block_shows_none_if_not_set( single_reply_to_email_address, no_letter_contact_blocks, single_sms_sender, - mock_get_letter_organisations, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): service_one['permissions'] = ['letter'] response = logged_in_client.get(url_for( @@ -256,8 +261,7 @@ def test_escapes_letter_contact_block( single_reply_to_email_address, single_sms_sender, injected_letter_contact_block, - mock_get_letter_organisations, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): service_one['permissions'] = ['letter'] response = logged_in_client.get(url_for( @@ -303,11 +307,10 @@ def test_should_redirect_after_change_service_name( def test_show_restricted_service( logged_in_client, service_one, - mock_get_letter_organisations, single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): response = logged_in_client.get(url_for('main.service_settings', service_id=service_one['id'])) page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') @@ -341,8 +344,7 @@ def test_show_live_service( single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_letter_organisations, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): response = logged_in_client.get(url_for('main.service_settings', service_id=service_one['id'])) page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') @@ -355,7 +357,7 @@ def test_switch_service_to_restricted( service_one, mock_get_live_service, mock_update_service, - mock_get_inbound_number_for_service + mock_get_inbound_number_for_service, ): response = logged_in_platform_admin_client.get( url_for('main.service_switch_live', service_id=service_one['id'])) @@ -404,7 +406,7 @@ def test_should_redirect_after_service_name_confirmation( service_one, mock_update_service, mock_verify_password, - mock_get_inbound_number_for_service + mock_get_inbound_number_for_service, ): service_id = service_one['id'] service_new_name = 'New Name' @@ -468,8 +470,7 @@ def test_should_redirect_after_request_to_go_live( single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_letter_organisations, - mock_get_inbound_number_for_service, + mock_get_service_settings_page_common ): mock_post = mocker.patch( 'app.main.views.feedback.requests.post', @@ -567,9 +568,8 @@ def test_route_permissions( single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_letter_organisations, route, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): validate_route_permission( mocker, @@ -627,9 +627,8 @@ def test_route_for_platform_admin( single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_letter_organisations, route, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): validate_route_permission(mocker, app_, @@ -697,11 +696,10 @@ def test_enabling_and_disabling_email_and_sms( def test_and_more_hint_appears_on_settings_with_more_than_just_a_single_sender( client_request, service_one, - mock_get_letter_organisations, - mock_get_inbound_number_for_service, multiple_reply_to_email_addresses, multiple_letter_contact_blocks, - multiple_sms_senders + multiple_sms_senders, + mock_get_service_settings_page_common, ): service_one['permissions'] = ['email', 'sms', 'letter'] @@ -1240,11 +1238,10 @@ def test_shows_research_mode_indicator( logged_in_client, service_one, mocker, - mock_get_letter_organisations, single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): service_one['research_mode'] = True mocker.patch('app.service_api_client.update_service_with_properties', return_value=service_one) @@ -1260,11 +1257,10 @@ def test_shows_research_mode_indicator( def test_does_not_show_research_mode_indicator( logged_in_client, service_one, - mock_get_letter_organisations, single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): response = logged_in_client.get(url_for('main.service_settings', service_id=service_one['id'])) assert response.status_code == 200 @@ -1575,6 +1571,7 @@ def test_should_set_organisation_type( def test_should_show_page_to_set_sms_allowance( logged_in_platform_admin_client, + mock_get_free_sms_fragment_limit ): response = logged_in_platform_admin_client.get(url_for( 'main.set_free_sms_allowance', @@ -1584,8 +1581,10 @@ def test_should_show_page_to_set_sms_allowance( page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') assert normalize_spaces(page.select_one('label').text) == 'Numbers of text message fragments per year' + mock_get_free_sms_fragment_limit.assert_called_once_with(SERVICE_ONE_ID) +@freeze_time("2017-04-01 11:09:00.061258") @pytest.mark.parametrize('given_allowance, expected_api_argument', [ ('1', 1), ('250000', 250000), @@ -1596,7 +1595,10 @@ def test_should_set_sms_allowance( mock_update_service, given_allowance, expected_api_argument, + mock_get_free_sms_fragment_limit, + mock_create_or_update_free_sms_fragment_limit, ): + response = logged_in_platform_admin_client.post( url_for( 'main.set_free_sms_allowance', @@ -1613,6 +1615,11 @@ def test_should_set_sms_allowance( SERVICE_ONE_ID, free_sms_fragment_limit=expected_api_argument, ) + # Not assert until using the annual_billing end points + # mock_create_or_update_free_sms_fragment_limit.assert_called_with( + # SERVICE_ONE_ID, + # expected_api_argument + # ) def test_switch_service_enable_letters( @@ -1831,8 +1838,7 @@ def test_archive_service_prompts_user( single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_letter_organisations, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): mocked_fn = mocker.patch('app.service_api_client.post') @@ -1850,8 +1856,7 @@ def test_cant_archive_inactive_service( single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_letter_organisations, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common ): service_one['active'] = False @@ -1884,8 +1889,7 @@ def test_suspend_service_prompts_user( single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_letter_organisations, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): mocked_fn = mocker.patch('app.service_api_client.post') @@ -1904,8 +1908,7 @@ def test_cant_suspend_inactive_service( single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_letter_organisations, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): service_one['active'] = False @@ -1941,8 +1944,7 @@ def test_resume_service_prompts_user( single_letter_contact_block, single_sms_sender, mocker, - mock_get_letter_organisations, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common, ): service_one['active'] = False mocked_fn = mocker.patch('app.service_api_client.post') @@ -1962,8 +1964,7 @@ def test_cant_resume_active_service( single_reply_to_email_address, single_letter_contact_block, single_sms_sender, - mock_get_letter_organisations, - mock_get_inbound_number_for_service + mock_get_service_settings_page_common ): response = logged_in_platform_admin_client.get(url_for('main.service_settings', service_id=service_one['id'])) @@ -2027,6 +2028,7 @@ def test_service_settings_when_inbound_number_is_not_set( single_sms_sender, mocker, mock_get_letter_organisations, + mock_get_free_sms_fragment_limit, ): mocker.patch('app.inbound_number_client.get_inbound_sms_number_for_service', return_value={'data': {}}) diff --git a/tests/app/notify_client/test_billing_client.py b/tests/app/notify_client/test_billing_client.py index 250ad24cd..1ba7a4be0 100644 --- a/tests/app/notify_client/test_billing_client.py +++ b/tests/app/notify_client/test_billing_client.py @@ -25,3 +25,43 @@ def test_get_get_service_usage_calls_correct_endpoint(mocker, api_user_active): client.get_service_usage(service_id, 2017) mock_get.assert_called_once_with(expected_url, params={'year': 2017}) + + +def test_get_free_sms_fragment_limit_for_year_correct_endpoint(mocker, api_user_active): + service_id = uuid.uuid4() + expected_url = '/service/{}/billing/free-sms-fragment-limit'.format(service_id) + client = BillingAPIClient() + + mock_get = mocker.patch('app.notify_client.billing_api_client.BillingAPIClient.get') + + client.get_free_sms_fragment_limit_for_year(service_id, year=1999) + mock_get.assert_called_once_with(expected_url, params={'financial_year_start': 1999}) + + +def test_post_free_sms_fragment_limit_for_current_year_endpoint(mocker, api_user_active): + service_id = uuid.uuid4() + sms_limit_data = {'free_sms_fragment_limit': 1111, 'financial_year_start': None} + mock_post = mocker.patch('app.notify_client.billing_api_client.BillingAPIClient.post') + client = BillingAPIClient() + + client.create_or_update_free_sms_fragment_limit(service_id=service_id, free_sms_fragment_limit=1111) + + mock_post.assert_called_once_with( + url='/service/{}/billing/free-sms-fragment-limit'.format(service_id), + data=sms_limit_data + ) + + +def test_post_free_sms_fragment_limit_for_year_endpoint(mocker, api_user_active): + service_id = uuid.uuid4() + sms_limit_data = {'free_sms_fragment_limit': 1111, 'financial_year_start': 2017} + mock_post = mocker.patch('app.notify_client.billing_api_client.BillingAPIClient.post') + client = BillingAPIClient() + + client.create_or_update_free_sms_fragment_limit(service_id=service_id, + free_sms_fragment_limit=1111, + year=2017) + mock_post.assert_called_once_with( + url='/service/{}/billing/free-sms-fragment-limit'.format(service_id), + data=sms_limit_data + ) diff --git a/tests/conftest.py b/tests/conftest.py index 925456a4e..85a5c56ab 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2452,6 +2452,29 @@ def mock_get_aggregate_platform_stats(mocker): return mocker.patch('app.service_api_client.get_aggregate_platform_stats', return_value=stats) +@pytest.fixture(scope='function') +def mock_get_free_sms_fragment_limit(mocker): + sample_limit = 250000 + return mocker.patch('app.billing_api_client.get_free_sms_fragment_limit_for_year', + return_value=sample_limit) + + +@pytest.fixture(scope='function') +def mock_create_or_update_free_sms_fragment_limit(mocker): + sample_limit = 250000 + return mocker.patch('app.billing_api_client.create_or_update_free_sms_fragment_limit', + return_value=sample_limit) + + +@pytest.fixture(scope='function') +def mock_get_free_sms_fragment_limit_for_all_years(mocker): + sample_limit = [{'financial_year_start': 2016, 'free_sms_fragment_limit': 250000}, + {'financial_year_start': 2017, 'free_sms_fragment_limit': 500000}] + + return mocker.patch('app.billing_api_client.get_free_sms_fragment_limit_for_all_years', + return_value=sample_limit) + + @contextmanager def set_config(app, name, value): old_val = app.config.get(name)