diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py
index 3f8c66cff..347f522df 100644
--- a/app/main/views/dashboard.py
+++ b/app/main/views/dashboard.py
@@ -102,19 +102,18 @@ def template_history(service_id):
@user_has_permissions('manage_settings', admin_override=True)
def usage(service_id):
year, current_financial_year = requested_and_current_financial_year(request)
- monthly_breakdown = get_free_paid_breakdown_for_billable_units(
- year, service_api_client.get_billable_units(service_id, year))
return render_template(
'views/usage.html',
- months=list(monthly_breakdown),
+ months=list(get_free_paid_breakdown_for_billable_units(
+ year, service_api_client.get_billable_units(service_id, year)
+ )),
selected_year=year,
years=get_tuples_of_financial_years(
partial(url_for, '.usage', service_id=service_id),
start=current_financial_year - 1,
end=current_financial_year + 1,
),
- # **calculate_usage(dict(monthly_breakdown))
- **calculate_usage(service_api_client.get_service_usage(service_id, year)['data'], monthly_breakdown)
+ **calculate_usage(service_api_client.get_service_usage(service_id, year))
)
@@ -190,7 +189,7 @@ def get_dashboard_partials(service_id):
**calculate_usage(service_api_client.get_service_usage(
service_id,
get_current_financial_year(),
- )['data'])
+ ))
),
}
@@ -202,15 +201,13 @@ def get_dashboard_totals(statistics):
return statistics
-def calculate_usage(usage, monthly_breakdown):
+def calculate_usage(usage):
# TODO: Don't hardcode these - get em from the API
sms_free_allowance = 250000
- sms_rate = 0.0165
+ sms_rate = usage[0].get("rate", 0)
+ sms_sent = get_sum_billing_units(breakdown for breakdown in usage if breakdown['notification_type'] == 'sms')
+ emails_sent = [breakdown["billing_units"] for breakdown in usage if breakdown['notification_type'] == 'email'][0]
- sms_sent = get_sum_units(usage.get('sms_breakdown', []))
- emails_sent = usage.get('email_count', 0)
- sms_breakdown = get_sms_breakdown_adjusted_free_allowance(
- usage.get('sms_breakdown', []), sms_free_allowance)
return {
'emails_sent': emails_sent,
'sms_free_allowance': sms_free_allowance,
@@ -218,8 +215,6 @@ def calculate_usage(usage, monthly_breakdown):
'sms_allowance_remaining': max(0, (sms_free_allowance - sms_sent)),
'sms_chargeable': max(0, sms_sent - sms_free_allowance),
'sms_rate': sms_rate,
- 'sms_breakdown': sms_breakdown,
- 'sms_free_units_used': usage.get('free_units_used', 0)
}
@@ -266,67 +261,29 @@ def get_months_for_year(start, end, year):
return [datetime(year, month, 1) for month in range(start, end)]
-def get_sum_billable_units(usage):
- return sum(rate['units'] * rate['multiplier'] for rate in usage)
+def get_sum_billing_units(billing_units, month=None):
+ if month:
+ return sum(b['billing_units'] * b.get('rate_multiplier', 1) for b in billing_units if b['month'] == month)
+ return sum(b['billing_units'] * b.get('rate_multiplier', 1) for b in billing_units)
-def get_sum_units(usage):
- return sum(rate['units'] for rate in usage)
-
-
-def get_sum_free_units(usage):
- return sum(rate.get('free_units', 0) * rate['multiplier'] for rate in usage)
-
-
-def get_free_paid_breakdown_for_billable_units(year, billable_units):
+def get_free_paid_breakdown_for_billable_units(year, billing_units):
cumulative = 0
for month in get_months_for_financial_year(year):
previous_cumulative = cumulative
- monthly_usage = get_sum_billable_units(billable_units.get(month, []))
+ monthly_usage = get_sum_billing_units(billing_units, month)
cumulative += monthly_usage
breakdown = get_free_paid_breakdown_for_month(
- cumulative, previous_cumulative, billable_units.get(month, [])
+ cumulative, previous_cumulative,
+ [billing_month for billing_month in billing_units if billing_month['month'] == month]
)
yield {
'name': month,
'paid': breakdown['paid'],
- 'free': breakdown['free'],
- 'sms_breakdown': breakdown.get('sms_breakdown', []),
- 'free_units_used': get_sum_free_units(breakdown.get('sms_breakdown', []))
+ 'free': breakdown['free']
}
-def get_sms_breakdown_adjusted_free_allowance(breakdown_list, free_allowance=0):
- sms_breakdown = []
-
- for breakdown in breakdown_list:
- free_units = 0
- if free_allowance > 0:
- normalised_units = breakdown["units"] * breakdown["multiplier"]
- billable_units = normalised_units - free_allowance
-
- if billable_units <= 0:
- free_units = breakdown["units"]
- free_allowance = abs(billable_units)
- else:
- free_units = int(free_allowance / breakdown["multiplier"])
-
- if free_allowance < normalised_units:
- free_allowance = 0
- else:
- free_allowance -= normalised_units
-
- adj_breakdown = {
- "international": breakdown["international"],
- "free_units": free_units,
- "units": breakdown["units"] - free_units,
- "multiplier": breakdown["multiplier"]
- }
- sms_breakdown.append(adj_breakdown)
-
- return sms_breakdown
-
-
def get_free_paid_breakdown_for_month(
cumulative,
previous_cumulative,
@@ -334,25 +291,23 @@ def get_free_paid_breakdown_for_month(
):
allowance = 250000
- total_monthly_billable_units = get_sum_billable_units(monthly_usage)
+ total_monthly_billing_units = get_sum_billing_units(monthly_usage)
if cumulative < allowance:
return {
'paid': 0,
- 'free': total_monthly_billable_units,
+ 'free': total_monthly_billing_units,
}
elif previous_cumulative < allowance:
remaining_allowance = allowance - previous_cumulative
return {
- 'paid': total_monthly_billable_units - remaining_allowance,
+ 'paid': total_monthly_billing_units - remaining_allowance,
'free': remaining_allowance,
- 'sms_breakdown': get_sms_breakdown_adjusted_free_allowance(monthly_usage, remaining_allowance)
}
else:
return {
- 'paid': total_monthly_billable_units,
+ 'paid': total_monthly_billing_units,
'free': 0,
- 'sms_breakdown': get_sms_breakdown_adjusted_free_allowance(monthly_usage)
}
diff --git a/app/notify_client/service_api_client.py b/app/notify_client/service_api_client.py
index 5394ad1a6..dc48d0043 100644
--- a/app/notify_client/service_api_client.py
+++ b/app/notify_client/service_api_client.py
@@ -217,7 +217,7 @@ class ServiceAPIClient(NotifyAdminAPIClient):
def get_service_usage(self, service_id, year=None):
return self.get(
- '/service/{0}/fragment/aggregate_statistics'.format(service_id),
+ '/service/{0}/yearly-usage'.format(service_id),
params=dict(year=year)
)
@@ -231,7 +231,10 @@ class ServiceAPIClient(NotifyAdminAPIClient):
return self.put(url='/service/{}/whitelist'.format(service_id), data=data)
def get_billable_units(self, service_id, year):
- return self.get(url='/service/{}/billable-units?year={}'.format(service_id, year))
+ return self.get(
+ '/service/{0}/monthly-usage'.format(service_id),
+ params=dict(year=year)
+ )
class ServicesBrowsableItem(BrowsableItem):
diff --git a/app/templates/views/usage.html b/app/templates/views/usage.html
index 6ccf58f7e..3b8fe412d 100644
--- a/app/templates/views/usage.html
+++ b/app/templates/views/usage.html
@@ -82,22 +82,12 @@
smallest=True
) }}
- {% if month.rate_groups %}
- rate_group {{ month.rate_groups|length }}
- {% for rate in month.rate_groups %}
- {% if rate.free_units %}
- - {{ "{:,}".format(rate.free_units) }} {% if rate.international %}international{% else %}UK{% endif %} free text messages
- {% endif %}
- {% if rate.units %}
- - {{ "{:,}".format(rate.units) }} {% if rate.international %}international{% else %}UK{% endif %} text messages at
- {{- ' {:.2f}p'.format(rate.multiplier * sms_rate * 100) }}
- {% endif %}
- {% endfor %}
- {% else %}
- {% if month.paid %}
- - {{ "{:,}".format(month.paid) }} text messages at
- {{- ' {:.2f}p'.format(sms_rate * 100) }}
- {% endif %}
+ {% if month.free %}
+ - {{ "{:,}".format(month.free) }} free text messages
+ {% endif %}
+ {% if month.paid %}
+ - {{ "{:,}".format(month.paid) }} text messages at
+ {{- ' {:.2f}p'.format(sms_rate * 100) }}
{% endif %}
{% if not (month.free or month.paid) %}
- –
diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py
index 29306fc4c..b9b8605b1 100644
--- a/tests/app/main/views/test_dashboard.py
+++ b/tests/app/main/views/test_dashboard.py
@@ -11,7 +11,6 @@ from app.main.views.dashboard import (
get_dashboard_totals,
format_monthly_stats_to_list,
get_free_paid_breakdown_for_billable_units,
- get_sms_breakdown_adjusted_free_allowance,
aggregate_status_types,
format_template_stats_to_list,
get_tuples_of_financial_years,
@@ -224,95 +223,22 @@ def test_usage_page(
assert normalize_spaces(nav_links[0].text) == '2010 to 2011 financial year'
assert normalize_spaces(nav.find('li', {'aria-selected': 'true'}).text) == '2011 to 2012 financial year'
assert normalize_spaces(nav_links[1].text) == '2012 to 2013 financial year'
-
- assert '123' in cols[0].text
- assert 'Emails' in cols[0].text
-
- assert '456,123' in cols[1].text
+ assert '252,190' in cols[1].text
assert 'Text messages' in cols[1].text
table = page.find('table').text.strip()
+ assert '249,860 free text messages' in table
+ assert '40 free text messages' in table
+ assert '960 text messages at 1.65p' in table
+
assert 'April' in table
+ assert 'February' in table
assert 'March' in table
- assert '123 free text messages' in table
- assert '£3,403.06' in table
- assert '249,877 free text messages' in table
- assert '206,246 text messages at 1.65p' in table
-
-
-@freeze_time("2012-03-31 12:12:12")
-def test_international_usage_page(
- logged_in_client,
- mock_get_international_usage,
- mock_get_billable_international_units,
-):
- response = logged_in_client.get(url_for('main.usage', service_id=SERVICE_ONE_ID))
-
- assert response.status_code == 200
-
- mock_get_billable_international_units.assert_called_once_with(SERVICE_ONE_ID, 2011)
- mock_get_international_usage.assert_called_once_with(SERVICE_ONE_ID, 2011)
-
- page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
-
- cols = page.find_all('div', {'class': 'column-half'})
- nav = page.find('ul', {'class': 'pill', 'role': 'tablist'})
- nav_links = nav.find_all('a')
-
- assert normalize_spaces(nav_links[0].text) == '2010 to 2011 financial year'
- assert normalize_spaces(nav.find('li', {'aria-selected': 'true'}).text) == '2011 to 2012 financial year'
- assert normalize_spaces(nav_links[1].text) == '2012 to 2013 financial year'
-
- assert '0' in cols[0].text
- assert 'Emails' in cols[0].text
-
- assert '252,390' in cols[1].text
- assert 'Text messages' in cols[1].text
-
- table = page.find('table').text.strip()
-
- print(table)
-
- assert '249,900 UK free text messages' in table
- assert '100 international free text messages' in table
- assert '900 international text messages at 1.65p' in table
- assert 'April' in table
- assert 'March' in table
- assert '£20.30' in table
- assert '£19.14' in table
-
-
-@freeze_time("2012-03-31 12:12:12")
-def test_international_usage_page(
- logged_in_client,
- mock_get_international_usage,
- mock_get_billable_international_units,
-):
- response = logged_in_client.get(url_for('main.usage', service_id=SERVICE_ONE_ID))
-
- assert response.status_code == 200
-
- mock_get_billable_international_units.assert_called_once_with(SERVICE_ONE_ID, 2011)
- mock_get_international_usage.assert_called_once_with(SERVICE_ONE_ID, 2011)
-
- page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
-
- cols = page.find_all('div', {'class': 'column-half'})
- nav = page.find('ul', {'class': 'pill', 'role': 'tablist'})
- nav_links = nav.find_all('a')
-
- assert '252,180' in cols[1].text
- assert 'Text messages' in cols[1].text
-
- table = page.find('table').text.strip()
-
- assert '250000 free allowance used' in table
- assert '20 international text at 4.95p' in table
- assert 'April' in table
- assert 'March' in table
- assert '£0.99' in table
+ assert '£15.84' in table
+ assert '140 free text messages' in table
assert '£20.30' in table
+ assert '1,230 text messages at 1.65p' in table
def test_usage_page_with_year_argument(
@@ -627,110 +553,40 @@ 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):
with now:
- assert list(get_free_paid_breakdown_for_billable_units(
- 2016, {
- 'April': 100000,
- 'May': 100000,
- 'June': 100000,
- 'February': 1234
- }
- )) == [
- {'name': 'April', 'free': 100000, 'paid': 0},
- {'name': 'May', 'free': 100000, 'paid': 0},
- {'name': 'June', 'free': 50000, 'paid': 50000},
- {'name': 'July', 'free': 0, 'paid': 0},
- {'name': 'August', 'free': 0, 'paid': 0},
- {'name': 'September', 'free': 0, 'paid': 0},
- {'name': 'October', 'free': 0, 'paid': 0},
- {'name': 'November', 'free': 0, 'paid': 0},
- {'name': 'December', 'free': 0, 'paid': 0},
- {'name': 'January', 'free': 0, 'paid': 0},
- {'name': 'February', 'free': 0, 'paid': 1234},
- {'name': 'March', 'free': 0, 'paid': 0}
- ][:expected_number_of_months]
-
-
-@pytest.mark.parametrize(
- 'usage, expected_breakdown', [
- (
- [
- {"international": False, "multiplier": 1, "units": 240000},
- {"international": True, "multiplier": 2, "units": 20},
- ],
- [
- {'units': 0, 'free_units': 240000, 'international': False, 'multiplier': 1},
- {'units': 0, 'free_units': 20, 'international': True, 'multiplier': 2}
- ]
- ),
- (
- [
- {"international": False, "multiplier": 1, "units": 250000},
- {"international": True, "multiplier": 2, "units": 20},
- ],
- [
- {'units': 0, 'free_units': 250000, 'international': False, 'multiplier': 1},
- {'units': 20, 'free_units': 0, 'international': True, 'multiplier': 2}
- ]
- ),
- (
- [
- {"international": False, "multiplier": 1, "units": 300000},
- {"international": True, "multiplier": 2, "units": 20},
- ],
- [
- {'units': 50000, 'free_units': 250000, 'international': False, 'multiplier': 1},
- {'units': 20, 'free_units': 0, 'international': True, 'multiplier': 2}
- ]
- ),
- (
- [
- {"international": False, "rate": 1.65, "multiplier": 1, "units": 249700},
- {"international": True, "rate": 1.65, "multiplier": 1, "units": 100},
- {"international": True, "rate": 1.65, "multiplier": 2, "units": 100},
- {"international": True, "rate": 1.65, "multiplier": 3, "units": 20},
- ],
- [
- {'international': False, 'free_units': 249700, 'units': 0, 'multiplier': 1},
- {'international': True, 'free_units': 100, 'units': 0, 'multiplier': 1},
- {'international': True, 'free_units': 100, 'units': 0, 'multiplier': 2},
- {'international': True, 'free_units': 0, 'units': 20, 'multiplier': 3}
- ]
- ),
- (
- [
- {"international": False, "rate": 1.65, "multiplier": 1, "units": 249600},
- {"international": True, "rate": 1.65, "multiplier": 1, "units": 100},
- {"international": True, "rate": 1.65, "multiplier": 2, "units": 100},
- {"international": True, "rate": 1.65,"multiplier": 3, "units": 20},
- ],
- [
- {'units': 0, 'free_units': 249600, 'international': False, 'multiplier': 1},
- {'units': 0, 'free_units': 100, 'international': True, 'multiplier': 1},
- {'units': 0, 'free_units': 100, 'international': True, 'multiplier': 2},
- {'units': 0, 'free_units': 20, 'international': True, 'multiplier': 3}
- ]
- ),
- (
- [
- {"international": False, "rate": 1.65, "multiplier": 1, "units": 249800},
- {"international": True, "rate": 1.65, "multiplier": 1, "units": 100},
- {"international": True, "rate": 1.65, "multiplier": 2, "units": 100},
- {"international": True, "rate": 1.65,"multiplier": 3, "units": 20},
- ],
- [
- {'units': 0, 'free_units': 249800, 'international': False, 'multiplier': 1},
- {'units': 0, 'free_units': 100, 'international': True, 'multiplier': 1},
- {'units': 50, 'free_units': 50, 'international': True, 'multiplier': 2},
- {'units': 20, 'free_units': 0, 'international': True, 'multiplier': 3}
+ billing_units = get_free_paid_breakdown_for_billable_units(
+ 2016, [
+ {
+ 'month': 'April', 'international': False, 'rate_multiplier': 1,
+ 'notification_type': 'sms', 'rate': 1.65, 'billing_units': 100000
+ },
+ {
+ 'month': 'May', 'international': False, 'rate_multiplier': 1,
+ 'notification_type': 'sms', 'rate': 1.65, 'billing_units': 100000
+ },
+ {
+ 'month': 'June', 'international': False, 'rate_multiplier': 1,
+ 'notification_type': 'sms', 'rate': 1.65, 'billing_units': 100000
+ },
+ {
+ 'month': 'February', 'international': False, 'rate_multiplier': 1,
+ 'notification_type': 'sms', 'rate': 1.65, 'billing_units': 2000
+ },
]
)
- ]
-)
-def test_get_sms_breakdown_adjusted_free_allowance(usage, expected_breakdown):
- free_allowance = 250000
- breakdown = get_sms_breakdown_adjusted_free_allowance(usage, free_allowance)
- print(breakdown)
- assert breakdown == expected_breakdown
+ assert list(billing_units) == [
+ {'free': 100000, 'name': 'April', 'paid': 0},
+ {'free': 100000, 'name': 'May', 'paid': 0},
+ {'free': 50000, 'name': 'June', 'paid': 50000},
+ {'free': 0, 'name': 'July', 'paid': 0},
+ {'free': 0, 'name': 'August', 'paid': 0},
+ {'free': 0, 'name': 'September', 'paid': 0},
+ {'free': 0, 'name': 'October', 'paid': 0},
+ {'free': 0, 'name': 'November', 'paid': 0},
+ {'free': 0, 'name': 'December', 'paid': 0},
+ {'free': 0, 'name': 'January', 'paid': 0},
+ {'free': 0, 'name': 'February', 'paid': 2000},
+ {'free': 0, 'name': 'March', 'paid': 0}
+ ][:expected_number_of_months]
def test_format_template_stats_to_list_with_no_stats():
diff --git a/tests/conftest.py b/tests/conftest.py
index 612cc1c47..380f1c733 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1315,10 +1315,18 @@ def mock_get_template_statistics_for_template(mocker, service_one):
@pytest.fixture(scope='function')
def mock_get_usage(mocker, service_one, fake_uuid):
def _get_usage(service_id, year=None):
- return {'data': {
- "sms_count": 456123,
- "email_count": 123
- }}
+ return [
+ {"international": False, "rate": 0.0165, "rate_multiplier": 1,
+ "notification_type": "sms", "billing_units": 251500},
+ {"international": True, "rate": 0.0165, "rate_multiplier": 1,
+ "notification_type": "sms", "billing_units": 300},
+ {"international": True, "rate": 0.0165, "rate_multiplier": 2,
+ "notification_type": "sms", "billing_units": 150},
+ {"international": True, "rate": 0.0165, "rate_multiplier": 3,
+ "notification_type": "sms", "billing_units": 30},
+ {"international": False, "rate": 0.0165, "notification_type": "email",
+ "rate_multiplier": None, "billing_units": 1000}
+ ]
return mocker.patch(
'app.service_api_client.get_service_usage', side_effect=_get_usage)
@@ -1327,115 +1335,89 @@ def mock_get_usage(mocker, service_one, fake_uuid):
@pytest.fixture(scope='function')
def mock_get_billable_units(mocker):
def _get_usage(service_id, year):
- return {
- "April": 123,
- "March": 456123
- }
+ return [
+ {
+ 'month': 'April',
+ 'international': False,
+ 'rate_multiplier': 1,
+ 'notification_type': 'sms',
+ 'rate': 1.65,
+ 'billing_units': 249500
+ },
+ {
+ 'month': 'April',
+ 'international': True,
+ 'rate_multiplier': 1,
+ 'notification_type': 'sms',
+ 'rate': 1.65,
+ 'billing_units': 100
+ },
+ {
+ 'month': 'April',
+ 'international': True,
+ 'rate_multiplier': 2,
+ 'notification_type': 'sms',
+ 'rate': 1.65,
+ 'billing_units': 100
+ },
+ {
+ 'month': 'April',
+ 'international': True,
+ 'rate_multiplier': 3,
+ 'notification_type': 'sms',
+ 'rate': 1.65,
+ 'billing_units': 20
+ },
+ {
+ 'month': 'March',
+ 'international': False,
+ 'rate_multiplier': 1,
+ 'notification_type': 'sms',
+ 'rate': 1.65,
+ 'billing_units': 1000
+ },
+ {
+ 'month': 'March',
+ 'international': True,
+ 'rate_multiplier': 1,
+ 'notification_type': 'sms',
+ 'rate': 1.65,
+ 'billing_units': 100
+ },
+ {
+ 'month': 'March',
+ 'international': True,
+ 'rate_multiplier': 2,
+ 'notification_type': 'sms',
+ 'rate': 1.65,
+ 'billing_units': 50
+ },
+ {
+ 'month': 'March',
+ 'international': True,
+ 'rate_multiplier': 3,
+ 'notification_type': 'sms',
+ 'rate': 1.65,
+ 'billing_units': 10
+ },
+ {
+ 'month': 'February',
+ 'international': False,
+ 'rate_multiplier': 1,
+ 'notification_type': 'sms',
+ 'rate': 1.65,
+ 'billing_units': 1000
+ },
+ {
+ 'month': 'February',
+ 'international': True,
+ 'rate_multiplier': 1,
+ 'notification_type': 'sms',
+ 'rate': 1.65,
+ 'billing_units': 100
+ },
- return mocker.patch(
- 'app.service_api_client.get_billable_units', side_effect=_get_usage)
-
-
-@pytest.fixture(scope='function')
-def mock_get_international_usage(mocker, service_one, fake_uuid):
- # def _get_usage(service_id, year=None):
- # return {'data': {
- # "sms_count": 252390,
- # "email_count": 0
- # }}
-
- def _get_usage(service_id, year=None):
- return {'data': {
- "sms_breakdown": [
- {
- "international": False,
- "rate": 1.65,
- "multiplier": 1,
- "units": 250900
- },
- {
- "international": True,
- "rate": 1.65,
- "multiplier": 1,
- "units": 1100
- },
- {
- "international": True,
- "rate": 1.65,
- "multiplier": 2,
- "units": 150
- },
- {
- "international": True,
- "rate": 1.65,
- "multiplier": 3,
- "units": 30
- }
- ],
- "email_count": 0
- }}
-
- return mocker.patch(
- 'app.service_api_client.get_service_usage', side_effect=_get_usage)
-
-
-@pytest.fixture(scope='function')
-def mock_get_billable_international_units(mocker):
- def _get_usage(service_id, year):
- return {
- "April": [
- {
- "international": False,
- "rate": 1.65,
- "multiplier": 1,
- "units": 249700
- },
- {
- "international": True,
- "rate": 1.65,
- "multiplier": 1,
- "units": 100
- },
- {
- "international": True,
- "rate": 1.65,
- "multiplier": 2,
- "units": 100
- },
- {
- "international": True,
- "rate": 1.65,
- "multiplier": 3,
- "units": 20
- },
- ],
- "March": [
- {
- "international": False,
- "rate": 1.65,
- "multiplier": 1,
- "units": 1000
- },
- {
- "international": True,
- "rate": 1.65,
- "multiplier": 1,
- "units": 100
- },
- {
- "international": True,
- "rate": 1.65,
- "multiplier": 2,
- "units": 50
- },
- {
- "international": True,
- "rate": 1.65,
- "multiplier": 3,
- "units": 10
- },
- ]
- }
+ ]
return mocker.patch(
'app.service_api_client.get_billable_units', side_effect=_get_usage)