def test_create_global_stats_sets_failure_rates(fake_uuid):
    services = [
        service_json(fake_uuid, 'a', []),
        service_json(fake_uuid, 'b', [])
    ]
    services[0]['statistics'] = create_stats(
            emails_requested=1,
            emails_delivered=1,
            emails_failed=0,
    )
    services[1]['statistics'] = create_stats(
            emails_requested=2,
            emails_delivered=1,
            emails_failed=1,
    )

    stats = create_global_stats(services)

    assert stats == {
        'email': {
            'delivered': 2,
            'failed': 1,
            'requested': 3,
            'failure_rate': '33.3'
        },
        'sms': {
            'delivered': 0,
            'failed': 0,
            'requested': 0,
            'failure_rate': '0'
        }
    }
Example #2
0
def test_create_global_stats_sets_failure_rates(fake_uuid):
    services = [
        service_json(fake_uuid, 'a', []),
        service_json(fake_uuid, 'b', [])
    ]
    services[0]['statistics'] = create_stats(
        emails_requested=1,
        emails_delivered=1,
        emails_failed=0,
    )
    services[1]['statistics'] = create_stats(
        emails_requested=2,
        emails_delivered=1,
        emails_failed=1,
    )

    stats = create_global_stats(services)

    assert stats == {
        'email': {
            'delivered': 2,
            'failed': 1,
            'requested': 3,
            'failure_rate': '33.3'
        },
        'sms': {
            'delivered': 0,
            'failed': 0,
            'requested': 0,
            'failure_rate': '0'
        }
    }
Example #3
0
def test_organisation_trial_mode_services_shows_all_non_live_services(
    client_request,
    platform_admin_user,
    mock_get_organisation,
    mocker,
    fake_uuid,
):
    mocker.patch(
        'app.organisations_client.get_organisation_services',
        return_value=[
            service_json(id_='1', name='1', restricted=False,
                         active=True),  # live
            service_json(id_='2', name='2', restricted=True,
                         active=True),  # trial
            service_json(id_='3', name='3', restricted=False,
                         active=False),  # archived
        ])

    client_request.login(platform_admin_user)
    page = client_request.get('.organisation_trial_mode_services',
                              org_id=ORGANISATION_ID,
                              _test_page_title=False)

    services = page.select('.browse-list-item')
    assert len(services) == 2

    assert normalize_spaces(services[0].text) == '2'
    assert normalize_spaces(services[1].text) == '3'
    assert services[0].find('a')['href'] == url_for('main.service_dashboard',
                                                    service_id='2')
    assert services[1].find('a')['href'] == url_for('main.service_dashboard',
                                                    service_id='3')
def test_should_show_archived_services_last(
    client,
    platform_admin_user,
    mocker,
    mock_get_detailed_services,
    restricted,
    table_index
):
    services = [
        service_json(name='C', restricted=restricted, active=False, created_at='2002-02-02 12:00:00'),
        service_json(name='B', restricted=restricted, active=True, created_at='2001-01-01 12:00:00'),
        service_json(name='A', restricted=restricted, active=True, created_at='2003-03-03 12:00:00'),
    ]
    services[0]['statistics'] = create_stats()
    services[1]['statistics'] = create_stats()
    services[2]['statistics'] = create_stats()

    mock_get_detailed_services.return_value = {'data': services}
    mock_get_user(mocker, user=platform_admin_user)
    client.login(platform_admin_user)
    response = client.get(url_for('main.platform_admin'))

    assert response.status_code == 200
    mock_get_detailed_services.assert_called_once_with({'detailed': True})
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')

    table_body = page.find_all('table')[table_index].find_all('tbody')[0]
    services = [service.tr for service in table_body.find_all('tbody')]
    assert len(services) == 3
    assert services[0].td.text.strip() == 'A'
    assert services[1].td.text.strip() == 'B'
    assert services[2].td.text.strip() == 'C'
def test_should_show_archived_services_last(
    endpoint,
    platform_admin_client,
    mock_get_detailed_services,
    restricted,
):
    services = [
        service_json(name='C', restricted=restricted, active=False, created_at='2002-02-02 12:00:00'),
        service_json(name='B', restricted=restricted, active=True, created_at='2001-01-01 12:00:00'),
        service_json(name='A', restricted=restricted, active=True, created_at='2003-03-03 12:00:00'),
    ]
    services[0]['statistics'] = create_stats()
    services[1]['statistics'] = create_stats()
    services[2]['statistics'] = create_stats()

    mock_get_detailed_services.return_value = {'data': services}
    response = platform_admin_client.get(url_for(endpoint))

    assert response.status_code == 200
    mock_get_detailed_services.assert_called_once_with({'detailed': True,
                                                        'include_from_test_key': True,
                                                        'only_active': ANY})
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')

    table_body = page.find_all('table')[0].find_all('tbody')[0]
    services = [service.tr for service in table_body.find_all('tbody')]
    assert len(services) == 3
    assert normalize_spaces(services[0].td.text) == 'A'
    assert normalize_spaces(services[1].td.text) == 'B'
    assert normalize_spaces(services[2].td.text) == 'C Archived'
