def test_create_service_with_children(self): """Tests specifying a service with children.""" team = random_obj_for_model(TeamModel) url = reverse('api-v3:event:collection') request_data = { 'name': 'Grand exhibition', 'end_date': '2010-09-12', 'event_type': EventType.seminar.value.id, 'address_1': 'Grand Court Exhibition Centre', 'address_town': 'London', 'address_country': Country.united_kingdom.value.id, 'uk_region': UKRegion.east_of_england.value.id, 'organiser': AdviserFactory().pk, 'lead_team': team.pk, 'teams': [team.pk], 'service': Service.enquiry_or_referral_received.value.id, 'start_date': '2010-09-12', 'has_related_trade_agreements': True, 'related_trade_agreements': [TradeAgreement.uk_japan.value.id], } response = self.api_client.post(url, data=request_data) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = response.json() assert response_data == { 'service': ['This field is valid for services without children services.'], }
def make_matched_rows(num_records): """Make multiple interaction CSV rows that should pass contact matching.""" adviser = AdviserFactory( first_name='Adviser for', last_name='Matched interaction', ) service = random_service() communication_channel = random_communication_channel() contacts = ContactFactory.create_batch( num_records, email=factory.Sequence(lambda i: f'unique{i}@matched.uk'), ) return [ { 'theme': Interaction.Theme.EXPORT, 'kind': Interaction.Kind.INTERACTION, 'date': '01/01/2018', 'adviser_1': adviser.name, 'contact_email': contact.email, 'service': service.name, 'communication_channel': communication_channel.name, } for contact in contacts ]
def test_cannot_change_status(self, refund_factory): """Test that the status field cannot be changed at any point.""" refund = refund_factory() now_datetime = now() date_str = now_datetime.date().isoformat() time_str = now_datetime.time().isoformat() url = reverse('admin:omis_payment_refund_change', args=(refund.id, )) default_data = { 'order': refund.order.pk, 'requested_on_0': date_str, 'requested_on_1': time_str, 'requested_amount': refund.requested_amount, 'refund_reason': refund.refund_reason, 'level1_approved_on_0': date_str, 'level1_approved_on_1': time_str, 'level1_approved_by': AdviserFactory().pk, 'level2_approved_on_0': date_str, 'level2_approved_on_1': time_str, 'level2_approved_by': AdviserFactory().pk, 'method': refund.method or '', 'net_amount': '' if refund.net_amount is None else refund.net_amount, 'vat_amount': '' if refund.vat_amount is None else refund.vat_amount, } for changed_status, _ in RefundStatus.choices: if changed_status == refund.status: continue data = { **default_data, 'status': changed_status, } response = self.client.post(url, data, follow=True) assert response.status_code == status.HTTP_200_OK form = response.context['adminform'].form assert not form.is_valid() assert form.errors == { 'status': [ f'Select a valid choice. {changed_status} is not one of the available ' f'choices.', ], }
def test_can_replace_some_participants(self): """Test that a subset of existing DIT participants can be replaced.""" interaction = CompanyInteractionFactory(dit_participants=[]) dit_participants = InteractionDITParticipantFactory.create_batch( 3, interaction=interaction, ) # Change the first adviser's team so that we can check that the participant's team is # unchanged after the update. dit_participants[0].adviser.dit_team = TeamFactory() dit_participants[0].adviser.save() new_advisers = [ dit_participants[0].adviser, AdviserFactory(), ] request_data = { 'dit_participants': [ { 'adviser': { 'id': adviser.pk, }, } for adviser in new_advisers ], } url = reverse('api-v3:interaction:item', kwargs={'pk': interaction.pk}) response = self.api_client.patch(url, data=request_data) assert response.status_code == status.HTTP_200_OK response_data = response.json() response_data['dit_participants'].sort( key=lambda dit_participant: dit_participant['adviser']['id'], ) expected_advisers_and_teams = [ (new_advisers[0], dit_participants[0].team), (new_advisers[1], new_advisers[1].dit_team), ] expected_advisers_and_teams.sort(key=lambda adviser_and_team: adviser_and_team[0].pk) assert response_data['dit_participants'] == [ { 'adviser': { 'id': str(adviser.pk), 'first_name': adviser.first_name, 'last_name': adviser.last_name, 'name': adviser.name, }, 'team': { 'id': str(team.pk), 'name': team.name, }, } for adviser, team in expected_advisers_and_teams ]
def test_create_first_session_from_order(self, requests_mock, monkeypatch): """ Test the successful creation of the first payment gateway session for an order. """ monkeypatch.setattr( 'uuid.uuid4', mock.Mock(return_value='0123abcd-0000-0000-0000-000000000000'), ) # mock request govuk_payment_id = '123abc123abc123abc123abc12' govuk_payments_url = govuk_url('payments') requests_mock.post( govuk_payments_url, status_code=201, json={ 'state': {'status': 'created', 'finished': False}, 'payment_id': govuk_payment_id, '_links': { 'next_url': { 'href': 'https://payment.example.com/123abc', 'method': 'GET', }, }, }, ) assert PaymentGatewaySession.objects.count() == 0 # call method adviser = AdviserFactory() order = OrderWithAcceptedQuoteFactory() session = PaymentGatewaySession.objects.create_from_order( order=order, attrs={'created_by': adviser}, ) # check session assert session.order == order assert session.status == PaymentGatewaySessionStatus.CREATED assert session.govuk_payment_id == govuk_payment_id assert session.created_by == adviser assert PaymentGatewaySession.objects.count() == 1 # check mocked request assert requests_mock.call_count == 1 assert requests_mock.request_history[-1].url == govuk_payments_url assert requests_mock.request_history[-1].json() == { 'amount': order.total_cost, 'reference': f'{order.reference}-0123ABCD', 'description': settings.GOVUK_PAY_PAYMENT_DESCRIPTION.format( reference=order.reference, ), 'return_url': settings.GOVUK_PAY_RETURN_URL.format( public_token=order.public_token, session_id=session.pk, ), }
def test_success(self, data_flow_api_client): """Test that endpoint returns with expected data for a single company""" adviser = AdviserFactory() response = data_flow_api_client.get(self.view_url) assert response.status_code == status.HTTP_200_OK assert response.json()['results'] == [get_expected_data_from_adviser(adviser)]
def test_restricted_users_cannot_see_other_teams_projects(self, setup_es): """Test that restricted users cannot see other teams' projects in the export.""" team = TeamFactory() team_other = TeamFactory() adviser_other = AdviserFactory(dit_team_id=team_other.id) adviser_same_team = AdviserFactory(dit_team_id=team.id) request_user = create_test_user( permission_codenames=( InvestmentProjectPermission.view_associated, InvestmentProjectPermission.export, ), dit_team=team, ) api_client = self.create_api_client(user=request_user) project_other = InvestmentProjectFactory() team_projects = [ InvestmentProjectFactory(), InvestmentProjectFactory(created_by=adviser_same_team), InvestmentProjectFactory(client_relationship_manager=adviser_same_team), InvestmentProjectFactory(project_manager=adviser_same_team), InvestmentProjectFactory(project_assurance_adviser=adviser_same_team), ] InvestmentProjectTeamMemberFactory(adviser=adviser_other, investment_project=project_other) InvestmentProjectTeamMemberFactory( adviser=adviser_same_team, investment_project=team_projects[0], ) setup_es.indices.refresh() url = reverse('api-v3:search:investment_project-export') response = api_client.post(url, {}) assert response.status_code == status.HTTP_200_OK response_text = response.getvalue().decode('utf-8-sig') reader = DictReader(StringIO(response_text)) actual_rows = [dict(item) for item in reader] assert len(actual_rows) == 5 expected_names = {project.name for project in team_projects} assert {row['Project name'] for row in actual_rows} == expected_names
def test_global_restricted_users_cannot_see_other_teams_projects(self, setup_es): """ Automatic filter to see only associated IP for a specific (leps) user """ team = TeamFactory() team_other = TeamFactory() adviser_other = AdviserFactory(dit_team_id=team_other.id) adviser_same_team = AdviserFactory(dit_team_id=team.id) request_user = create_test_user( permission_codenames=['view_associated_investmentproject'], dit_team=team, ) api_client = self.create_api_client(user=request_user) project_other = InvestmentProjectFactory() project_1 = InvestmentProjectFactory() project_2 = InvestmentProjectFactory(created_by=adviser_same_team) project_3 = InvestmentProjectFactory(client_relationship_manager=adviser_same_team) project_4 = InvestmentProjectFactory(project_manager=adviser_same_team) project_5 = InvestmentProjectFactory(project_assurance_adviser=adviser_same_team) InvestmentProjectTeamMemberFactory(adviser=adviser_other, investment_project=project_other) InvestmentProjectTeamMemberFactory(adviser=adviser_same_team, investment_project=project_1) setup_es.indices.refresh() url = reverse('api-v3:search:basic') response = api_client.get( url, data={ 'term': '', 'entity': 'investment_project', }, ) assert response.status_code == status.HTTP_200_OK response_data = response.json() assert response_data['count'] == 5 results = response_data['results'] expected_ids = { str(project_1.id), str(project_2.id), str(project_3.id), str(project_4.id), str(project_5.id), } assert {result['id'] for result in results} == expected_ids
def test_you_have_been_added_for_adviser(self, settings): """ Test the notification for when an adviser is added to an order. If the template variables have been changed in GOV.UK notifications this is going to raise HTTPError (400 - Bad Request). """ settings.OMIS_NOTIFICATION_API_KEY = settings.OMIS_NOTIFICATION_TEST_API_KEY notify = Notify() order = OrderFactory() notify.adviser_added( order=order, adviser=AdviserFactory(), by=AdviserFactory(), creation_date=dateutil_parse('2017-05-18'), )
def test_associated_advisers_specific_roles(field): """Tests that get_associated_advisers() includes advisers in specific roles.""" adviser = AdviserFactory() factory_kwargs = { field: adviser, } project = InvestmentProjectFactory(**factory_kwargs) assert adviser in tuple(project.get_associated_advisers())
def test_ok_if_order_in_allowed_status(self, allowed_status): """ Test that an order can be reopened if it's in one of the allowed statuses. """ order = OrderFactory(status=allowed_status) order.reopen(by=AdviserFactory()) assert order.status == OrderStatus.draft
def test_notify_email_ingest_success(mock_statsd): """ Test that the `notify_email_ingest_failure` fucntion increments the right counters in StatsD. """ adviser = AdviserFactory(contact_email='*****@*****.**') notify_meeting_ingest_success(adviser, Mock(), ()) mock_statsd.incr.assert_called_once_with( 'celery.calendar-invite-ingest.success.dit_gov_uk', )
def test_link_company_with_dnb_duns_already_set(): """ Test link_company_with_dnb when it is called for a company which has already been linked with a DNB record. """ company = CompanyFactory(duns_number='123456788') modifying_adviser = AdviserFactory() with pytest.raises(CompanyAlreadyDNBLinkedError): link_company_with_dnb(company.id, '123456789', modifying_adviser)
def test_with_multiple_advisers(self, data_flow_api_client): """Test that endpoint returns correct order of records""" adviser_1 = AdviserFactory( date_joined=datetime(2019, 1, 2, tzinfo=utc)) adviser_2 = AdviserFactory( date_joined=datetime(2019, 1, 3, tzinfo=utc)) adviser_3 = AdviserFactory( date_joined=datetime(2019, 1, 1, tzinfo=utc)) adviser_4 = AdviserFactory( date_joined=datetime(2019, 1, 1, tzinfo=utc)) response = data_flow_api_client.get(self.view_url) assert response.status_code == status.HTTP_200_OK assert [a['id'] for a in response.json()['results']] == [ str(a.id) for a in sorted([adviser_3, adviser_4], key=lambda x: x.id) + [adviser_1, adviser_2] ]
def test_get_adviser_by_sso_email_non_staff_or_active(flags): """ Test that AuthenticationFailed is raised if SSO email matches and user has neither is_staff nor is_active flags set. """ AdviserFactory(email='some@email', **flags) with pytest.raises(AuthenticationFailed) as excinfo: get_adviser_by_sso_user_profile({'email': 'some@email'}) assert excinfo.value.detail == 'User not found.'
def test_quote_cancelled(self, end_to_end_notify, notify_task_return_value_tracker): """ Test templates of quote cancelled for customer and advisers. If the template variables have been changed in GOV.UK notifications the celery task will be unsuccessful. """ order = OrderWithOpenQuoteFactory() end_to_end_notify.quote_cancelled(order, by=AdviserFactory()) self._assert_tasks_successful(2, notify_task_return_value_tracker)
def setup_data(): """Sets up the data and makes the ES client available.""" ContactFactory( first_name='abc', last_name='defg', company__name='name0', company__trading_names=['trading0'], ) ContactFactory( first_name='first', last_name='last', company__name='name1', company__trading_names=['trading1'], ) InvestmentProjectFactory( name='abc defg', description='investmentproject1', estimated_land_date=datetime.datetime(2011, 6, 13, 9, 44, 31, 62870), project_manager=AdviserFactory(first_name='name 0', last_name='surname 0'), project_assurance_adviser=AdviserFactory(first_name='name 1', last_name='surname 1'), investor_company=CompanyFactory(name='name3', trading_names=['trading3']), client_relationship_manager=AdviserFactory(first_name='name 2', last_name='surname 2'), referral_source_adviser=AdviserFactory(first_name='name 3', last_name='surname 3'), client_contacts=[], ) InvestmentProjectFactory( description='investmentproject2', estimated_land_date=datetime.datetime(2057, 6, 13, 9, 44, 31, 62870), project_manager=AdviserFactory(first_name='name 4', last_name='surname 4'), project_assurance_adviser=AdviserFactory(first_name='name 5', last_name='surname 5'), investor_company=CompanyFactory(name='name4', trading_names=['trading4']), client_relationship_manager=AdviserFactory(first_name='name 6', last_name='surname 6'), referral_source_adviser=AdviserFactory(first_name='name 7', last_name='surname 7'), client_contacts=[], ) country_uk = constants.Country.united_kingdom.value.id country_us = constants.Country.united_states.value.id CompanyFactory( name='abc defg ltd', trading_names=['abc defg trading ltd'], address_1='1 Fake Lane', address_town='Downtown', address_country_id=country_uk, ) CompanyFactory( name='abc defg us ltd', trading_names=['abc defg us trading ltd'], address_1='1 Fake Lane', address_town='Downtown', address_country_id=country_us, registered_address_country_id=country_us, )
def test_validate_team_instance_success(): """Tests validating a complete team section using a model instance.""" adviser = AdviserFactory() project = InvestmentProjectFactory( stage_id=constants.InvestmentProjectStage.active.value.id, project_manager=adviser, project_assurance_adviser=adviser, ) errors = validate(instance=project, fields=TEAM_FIELDS) assert not errors
def test_can_override_adviser(self): """Test that an explicitly provided adviser is used over the one in the request.""" adviser = AdviserFactory() request = Mock(user=Mock(), path='test-path') event = record_user_event(request, UserEventType.SEARCH_EXPORT, adviser=adviser) event.refresh_from_db() assert event.adviser == adviser
def test_get_adviser_by_sso_user_profile_email_id(): """Test that adviser is returned if staff SSO email user id matches.""" adviser = AdviserFactory(sso_email_user_id='some-123@email', is_staff=True, is_active=True) sso_adviser = get_adviser_by_sso_user_profile( {'email_user_id': 'some-123@email'}) assert sso_adviser.pk == adviser.pk assert sso_adviser.sso_email_user_id == 'some-123@email'
def test_you_have_been_added_for_adviser( self, end_to_end_notify, notify_task_return_value_tracker, ): """ Test the notification for when an adviser is added to an order. If the template variables have been changed in GOV.UK notifications the celery task will be unsuccessful. """ order = OrderFactory() end_to_end_notify.adviser_added( order=order, adviser=AdviserFactory(), by=AdviserFactory(), creation_date=dateutil_parse('2017-05-18'), ) self._assert_tasks_successful(1, notify_task_return_value_tracker)
def test_save_creates_interactions(self, num_unmatched, num_multiple_matches): """Test that save() creates interactions.""" num_matching = 3 matched_rows = make_matched_rows(num_matching) unmatched_rows = make_unmatched_rows(num_unmatched) multiple_matches_rows = make_multiple_matches_rows( num_multiple_matches) user = AdviserFactory(first_name='Admin', last_name='User') file = make_csv_file_from_dicts( *matched_rows, *unmatched_rows, *multiple_matches_rows, ) file_contents = file.getvalue() form = InteractionCSVForm(files={ 'csv_file': SimpleUploadedFile(file.name, file_contents), }, ) assert form.is_valid() form.save(user) created_interactions = list(Interaction.objects.all()) assert len(created_interactions) == num_matching expected_contact_emails = { row['contact_email'] for row in matched_rows } actual_contact_emails = { interaction.contacts.first().email for interaction in created_interactions } # Make sure the test was correctly set up with unique contact emails assert len(actual_contact_emails) == num_matching # Check that the interactions created are the ones we expect # Note: the full saving logic for a row is tested in the InteractionCSVRowForm tests assert expected_contact_emails == actual_contact_emails expected_source = { 'file': { 'name': file.name, 'size': len(file_contents), 'sha256': hashlib.sha256(file_contents).hexdigest(), }, } # `source` has been set (list used rather than a generator for useful failure messages) assert all([ interaction.source == expected_source for interaction in created_interactions ])
def test_one_list_report_generation(): """Test the generation of the One List.""" companies = CompanyFactory.create_batch( 2, headquarter_type_id=constants.HeadquarterType.ghq.value.id, one_list_tier=factory.Iterator( OneListTier.objects.all(), # keeps the ordering ), one_list_account_owner=AdviserFactory(), ) # ignored because headquarter_type is None CompanyFactory( headquarter_type=None, one_list_tier=OneListTier.objects.first(), one_list_account_owner=AdviserFactory(), ) # ignored because one_list_tier is None CompanyFactory( headquarter_type_id=constants.HeadquarterType.ghq.value.id, one_list_tier=None, one_list_account_owner=AdviserFactory(), ) # ignored because one_list_account_owner is None CompanyFactory( headquarter_type_id=constants.HeadquarterType.ghq.value.id, one_list_tier=OneListTier.objects.first(), one_list_account_owner=None, ) report = OneListReport() assert list(report.rows()) == [{ 'name': company.name, 'one_list_tier__name': company.one_list_tier.name, 'sector__segment': company.sector.segment, 'primary_contact_name': company.one_list_account_owner.name, 'one_list_account_owner__telephone_number': company.one_list_account_owner.telephone_number, 'one_list_account_owner__contact_email': company.one_list_account_owner.contact_email, 'address_country__name': company.address_country.name, 'address_town': company.address_town, 'url': f'{settings.DATAHUB_FRONTEND_URL_PREFIXES["company"]}/{company.id}', } for company in companies]
def test_displays_error_when_validation_fails( self, mock_get_user_by_email_user_id): """Test that an error is displayed when form validation fails.""" mock_get_user_by_email_user_id.return_value = FAKE_SSO_USER_DATA AdviserFactory(sso_email_user_id=FAKE_SSO_USER_DATA['email_user_id']) data = {'search_email': '*****@*****.**'} response = self.client.post(add_from_sso_url, data) assert response.status_code == status.HTTP_200_OK assert response.context['errors'] == [[DUPLICATE_USER_MESSAGE]]
def test_record_user_event(data, expected_data): """Test record_user_event() for various model and data values.""" adviser = AdviserFactory() request = Mock(user=adviser, path='test-path') event = record_user_event(request, USER_EVENT_TYPES.search_export, data=data) event.refresh_from_db() assert event.adviser == adviser assert event.type == USER_EVENT_TYPES.search_export assert event.api_url_path == 'test-path' assert event.data == expected_data
def test_adviser_list_view_default_sort_order(self): """Test default sorting.""" AdviserFactory(first_name='a', last_name='sorted adviser') AdviserFactory(first_name='z', last_name='sorted adviser') AdviserFactory(first_name='f', last_name='sorted adviser') url = reverse('api-v1:advisor-list') response = self.api_client.get(url) assert response.status_code == status.HTTP_200_OK result = response.json() assert len(result['results']) == 4 results = result['results'] assert [res['name'] for res in results] == [ 'a sorted adviser', 'f sorted adviser', # This is the test user making the request 'Testo Useri', 'z sorted adviser', ]
def test_assigning_non_ist_project_manager_doesnt_end_spi2(spi_report): """Test that non IST project manager wont end SPI 2.""" investment_project = InvestmentProjectFactory() # saving separately so that project_manager_first_assigned_on is updated investment_project.project_manager = AdviserFactory() investment_project.save() rows = list(spi_report.rows()) assert len(rows) == 1 assert 'Project manager assigned' not in rows[0]
def test_audit_log(s3_stubber): """Test that reversion revisions are created.""" advisers = [ AdviserFactory(contact_email='*****@*****.**'), AdviserFactory(contact_email='*****@*****.**'), AdviserFactory(contact_email='*****@*****.**'), ] bucket = 'test_bucket' object_key = 'test_key' csv_content = f"""id,contact_email {advisers[0].id},invalid_email {advisers[1].id},[email protected] {advisers[2].id},[email protected] """ s3_stubber.add_response( 'get_object', { 'Body': BytesIO(bytes(csv_content, encoding='utf-8')), }, expected_params={ 'Bucket': bucket, 'Key': object_key, }, ) call_command('update_adviser_contact_email', bucket, object_key) for adviser in advisers: adviser.refresh_from_db() versions = Version.objects.get_for_object(advisers[0]) assert versions.count() == 0 versions = Version.objects.get_for_object(advisers[1]) assert versions.count() == 1 assert versions[0].revision.get_comment() == 'Loaded contact email from spreadsheet.' versions = Version.objects.get_for_object(advisers[2]) assert versions.count() == 0
def test_one_list_download(self): """Test the download of the One List.""" CompanyFactory.create_batch( 2, headquarter_type_id=constants.HeadquarterType.ghq.value.id, classification=random_obj_for_model(CompanyClassification), one_list_account_owner=AdviserFactory(), ) # ignored because headquarter_type is None CompanyFactory( headquarter_type=None, classification=random_obj_for_model(CompanyClassification), one_list_account_owner=AdviserFactory(), ) # ignored because classification is None CompanyFactory( headquarter_type_id=constants.HeadquarterType.ghq.value.id, classification=None, one_list_account_owner=AdviserFactory(), ) # ignored because one_list_account_owner is None CompanyFactory( headquarter_type_id=constants.HeadquarterType.ghq.value.id, classification=random_obj_for_model(CompanyClassification), one_list_account_owner=None, ) url = reverse('admin-report:download-report', kwargs={'report_id': 'one-list'}) user = create_test_user( permission_codenames=('view_company', ), is_staff=True, password=self.PASSWORD, ) client = self.create_client(user=user) response = client.get(url) assert response.status_code == status.HTTP_200_OK # 3 = header + the first 2 companies assert len(response.getvalue().decode('utf-8').splitlines()) == 3
def test_you_have_been_removed_for_adviser(self, settings): """ Test the notification for when an adviser is removed from an order. If the template variables have been changed in GOV.UK notifications this is going to raise HTTPError (400 - Bad Request). """ settings.OMIS_NOTIFICATION_API_KEY = settings.OMIS_NOTIFICATION_TEST_API_KEY notify = Notify() order = OrderFactory() notify.adviser_removed(order=order, adviser=AdviserFactory())