diff --git a/api/integrations/lead_tracking/hubspot/lead_tracker.py b/api/integrations/lead_tracking/hubspot/lead_tracker.py index b7347443d76c..510e0976fb44 100644 --- a/api/integrations/lead_tracking/hubspot/lead_tracker.py +++ b/api/integrations/lead_tracking/hubspot/lead_tracker.py @@ -56,7 +56,9 @@ def create_lead(self, user: FFAdminUser, organisation: Organisation = None) -> N response = self.client.create_contact(user, hubspot_id) - HubspotLead.objects.create(user=user, hubspot_id=response["id"]) + HubspotLead.objects.update_or_create( + user=user, defaults={"hubspot_id": response["id"]} + ) if tracker := HubspotTracker.objects.filter(user=user).first(): self.client.create_lead_form( diff --git a/api/tests/unit/integrations/lead_tracking/hubspot/test_unit_hubspot_lead_tracking.py b/api/tests/unit/integrations/lead_tracking/hubspot/test_unit_hubspot_lead_tracking.py index 587cbf6ca0a2..04af3df92474 100644 --- a/api/tests/unit/integrations/lead_tracking/hubspot/test_unit_hubspot_lead_tracking.py +++ b/api/tests/unit/integrations/lead_tracking/hubspot/test_unit_hubspot_lead_tracking.py @@ -279,6 +279,78 @@ def test_hubspot_with_new_contact_and_existing_organisation( mock_get_contact.assert_called_once_with(user) +def test_hubspot_with_new_contact_and_existing_organisation_with_hubspot_duplicate( + organisation: Organisation, + settings: SettingsWrapper, + mocker: MockerFixture, +) -> None: + # Given + settings.ENABLE_HUBSPOT_LEAD_TRACKING = True + user = FFAdminUser.objects.create( + email="new.user@example.com", + first_name="Frank", + last_name="Louis", + marketing_consent_given=True, + ) + + former_hubspot_id = "1023333333" + HubspotLead.objects.create(user=user, hubspot_id=former_hubspot_id) + + hubspot_id = "10280696017" + + # Create an existing hubspot organisation to mimic a previous + # successful API call with a different lead. + HubspotOrganisation.objects.create(organisation=organisation, hubspot_id=hubspot_id) + + mock_create_company = mocker.patch( + "integrations.lead_tracking.hubspot.client.HubspotClient.create_company" + ) + mock_get_contact = mocker.patch( + "integrations.lead_tracking.hubspot.client.HubspotClient.get_contact", + return_value=None, + ) + + hubspot_lead_id = "1000551" + mock_create_contact = mocker.patch( + "integrations.lead_tracking.hubspot.client.HubspotClient.create_contact", + return_value={ + "archived": False, + "archived_at": None, + "created_at": datetime.datetime(2024, 2, 26, 20, 2, 50, 69000), + "id": hubspot_lead_id, + "properties": { + "createdate": "2024-02-26T20:02:50.069Z", + "email": user.email, + "firstname": user.first_name, + "hs_all_contact_vids": "1000551", + "hs_email_domain": "example.com", + "hs_is_contact": "true", + "hs_is_unworked": "true", + "hs_marketable_status": user.marketing_consent_given, + "hs_object_id": "1000551", + "hs_object_source": "INTEGRATION", + "hs_object_source_id": "2902325", + "hs_object_source_label": "INTEGRATION", + "hs_pipeline": "contacts-lifecycle-pipeline", + "lastmodifieddate": "2024-02-26T20:02:50.069Z", + "lastname": user.last_name, + }, + "properties_with_history": None, + "updated_at": datetime.datetime(2024, 2, 26, 20, 2, 50, 69000), + }, + ) + + # When + user.add_organisation(organisation, role=OrganisationRole.ADMIN) + + # Then + assert HubspotLead.objects.filter(hubspot_id=hubspot_lead_id).exists() is True + assert HubspotLead.objects.filter(hubspot_id=former_hubspot_id).exists() is False + mock_create_company.assert_not_called() + mock_create_contact.assert_called_once_with(user, hubspot_id) + mock_get_contact.assert_called_once_with(user) + + def test_hubspot_with_existing_contact_and_new_organisation( organisation: Organisation, settings: SettingsWrapper,