Example #6
0
def test_organisation_trial_mode_services_shows_all_non_live_services(
    client_request,
    platform_admin_user,
    mock_get_organisation,
    mocker,
    fake_uuid,
):
    mocker.patch(
        "app.organisations_client.get_organisation_services",
        return_value=[
            service_json(id_="1", name="1", restricted=False,
                         active=True),  # live
            service_json(id_="2", name="2", restricted=True,
                         active=True),  # trial
            service_json(id_="3", name="3", restricted=False,
                         active=False),  # archived
        ],
    )

    client_request.login(platform_admin_user)
    page = client_request.get(
        ".organisation_trial_mode_services",
        org_id=ORGANISATION_ID,
        _test_page_title=False,
    )

    services = page.select(".browse-list-item")
    assert len(services) == 2

    assert normalize_spaces(services[0].text) == "2"
    assert normalize_spaces(services[1].text) == "3"
    assert services[0].find("a")["href"] == url_for("main.service_dashboard",
                                                    service_id="2")
    assert services[1].find("a")["href"] == url_for("main.service_dashboard",
                                                    service_id="3")
Example #7
0
def test_should_order_services_by_usage_with_inactive_last(
    endpoint,
    restricted,
    research_mode,
    client,
    platform_admin_user,
    mocker,
    mock_get_detailed_services,
    fake_uuid,
):
    services = [
        service_json(fake_uuid, 'My Service 1', [], restricted=restricted, research_mode=research_mode),
        service_json(fake_uuid, 'My Service 2', [], restricted=restricted, research_mode=research_mode),
        service_json(fake_uuid, 'My Service 3', [], restricted=restricted, research_mode=research_mode, active=False)
    ]
    services[0]['statistics'] = create_stats(
        emails_requested=100,
        emails_delivered=25,
        emails_failed=25,
        sms_requested=100,
        sms_delivered=25,
        sms_failed=25
    )

    services[1]['statistics'] = create_stats(
        emails_requested=200,
        emails_delivered=50,
        emails_failed=50,
        sms_requested=200,
        sms_delivered=50,
        sms_failed=50
    )

    services[2]['statistics'] = create_stats(
        emails_requested=200,
        emails_delivered=50,
        emails_failed=50,
        sms_requested=200,
        sms_delivered=50,
        sms_failed=50
    )

    mock_get_detailed_services.return_value = {'data': services}
    mock_get_user(mocker, user=platform_admin_user)
    client.login(platform_admin_user)
    response = client.get(url_for(endpoint))

    assert response.status_code == 200
    mock_get_detailed_services.assert_called_once_with({'detailed': True,
                                                        'include_from_test_key': True,
                                                        'only_active': ANY})
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')

    table_body = page.find_all('table')[0].find_all('tbody')[0]
    services = [service.tr for service in table_body.find_all('tbody')]
    assert len(services) == 3
    assert services[0].td.text.strip() == 'My Service 2'
    assert services[1].td.text.strip() == 'My Service 1'
    assert services[2].td.text.strip() == 'My Service 3'
Example #8
0
def test_should_show_total_on_live_trial_services_pages(
    client,
    platform_admin_user,
    mocker,
    mock_get_detailed_services,
    endpoint,
    fake_uuid,
    expected_big_numbers,
):
    services = [
        service_json(fake_uuid, 'My Service 1', [], restricted=False),
        service_json(fake_uuid, 'My Service 2', [], restricted=True),
    ]
    services[0]['statistics'] = create_stats(
        emails_requested=100,
        emails_delivered=50,
        emails_failed=5,
        sms_requested=200,
        sms_delivered=100,
        sms_failed=10,
        letters_requested=15,
        letters_delivered=12,
        letters_failed=3
    )

    services[1]['statistics'] = create_stats(
        emails_requested=10,
        emails_delivered=5,
        emails_failed=1,
        sms_requested=20,
        sms_delivered=10,
        sms_failed=1,
        letters_requested=30,
        letters_delivered=20,
        letters_failed=10
    )

    mock_get_detailed_services.return_value = {'data': services}

    mock_get_user(mocker, user=platform_admin_user)
    client.login(platform_admin_user)
    response = client.get(url_for(endpoint))
    assert response.status_code == 200
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
    assert (
        normalize_spaces(page.select('.big-number-with-status')[0].text),
        normalize_spaces(page.select('.big-number-with-status')[1].text),
        normalize_spaces(page.select('.big-number-with-status')[2].text),
    ) == expected_big_numbers
def test_find_services_by_name_displays_multiple_services(
    client_request,
    platform_admin_user,
    mocker
):
    client_request.login(platform_admin_user)
    mocker.patch(
        'app.service_api_client.find_services_by_name',
        return_value={"data": [service_json(name="Tadfield Police"), service_json(name="Tadfield Air Base")]}
    )
    document = client_request.post('main.find_services_by_name', _data={"search": "Tadfield"}, _expected_status=200)

    results = document.find_all('li', {'class': 'browse-list-item'})
    assert len(results) == 2
    assert sorted([result.text.strip() for result in results]) == ["Tadfield Air Base", "Tadfield Police"]
