diff --git a/src/Analytics/Adapter.php b/src/Analytics/Adapter.php index 48b270e..cbb3f79 100644 --- a/src/Analytics/Adapter.php +++ b/src/Analytics/Adapter.php @@ -170,23 +170,23 @@ public function call(string $method, string $path = '', array $headers = [], arr $responseType = $responseHeaders['Content-Type'] ?? ''; $responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); - switch(substr($responseType, 0, strpos($responseType, ';'))) { + switch (substr($responseType, 0, strpos($responseType, ';'))) { case 'application/json': $responseBody = json_decode($responseBody, true); break; } if (curl_errno($ch)) { - throw new \Exception(curl_error($ch)); + throw new \Exception(curl_error($ch), $responseStatus); } curl_close($ch); if ($responseStatus >= 400) { if (is_array($responseBody)) { - throw new \Exception(json_encode($responseBody)); + throw new \Exception(json_encode($responseBody), $responseStatus); } else { - throw new \Exception($responseStatus.': '.$responseBody); + throw new \Exception($responseStatus.': '.$responseBody, $responseStatus); } } @@ -225,5 +225,7 @@ protected function logError(Exception $e) Console::error('[Error] Message: '.$e->getMessage()); Console::error('[Error] File: '.$e->getFile()); Console::error('[Error] Line: '.$e->getLine()); + Console::error('[Error] Trace: '); + Console::error($e->getTraceAsString()); } } diff --git a/src/Analytics/Adapter/ActiveCampaign.php b/src/Analytics/Adapter/ActiveCampaign.php deleted file mode 100644 index 71f84a4..0000000 --- a/src/Analytics/Adapter/ActiveCampaign.php +++ /dev/null @@ -1,413 +0,0 @@ -call('GET', '/api/3/contacts', [], [ - 'email' => $email, - ]); - - $result = json_decode($result, true); - - if ($result && $result['meta']['total'] > 0) { - return $result['contacts'][0]['id']; - } else { - return false; - } - } catch (\Exception $e) { - $this->logError($e); - - return false; - } - } - - /** - * Create a contact - */ - public function createContact(string $email, string $firstName = '', string $lastName = '', string $phone = ''): bool - { - $body = ['contact' => [ - 'email' => $email, - 'firstName' => $firstName, - 'lastName' => $lastName, - 'phone' => $phone, - ]]; - - try { - $this->call('POST', '/api/3/contacts', [ - 'Content-Type' => 'application/json', - ], $body); - - return true; - } catch (\Exception $e) { - $this->logError($e); - - return false; - } - } - - /** - * Update contact - */ - public function updateContact(string $contactId, string $email, string $firstName = '', string $lastName = '', string $phone = ''): bool - { - $body = ['contact' => [ - 'email' => $email, - 'firstName' => $firstName, - 'lastName' => $lastName, - 'phone' => $phone, - ]]; - - try { - $this->call('PUT', '/api/3/contacts/'.$contactId, [ - 'Content-Type' => 'application/json', - ], $body); - - return true; - } catch (\Exception $e) { - $this->logError($e); - - return false; - } - } - - /** - * Delete a contact - */ - public function deleteContact(string $email): bool - { - $contact = $this->contactExists($email); - - if (! $contact) { - return false; - } - - try { - $this->call('DELETE', '/api/3/contacts/'.$contact); - - return true; - } catch (\Exception $e) { - $this->logError($e); - - return false; - } - } - - /** - * Account Exists - */ - public function accountExists(string $name): bool|int - { - try { - $result = $this->call('GET', '/api/3/accounts', [], [ - 'search' => $name, - ]); - - if (intval(json_decode($result, true)['meta']['total']) > 0) { - return intval((json_decode($result, true))['accounts'][0]['id']); - } else { - return false; - } - } catch (\Exception $e) { - $this->logError($e); - - return false; - } - } - - /** - * Create an account - */ - public function createAccount(string $name, string $url = '', int $ownerId = 1, array $fields = []): bool - { - $body = ['account' => [ - 'name' => $name, - 'accountUrl' => $url, - 'owner' => $ownerId, - 'fields' => array_values(array_filter($fields, function ($value) { - return $value['fieldValue'] !== '' && $value['fieldValue'] !== null && $value['fieldValue'] !== false; - })), - ]]; - - try { - $this->call('POST', '/api/3/accounts', [ - 'Content-Type' => 'application/json', - ], $body); - - return true; - } catch (\Exception $e) { - $this->logError($e); - - return false; - } - } - - /** - * Update an account - */ - public function updateAccount(string $accountId, string $name, string $url = '', int $ownerId = 1, array $fields = []): bool - { - $body = ['account' => [ - 'name' => $name, - 'accountUrl' => $url, - 'owner' => $ownerId, - 'fields' => array_values(array_filter($fields, function ($value) { - return $value['fieldValue'] !== '' && $value['fieldValue'] !== null && $value['fieldValue'] !== false; - })), - ]]; - - try { - $this->call('PUT', '/api/3/accounts/'.$accountId, [ - 'Content-Type' => 'application/json', - ], array_filter($body)); - - return true; - } catch (\Exception $e) { - $this->logError($e); - - return false; - } - } - - /** - * Delete an account - */ - public function deleteAccount(string $accountId): bool - { - try { - $this->call('DELETE', '/api/3/accounts/'.$accountId); - - return true; - } catch (\Exception $e) { - $this->logError($e); - - return false; - } - } - - /** - * Sync an association - * - * Creates an association if it doesn't exist and updates it if it does - */ - public function syncAssociation(string $accountId, string $contactId, string $role = ''): bool - { - // See if the association already exists - - try { - $result = $this->call('GET', '/api/3/accountContacts', [], [ - 'filters[account]' => $accountId, - 'filters[contact]' => $contactId, - ]); - } catch (\Exception $e) { - $this->logError($e); - - return false; - } - - if (intval(json_decode($result, true)['meta']['total']) > 0) { - // Update the association - $associationId = intval((json_decode($result, true))['accountContacts'][0]['id']); - - try { - $result = $this->call('PUT', '/api/3/accountContacts/'.$associationId, [ - 'Content-Type' => 'application/json', - ], [ - 'accountContact' => [ - 'jobTitle' => $role, - ], - ]); - - return true; - } catch (\Exception $e) { - $this->logError($e); - - return false; - } - } else { - // Create the association - $result = $this->call('POST', '/api/3/accountContacts', [ - 'Content-Type' => 'application/json', - ], ['accountContact' => [ - 'account' => $accountId, - 'contact' => $contactId, - 'jobTitle' => $role, - ]]); - - return true; - } - } - - /** - * @return ActiveCampaign - */ - public function __construct(string $key, string $actId, string $apiKey, string $organisationId) - { - $this->key = $key; - $this->actId = $actId; - $this->apiKey = $apiKey; - $this->endpoint = 'https://'.$organisationId.'.api-us1.com/'; // ActiveCampaign API URL, Refer to https://developers.activecampaign.com/reference/url for more details. - $this->headers = [ - 'Api-Token' => $this->apiKey, - 'Content-Type' => null, - ]; - } - - /** - * Creates an Event on the remote analytics platform. - */ - public function send(Event $event): bool - { - if (! $this->enabled) { - return false; - } - - $query = [ - 'key' => $this->key, - 'event' => $event->getName(), - 'actid' => $this->actId, - 'eventdata' => json_encode($event->getProps()), - 'visit' => json_encode(['email' => $event->getProp('email')]), - ]; - - $query = array_filter($query, fn ($value) => ! is_null($value) && $value !== ''); - - $res = $this->call('POST', 'https://trackcmp.net/event', [], $query); // Active Campaign event URL, Refer to https://developers.activecampaign.com/reference/track-event/ for more details - if (json_decode($res, true)['success'] === 1) { - return true; - } else { - return false; - } - } - - /** - * Sets the client IP address. - * - * @param string $ip The IP address to use. - */ - public function setClientIP(string $clientIP): self - { - throw new \Exception('Not implemented'); - } - - /** - * Sets the client user agent. - * - * @param string $userAgent The user agent to use. - */ - public function setUserAgent(string $userAgent): self - { - throw new \Exception('Not implemented'); - } - - /** - * Set Tags - */ - public function setTags(string $contactId, array $tags): bool - { - foreach ($tags as $tag) { - try { - $this->call('POST', '/api/3/contactTags', [ - 'Content-Type' => 'application/json', - ], [ - 'contactTag' => [ - 'contact' => $contactId, - 'tag' => $tag, - ], - ]); - } catch (\Exception $e) { - $this->logError($e); - - return false; - } - } - - return true; - } - - public function validate(Event $event): bool - { - if (! $this->enabled) { - return false; - } - - $email = $event->getProp('email'); - - if (empty($email)) { - throw new \Exception('Email is required.'); - } - - if (! filter_var($email, FILTER_VALIDATE_EMAIL)) { - throw new \Exception('Invalid email address.'); - } - - $contactID = $this->contactExists($email); - $foundLog = false; - - // Get contact again, since AC doesn't refresh logs immediately - $response = $this->call('GET', '/api/3/activities', [], [ - 'contact' => $contactID, - 'orders[tstamp]' => 'DESC', - ]); - - $response = json_decode($response, true); - - if (empty($response['trackingLogs'])) { - throw new \Exception('Failed to find event on ActiveCampaign side.'); - } - - foreach ($response['trackingLogs'] as $log) { - if ($log['type'] === $event->getName()) { - $foundLog = true; - break; - } - } - - if (! $foundLog) { - throw new \Exception('Failed to find event on ActiveCampaign side.'); - } - - return true; - } -} diff --git a/src/Analytics/Adapter/HubSpot.php b/src/Analytics/Adapter/HubSpot.php new file mode 100644 index 0000000..14c0212 --- /dev/null +++ b/src/Analytics/Adapter/HubSpot.php @@ -0,0 +1,335 @@ +headers = [ + 'Authorization' => 'Bearer '.$token, + 'Content-Type' => '', + ]; + } + + /** + * Creates an Event on the remote analytics platform. + */ + public function send(Event $event): bool + { + if (! $this->enabled) { + return false; + } + + // HubSpot event tracking isn't possible due to their chrome based extention system + return false; + } + + public function validate(Event $event): bool + { + if (! $this->enabled) { + return false; + } + + // HubSpot event tracking isn't possible due to their chrome based extention system + return false; + } + + /** + * Gets the name of the adapter. + */ + public function getName(): string + { + return 'HubSpot'; + } + + /** + * Checks if a contact exists by the email ID. Returns the User ID if it exists and false if it doesn't. + */ + public function contactExists(string $email): bool|int + { + try { + $result = $this->call('POST', '/crm/v3/objects/contacts/search', [ + 'Content-Type' => 'application/json', + ], [ + 'filterGroups' => [[ + 'filters' => [ + [ + 'value' => $email, + 'propertyName' => 'email', + 'operator' => 'EQ', + ], + ], + ], ], + ]); + + $result = json_decode($result, true); + + if ($result && $result['total'] > 0 && count($result['results']) > 0) { + return $result['results'][0]['id']; + } else { + return false; + } + } catch (\Exception $e) { + $this->logError($e); + + return false; + } + } + + /** + * Create a contact + */ + public function createContact(string $email, string $firstName = '', string $lastName = '', string $phone = ''): bool + { + $body = ['properties' => [ + 'email' => $email, + 'firstname' => $firstName, + 'lastname' => $lastName, + 'phone' => $phone, + ]]; + + try { + $this->call('POST', '/crm/v3/objects/contacts', [ + 'Content-Type' => 'application/json', + ], $body); + + return true; + } catch (\Exception $e) { + $this->logError($e); + + return false; + } + } + + /** + * Update contact + */ + public function updateContact(string $contactId, string $email, string $firstName = '', string $lastName = '', string $phone = ''): bool + { + $body = [ + 'email' => $email, + 'firstname' => $firstName, + 'lastname' => $lastName, + 'phone' => $phone, + ]; + + try { + $this->call('PATCH', '/crm/v3/objects/contacts/'.$contactId, [ + 'Content-Type' => 'application/json', + ], $body); + + return true; + } catch (\Exception $e) { + if ($e->getCode() == 400) { + // No changes to make + return true; + } + + $this->logError($e); + + return false; + } + } + + /** + * Delete a contact + */ + public function deleteContact(string $email): bool + { + $contact = $this->contactExists($email); + + if (! $contact) { + return false; + } + + try { + $this->call('DELETE', '/crm/v3/objects/contacts/'.$contact, [ + 'Content-Type' => 'application/json', + ]); + + return true; + } catch (\Exception $e) { + $this->logError($e); + + return false; + } + } + + /** + * Account Exists + */ + public function accountExists(string $name): bool|int + { + try { + $result = $this->call('POST', '/crm/v3/objects/companies/search', [ + 'Content-Type' => 'application/json', + ], [ + 'filterGroups' => [[ + 'filters' => [ + [ + 'value' => $name, + 'propertyName' => 'name', + 'operator' => 'EQ', + ], + ], + ]], + ]); + + $result = json_decode($result, true); + + if ($result && $result['total'] > 0 && count($result['results']) > 0) { + return $result['results'][0]['id']; + } else { + return false; + } + } catch (\Exception $e) { + $this->logError($e); + + return false; + } + } + + /** + * Create an account + */ + public function createAccount(string $name, string $url = ''): bool + { + $body = ['properties' => [ + 'name' => $name, + 'domain' => $url, + ]]; + + try { + $this->call('POST', '/crm/v3/objects/companies', [ + 'Content-Type' => 'application/json', + ], $body); + + return true; + } catch (\Exception $e) { + $this->logError($e); + + return false; + } + } + + /** + * Update an account + */ + public function updateAccount(string $accountId, string $name, string $url = '', int $ownerId = 1, array $fields = []): bool + { + $body = [ + 'name' => $name, + 'domain' => $url, + ]; + + try { + $this->call('PATCH', '/crm/v3/objects/companies/'.$accountId, [ + 'Content-Type' => 'application/json', + ], $body); + + return true; + } catch (\Exception $e) { + if ($e->getCode() == 400) { + // No changes to make + return true; + } + + $this->logError($e); + + return false; + } + } + + /** + * Delete an account + */ + public function deleteAccount(string $accountId): bool + { + try { + $this->call('DELETE', '/crm/v3/objects/companies/'.$accountId, [ + 'Content-Type' => 'application/json', + ]); + + return true; + } catch (\Exception $e) { + $this->logError($e); + + return false; + } + } + + /** + * Sync an association + * + * Creates an association if it doesn't exist and updates it if it does + */ + public function syncAssociation(string $accountId, string $contactId, string $role = ''): bool + { + // See if the association already exists + + try { + $response = $this->call('GET', '/crm/v4/objects/contact/'.$accountId.'/associations/company'); + + $response = json_decode($response, true); + + $associationId = null; + + foreach ($response['results'] as $association) { + if ($association['from']['id'] == $contactId) { + $associationId = $association['id']; + } + } + + if (empty($associationId)) { + // Create the association + $this->call('PUT', '/crm/v4/objects/contact/'.$contactId.'/associations/default/company/'.$accountId, [ + 'Content-Type' => 'application/json', + ]); + } else { + // Delete and recreate the association + $this->call('DELETE', '/crm/v4/objects/contact/'.$contactId.'/associations/company/'.$accountId, [ + 'Content-Type' => 'application/json', + ]); + + $this->call('PUT', '/crm/v4/objects/contact/'.$contactId.'/associations/default/company/'.$accountId, [ + 'Content-Type' => 'application/json', + ]); + } + } catch (\Exception $e) { + $this->logError($e); + + return false; + } + + return true; + } + + /** + * Add a contact to a list + */ + public function addToList(int $listId, int $contactId): bool + { + try { + $this->call('POST', '/contacts/v1/lists/'.$listId.'/add', [ + 'Content-Type' => 'application/json', + ], [ + 'vids' => [$contactId], + ]); + + return true; + } catch (\Exception $e) { + $this->logError($e); + + return false; + } + } +} diff --git a/tests/Analytics/AnalyticsTest.php b/tests/Analytics/AnalyticsTest.php index e2a1d7a..5efd84c 100644 --- a/tests/Analytics/AnalyticsTest.php +++ b/tests/Analytics/AnalyticsTest.php @@ -3,8 +3,8 @@ namespace Utopia\Tests; use PHPUnit\Framework\TestCase; -use Utopia\Analytics\Adapter\ActiveCampaign; use Utopia\Analytics\Adapter\GoogleAnalytics; +use Utopia\Analytics\Adapter\HubSpot; use Utopia\Analytics\Adapter\Mixpanel; use Utopia\Analytics\Adapter\Orbit; use Utopia\Analytics\Adapter\Plausible; @@ -16,9 +16,6 @@ class AnalyticsTest extends TestCase /** @var \Utopia\Analytics\Adapter\GoogleAnalytics */ public $ga; - /** @var \Utopia\Analytics\Adapter\ActiveCampaign|null */ - public $ac; - /** @var \Utopia\Analytics\Adapter\Plausible */ public $pa; @@ -28,43 +25,21 @@ class AnalyticsTest extends TestCase /** @var \Utopia\Analytics\Adapter\Mixpanel */ public $mp; + /** @var \Utopia\Analytics\Adapter\HubSpot */ + public $hs; + public function setUp(): void { $this->ga = new GoogleAnalytics(App::getEnv('GA_TID'), App::getEnv('GA_CID')); - $this->ac = new ActiveCampaign( - App::getEnv('AC_KEY'), - App::getEnv('AC_ACTID'), - App::getEnv('AC_APIKEY'), - App::getEnv('AC_ORGID') - ); $this->pa = new Plausible(App::getEnv('PA_DOMAIN'), App::getEnv('PA_APIKEY'), 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36', '192.168.0.1'); $this->orbit = new Orbit(App::getEnv('OR_WORKSPACEID'), App::getEnv('OR_APIKEY'), 'Utopia Testing Suite'); $this->mp = new Mixpanel(App::getEnv('MP_PROJECT_TOKEN')); + $this->hs = new HubSpot(App::getEnv('HS_APIKEY')); } - public function testGoogleAnalytics(): void - { - // Use Measurement Protocol Validation Server for testing. - $pageviewEvent = new Event(); - $pageviewEvent - ->setType('pageview') - ->setName('pageview') - ->setUrl('https://www.appwrite.io/docs/installation'); - - $normalEvent = new Event(); - $normalEvent->setType('testEvent') - ->setName('testEvent') - ->setUrl('https://www.appwrite.io/docs/installation') - ->setProps(['category' => 'testEvent']); - - $this->assertTrue($this->ga->validate($pageviewEvent)); - $this->assertTrue($this->ga->validate($normalEvent)); - - $this->ga->disable(); - $this->assertFalse($this->ga->validate($pageviewEvent)); - $this->assertFalse($this->ga->validate($normalEvent)); - } - + /** + * @group plausible + */ public function testPlausible() { $pageviewEvent = new Event(); @@ -83,33 +58,86 @@ public function testPlausible() $this->assertTrue($this->pa->validate($normalEvent)); } - public function testActiveCampaignCreateContact() + /** + * @group hubspot + */ + public function testHubSpotCreateContact() { - $this->assertTrue($this->ac->createContact('analytics2@utopiaphp.com', 'Analytics', 'Utopia')); + $this->assertTrue($this->hs->createContact('analytics2@utopiaphp.com', 'Analytics', 'Utopia')); + + sleep(5); // Sometimes it can take a few seconds for HubSpot to index the new contact } - public function testActiveCampaignGetContact() + /** + * @group hubspot + * + * @depends testHubSpotCreateContact + */ + public function testHubSpotGetContact() { - $contactID = $this->ac->contactExists('analytics2@utopiaphp.com'); - $this->assertIsNumeric($contactID); + $tries = 0; + + while ($tries < 5) { + $contactID = $this->hs->contactExists('analytics2@utopiaphp.com'); + + if ($contactID) { + $this->assertIsNumeric($contactID); + break; + } + + var_dump('Waiting for HubSpot to index the new contact... Attempt: '.$tries.'/5'); + sleep(5); + $tries++; + + if ($tries === 5) { + $this->fail('HubSpot failed to index the new contact in a reasonable amount of time'); + } + } return [ 'contactID' => $contactID, ]; } - public function testActiveCampaignCreateAccount() + /** + * @group hubspot + * + * @depends testHubSpotGetContact + */ + public function testHubSpotCreateAccount($data) { - $this->assertTrue($this->ac->createAccount('Example Account 1', 'https://example.com', '1234567890')); + $this->assertTrue($this->hs->createAccount('Example Account 1', 'https://example.com', '1234567890')); + + sleep(5); // Sometimes it can take a few seconds for HubSpot to index the new account + + return $data; } /** - * @depends testActiveCampaignGetContact + * @group hubspot + * + * @depends testHubSpotCreateAccount */ - public function testActiveCampaignGetAccount($data) + public function testHubSpotGetAccount($data) { - $accountID = $this->ac->accountExists('Example Account 1'); - $this->assertIsNumeric($accountID); + $tries = 0; + + while ($tries < 5) { + $accountID = $this->hs->accountExists('Example Account 1'); + + if ($accountID) { + $this->assertIsNumeric($accountID); + break; + } + + var_dump('Waiting for HubSpot to index the new account... Attempt: '.$tries.'/5'); + sleep(5); + $tries++; + + if ($tries === 5) { + $this->fail('HubSpot failed to index the new account'); + } + } return array_merge([ 'accountID' => $accountID, @@ -117,62 +145,72 @@ public function testActiveCampaignGetAccount($data) } /** - * @depends testActiveCampaignGetAccount + * @depends testHubSpotGetAccount + * + * @group hubspot */ - public function testActiveCampaignSyncAsociation($data) + public function testHubSpotSyncAsociation($data) { - $this->assertTrue($this->ac->syncAssociation($data['accountID'], $data['contactID'], 'Owner')); - $this->assertTrue($this->ac->syncAssociation($data['accountID'], $data['contactID'], 'Software Developer')); + $this->assertTrue($this->hs->syncAssociation($data['accountID'], $data['contactID'], 'Owner')); + $this->assertTrue($this->hs->syncAssociation($data['accountID'], $data['contactID'], 'Software Developer')); + + return $data; } /** - * @depends testActiveCampaignGetContact + * @depends testHubSpotSyncAsociation + * + * @group hubspot */ - public function testActiveCampaignUpdateContact($data) + public function testHubSpotUpdateContact($data) { - $this->assertTrue($this->ac->updateContact($data['contactID'], 'analytics2@utopiaphp.com', '', '', '7223224241')); + $this->assertTrue($this->hs->updateContact($data['contactID'], 'analytics2@utopiaphp.com', '', '', '7223224241')); + + return $data; } - public function testActiveCampaignDeleteContact() + /** + * @depends testHubSpotUpdateContact + * + * @group hubspot + */ + public function testHubSpotDeleteContact($data) { - $this->assertTrue($this->ac->deleteContact('analytics2@utopiaphp.com')); + $this->assertTrue($this->hs->deleteContact('analytics2@utopiaphp.com')); + + return $data; } /** - * @depends testActiveCampaignGetAccount + * @depends testHubSpotDeleteContact + * + * @group hubspot */ - public function testActiveCampaignUpdateAccount($data) + public function testHubSpotUpdateAccount($data) { - $this->assertTrue($this->ac->updateAccount( + $this->assertTrue($this->hs->updateAccount( $data['accountID'], 'Utopia', 'utopia.com', - 1)); + 1 + )); + + return $data; } /** - * @depends testActiveCampaignGetAccount + * @depends testHubSpotUpdateAccount + * + * @group hubspot */ - public function testActiveCampaignDeleteAccount($data) + public function testHubSpotDeleteAccount($data) { - $this->assertTrue($this->ac->deleteAccount($data['accountID'])); - } - - public function testActiveCampaign() - { - $this->assertTrue($this->ac->createContact('analytics@utopiaphp.com', 'Analytics', 'Utopia')); - - $event = new Event(); - $event->setType('testEvent') - ->setName('testEvent'.chr(mt_rand(97, 122)).substr(md5(time()), 1, 5)) - ->setUrl('https://www.appwrite.io/docs/installation') - ->setProps(['category' => 'analytics:test', 'email' => 'analytics@utopiaphp.com', 'tags' => ['test', 'test2']]); - - $this->assertTrue($this->ac->send($event)); - sleep(10); - $this->assertTrue($this->ac->validate($event)); + $this->assertTrue($this->hs->deleteAccount($data['accountID'])); } + /** + * @group orbit + */ public function testOrbit(): void { $event = new Event(); @@ -185,21 +223,29 @@ public function testOrbit(): void $this->assertTrue($this->orbit->validate($event)); } + /** + * @group hubspot + */ public function testCleanup(): void { - if ($this->ac->contactExists('analytics@utopiaphp.com')) { - $this->assertTrue($this->ac->deleteContact('analytics@utopiaphp.com')); + if ($this->hs->contactExists('analytics@utopiaphp.com')) { + $this->assertTrue($this->hs->deleteContact('analytics@utopiaphp.com')); } - if ($this->ac->contactExists('analytics2@utopiaphp.com')) { - $this->assertTrue($this->ac->deleteContact('analytics2@utopiaphp.com')); + if ($this->hs->contactExists('analytics2@utopiaphp.com')) { + $this->assertTrue($this->hs->deleteContact('analytics2@utopiaphp.com')); } - if ($this->ac->accountExists('Example Account 1')) { - $this->assertTrue($this->ac->deleteAccount($this->ac->accountExists('Example Account 1'))); + if ($this->hs->accountExists('Example Account 1')) { + $this->assertTrue($this->hs->deleteAccount($this->hs->accountExists('Example Account 1'))); } + + $this->assertTrue(true); } + /** + * @group mixpanel + */ public function testMixpanel() { /** Create a simple track event */