Skip to content
This repository has been archived by the owner on Dec 9, 2024. It is now read-only.

Commit

Permalink
Feature/cps 415 more informative error message (#466)
Browse files Browse the repository at this point in the history
* More informative error message. Add trouble shooting documentation.
  • Loading branch information
marijnkampf authored Jan 19, 2023
1 parent e0a1ca4 commit 00e61f8
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 0 deletions.
File renamed without changes.
70 changes: 70 additions & 0 deletions app/docs/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Local troubleshooting

This document was created to provide solutions to common issues that occur when running Enquiry Management. The issues are categorised by the method used to bring up the application.

When updating this document please use the following template:

```
### Issue title
[brief description of issue]
Screenshot or text:
![image-title](./Troubleshooting/[image-name].png)
**Solution** If there is a single permanent fix for this issue enter it here.
**Short-term fix** If there is a temporary workaround or some of 'sticky-tape' solution enter it here.
**Long-term fix** If there is a permanent fix for the issue (or if one is being worked on) enter it here.
```

## Docker issues

This section should include issues that occur when running Enquiry Management in Docker.

### TypeError at /enquiries/14/company-search 'NoneType' object is not subscriptable

This occurs when the connection to Data Hub is setup but the browser isn't logged in to the Django admin on http://localhost:8000/admin/.

```
TypeError at /enquiries/14/company-search
'NoneType' object is not subscriptable
solution: login to Django admin on http://localhost:8000/admin/
Request Method: POST
Request URL: http://localhost:8001/enquiries/14/company-search
Django Version: 3.1.14
Exception Type: TypeError
Exception Value: 'NoneType' object is not subscriptable
Exception Location: /usr/src/app/app/enquiries/common/datahub_utils.py, line 63, in dh_request
Python Executable: /usr/local/bin/python
Python Version: 3.8.14
Python Path: ['/usr/src/app',
'/usr/src/app',
'/usr/local/lib/python38.zip',
'/usr/local/lib/python3.8',
'/usr/local/lib/python3.8/lib-dynload',
'/usr/local/lib/python3.8/site-packages']
Server time: Thu, 22 Sep 2022 11:28:44 +0000
```

**Solution** login to Django admin on http://localhost:8000/admin/


## Native issues

### TypeError at /enquiries/14/company-search 'NoneType' object is not subscriptable

This occurs when the connection to Data Hub is setup but the browser isn't logged in to the Django admin on http://localhost:8000/admin/.


This section should be used for native issues that occur regardless of what API you are using.

### There is a problem. Referral Advisor: Error validating your identity in DataHub

```
There is a problem.
Referral Advisor: Error validating your identity in DataHub
```

**Solution** Update/renew the MOCK_SSO_TOKEN from DataHub. (//[your-datahub-api]/admin/add-access-token/)
37 changes: 37 additions & 0 deletions app/enquiries/common/datahub_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,28 @@ def dh_get_matching_company_contact(first_name, last_name, email, company_contac
)


def dh_get_matching_company_contact_by_email(email, company_contacts):
"""
Performs check identifying whether an enquirer's email exists in their company's contact
list in |data-hub-api|_.
:param email:
:type email: str
:param company_contacts:
:type company_contacts: list
:returns: The first matching contact if any exist
:rtype: dict or None
"""
return next((
company_contact for company_contact in company_contacts
if company_contact["email"].lower() == email.lower()
),
None
)


def dh_contact_create(request, access_token, enquirer, company_id, primary=False):
"""
Create a |data-hub|_ `contact` and associate it with the given `company`.
Expand Down Expand Up @@ -362,6 +384,21 @@ def dh_prepare_contact(request, access_token, enquirer, company_id):
if matching_contact:
enquiry_contact = matching_contact
return enquiry_contact["datahub_id"], None
else:
matching_contact_email = dh_get_matching_company_contact_by_email(
enquirer.email,
existing_contacts,
)
if matching_contact_email:
return None, {
"contact_details_mismatch":
f"a contact with the email "
f"{matching_contact_email['email']} already exists on Data Hub for this company. "
f"The name {enquirer.first_name} {enquirer.last_name} doesn't match the name "
f"{matching_contact_email['first_name']} {matching_contact_email['last_name']} on "
"Data Hub. Please ensure the names match accross both systems or use an "
"alternative email address."
}

# If enquirer is a new contact, add them to DH
enquiry_contact, error = dh_contact_create(
Expand Down
78 changes: 78 additions & 0 deletions app/enquiries/tests/test_dh_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from app.enquiries.models import Enquirer
from app.enquiries.common.datahub_utils import (
dh_get_matching_company_contact,
dh_get_matching_company_contact_by_email,
dh_prepare_contact,
)

Expand Down Expand Up @@ -59,6 +60,15 @@ def setUp(self):
phone=faker.phone_number(),
request_for_call=ref_data.RequestForCall.YES_AFTERNOON.value,
)
self.partially_matching_on_email_enquirer = Enquirer.objects.create(
first_name=faker.name(),
last_name=faker.name(),
email=MATCHING_CONTACT_DETAILS["email"],
job_title='Manager',
phone_country_code='1',
phone=faker.phone_number(),
request_for_call=ref_data.RequestForCall.YES_AFTERNOON.value,
)
self.new_enquirer = Enquirer.objects.create(
first_name=faker.name(),
last_name=faker.name(),
Expand Down Expand Up @@ -120,6 +130,33 @@ def test_dh_get_matching_company_contact_no_match(self):
)
self.assertIsNone(contact)

def test_dh_get_matching_company_contact_by_email_match(self):
"""Test company contact match by email function returns matching contact"""

contact = dh_get_matching_company_contact_by_email(
self.matching_enquirer.email,
self.company_results
)
self.assertEqual(contact["email"], MATCHING_CONTACT_DETAILS["email"])

def test_dh_get_matching_company_contact_by_email_partial_match(self):
"""Test company contact match by email function does not return a partial match"""

contact = dh_get_matching_company_contact_by_email(
self.partially_matching_enquirer.email,
self.company_results
)
self.assertIsNone(contact)

def test_dh_get_matching_company_contact_by_email_no_match(self):
"""Test company contact match by email function returns None if no match"""

contact = dh_get_matching_company_contact_by_email(
self.new_enquirer.email,
self.company_results
)
self.assertIsNone(contact)

@mock.patch('app.enquiries.common.datahub_utils.dh_contact_create')
@mock.patch('app.enquiries.common.datahub_utils.dh_get_matching_company_contact')
@mock.patch('app.enquiries.common.datahub_utils.dh_get_company_contact_list')
Expand Down Expand Up @@ -187,6 +224,47 @@ def test_dh_prepare_contact_new_contact_existing_contacts(
self.assertEqual(contact_id, self.dh_contact_id)
self.assertIsNone(error)

@mock.patch('app.enquiries.common.datahub_utils.dh_contact_create')
@mock.patch('app.enquiries.common.datahub_utils.dh_get_matching_company_contact_by_email')
@mock.patch('app.enquiries.common.datahub_utils.dh_get_company_contact_list')
def test_dh_prepare_contact_mismatch_contact_existing_contacts(
self,
mock_dh_contact_list,
mock_matching_company_contact_by_email,
mock_create_dh_contact,
):
"""Test contact prepare function in case of company having different existing """
"""contacts with mismatched name"""
mock_dh_contact_list.return_value = [self.company_results, None]
mock_create_dh_contact.return_value = [{"id": self.dh_contact_id}, None]
mock_matching_company_contact_by_email.return_value = {
'datahub_id': self.dh_company_id,
'first_name': self.matching_enquirer.first_name,
'last_name': self.matching_enquirer.last_name,
'job_title': self.matching_enquirer.job_title,
'email': self.matching_enquirer.email,
'phone': self.matching_enquirer.phone,
}

contact_id, error = dh_prepare_contact(
self.request,
self.access_token,
self.partially_matching_on_email_enquirer,
self.dh_company_id
)

self.assertIsNotNone(error)
contact_details_mismatch_error = (
f"a contact with the email "
f"{self.matching_enquirer.email} already exists on Data Hub for this company. "
f"The name {self.partially_matching_on_email_enquirer.first_name} "
f"{self.partially_matching_on_email_enquirer.last_name} doesn't match the name "
f"{MATCHING_CONTACT_DETAILS['first_name']} {MATCHING_CONTACT_DETAILS['last_name']} on "
"Data Hub. Please ensure the names match accross both systems or use an "
"alternative email address."
)
self.assertEqual(error['contact_details_mismatch'], contact_details_mismatch_error)

@mock.patch('app.enquiries.common.datahub_utils.dh_contact_create')
@mock.patch('app.enquiries.common.datahub_utils.dh_get_matching_company_contact')
@mock.patch('app.enquiries.common.datahub_utils.dh_get_company_contact_list')
Expand Down

0 comments on commit 00e61f8

Please sign in to comment.