def test_shows_research_mode_indicator(app_, service_one, mock_login,
                                       mock_get_user,
                                       active_user_with_permissions,
                                       mock_get_service, mock_has_permissions,
                                       mock_get_organisation, mocker):
    with app_.test_request_context():
        with app_.test_client() as client:
            service = service_json("1234",
                                   "Test Service",
                                   [active_user_with_permissions.id],
                                   message_limit=1000,
                                   active=False,
                                   restricted=True,
                                   research_mode=True)
            mocker.patch('app.service_api_client.get_service',
                         return_value={"data": service})
            mocker.patch(
                'app.service_api_client.update_service_with_properties',
                return_value=service_one)

            client.login(active_user_with_permissions)
            response = client.get(
                url_for('main.service_settings', service_id=service_one['id']))
            assert response.status_code == 200

            page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
            element = page.find('span', {"id": "research-mode"})
            assert element.text == 'research mode'
def test_switch_service_from_research_mode_to_normal(
        app_, service_one, mock_login, mock_get_user,
        active_user_with_permissions, mock_get_service, mock_has_permissions,
        mocker):
    with app_.test_request_context():
        with app_.test_client() as client:
            service = service_json("1234",
                                   "Test Service",
                                   [active_user_with_permissions.id],
                                   message_limit=1000,
                                   active=False,
                                   restricted=True,
                                   research_mode=True)
            mocker.patch('app.service_api_client.get_service',
                         return_value={"data": service})
            mocker.patch(
                'app.service_api_client.update_service_with_properties',
                return_value=service_one)

            client.login(active_user_with_permissions)
            response = client.get(
                url_for('main.service_switch_research_mode',
                        service_id=service_one['id']))
            assert response.status_code == 302
            assert response.location == url_for('main.service_settings',
                                                service_id=service_one['id'],
                                                _external=True)
            app.service_api_client.update_service_with_properties.assert_called_with(
                service_one['id'], {"research_mode": False})
def test_shows_research_mode_indicator(
    app_,
    service_one,
    mock_login,
    mock_get_user,
    active_user_with_permissions,
    mock_get_service,
    mock_has_permissions,
    mock_get_organisation,
    mocker
):
    with app_.test_request_context():
        with app_.test_client() as client:
            service = service_json(
                "1234",
                "Test Service",
                [active_user_with_permissions.id],
                message_limit=1000,
                active=False,
                restricted=True,
                research_mode=True
            )
            mocker.patch('app.service_api_client.get_service', return_value={"data": service})
            mocker.patch('app.service_api_client.update_service_with_properties', return_value=service_one)

            client.login(active_user_with_permissions)
            response = client.get(url_for('main.service_settings', service_id=service_one['id']))
            assert response.status_code == 200

            page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
            element = page.find('span', {"id": "research-mode"})
            assert element.text == 'research mode'
def test_switch_service_from_research_mode_to_normal(
        app_,
        service_one,
        mock_login,
        mock_get_user,
        active_user_with_permissions,
        mock_get_service,
        mock_has_permissions,
        mocker):
    with app_.test_request_context():
        with app_.test_client() as client:
            service = service_json(
                users=[active_user_with_permissions.id],
                restricted=True,
                research_mode=True
            )
            mocker.patch('app.service_api_client.get_service', return_value={"data": service})
            mocker.patch('app.service_api_client.update_service_with_properties', return_value=service_one)

            client.login(active_user_with_permissions)
            response = client.get(url_for('main.service_switch_research_mode', service_id=service_one['id']))
            assert response.status_code == 302
            assert response.location == url_for('main.service_settings', service_id=service_one['id'], _external=True)
            app.service_api_client.update_service_with_properties.assert_called_with(
                service_one['id'], {"research_mode": False}
            )
def test_should_show_research_and_restricted_mode(
    restricted,
    table_index,
    research_mode,
    displayed,
    app_,
    platform_admin_user,
    mocker,
    mock_get_detailed_services,
    fake_uuid
):
    services = [service_json(fake_uuid, 'My Service', [], restricted=restricted, research_mode=research_mode)]
    services[0]['statistics'] = create_stats()

    mock_get_detailed_services.return_value = {'data': services}
    with app_.test_request_context():
        with app_.test_client() as client:
            mock_get_user(mocker, user=platform_admin_user)
            client.login(platform_admin_user)
            response = client.get(url_for('main.platform_admin'))

    assert response.status_code == 200
    mock_get_detailed_services.assert_called_once_with({'detailed': True})
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
    # get first column in second row, which contains flags as text.
    table_body = page.find_all('table')[table_index].find_all('tbody')[0]
    service_mode = table_body.find_all('tbody')[0].find_all('tr')[1].find_all('td')[0].text.strip()
    assert service_mode == displayed
