Updated code and added tests

This commit is contained in:
Ken Tsang
2017-04-25 19:03:59 +01:00
parent 55a0ed22d9
commit 260dfb1e32
4 changed files with 215 additions and 14 deletions

View File

@@ -262,22 +262,57 @@ def get_months_for_year(start, end, year):
return [datetime(year, month, 1) for month in range(start, end)]
def get_total_units_for_month(monthly_usage):
total = 0
for rate_group in monthly_usage:
total += rate_group['units'] * rate_group['multiplier']
return total
def get_free_paid_breakdown_for_billable_units(year, billable_units):
cumulative = 0
for month in get_months_for_financial_year(year):
previous_cumulative = cumulative
monthly_usage = billable_units.get(month, 0)
monthly_usage = get_total_units_for_month(billable_units.get(month, []))
cumulative += monthly_usage
breakdown = get_free_paid_breakdown_for_month(
cumulative, previous_cumulative, monthly_usage
cumulative, previous_cumulative, billable_units.get(month, [])
)
yield {
'name': month,
'paid': breakdown['paid'],
'free': breakdown['free']
'free': breakdown['free'],
'rate_groups': breakdown['rate_groups']
}
def get_rate_groups(monthly_usage, free_allowance=0):
rate_groups = []
for rate_group in monthly_usage:
free_units = 0
units = rate_group["units"]
if free_allowance > 0:
units = rate_group["units"] * rate_group["multiplier"] - free_allowance
if units < 0:
free_units = rate_group["units"] * rate_group["multiplier"]
free_allowance = abs(units)
units = 0
else:
free_units = free_allowance
free_allowance = 0
rate_group = {
"international": rate_group["international"],
"free_units": free_units,
"units": units,
"multiplier": rate_group["multiplier"]
}
rate_groups.append(rate_group)
return rate_groups
def get_free_paid_breakdown_for_month(
cumulative,
previous_cumulative,
@@ -285,20 +320,25 @@ def get_free_paid_breakdown_for_month(
):
allowance = 250000
total_monthly_units = get_total_units_for_month(monthly_usage)
if cumulative < allowance:
return {
'paid': 0,
'free': monthly_usage,
'free': total_monthly_units,
}
elif previous_cumulative < allowance:
remaining_allowance = allowance - previous_cumulative
return {
'paid': monthly_usage - (allowance - previous_cumulative),
'free': allowance - previous_cumulative
'paid': total_monthly_units - remaining_allowance,
'free': remaining_allowance,
'rate_groups': get_rate_groups(monthly_usage, remaining_allowance)
}
else:
return {
'paid': monthly_usage,
'free': 0
'paid': total_monthly_units,
'free': 0,
'rate_groups': get_rate_groups(monthly_usage)
}

View File

@@ -82,12 +82,22 @@
smallest=True
) }}
<ul>
{% if month.free %}
<li class="tabular-numbers">{{ "{:,}".format(month.free) }} free text messages</li>
{% endif %}
{% if month.paid %}
<li class="tabular-numbers">{{ "{:,}".format(month.paid) }} text messages at
{{- ' {:.2f}p'.format(sms_rate * 100) }}</li>
{% if month.rate_groups %}
rate_group {{ month.rate_groups|length }}
{% for rate in month.rate_groups %}
{% if rate.free_units %}
<li class="tabular-numbers">{{ "{:,}".format(rate.free_units) }} {% if rate.international %}international{% else %}UK{% endif %} free text messages</li>
{% endif %}
{% if rate.units %}
<li class="tabular-numbers">{{ "{:,}".format(rate.units) }} {% if rate.international %}international{% else %}UK{% endif %} text messages at
{{- ' {:.2f}p'.format(rate.multiplier * sms_rate * 100) }}</li>
{% endif %}
{% endfor %}
{% else %}
{% if month.paid %}
<li class="tabular-numbers">{{ "{:,}".format(month.paid) }} text messages at
{{- ' {:.2f}p'.format(sms_rate * 100) }}</li>
{% endif %}
{% endif %}
{% if not (month.free or month.paid) %}
<li aria-hidden="true"></li>

View File

@@ -240,6 +240,83 @@ def test_usage_page(
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,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
def test_usage_page_with_year_argument(
logged_in_client,
mock_get_usage,

View File

@@ -1336,6 +1336,80 @@ def mock_get_billable_units(mocker):
'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
}}
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": 249900
},
{
"international": True,
"rate": 1.65,
"multiplier": 1,
"units": 1000
},
{
"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)
@pytest.fixture(scope='function')
def mock_events(mocker):
def _create_event(event_type, event_data):