Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create custom contact properties and verify replication of those properties #244

Merged
merged 13 commits into from
Jan 25, 2024
116 changes: 115 additions & 1 deletion tests/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import requests
from base import HubspotBaseTest
from tap_tester import LOGGER
import time
import time
from copy import deepcopy

DEBUG = False
BASE_URL = "https://api.hubapi.com"
Expand Down Expand Up @@ -38,6 +39,7 @@ def giveup(exc):
jitter=None,
giveup=giveup,
interval=10)

def get(self, url, params=dict()):
"""Perform a GET using the standard requests method and logs the action"""
response = requests.get(url, params=params, headers=self.HEADERS)
Expand Down Expand Up @@ -842,6 +844,107 @@ def create(self, stream, company_ids=[], subscriptions=[], times=1):
else:
raise NotImplementedError(f"There is no create_{stream} method in this dipatch!")

def create_custom_contact_properties(self):
"""Create custom contact properties of all the types"""

url = f"{BASE_URL}/properties/v1/contacts/properties"
data = []
property = {
"name": "custom_string",
"label": "A New String Custom Property",
"description": "A new string property for you",
"groupName": "contactinformation",
"type": "string",
"fieldType": "text",
"formField": True,
"displayOrder": 6,
"options": [
]
}
data.append(deepcopy(property))

property = {
"name": "custom_number",
"label": "A New Number Custom Property",
"description": "A new number property for you",
"groupName": "contactinformation",
"type": "number",
"fieldType": "text",
"formField": True,
"displayOrder": 7,
"options": [
]
}
data.append(deepcopy(property))

property = {
"name": "custom_date",
"label": "A New Date Custom Property",
"description": "A new date property for you",
"groupName": "contactinformation",
"type": "date",
"fieldType": "text",
"formField": True,
"displayOrder": 9,
"options": [
]
}
data.append(deepcopy(property))

property = {
"name": "custom_datetime",
"label": "A New Datetime Custom Property",
"description": "A new datetime property for you",
"groupName": "contactinformation",
"type": "datetime",
"fieldType": "text",
"formField": True,
"displayOrder": 10,
"options": [
]
}
data.append(deepcopy(property))

property = {
"name": "multi_pick",
"label": "multi pick",
"description": "multi select picklist test",
"groupName": "contactinformation",
"type": "enumeration",
"fieldType": "checkbox",
"hidden": False,
"options": [
{
"label": "Option A",
"value": "option_a"
},
{
"label": "Option B",
"value": "option_b"
},
{
"label": "Option C",
"value": "option_c"
}
],
"formField": True
}
data.append(deepcopy(property))
Comment on lines +880 to +932
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is great that you are creating a variety of data types in the custom fields. Since you went through the pain of creating them we should also use them all when creating a contact - instead of just the first two - to make sure that we support all of the types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) was expecting this comment.. The other types seems complicated, I'll need more time to figure out how to do. Can I write a separate card for that ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure.

# generate a contacts record

for current_data in data:
try:
response = self.post(url, current_data)
LOGGER.info("response is %s", response)
# Setting up the property is a one time task, If exception occurs because, it already exists, ignore
except requests.exceptions.HTTPError as err:
LOGGER.info("Data already exists for %s", current_data)
if '409' in str(err):
pass
else:
response.raise_for_status()


def create_contacts(self):
"""
Generate a single contacts record.
Expand All @@ -852,6 +955,14 @@ def create_contacts(self):
url = f"{BASE_URL}/contacts/v1/contact"
data = {
"properties": [
{
"property": "custom_string",
"value": "custom_string_value"
},
{
"property": "custom_number",
"value": 1567
},
Comment on lines +958 to +965
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are setting custom properties for every call of create_contacts we need the create_custom_contact_properties to be called prior to calling the create_contacts. I see you are doing this in the test, but what about other tests that would need to add contacts, those would probably break if the custom properties were not present. I believe we should call create_custom_contact_properties in the __init__ of the client so that we call it once when it starts up instead of depending on the tester to know about this or remember to add it in each test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, creating the custom contact property is a one time task. After my first successful run of the test, it never creates and gives a 409, that's why I am skipping it. Probably doing it in init is a good idea. Will try that

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you moved it to setup. I meant the init of the client so anyone using the client makes sure it is in good shape, vs just for your test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, moved it to init

{
"property": "email",
"value": f"{record_uuid}@stitchdata.com"
Expand Down Expand Up @@ -1865,6 +1976,9 @@ def __init__(self, start_date=''):
self.cleanup(stream, records, delete_count)
LOGGER.info(f"TEST CLIENT | {delete_count} records deleted from {stream}")

# Create custom properties for contacts
self.create_custom_contact_properties()

def print_histogram_data(self):
for stream, recorded_times in self.record_create_times.items():
LOGGER.info("Time taken for stream {} is total: {}, avg: {}, minimum: {}, maximum: {}".
Expand Down