Example #15
0
def test_should_show_research_and_restricted_mode(
    endpoint,
    restricted,
    research_mode,
    displayed,
    client,
    platform_admin_user,
    mocker,
    mock_get_detailed_services,
    fake_uuid,
):
    services = [service_json(fake_uuid, 'My Service', [], restricted=restricted, research_mode=research_mode)]
    services[0]['statistics'] = create_stats()

    mock_get_detailed_services.return_value = {'data': services}
    mock_get_user(mocker, user=platform_admin_user)
    client.login(platform_admin_user)
    response = client.get(url_for(endpoint))

    assert response.status_code == 200
    mock_get_detailed_services.assert_called_once_with({'detailed': True,
                                                        'include_from_test_key': True,
                                                        'only_active': False})
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
    # get first column in second row, which contains flags as text.
    table_body = page.find_all('table')[0].find_all('tbody')[0]
    service_mode = table_body.find_all('tbody')[0].find_all('tr')[1].find_all('td')[0].text.strip()
    assert service_mode == displayed
Example #16
0
def test_shows_archived_label_instead_of_live_or_research_mode_label(
    client,
    platform_admin_user,
    mocker,
    mock_get_detailed_services,
    research_mode,
):
    services = [
        service_json(restricted=False,
                     research_mode=research_mode,
                     active=False)
    ]
    services[0]['statistics'] = create_stats()

    mock_get_detailed_services.return_value = {'data': services}
    mock_get_user(mocker, user=platform_admin_user)
    client.login(platform_admin_user)
    response = client.get(url_for('main.live_services'))

    assert response.status_code == 200
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')

    table_body = page.find_all('table')[0].find_all('tbody')[0]
    service_mode = table_body.find_all('tbody')[0].find_all(
        'tr')[1].td.text.strip()
    # get second column, which contains flags as text.
    assert service_mode == 'archived'
def test_format_stats_by_service_returns_correct_values(fake_uuid):
    services = [service_json(fake_uuid, 'a', [])]
    services[0]['statistics'] = create_stats(
        emails_requested=10,
        emails_delivered=3,
        emails_failed=5,
        sms_requested=50,
        sms_delivered=7,
        sms_failed=11,
        letters_requested=40,
        letters_delivered=20,
        letters_failed=7
    )

    ret = list(format_stats_by_service(services))
    assert len(ret) == 1

    assert ret[0]['stats']['email']['requested'] == 10
    assert ret[0]['stats']['email']['delivered'] == 3
    assert ret[0]['stats']['email']['failed'] == 5

    assert ret[0]['stats']['sms']['requested'] == 50
    assert ret[0]['stats']['sms']['delivered'] == 7
    assert ret[0]['stats']['sms']['failed'] == 11

    assert ret[0]['stats']['letter']['requested'] == 40
    assert ret[0]['stats']['letter']['delivered'] == 20
    assert ret[0]['stats']['letter']['failed'] == 7
Example #18
0
def test_service_navigation_for_org_user(
    client_request,
    mocker,
    api_user_active,
    mock_get_billable_units,
    mock_get_free_sms_fragment_limit,
    mock_get_service,
    mock_get_invites_for_service,
    mock_get_users_by_service,
    mock_get_service_organisation,
):
    api_user_active['services'] = []
    api_user_active['organisations'] = [ORGANISATION_ID]
    service = service_json(
        id_=SERVICE_ONE_ID,
        organisation_id=ORGANISATION_ID,
    )
    mocker.patch(
        'app.service_api_client.get_service',
        return_value={'data': service}
    )
    client_request.login(api_user_active, service=service)

    page = client_request.get(
        'main.service_dashboard',
        service_id=SERVICE_ONE_ID,
    )

    assert [
        item.text.strip() for item in page.select('nav.navigation a')
    ] == [
        'Team members'
    ]
def test_should_show_email_and_sms_stats_for_all_service_types(
    endpoint,
    restricted,
    research_mode,
    platform_admin_client,
    mock_get_detailed_services,
    fake_uuid,
):
    services = [service_json(fake_uuid, 'My Service', [], restricted=restricted, research_mode=research_mode)]
    services[0]['statistics'] = create_stats(
        emails_requested=10,
        emails_delivered=3,
        emails_failed=5,
        sms_requested=50,
        sms_delivered=7,
        sms_failed=11
    )

    mock_get_detailed_services.return_value = {'data': services}
    response = platform_admin_client.get(url_for(endpoint))

    assert response.status_code == 200
    mock_get_detailed_services.assert_called_once_with({'detailed': True,
                                                        'include_from_test_key': True,
                                                        'only_active': ANY})
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')

    table_body = page.find_all('table')[0].find_all('tbody')[0]
    service_row_group = table_body.find_all('tbody')[0].find_all('tr')
    email_stats = service_row_group[1].select('.big-number-number')[0]
    sms_stats = service_row_group[1].select('.big-number-number')[1]

    assert normalize_spaces(email_stats.text) == '10'
    assert normalize_spaces(sms_stats.text) == '50'
