diff --git a/app/dao/organisation_dao.py b/app/dao/organisation_dao.py index 01bc90de4..a667661c2 100644 --- a/app/dao/organisation_dao.py +++ b/app/dao/organisation_dao.py @@ -6,6 +6,7 @@ from app.models import ( Organisation, Domain, InvitedOrganisationUser, + Service, User ) @@ -16,6 +17,14 @@ def dao_get_organisations(): ).all() +def dao_count_organsations_with_live_services(): + return db.session.query(Organisation.id).join(Organisation.services).filter( + Service.active.is_(True), + Service.restricted.is_(False), + Service.count_as_live.is_(True), + ).distinct().count() + + def dao_get_organisation_services(organisation_id): return Organisation.query.filter_by( id=organisation_id diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 0685699a8..b033e9cad 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -61,6 +61,14 @@ def dao_fetch_all_services(only_active=False): return query.all() +def dao_count_live_services(): + return Service.query.filter_by( + active=True, + restricted=False, + count_as_live=True, + ).count() + + def dao_fetch_service_by_id(service_id, only_active=False): query = Service.query.filter_by( id=service_id diff --git a/app/status/healthcheck.py b/app/status/healthcheck.py index b0c451d0f..4b248ae26 100644 --- a/app/status/healthcheck.py +++ b/app/status/healthcheck.py @@ -5,6 +5,8 @@ from flask import ( ) from app import db, version +from app.dao.services_dao import dao_count_live_services +from app.dao.organisation_dao import dao_count_organsations_with_live_services status = Blueprint('status', __name__) @@ -23,6 +25,14 @@ def show_status(): db_version=get_db_version()), 200 +@status.route('/_status/live-service-and-organisation-counts') +def live_service_and_organisation_counts(): + return jsonify( + organisations=dao_count_organsations_with_live_services(), + services=dao_count_live_services(), + ), 200 + + def get_db_version(): query = 'SELECT version_num FROM alembic_version' full_name = db.session.execute(query).fetchone()[0] diff --git a/tests/app/db.py b/tests/app/db.py index 94ca9325b..8b3702794 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -85,6 +85,7 @@ def create_service( service_name="Sample service", service_id=None, restricted=False, + count_as_live=True, service_permissions=[EMAIL_TYPE, SMS_TYPE], research_mode=False, active=True, @@ -110,6 +111,7 @@ def create_service( service.active = active service.research_mode = research_mode + service.count_as_live = count_as_live else: if user and user not in service.users: dao_add_user_to_service(service, user) diff --git a/tests/app/status/test_status.py b/tests/app/status/test_status.py index f96289988..e75639289 100644 --- a/tests/app/status/test_status.py +++ b/tests/app/status/test_status.py @@ -1,6 +1,8 @@ import pytest from flask import json +from tests.app.db import create_organisation, create_service + @pytest.mark.parametrize('path', ['/', '/_status']) def test_get_status_all_ok(client, notify_db_session, path): @@ -12,3 +14,55 @@ def test_get_status_all_ok(client, notify_db_session, path): assert resp_json['travis_commit'] assert resp_json['travis_build_number'] assert resp_json['build_time'] + + +def test_empty_live_service_and_organisation_counts(admin_request): + assert admin_request.get('status.live_service_and_organisation_counts') == { + 'organisations': 0, + 'services': 0, + } + + +def test_populated_live_service_and_organisation_counts(admin_request): + + # Org 1 has three real live services and one fake, for a total of 3 + org_1 = create_organisation('org 1') + live_service_1 = create_service(service_name='1') + live_service_1.organisation = org_1 + live_service_2 = create_service(service_name='2') + live_service_2.organisation = org_1 + live_service_3 = create_service(service_name='3') + live_service_3.organisation = org_1 + fake_live_service_1 = create_service(service_name='f1', count_as_live=False) + fake_live_service_1.organisation = org_1 + inactive_service_1 = create_service(service_name='i1', active=False) + inactive_service_1.organisation = org_1 + + # This service isn’t associated to an org, but should still be counted as live + create_service(service_name='4') + + # Org 2 has no real live services + org_2 = create_organisation('org 2') + trial_service_1 = create_service(service_name='t1', restricted=True) + trial_service_1.organisation = org_2 + fake_live_service_2 = create_service(service_name='f2', count_as_live=False) + fake_live_service_2.organisation = org_2 + inactive_service_2 = create_service(service_name='i2', active=False) + inactive_service_2.organisation = org_2 + + # Org 2 has no services at all + create_organisation('org 3') + + # This service isn’t associated to an org, and should not be counted as live + # because it’s marked as not counted + create_service(service_name='f3', count_as_live=False) + + # This service isn’t associated to an org, and should not be counted as live + # because it’s in trial mode + create_service(service_name='t', restricted=True) + create_service(service_name='i', restricted=False, active=False) + + assert admin_request.get('status.live_service_and_organisation_counts') == { + 'organisations': 1, + 'services': 4, + }