mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-24 00:07:02 -04:00
Merge pull request #558 from alphagov/template-stats-2
Make template usage on dashboard easier to scan
This commit is contained in:
@@ -1,19 +1,29 @@
|
|||||||
%big-number,
|
%big-number,
|
||||||
.big-number {
|
.big-number {
|
||||||
|
|
||||||
@include bold-48;
|
display: block;
|
||||||
|
|
||||||
|
&-number {
|
||||||
|
@include bold-48;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
&-label {
|
&-label {
|
||||||
@include core-19;
|
@include core-19;
|
||||||
display: block;
|
display: inline-block;
|
||||||
padding-bottom: $gutter-half;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.big-number-smaller {
|
.big-number-smaller {
|
||||||
|
|
||||||
@extend %big-number;
|
@extend %big-number;
|
||||||
@include bold-36($tabular-numbers: true);
|
|
||||||
|
.big-number-number {
|
||||||
|
@include bold-36($tabular-numbers: true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.big-number-with-status {
|
.big-number-with-status {
|
||||||
@@ -22,25 +32,12 @@
|
|||||||
background: $text-colour;
|
background: $text-colour;
|
||||||
color: $white;
|
color: $white;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
margin-bottom: $gutter-half;
|
||||||
&-show-more-link {
|
|
||||||
@include core-16;
|
|
||||||
display: block;
|
|
||||||
padding: 0.75em 0 0.5625em 0;
|
|
||||||
margin-bottom: $gutter-half;
|
|
||||||
text-align: center;
|
|
||||||
border-bottom: 1px solid $border-colour;
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: none;
|
|
||||||
color: $text-colour;
|
|
||||||
border-bottom: 1px solid $brown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.big-number {
|
.big-number {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.big-number-overlay-link {
|
.big-number-overlay-link {
|
||||||
@@ -66,6 +63,8 @@
|
|||||||
&:link,
|
&:link,
|
||||||
&:visited {
|
&:visited {
|
||||||
color: $white;
|
color: $white;
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px solid $white;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -85,6 +84,8 @@
|
|||||||
&:active,
|
&:active,
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $white;
|
color: $white;
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px solid $white;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
34
app/assets/stylesheets/components/show-more.scss
Normal file
34
app/assets/stylesheets/components/show-more.scss
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
.show-more {
|
||||||
|
|
||||||
|
@include core-16;
|
||||||
|
display: block;
|
||||||
|
padding: 0 0;
|
||||||
|
margin: $gutter-half 0 $gutter 0;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid $border-colour;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
|
||||||
|
outline: none;
|
||||||
|
color: $text-colour;
|
||||||
|
box-shadow: 0 -10px 0 0 $yellow;
|
||||||
|
border-color: $yellow;
|
||||||
|
|
||||||
|
span {
|
||||||
|
background: $yellow;
|
||||||
|
outline: none;
|
||||||
|
border-color: $text-colour;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
position: relative;
|
||||||
|
top: -11px;
|
||||||
|
outline: 10px solid white;
|
||||||
|
background: $white;
|
||||||
|
display: inline-block;
|
||||||
|
border-bottom: 1px solid $light-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -50,6 +50,7 @@ $path: '/static/images/';
|
|||||||
@import 'components/vendor/previous-next-navigation';
|
@import 'components/vendor/previous-next-navigation';
|
||||||
@import 'components/pill';
|
@import 'components/pill';
|
||||||
@import 'components/secondary-button';
|
@import 'components/secondary-button';
|
||||||
|
@import 'components/show-more';
|
||||||
|
|
||||||
@import 'views/job';
|
@import 'views/job';
|
||||||
@import 'views/edit-template';
|
@import 'views/edit-template';
|
||||||
|
|||||||
@@ -5,16 +5,45 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.keyline-block {
|
.keyline-block {
|
||||||
|
|
||||||
border-top: 1px solid $border-colour;
|
border-top: 1px solid $border-colour;
|
||||||
padding-top: $gutter-half;
|
padding-top: $gutter-half;
|
||||||
|
}
|
||||||
|
|
||||||
&-show-more-link {
|
.spark-bar {
|
||||||
@include core-16;
|
|
||||||
border-top: 1px solid $border-colour;
|
@include core-16;
|
||||||
border-bottom: 1px solid $border-colour;
|
box-sizing: border-box;
|
||||||
padding: 0.75em 0 0.5625em 0;
|
display: block;
|
||||||
text-align: center;
|
width: 100%;
|
||||||
|
text-align: right;
|
||||||
|
margin-bottom: $gutter-half;
|
||||||
|
height: $gutter-half;
|
||||||
|
color: $govuk-blue;
|
||||||
|
text-align: left;
|
||||||
|
color: $govuk-blue;
|
||||||
|
|
||||||
|
span {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
background: $govuk-blue;
|
||||||
|
color: $white;
|
||||||
|
height: $gutter-half;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
margin: 3px 0 5px 0;
|
||||||
|
transition: width 0.6s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-label {
|
||||||
|
@include bold-19;
|
||||||
|
display: block;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: $govuk-blue;
|
||||||
|
max-width: 100%;
|
||||||
|
background: $white;
|
||||||
|
margin-bottom: $gutter;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,10 +71,14 @@ def service_dashboard_updates(service_id):
|
|||||||
@login_required
|
@login_required
|
||||||
@user_has_permissions('view_activity', admin_override=True)
|
@user_has_permissions('view_activity', admin_override=True)
|
||||||
def template_history(service_id):
|
def template_history(service_id):
|
||||||
|
template_statistics = aggregate_usage(
|
||||||
|
template_statistics_client.get_template_statistics_for_service(service_id)
|
||||||
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
'views/dashboard/all-template-statistics.html',
|
'views/dashboard/all-template-statistics.html',
|
||||||
template_statistics=aggregate_usage(
|
template_statistics=template_statistics,
|
||||||
template_statistics_client.get_template_statistics_for_service(service_id)
|
most_used_template_count=max(
|
||||||
|
[row['usage_count'] for row in template_statistics] or [0]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -197,12 +201,17 @@ def get_dashboard_statistics_for_service(service_id):
|
|||||||
sms_sent = usage['data'].get('sms_count', 0)
|
sms_sent = usage['data'].get('sms_count', 0)
|
||||||
emails_sent = usage['data'].get('email_count', 0)
|
emails_sent = usage['data'].get('email_count', 0)
|
||||||
|
|
||||||
|
template_statistics = aggregate_usage(
|
||||||
|
template_statistics_client.get_template_statistics_for_service(service_id, limit_days=7)
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'statistics': add_rates_to(sum_of_statistics(
|
'statistics': add_rates_to(sum_of_statistics(
|
||||||
statistics_api_client.get_statistics_for_service(service_id, limit_days=7)['data']
|
statistics_api_client.get_statistics_for_service(service_id, limit_days=7)['data']
|
||||||
)),
|
)),
|
||||||
'template_statistics': aggregate_usage(
|
'template_statistics': template_statistics,
|
||||||
template_statistics_client.get_template_statistics_for_service(service_id, limit_days=7)
|
'most_used_template_count': max(
|
||||||
|
[row['usage_count'] for row in template_statistics] or [0]
|
||||||
),
|
),
|
||||||
'emails_sent': emails_sent,
|
'emails_sent': emails_sent,
|
||||||
'sms_free_allowance': sms_free_allowance,
|
'sms_free_allowance': sms_free_allowance,
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
{% macro big_number(number, label, label_link=None, currency='', smaller=False) %}
|
{% macro big_number(number, label, label_link=None, currency='', smaller=False) %}
|
||||||
<div class="big-number{% if smaller %}-smaller{% endif %}">
|
<div class="big-number{% if smaller %}-smaller{% endif %}">
|
||||||
{% if number is number %}
|
<div class="big-number-number">
|
||||||
{% if currency %}
|
{% if number is number %}
|
||||||
{{ "{}{:,.2f}".format(currency, number) }}
|
{% if currency %}
|
||||||
|
{{ "{}{:,.2f}".format(currency, number) }}
|
||||||
|
{% else %}
|
||||||
|
{{ "{}{:,}".format(currency, number) }}
|
||||||
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ "{}{:,}".format(currency, number) }}
|
{{ number }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
</div>
|
||||||
{{ number }}
|
|
||||||
{% endif %}
|
|
||||||
{% if label_link %}
|
{% if label_link %}
|
||||||
<a class="big-number-label" href="{{ label_link }}">{{ label }}</a>
|
<a class="big-number-label" href="{{ label_link }}">{{ label }}</a>
|
||||||
<a class="big-number-overlay-link" href="{{ label_link }}" aria-hidden="true"></a>
|
<a class="big-number-overlay-link" href="{{ label_link }}" aria-hidden="true"></a>
|
||||||
|
|||||||
15
app/templates/components/message-count-label.html
Normal file
15
app/templates/components/message-count-label.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{% macro message_count_label(count, template_type) -%}
|
||||||
|
{%- if template_type == 'sms' -%}
|
||||||
|
{%- if count == 1 -%}
|
||||||
|
text message
|
||||||
|
{%- else -%}
|
||||||
|
text messages
|
||||||
|
{%- endif -%}
|
||||||
|
{%- elif template_type == 'email' -%}
|
||||||
|
{%- if count == 1 -%}
|
||||||
|
email
|
||||||
|
{%- else -%}
|
||||||
|
emails
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endif %} sent
|
||||||
|
{%- endmacro %}
|
||||||
3
app/templates/components/show-more.html
Normal file
3
app/templates/components/show-more.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{% macro show_more(url, label) %}
|
||||||
|
<a href="{{ url }}" class="show-more"><span>{{ label }}</span></a>
|
||||||
|
{% endmacro %}
|
||||||
@@ -5,13 +5,16 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
<h1 class='heading-large'>
|
|
||||||
Templates sent this year
|
<div class="grid-row bottom-gutter">
|
||||||
</h1>
|
<div class="column-half">
|
||||||
<p>
|
<h2 class="heading-large">Templates sent</h2>
|
||||||
1 April 2016 to date
|
</div>
|
||||||
</p>
|
<div class="column-half">
|
||||||
{% with period = "" %}
|
<span class="align-with-heading-copy">1 April 2016 to date</span>
|
||||||
{% include 'views/dashboard/template-statistics.html' %}
|
</div>
|
||||||
{% endwith %}
|
</div>
|
||||||
|
|
||||||
|
{% include 'views/dashboard/template-statistics.html' %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
<div class="dashboard">
|
<div class="dashboard">
|
||||||
|
|
||||||
|
<h1 class="visuallyhidden">Dashboard</h1>
|
||||||
|
|
||||||
{% if not templates and current_user.has_permissions(['send_texts', 'send_emails', 'send_letters'], any_=True) %}
|
{% if not templates and current_user.has_permissions(['send_texts', 'send_emails', 'send_letters'], any_=True) %}
|
||||||
{% include 'views/dashboard/get-started.html' %}
|
{% include 'views/dashboard/get-started.html' %}
|
||||||
{% elif current_user.has_permissions([
|
{% elif current_user.has_permissions([
|
||||||
@@ -20,9 +22,9 @@
|
|||||||
{% include 'views/dashboard/no-permissions-banner.html' %}
|
{% include 'views/dashboard/no-permissions-banner.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h1 class="heading-medium">
|
<h2 class="heading-medium">
|
||||||
In the last 7 days
|
In the last 7 days
|
||||||
</h1>
|
</h2>
|
||||||
{% include 'views/dashboard/today.html' %}
|
{% include 'views/dashboard/today.html' %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,23 +1,26 @@
|
|||||||
{% from "components/table.html" import list_table, field, hidden_field_heading, right_aligned_field_heading %}
|
{% from "components/message-count-label.html" import message_count_label %}
|
||||||
|
|
||||||
{% call(item, row_number) list_table(
|
<dl>
|
||||||
template_statistics,
|
{% for item in template_statistics %}
|
||||||
caption="Templates",
|
<div class="grid-row">
|
||||||
caption_visible=True,
|
|
||||||
empty_message='You haven’t used any templates {}'.format(period),
|
<dt class="column-half">
|
||||||
field_headings=['Template', hidden_field_heading('Type'), hidden_field_heading('Messages sent')],
|
<span class="spark-bar-label">
|
||||||
field_headings_visible=False
|
<a href="{{ url_for('.view_template', service_id=current_service.id, template_id=item.template.id) }}">{{ item.template.name }}</a>
|
||||||
) %}
|
</span>
|
||||||
{% call field() %}
|
</dt>
|
||||||
<a href="{{ url_for('.view_template', service_id=current_service.id, template_id=item.template.id) }}">
|
|
||||||
{{ item.template.name }}
|
|
||||||
</a>
|
|
||||||
{% endcall %}
|
|
||||||
{% call field(align='right') %}
|
|
||||||
{{ item.usage_count }}
|
|
||||||
{% endcall %}
|
|
||||||
{% call field() %}
|
|
||||||
{{'text messages sent' if 'sms' == item.template.template_type else 'emails sent'}}
|
|
||||||
{% endcall %}
|
|
||||||
{% endcall %}
|
|
||||||
|
|
||||||
|
<dd class="column-half">
|
||||||
|
{% if template_statistics|length > 1 %}
|
||||||
|
<span class="spark-bar">
|
||||||
|
<span style="width: {{ item.usage_count / most_used_template_count * 100 }}%"></span>
|
||||||
|
{{ item.usage_count }} {{ message_count_label(item.usage_count, item.template.template_type) }}
|
||||||
|
</span>
|
||||||
|
{% else %}
|
||||||
|
{{ item.usage_count }} {{ message_count_label(item.usage_count, item.template.template_type) }}
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</dl>
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
{% from "components/big-number.html" import big_number, big_number_with_status %}
|
{% from "components/big-number.html" import big_number, big_number_with_status %}
|
||||||
|
{% from "components/show-more.html" import show_more %}
|
||||||
|
{% from "components/message-count-label.html" import message_count_label %}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
data-module="update-content"
|
data-module="update-content"
|
||||||
@@ -11,7 +13,7 @@
|
|||||||
<div class="column-half">
|
<div class="column-half">
|
||||||
{{ big_number_with_status(
|
{{ big_number_with_status(
|
||||||
statistics.emails_requested,
|
statistics.emails_requested,
|
||||||
'email' if statistics.emails_requested == 1 else 'emails',
|
message_count_label(statistics.emails_requested, 'email'),
|
||||||
statistics.emails_failed,
|
statistics.emails_failed,
|
||||||
statistics.get('emails_failure_rate', 0.0),
|
statistics.get('emails_failure_rate', 0.0),
|
||||||
statistics.get('emails_failure_rate', 0)|float > 3,
|
statistics.get('emails_failure_rate', 0)|float > 3,
|
||||||
@@ -22,7 +24,7 @@
|
|||||||
<div class="column-half">
|
<div class="column-half">
|
||||||
{{ big_number_with_status(
|
{{ big_number_with_status(
|
||||||
statistics.sms_requested,
|
statistics.sms_requested,
|
||||||
'text message' if statistics.sms_requested == 1 else 'text messages',
|
message_count_label(statistics.sms_requested, 'sms'),
|
||||||
statistics.sms_failed,
|
statistics.sms_failed,
|
||||||
statistics.get('sms_failure_rate', 0.0),
|
statistics.get('sms_failure_rate', 0.0),
|
||||||
statistics.get('sms_failure_rate', 0)|float > 3,
|
statistics.get('sms_failure_rate', 0)|float > 3,
|
||||||
@@ -31,18 +33,23 @@
|
|||||||
) }}
|
) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="column-whole">
|
<div class="column-whole">
|
||||||
<a class="big-number-with-status-show-more-link" href="{{ url_for('.weekly', service_id=current_service.id) }}">Compare to previous weeks</a>
|
{{ show_more(
|
||||||
|
url_for('.weekly', service_id=current_service.id),
|
||||||
|
'Compare to previous weeks'
|
||||||
|
) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% with period = "in the last 7 days" %}
|
|
||||||
|
{% if template_statistics|length %}
|
||||||
{% include 'views/dashboard/template-statistics.html' %}
|
{% include 'views/dashboard/template-statistics.html' %}
|
||||||
{% endwith %}
|
{{ show_more(
|
||||||
<p class='table-show-more-link'>
|
url_for('.template_history', service_id=current_service.id),
|
||||||
<a href="{{ url_for('.template_history', service_id=current_service.id) }}">See all templates sent this year</a>
|
'See all templates sent this year'
|
||||||
</p>
|
) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if current_user.has_permissions(['manage_settings'], admin_override=True) %}
|
{% if current_user.has_permissions(['manage_settings'], admin_override=True) %}
|
||||||
<h2 class='heading-medium'>Usage</h2>
|
<h2 class='heading-medium'>This year</h2>
|
||||||
|
|
||||||
<div class='grid-row'>
|
<div class='grid-row'>
|
||||||
<div class='column-half'>
|
<div class='column-half'>
|
||||||
@@ -65,9 +72,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="keyline-block-show-more-link">
|
{{ show_more(
|
||||||
<a href="{{ url_for(".usage", service_id=current_service['id']) }}">See breakdown</a>
|
url_for(".usage", service_id=current_service['id']),
|
||||||
</div>
|
'See usage breakdown'
|
||||||
|
) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -86,21 +86,16 @@ def test_should_show_recent_templates_on_dashboard(app_,
|
|||||||
headers = [header.text.strip() for header in page.find_all('h2') + page.find_all('h1')]
|
headers = [header.text.strip() for header in page.find_all('h2') + page.find_all('h1')]
|
||||||
assert 'Test Service' in headers
|
assert 'Test Service' in headers
|
||||||
assert 'In the last 7 days' in headers
|
assert 'In the last 7 days' in headers
|
||||||
template_usage_headers = [th.text.strip() for th in page.thead.find_all('th')]
|
|
||||||
for th in ['Template', 'Type', 'Messages sent']:
|
table_rows = page.find_all('dt')
|
||||||
assert th in template_usage_headers
|
|
||||||
table_rows = page.tbody.find_all('tr')
|
|
||||||
|
|
||||||
assert len(table_rows) == 2
|
assert len(table_rows) == 2
|
||||||
first_row = page.tbody.find_all('tr')[0]
|
|
||||||
table_data = first_row.find_all('td')
|
|
||||||
assert len(table_data) == 3
|
|
||||||
assert table_data[1].text.strip() == '206'
|
|
||||||
|
|
||||||
second_row = page.tbody.find_all('tr')[1]
|
assert page.find_all('dt')[0].text.strip() == 'Pickle feet'
|
||||||
table_data = second_row.find_all('td')
|
assert page.find_all('dd')[0].text.strip() == '206 text messages sent'
|
||||||
assert len(table_data) == 3
|
|
||||||
assert table_data[1].text.strip() == '13'
|
assert page.find_all('dt')[1].text.strip() == 'Brine Shrimp'
|
||||||
|
assert page.find_all('dd')[1].text.strip() == '13 text messages sent'
|
||||||
|
|
||||||
|
|
||||||
def test_should_show_all_templates_on_template_statistics_page(
|
def test_should_show_all_templates_on_template_statistics_page(
|
||||||
@@ -130,20 +125,15 @@ def test_should_show_all_templates_on_template_statistics_page(
|
|||||||
mock_template_stats.assert_called_once_with(SERVICE_ONE_ID)
|
mock_template_stats.assert_called_once_with(SERVICE_ONE_ID)
|
||||||
|
|
||||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||||
headers = [header.text.strip() for header in page.find_all('h2')]
|
table_rows = page.find_all('dt')
|
||||||
table_rows = page.tbody.find_all('tr')
|
|
||||||
|
|
||||||
assert len(table_rows) == 2
|
assert len(table_rows) == 2
|
||||||
|
|
||||||
first_row = page.tbody.find_all('tr')[0]
|
assert page.find_all('dt')[0].text.strip() == 'Pickle feet'
|
||||||
table_data = first_row.find_all('td')
|
assert page.find_all('dd')[0].text.strip() == '206 text messages sent'
|
||||||
assert len(table_data) == 3
|
|
||||||
assert table_data[1].text.strip() == '206'
|
|
||||||
|
|
||||||
second_row = page.tbody.find_all('tr')[1]
|
assert page.find_all('dt')[1].text.strip() == 'Brine Shrimp'
|
||||||
table_data = second_row.find_all('td')
|
assert page.find_all('dd')[1].text.strip() == '13 text messages sent'
|
||||||
assert len(table_data) == 3
|
|
||||||
assert table_data[1].text.strip() == '13'
|
|
||||||
|
|
||||||
|
|
||||||
def _test_dashboard_menu(mocker, app_, usr, service, permissions):
|
def _test_dashboard_menu(mocker, app_, usr, service, permissions):
|
||||||
|
|||||||
Reference in New Issue
Block a user