def test_org_breadcrumbs_show_if_user_is_a_member_of_the_services_org(
    mocker,
    mock_get_template_statistics,
    mock_get_service_templates_when_no_templates_exist,
    mock_get_jobs,
    active_user_with_permissions,
    client_request,
):
    # active_user_with_permissions (used by the client_request) is an org member

    service_one_json = service_json(SERVICE_ONE_ID,
                                    users=[active_user_with_permissions['id']],
                                    restricted=False,
                                    organisation_id=ORGANISATION_ID)

    mocker.patch('app.service_api_client.get_service',
                 return_value={'data': service_one_json})
    mocker.patch('app.models.service.Organisation')

    page = client_request.get('main.service_dashboard',
                              service_id=SERVICE_ONE_ID)
    assert page.select_one('.navigation-organisation-link')['href'] == url_for(
        'main.organisation_dashboard',
        org_id=ORGANISATION_ID,
    )
Example #21
0
def test_should_show_email_and_sms_stats_for_all_service_types(
    endpoint,
    restricted,
    research_mode,
    client,
    platform_admin_user,
    mocker,
    mock_get_detailed_services,
    fake_uuid,
):
    services = [
        service_json(fake_uuid,
                     'My Service', [],
                     restricted=restricted,
                     research_mode=research_mode)
    ]
    services[0]['statistics'] = create_stats(emails_requested=10,
                                             emails_delivered=3,
                                             emails_failed=5,
                                             sms_requested=50,
                                             sms_delivered=7,
                                             sms_failed=11)

    mock_get_detailed_services.return_value = {'data': services}
    mock_get_user(mocker, user=platform_admin_user)
    client.login(platform_admin_user)
    response = client.get(url_for(endpoint))

    assert response.status_code == 200
    mock_get_detailed_services.assert_called_once_with({
        'detailed':
        True,
        'include_from_test_key':
        True,
        'only_active':
        ANY
    })
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')

    table_body = page.find_all('table')[0].find_all('tbody')[0]
    service_row_group = table_body.find_all('tbody')[0].find_all('tr')
    email_stats = service_row_group[0].find_all('div',
                                                class_='big-number-number')
    sms_stats = service_row_group[1].find_all('div',
                                              class_='big-number-number')
    email_sending, email_delivered, email_failed = [
        int(x.text.strip()) for x in email_stats
    ]
    sms_sending, sms_delivered, sms_failed = [
        int(x.text.strip()) for x in sms_stats
    ]

    assert email_sending == 2
    assert email_delivered == 3
    assert email_failed == 5
    assert sms_sending == 32
    assert sms_delivered == 7
    assert sms_failed == 11
Example #22
0
def test_sum_service_usage_is_sum_of_all_activity(fake_uuid):
    service = service_json(fake_uuid, 'My Service 1')
    service['statistics'] = create_stats(emails_requested=100,
                                         emails_delivered=25,
                                         emails_failed=25,
                                         sms_requested=100,
                                         sms_delivered=25,
                                         sms_failed=25)
    assert sum_service_usage(service) == 200
Example #23
0
def test_sum_service_usage_with_zeros(fake_uuid):
    service = service_json(fake_uuid, 'My Service 1')
    service['statistics'] = create_stats(emails_requested=0,
                                         emails_delivered=0,
                                         emails_failed=25,
                                         sms_requested=0,
                                         sms_delivered=0,
                                         sms_failed=0)
    assert sum_service_usage(service) == 0
def test_can_see_letters_if_allowed(logged_in_client, mocker):
    service = service_json(can_send_letters=True)
    mocker.patch('app.service_api_client.get_service', return_value={"data": service})

    response = logged_in_client.get(url_for('main.service_settings', service_id=service['id']))

    assert response.status_code == 200
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
    assert 'Letter templates' in page.find('nav', class_='navigation').text
def test_switch_service_disable_letters(client, platform_admin_user, mocker):
    service = service_json("1234", "Test Service", [], can_send_letters=True)
    mocker.patch('app.service_api_client.get_service', return_value={"data": service})
    mocked_fn = mocker.patch('app.service_api_client.update_service_with_properties', return_value=service)

    client.login(platform_admin_user, mocker, service)
    response = client.get(url_for('main.service_switch_can_send_letters', service_id=service['id']))

    assert response.status_code == 302
    assert response.location == url_for('main.service_settings', service_id=service['id'], _external=True)
    assert mocked_fn.call_args == call(service['id'], {"can_send_letters": False})
Example #26
0
def test_services_pages_that_org_users_are_allowed_to_see(
    client_request,
    mocker,
    api_user_active,
    mock_get_usage,
    mock_get_billable_units,
    mock_get_free_sms_fragment_limit,
    mock_get_service,
    mock_get_invites_for_service,
    mock_get_users_by_service,
    mock_get_template_folders,
    mock_get_service_organisation,
    mock_has_jobs,
    user_services,
    user_organisations,
    expected_status,
    organisation_checked,
):
    api_user_active['services'] = user_services
    api_user_active['organisations'] = user_organisations
    api_user_active['permissions'] = {
        service_id: ['manage_service']
        for service_id in user_services
    }
    service = service_json(
        name='SERVICE WITH ORG',
        id_=SERVICE_ONE_ID,
        users=[api_user_active['id']],
        organisation_id=ORGANISATION_ID,
    )

    mock_get_service = mocker.patch(
        'app.notify_client.service_api_client.service_api_client.get_service',
        return_value={'data': service}
    )
    client_request.login(
        api_user_active,
        service=service if SERVICE_ONE_ID in user_services else None,
    )

    endpoints = (
        'main.usage',
        'main.manage_users',
    )

    for endpoint in endpoints:
        client_request.get(
            endpoint,
            service_id=SERVICE_ONE_ID,
            _expected_status=expected_status,
        )

    assert mock_get_service.called is organisation_checked
