def test_get_organisation_services_usage_sort_active_first(admin_request, notify_db_session): org = create_organisation(name='Organisation without live services') service = create_service(service_name='live service') archived_service = create_service(service_name='archived_service') template = create_template(service=service) dao_add_service_to_organisation(service=service, organisation_id=org.id) dao_add_service_to_organisation(service=archived_service, organisation_id=org.id) create_annual_billing(service_id=service.id, free_sms_fragment_limit=10, financial_year_start=2019) create_ft_billing(bst_date=datetime.utcnow().date(), template=template, billable_unit=19, rate=0.060, notifications_sent=19) response = admin_request.get( 'organisation.get_organisation_services_usage', organisation_id=org.id, **{"year": 2019} ) assert len(response) == 1 assert len(response['services']) == 2 first_service = response['services'][0] assert first_service['service_id'] == str(archived_service.id) assert first_service['service_name'] == archived_service.name assert first_service['active'] is True last_service = response['services'][1] assert last_service['service_id'] == str(service.id) assert last_service['service_name'] == service.name assert last_service['active'] is True dao_archive_service(service_id=archived_service.id) response_after_archive = admin_request.get( 'organisation.get_organisation_services_usage', organisation_id=org.id, **{"year": 2019} ) first_service = response_after_archive['services'][0] assert first_service['service_id'] == str(service.id) assert first_service['service_name'] == service.name assert first_service['active'] is True last_service = response_after_archive['services'][1] assert last_service['service_id'] == str(archived_service.id) assert last_service['service_name'] == archived_service.name assert last_service['active'] is False
def test_post_link_service_to_another_org(admin_request, sample_service, sample_organisation): data = {"service_id": str(sample_service.id)} admin_request.post( "organisation.link_service_to_organisation", _data=data, organisation_id=sample_organisation.id, _expected_status=204, ) assert len(sample_organisation.services) == 1 new_org = create_organisation() admin_request.post( "organisation.link_service_to_organisation", _data=data, organisation_id=new_org.id, _expected_status=204, ) assert not sample_organisation.services assert len(new_org.services) == 1
def test_post_link_service_to_organisation_rollback_service_if_annual_billing_update_fails( admin_request, sample_service, mocker ): mocker.patch('app.dao.annual_billing_dao.dao_create_or_update_annual_billing_for_year', side_effect=SQLAlchemyError) data = { 'service_id': str(sample_service.id) } assert not sample_service.organisation_type organisation = create_organisation(organisation_type='central') assert len(organisation.services) == 0 assert len(AnnualBilling.query.all()) == 0 with pytest.raises(expected_exception=SQLAlchemyError): admin_request.post( 'organisation.link_service_to_organisation', _data=data, organisation_id=organisation.id ) assert not sample_service.organisation_type assert len(organisation.services) == 0 assert len(AnnualBilling.query.all()) == 0
def test_update_organisation_default_branding( admin_request, notify_db_session, ): org = create_organisation(name='Test Organisation') email_branding = create_email_branding() letter_branding = create_letter_branding() assert org.email_branding is None assert org.letter_branding is None admin_request.post('organisation.update_organisation', _data={ 'email_branding_id': str(email_branding.id), 'letter_branding_id': str(letter_branding.id), }, organisation_id=org.id, _expected_status=204) assert org.email_branding == email_branding assert org.letter_branding == letter_branding
def test_post_update_organisation_updates_domains( admin_request, notify_db_session, domain_list, ): org = create_organisation(name='test_org_2') data = { 'domains': domain_list, } admin_request.post( 'organisation.update_organisation', _data=data, organisation_id=org.id, _expected_status=204 ) organisation = Organisation.query.all() assert len(organisation) == 1 assert [ domain.domain for domain in organisation[0].domains ] == domain_list
def test_get_organisation_by_id(admin_request, notify_db_session): org = create_organisation() response = admin_request.get('organisation.get_organisation_by_id', _expected_status=200, organisation_id=org.id) assert set(response.keys()) == { 'id', 'name', 'active', 'crown', 'organisation_type', 'agreement_signed', 'agreement_signed_at', 'agreement_signed_by_id', 'agreement_signed_version', 'agreement_signed_on_behalf_of_name', 'agreement_signed_on_behalf_of_email_address', 'letter_branding_id', 'email_branding_id', 'domains', 'request_to_go_live_notes', 'count_of_live_services', 'notes', 'billing_contact_names', 'billing_contact_email_addresses', 'billing_reference', 'purchase_order_number' } assert response['id'] == str(org.id) assert response['name'] == 'test_org_1' assert response['active'] is True assert response['crown'] is None assert response['organisation_type'] is None assert response['agreement_signed'] is None assert response['agreement_signed_by_id'] is None assert response['agreement_signed_version'] is None assert response['letter_branding_id'] is None assert response['email_branding_id'] is None assert response['domains'] == [] assert response['request_to_go_live_notes'] is None assert response['count_of_live_services'] == 0 assert response['agreement_signed_on_behalf_of_name'] is None assert response['agreement_signed_on_behalf_of_email_address'] is None assert response['notes'] is None assert response['billing_contact_names'] is None assert response['billing_contact_email_addresses'] is None assert response['billing_reference'] is None assert response['purchase_order_number'] is None
def test_fetch_usage_year_for_organisation_populates_ft_billing_for_today( notify_db_session): create_letter_rate(start_date=datetime.utcnow() - timedelta(days=1)) create_rate(start_date=datetime.utcnow() - timedelta(days=1), value=0.65, notification_type='sms') new_org = create_organisation(name='New organisation') service = create_service() template = create_template(service=service) dao_add_service_to_organisation(service=service, organisation_id=new_org.id) current_year = datetime.utcnow().year create_annual_billing(service_id=service.id, free_sms_fragment_limit=10, financial_year_start=current_year) assert FactBilling.query.count() == 0 create_notification(template=template, status='delivered') results = fetch_usage_year_for_organisation(organisation_id=new_org.id, year=current_year) assert len(results) == 1 assert FactBilling.query.count() == 1
def test_get_organisation_by_id_gets_correct_organisation(notify_db_session): organisation = create_organisation() organisation_from_db = dao_get_organisation_by_id(organisation.id) assert organisation_from_db == organisation
def test_fetch_sms_billing_for_all_services_with_remainder(notify_db_session): service = create_service(service_name='a - has free allowance') template = create_template(service=service) org = create_organisation(name="Org for {}".format(service.name)) dao_add_service_to_organisation(service=service, organisation_id=org.id) create_annual_billing(service_id=service.id, free_sms_fragment_limit=10, financial_year_start=2019) create_ft_billing(service=service, template=template, utc_date=datetime(2019, 4, 20), notification_type='sms', billable_unit=2, rate=0.11) create_ft_billing(service=service, template=template, utc_date=datetime(2019, 5, 20), notification_type='sms', billable_unit=2, rate=0.11) create_ft_billing(service=service, template=template, utc_date=datetime(2019, 5, 22), notification_type='sms', billable_unit=1, rate=0.11) service_2 = create_service(service_name='b - used free allowance') template_2 = create_template(service=service_2) org_2 = create_organisation(name="Org for {}".format(service_2.name)) dao_add_service_to_organisation(service=service_2, organisation_id=org_2.id) create_annual_billing(service_id=service_2.id, free_sms_fragment_limit=10, financial_year_start=2019) create_ft_billing(service=service_2, template=template_2, utc_date=datetime(2019, 4, 20), notification_type='sms', billable_unit=12, rate=0.11) create_ft_billing(service=service_2, template=template_2, utc_date=datetime(2019, 5, 20), notification_type='sms', billable_unit=3, rate=0.11) service_3 = create_service(service_name='c - partial allowance') template_3 = create_template(service=service_3) org_3 = create_organisation(name="Org for {}".format(service_3.name)) dao_add_service_to_organisation(service=service_3, organisation_id=org_3.id) create_annual_billing(service_id=service_3.id, free_sms_fragment_limit=10, financial_year_start=2019) create_ft_billing(service=service_3, template=template_3, utc_date=datetime(2019, 4, 20), notification_type='sms', billable_unit=5, rate=0.11) create_ft_billing(service=service_3, template=template_3, utc_date=datetime(2019, 5, 20), notification_type='sms', billable_unit=7, rate=0.11) service_4 = create_service(service_name='d - email only') email_template = create_template(service=service_4, template_type='email') org_4 = create_organisation(name="Org for {}".format(service_4.name)) dao_add_service_to_organisation(service=service_4, organisation_id=org_4.id) create_annual_billing(service_id=service_4.id, free_sms_fragment_limit=10, financial_year_start=2019) create_ft_billing(service=service_4, template=email_template, utc_date=datetime(2019, 5, 22), notifications_sent=5, notification_type='email', billable_unit=0, rate=0) results = fetch_sms_billing_for_all_services(datetime(2019, 5, 1), datetime(2019, 5, 31)) assert len(results) == 3 # (organisation_name, organisation_id, service_name, free_sms_fragment_limit, sms_rate, # sms_remainder, sms_billable_units, chargeable_billable_sms, sms_cost) assert results[0] == (org.name, org.id, service.name, service.id, 10, Decimal('0.11'), 8, 3, 0, Decimal('0')) assert results[1] == (org_2.name, org_2.id, service_2.name, service_2.id, 10, Decimal('0.11'), 0, 3, 3, Decimal('0.33')) assert results[2] == (org_3.name, org_3.id, service_3.name, service_3.id, 10, Decimal('0.11'), 5, 7, 2, Decimal('0.22'))
def test_get_orgs_and_services_only_returns_active(admin_request, sample_user): org1 = create_organisation(name='org1', active=True) org2 = create_organisation(name='org2', active=False) # in an active org service1 = create_service(service_name='service1', active=True) service2 = create_service(service_name='service2', active=False) # active but in an inactive org service3 = create_service(service_name='service3', active=True) # not in an org service4 = create_service(service_name='service4', active=True) service5 = create_service(service_name='service5', active=False) org1.services = [service1, service2] org2.services = [service3] sample_user.organisations = [org1, org2] sample_user.services = [service1, service2, service3, service4, service5] resp = admin_request.get('user.get_organisations_and_services_for_user', user_id=sample_user.id) assert set(resp.keys()) == { 'organisations', 'services_without_organisations', 'services', } assert resp['organisations'] == [{ 'name': org1.name, 'id': str(org1.id), 'services': [{ 'name': service1.name, 'id': str(service1.id), 'restricted': False, }], 'count_of_live_services': 1, }] assert resp['services_without_organisations'] == [{ 'name': service4.name, 'id': str(service4.id), 'restricted': False, }] assert resp['services'] == [ { 'name': service1.name, 'id': str(service1.id), 'restricted': False, 'organisation': str(org1.id) }, { 'name': service3.name, 'id': str(service3.id), 'restricted': False, 'organisation': str(org2.id) }, { 'name': service4.name, 'id': str(service4.id), 'restricted': False, 'organisation': None, }, ]
def test_dao_fetch_live_services_data(sample_user): org = create_organisation(organisation_type='nhs_central') service = create_service(go_live_user=sample_user, go_live_at='2014-04-20T10:00:00') template = create_template(service=service) service_2 = create_service(service_name='second', go_live_at='2017-04-20T10:00:00', go_live_user=sample_user) service_3 = create_service(service_name='third', go_live_at='2016-04-20T10:00:00') # below services should be filtered out: create_service(service_name='restricted', restricted=True) create_service(service_name='not_active', active=False) create_service(service_name='not_live', count_as_live=False) template2 = create_template(service=service, template_type='email') template_letter_1 = create_template(service=service, template_type='letter') template_letter_2 = create_template(service=service_2, template_type='letter') dao_add_service_to_organisation(service=service, organisation_id=org.id) # two sms billing records for 1st service within current financial year: create_ft_billing(utc_date='2019-04-20', notification_type='sms', template=template, service=service) create_ft_billing(utc_date='2019-04-21', notification_type='sms', template=template, service=service) # one sms billing record for 1st service from previous financial year, should not appear in the result: create_ft_billing(utc_date='2018-04-20', notification_type='sms', template=template, service=service) # one email billing record for 1st service within current financial year: create_ft_billing(utc_date='2019-04-20', notification_type='email', template=template2, service=service) # one letter billing record for 1st service within current financial year: create_ft_billing(utc_date='2019-04-15', notification_type='letter', template=template_letter_1, service=service) # one letter billing record for 2nd service within current financial year: create_ft_billing(utc_date='2019-04-16', notification_type='letter', template=template_letter_2, service=service_2) # 1st service: billing from 2018 and 2019 create_annual_billing(service.id, 500, 2018) create_annual_billing(service.id, 100, 2019) # 2nd service: billing from 2018 create_annual_billing(service_2.id, 300, 2018) # 3rd service: billing from 2019 create_annual_billing(service_3.id, 200, 2019) results = dao_fetch_live_services_data() assert len(results) == 3 # checks the results and that they are ordered by date: assert results == [{ 'service_id': mock.ANY, 'service_name': 'Sample service', 'organisation_name': 'test_org_1', 'organisation_type': 'nhs_central', 'consent_to_research': None, 'contact_name': 'Test User', 'contact_email': '*****@*****.**', 'contact_mobile': '+16502532222', 'live_date': datetime(2014, 4, 20, 10, 0), 'sms_volume_intent': None, 'email_volume_intent': None, 'letter_volume_intent': None, 'sms_totals': 2, 'email_totals': 1, 'letter_totals': 1, 'free_sms_fragment_limit': 100 }, { 'service_id': mock.ANY, 'service_name': 'third', 'organisation_name': None, 'consent_to_research': None, 'organisation_type': None, 'contact_name': None, 'contact_email': None, 'contact_mobile': None, 'live_date': datetime(2016, 4, 20, 10, 0), 'sms_volume_intent': None, 'email_volume_intent': None, 'letter_volume_intent': None, 'sms_totals': 0, 'email_totals': 0, 'letter_totals': 0, 'free_sms_fragment_limit': 200 }, { 'service_id': mock.ANY, 'service_name': 'second', 'organisation_name': None, 'consent_to_research': None, 'contact_name': 'Test User', 'contact_email': '*****@*****.**', 'contact_mobile': '+16502532222', 'live_date': datetime(2017, 4, 20, 10, 0), 'sms_volume_intent': None, 'organisation_type': None, 'email_volume_intent': None, 'letter_volume_intent': None, 'sms_totals': 0, 'email_totals': 0, 'letter_totals': 1, 'free_sms_fragment_limit': 300 }]
def test_get_organisation_by_email_address_ignores_gsi_gov_uk(notify_db_session): org = create_organisation() create_domain('example.gov.uk', org.id) found_org = dao_get_organisation_by_email_address('*****@*****.**') assert org == found_org
def test_dao_fetch_live_services_data(sample_user): org = create_organisation(organisation_type="nhs_central") service = create_service(go_live_user=sample_user, go_live_at="2014-04-20T10:00:00") template = create_template(service=service) service_2 = create_service( service_name="second", go_live_at="2017-04-20T10:00:00", go_live_user=sample_user, ) service_3 = create_service(service_name="third", go_live_at="2016-04-20T10:00:00") # below services should be filtered out: create_service(service_name="restricted", restricted=True) create_service(service_name="not_active", active=False) create_service(service_name="not_live", count_as_live=False) template2 = create_template(service=service, template_type="email") template_letter_1 = create_template(service=service, template_type="letter") template_letter_2 = create_template(service=service_2, template_type="letter") dao_add_service_to_organisation(service=service, organisation_id=org.id) # two sms billing records for 1st service within current financial year: create_ft_billing( utc_date="2019-04-20", notification_type="sms", template=template, service=service, ) create_ft_billing( utc_date="2019-04-21", notification_type="sms", template=template, service=service, ) # one sms billing record for 1st service from previous financial year, should not appear in the result: create_ft_billing( utc_date="2018-04-20", notification_type="sms", template=template, service=service, ) # one email billing record for 1st service within current financial year: create_ft_billing( utc_date="2019-04-20", notification_type="email", template=template2, service=service, ) # one letter billing record for 1st service within current financial year: create_ft_billing( utc_date="2019-04-15", notification_type="letter", template=template_letter_1, service=service, ) # one letter billing record for 2nd service within current financial year: create_ft_billing( utc_date="2019-04-16", notification_type="letter", template=template_letter_2, service=service_2, ) # 1st service: billing from 2018 and 2019 create_annual_billing(service.id, 500, 2018) create_annual_billing(service.id, 100, 2019) # 2nd service: billing from 2018 create_annual_billing(service_2.id, 300, 2018) # 3rd service: billing from 2019 create_annual_billing(service_3.id, 200, 2019) results = dao_fetch_live_services_data() assert len(results) == 3