def test_inactive_service_cannot_be_modified_by_normal_user(app_, api_user_active, method):
    api_client = NotifyAdminAPIClient('api_key', 'base_url', 'service_id')

    with app_.test_request_context() as request_context, app_.test_client() as client:
        client.login(api_user_active)
        request_context.service = service_json(active=False)

        with patch.object(api_client, 'request') as request:
            with pytest.raises(werkzeug.exceptions.Forbidden):
                getattr(api_client, method)('url', 'data')

    assert not request.called
def test_inactive_service_can_be_modified_by_platform_admin(app_, platform_admin_user, method):
    api_client = NotifyAdminAPIClient('api_key', 'base_url', 'service_id')

    with app_.test_request_context() as request_context, app_.test_client() as client:
        client.login(platform_admin_user)
        request_context.service = service_json(active=False)

        with patch.object(api_client, 'request') as request:
            ret = getattr(api_client, method)('url', 'data')

    assert request.called
    assert ret == request.return_value
Example #29
0
def test_organisation_services_shows_live_services_only(
    client_request,
    mock_get_organisation,
    mocker,
    active_user_with_permissions,
    fake_uuid,
):
    mocker.patch(
        "app.organisations_client.get_organisation_services",
        return_value=[
            service_json(id_=SERVICE_ONE_ID,
                         name="1",
                         restricted=False,
                         active=True),  # live
            service_json(id_="2", name="2", restricted=True,
                         active=True),  # trial
            service_json(id_="3", name="3", restricted=True,
                         active=False),  # trial, now archived
            service_json(id_="4", name="4", restricted=False,
                         active=False),  # was live, now archived
            service_json(id_=SERVICE_TWO_ID,
                         name="5",
                         restricted=False,
                         active=True),  # live, member of
        ],
    )

    client_request.login(active_user_with_permissions)
    page = client_request.get(".organisation_dashboard",
                              org_id=ORGANISATION_ID)

    services = page.select(".browse-list-item")
    assert len(services) == 2

    assert normalize_spaces(services[0].text) == "1"
    assert normalize_spaces(services[1].text) == "5"
    assert services[0].find("a")["href"] == url_for("main.usage",
                                                    service_id=SERVICE_ONE_ID)
    assert services[1].find("a")["href"] == url_for("main.usage",
                                                    service_id=SERVICE_TWO_ID)
def test_find_services_by_name_displays_services_found(client_request,
                                                       platform_admin_user,
                                                       mocker):
    client_request.login(platform_admin_user)
    get_services = mocker.patch('app.service_api_client.find_services_by_name',
                                return_value={"data": [service_json()]})
    document = client_request.post('main.find_services_by_name',
                                   _data={"search": "Test Service"},
                                   _expected_status=200)
    get_services.assert_called_once_with(service_name="Test Service")
    result = document.select_one('.browse-list-item a')
    assert result.text.strip() == 'Test Service'
    assert result.attrs["href"] == "/services/1234"
Example #31
0
def test_organisation_services_shows_live_services_only(
    client_request,
    mock_get_organisation,
    mocker,
    active_user_with_permissions,
    fake_uuid,
):
    mocker.patch(
        'app.organisations_client.get_organisation_services',
        return_value=[
            service_json(id_=SERVICE_ONE_ID,
                         name='1',
                         restricted=False,
                         active=True),  # live
            service_json(id_='2', name='2', restricted=True,
                         active=True),  # trial
            service_json(id_='3', name='3', restricted=True,
                         active=False),  # trial, now archived
            service_json(id_='4', name='4', restricted=False,
                         active=False),  # was live, now archived
            service_json(id_=SERVICE_TWO_ID,
                         name='5',
                         restricted=False,
                         active=True),  # live, member of
        ])

    client_request.login(active_user_with_permissions)
    page = client_request.get('.organisation_dashboard',
                              org_id=ORGANISATION_ID)

    services = page.select('.browse-list-item')
    assert len(services) == 2

    assert normalize_spaces(services[0].text) == '1'
    assert normalize_spaces(services[1].text) == '5'
    assert services[0].find('a')['href'] == url_for('main.usage',
                                                    service_id=SERVICE_ONE_ID)
    assert services[1].find('a')['href'] == url_for('main.usage',
                                                    service_id=SERVICE_TWO_ID)
def test_inactive_service_can_be_modified_by_platform_admin(
        app_, platform_admin_user, method):
    api_client = NotifyAdminAPIClient()

    with app_.test_request_context() as request_context, app_.test_client(
    ) as client:
        client.login(platform_admin_user)
        request_context.service = Service(service_json(active=False))

        with patch.object(api_client, "request") as request:
            ret = getattr(api_client, method)("url", "data")

    assert request.called
    assert ret == request.return_value
def test_inactive_service_cannot_be_modified_by_normal_user(
        app_, api_user_active, method):
    api_client = NotifyAdminAPIClient()

    with app_.test_request_context() as request_context, app_.test_client(
    ) as client:
        client.login(api_user_active)
        request_context.service = Service(service_json(active=False))

        with patch.object(api_client, "request") as request:
            with pytest.raises(werkzeug.exceptions.Forbidden):
                getattr(api_client, method)("url", "data")

    assert not request.called
Example #34
0
def test_inactive_service_cannot_be_modified_by_normal_user(
        app_, api_user_active, method):
    api_client = NotifyAdminAPIClient(SAMPLE_API_KEY, 'base_url')

    with app_.test_request_context() as request_context, app_.test_client(
    ) as client:
        client.login(api_user_active)
        request_context.service = service_json(active=False)

        with patch.object(api_client, 'request') as request:
            with pytest.raises(werkzeug.exceptions.Forbidden):
                getattr(api_client, method)('url', 'data')

    assert not request.called
Example #35
0
def test_inactive_service_can_be_modified_by_platform_admin(
        app_, platform_admin_user, method):
    api_client = NotifyAdminAPIClient(SAMPLE_API_KEY, 'base_url')

    with app_.test_request_context() as request_context, app_.test_client(
    ) as client:
        client.login(platform_admin_user)
        request_context.service = service_json(active=False)

        with patch.object(api_client, 'request') as request:
            ret = getattr(api_client, method)('url', 'data')

    assert request.called
    assert ret == request.return_value
def test_letters_access_restricted(
    logged_in_client,
    mocker,
    can_send_letters,
    response_code,
    mock_get_service_templates,
    url
):
    service = service_json(can_send_letters=can_send_letters)
    mocker.patch('app.service_api_client.get_service', return_value={"data": service})

    response = logged_in_client.get(url(service_id=service['id']))

    assert response.status_code == response_code
Example #37
0
def test_format_stats_by_service_sums_values_for_sending(fake_uuid):
    services = [service_json(fake_uuid, 'a', [])]
    services[0]['statistics'] = create_stats(emails_requested=10,
                                             emails_delivered=3,
                                             emails_failed=5,
                                             sms_requested=50,
                                             sms_delivered=7,
                                             sms_failed=11)

    ret = list(format_stats_by_service(services))

    assert len(ret) == 1
    assert ret[0]['sending'] == 34
    assert ret[0]['delivered'] == 10
    assert ret[0]['failed'] == 16
def test_logging_enabled_for_admin_users(app_, platform_admin_user, method,
                                         caplog):
    api_client = NotifyAdminAPIClient()

    with app_.test_request_context() as request_context, app_.test_client(
    ) as client:
        client.login(platform_admin_user)
        request_context.service = Service(service_json(active=False))

        with patch.object(api_client, "request") as request:
            ret = getattr(api_client, method)("url", "data")

    assert request.called
    assert len(caplog.records) == 1
    assert ret == request.return_value
def test_can_see_letters_without_permissions(
    client,
    mocker,
    mock_login,
    mock_has_permissions,
    api_user_active
):
    service = service_json(can_send_letters=True)
    mocker.patch('app.service_api_client.get_service', return_value={"data": service})

    client.login(api_user_active)
    response = client.get(url_for('main.service_settings', service_id=service['id']))

    assert response.status_code == 200
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
    assert 'Letter templates' in page.find('nav', class_='navigation').text
Example #40
0
def test_find_services_by_name_displays_services_found(client_request,
                                                       platform_admin_user,
                                                       mocker):
    client_request.login(platform_admin_user)
    get_services = mocker.patch(
        "app.service_api_client.find_services_by_name",
        return_value={"data": [service_json()]},
    )
    document = client_request.post(
        "main.find_services_by_name",
        _data={"search": "Test Service"},
        _expected_status=200,
    )
    get_services.assert_called_once_with(service_name="Test Service")
    result = document.find("a", {"class": "browse-list-link"})
    assert result.text.strip() == "Test Service"
    assert result.attrs["href"] == "/services/1234"
def test_letters_lets_in_without_permission(
    client,
    mocker,
    mock_login,
    mock_has_permissions,
    api_user_active,
    mock_get_service_templates,
    url
):
    service = service_json(can_send_letters=True)
    mocker.patch('app.service_api_client.get_service', return_value={"data": service})

    client.login(api_user_active)
    response = client.get(url(service_id=service['id']))

    assert api_user_active.permissions == {}
    assert response.status_code == 200
def test_should_show_email_and_sms_stats_for_all_service_types(
    restricted,
    table_index,
    research_mode,
    app_,
    platform_admin_user,
    mocker,
    mock_get_detailed_services,
    fake_uuid
):
    services = [service_json(fake_uuid, 'My Service', [], restricted=restricted, research_mode=research_mode)]
    services[0]['statistics'] = create_stats(
        emails_requested=10,
        emails_delivered=3,
        emails_failed=5,
        sms_requested=50,
        sms_delivered=7,
        sms_failed=11
    )

    mock_get_detailed_services.return_value = {'data': services}
    with app_.test_request_context():
        with app_.test_client() as client:
            mock_get_user(mocker, user=platform_admin_user)
            client.login(platform_admin_user)
            response = client.get(url_for('main.platform_admin'))

    assert response.status_code == 200
    mock_get_detailed_services.assert_called_once_with({'detailed': True})
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')

    table_body = page.find_all('table')[table_index].find_all('tbody')[0]
    service_row_group = table_body.find_all('tbody')[0].find_all('tr')
    email_stats = service_row_group[0].find_all('div', class_='big-number-number')
    sms_stats = service_row_group[1].find_all('div', class_='big-number-number')

    email_sending, email_delivered, email_failed = [int(x.text.strip()) for x in email_stats]
    sms_sending, sms_delivered, sms_failed = [int(x.text.strip()) for x in sms_stats]

    assert email_sending == 2
    assert email_delivered == 3
    assert email_failed == 5
    assert sms_sending == 32
    assert sms_delivered == 7
    assert sms_failed == 11
def test_service_user_without_manage_service_permission_can_see_usage_page_when_org_user(
    client_request,
    mocker,
    active_caseworking_user,
    mock_has_no_jobs,
    mock_get_usage,
    mock_get_billable_units,
    mock_get_free_sms_fragment_limit,
    mock_get_service,
    mock_get_invites_for_service,
    mock_get_users_by_service,
    mock_get_service_organisation,
    mock_get_service_templates,
    mock_get_template_folders,
    user_organisations,
    expected_status,
    expected_menu_items,
):
    active_caseworking_user['services'] = [SERVICE_ONE_ID]
    active_caseworking_user['organisations'] = user_organisations
    service = service_json(
        id_=SERVICE_ONE_ID,
        organisation_id=ORGANISATION_ID,
    )
    mocker.patch(
        'app.service_api_client.get_service',
        return_value={'data': service}
    )
    client_request.login(active_caseworking_user, service=service)
    page = client_request.get(
        'main.choose_template',
        service_id=SERVICE_ONE_ID,
    )
    assert tuple(
        item.text.strip() for item in page.select('nav.navigation a')
    ) == expected_menu_items

    client_request.get(
        'main.usage',
        service_id=SERVICE_ONE_ID,
        _expected_status=expected_status,
    )
def test_format_stats_by_service_returns_correct_values(fake_uuid):
    services = [service_json(fake_uuid, 'a', [])]
    services[0]['statistics'] = create_stats(
        emails_requested=10,
        emails_delivered=3,
        emails_failed=5,
        sms_requested=50,
        sms_delivered=7,
        sms_failed=11
    )

    ret = list(format_stats_by_service(services))
    assert len(ret) == 1

    assert ret[0]['stats']['email']['sending'] == 2
    assert ret[0]['stats']['email']['delivered'] == 3
    assert ret[0]['stats']['email']['failed'] == 5

    assert ret[0]['stats']['sms']['sending'] == 32
    assert ret[0]['stats']['sms']['delivered'] == 7
    assert ret[0]['stats']['sms']['failed'] == 11
def test_shows_archived_label_instead_of_live_or_research_mode_label(
    client,
    platform_admin_user,
    mocker,
    mock_get_detailed_services,
    research_mode
):
    services = [
        service_json(restricted=False, research_mode=research_mode, active=False)
    ]
    services[0]['statistics'] = create_stats()

    mock_get_detailed_services.return_value = {'data': services}
    mock_get_user(mocker, user=platform_admin_user)
    client.login(platform_admin_user)
    response = client.get(url_for('main.platform_admin'))

    assert response.status_code == 200
    page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')

    table_body = page.find_all('table')[0].find_all('tbody')[0]
    service_mode = table_body.find_all('tbody')[0].find_all('tr')[1].td.text.strip()
    # get second column, which contains flags as text.
    assert service_mode == 'archived'
from tests import service_json
from tests.conftest import api_user_active, platform_admin_user
from app.notify_client import NotifyAdminAPIClient


@pytest.mark.parametrize('method', [
    'put',
    'post',
    'delete'
])
@pytest.mark.parametrize('user', [
    api_user_active(str(uuid.uuid4())),
    platform_admin_user(str(uuid.uuid4()))
], ids=['api_user', 'platform_admin'])
@pytest.mark.parametrize('service', [
    service_json(active=True),
    None
], ids=['active_service', 'no_service'])
def test_active_service_can_be_modified(app_, method, user, service):
    api_client = NotifyAdminAPIClient('api_key', 'base_url', 'service_id')

    with app_.test_request_context() as request_context, app_.test_client() as client:
        client.login(user)
        request_context.service = service

        with patch.object(api_client, 'request') as request:
            ret = getattr(api_client, method)('url', 'data')

    assert request.called
    assert ret == request.return_value