From bf6c5d40b66888805d218b7b774d65093e410be7 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Thu, 21 Mar 2024 14:36:23 +0000 Subject: [PATCH 01/11] Started work on subscriber methods --- src/ConvertKit_API.php | 213 +++++++++++++++++++++++++++++++++-------- 1 file changed, 171 insertions(+), 42 deletions(-) diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index 3075af4..9ffedab 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -812,6 +812,148 @@ public function get_resources(string $resource) return $_resource; } + /** + * Get subscribers. + * + * @since 2.0.0 + * + * @param string $subscriber_state Subscriber State (active|bounced|cancelled|complained|inactive). + * @param string $email_address Search susbcribers by email address. This is an exact match search. + * @param \DateTime $created_after Filter subscribers who have been created after this date. + * @param \DateTime $created_before Filter subscribers who have been created before this date. + * @param \DateTime $added_after Filter subscribers who have been added to the form after this date. + * @param \DateTime $added_before Filter subscribers who have been added to the form before this date. + * @param string $sort_field Sort Field (id|updated_at|cancelled_at). + * @param string $sort_order Sort Order (asc|desc). + * @param string $after_cursor Return results after the given pagination cursor. + * @param string $before_cursor Return results before the given pagination cursor. + * @param integer $per_page Number of results to return. + * + * @see https://developers.convertkit.com/v4.html#list-subscribers + * + * @return false|mixed + */ + public function get_subscribers( + string $subscriber_state = 'active', + string $email_address = '', + \DateTime $created_after = null, + \DateTime $created_before = null, + \DateTime $updated_after = null, + \DateTime $updated_before = null, + string $sort_field = 'id', + string $sort_order = 'desc', + string $after_cursor = '', + string $before_cursor = '', + int $per_page = 100 + ) + { + // Build parameters. + $options = []; + + if (!empty($subscriber_state)) { + $options['status'] = $subscriber_state; + } + if (!empty($email_address)) { + $options['email_address'] = $email_address; + } + if (!is_null($created_after)) { + $options['created_after'] = $created_after->format('Y-m-d'); + } + if (!is_null($created_before)) { + $options['created_before'] = $created_before->format('Y-m-d'); + } + if (!is_null($updated_after)) { + $options['updated_after'] = $updated_after->format('Y-m-d'); + } + if (!is_null($updated_before)) { + $options['updated_before'] = $updated_before->format('Y-m-d'); + } + if (!empty($sort_field)) { + $options['sort_field'] = $sort_field; + } + if (!empty($sort_order)) { + $options['sort_order'] = $sort_order; + } + + // Build pagination parameters. + $options = $this->build_pagination_params( + params: $options, + after_cursor: $after_cursor, + before_cursor: $before_cursor, + per_page: $per_page + ); + + // Send request. + return $this->get( + endpoint: 'subscribers', + args: $options + ); + } + + /** + * Create a subscriber. + * + * Behaves as an upsert. If a subscriber with the provided email address does not exist, + * it creates one with the specified first name and state. If a subscriber with the provided + * email address already exists, it updates the first name. + * + * @since 2.0.0 + * + * @param string $email_address Email Address. + * @param string $first_name First Name. + * @param string $subscriber_state Subscriber State (active|bounced|cancelled|complained|inactive). + * @param array $fields Custom Fields. + * + * @see https://developers.convertkit.com/v4.html#create-a-subscriber + * + * @return mixed + */ + public function create_subscriber( + string $email_address, + string $first_name = '', + string $subscriber_state = '', + array $fields = [] + ) + { + // Build parameters. + $options = []; + + if (!empty($first_name)) { + $options['first_name'] = $first_name; + } + if (!empty($state)) { + $options['state'] = $state; + } + if (count($fields)) { + $options['fields'] = $fields; + } + + // Send request. + return $this->post( + endpoint: 'subscribers', + args: $options + ); + } + + public function create_subscribers(array $subscribers) + { + // @TODO. + } + + /** + * Get subscriber by id + * + * @param integer $subscriber_id Subscriber ID. + * + * @see https://developers.convertkit.com/v4.html#get-a-subscriber + * + * @return false|integer + */ + public function get_subscriber(int $subscriber_id) + { + return $this->get(sprintf('subscribers/%s', $subscriber_id)); + } + /** * Get the ConvertKit subscriber ID associated with email address if it exists. * Return false if subscriber not found. @@ -820,16 +962,12 @@ public function get_resources(string $resource) * * @throws \InvalidArgumentException If the email address is not a valid email format. * - * @see https://developers.convertkit.com/#list-subscribers + * @see https://developers.convertkit.com/v4.html#get-a-subscriber * * @return false|integer */ public function get_subscriber_id(string $email_address) { - if (!filter_var($email_address, FILTER_VALIDATE_EMAIL)) { - throw new \InvalidArgumentException('Email address is not a valid email format.'); - } - $subscribers = $this->get( 'subscribers', ['email_address' => $email_address] @@ -849,20 +987,6 @@ public function get_subscriber_id(string $email_address) return $subscribers->subscribers[0]->id; } - /** - * Get subscriber by id - * - * @param integer $subscriber_id Subscriber ID. - * - * @see https://developers.convertkit.com/#view-a-single-subscriber - * - * @return false|integer - */ - public function get_subscriber(int $subscriber_id) - { - return $this->get(sprintf('subscribers/%s', $subscriber_id)); - } - /** * Updates the information for a single subscriber. * @@ -871,7 +995,7 @@ public function get_subscriber(int $subscriber_id) * @param string $email_address New Email Address. * @param array $fields Updated Custom Fields. * - * @see https://developers.convertkit.com/#update-subscriber + * @see https://developers.convertkit.com/v4.html#update-a-subscriber * * @return false|mixed */ @@ -902,42 +1026,36 @@ public function update_subscriber( } /** - * Unsubscribe an email address from all forms and sequences. + * Unsubscribe an email address. * * @param string $email Email Address. * - * @see https://developers.convertkit.com/#unsubscribe-subscriber + * @see https://developers.convertkit.com/v4.html#unsubscribe-subscriber * * @return false|object */ public function unsubscribe(string $email) { - return $this->put( - 'unsubscribe', - ['email' => $email] + return $this->post( + sprintf( + 'subscribers/%s/unsubscribe', + $this->get_subscriber_id($email) + ) ); } /** - * Remove subscription from a form + * Unsubscribe the given subscriber ID. * - * @param array $options Array of user data (email). + * @param int $subscriber_id Subscriber ID. * - * @see https://developers.convertkit.com/#unsubscribe-subscriber + * @see https://developers.convertkit.com/v4.html#unsubscribe-subscriber * * @return false|object */ - public function form_unsubscribe(array $options) + public function unsubscribe_by_id(int $subscriber_id) { - // This function is deprecated in 1.0, as we prefer functions with structured arguments. - // This function name is also misleading, as it doesn't just unsubscribe the email - // address from forms. - trigger_error( - 'form_unsubscribe() is deprecated in 1.0. Use unsubscribe($email) instead.', - E_USER_NOTICE - ); - - return $this->put('unsubscribe', $options); + return $this->post(sprintf('subscribers/%s/unsubscribe', $subscriber_id)); } /** @@ -945,13 +1063,24 @@ public function form_unsubscribe(array $options) * * @param integer $subscriber_id Subscriber ID. * - * @see https://developers.convertkit.com/#list-tags-for-a-subscriber + * @see https://developers.convertkit.com/v4.html#list-tags-for-a-subscriber * * @return false|array */ - public function get_subscriber_tags(int $subscriber_id) - { - return $this->get(sprintf('subscribers/%s/tags', $subscriber_id)); + public function get_subscriber_tags( + int $subscriber_id, + string $after_cursor = '', + string $before_cursor = '', + int $per_page = 100 + ) { + return $this->get( + endpoint: sprintf('subscribers/%s/tags', $subscriber_id), + args: $this->build_pagination_params( + after_cursor: $after_cursor, + before_cursor: $before_cursor, + per_page: $per_page + ) + ); } /** From 344b717271b310f7cdaf7158fef5223101856deb Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Thu, 21 Mar 2024 15:04:35 +0000 Subject: [PATCH 02/11] Completed first pass of subscriber methods --- src/ConvertKit_API.php | 63 +++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index 9ffedab..d831b6d 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -814,21 +814,21 @@ public function get_resources(string $resource) /** * Get subscribers. - * - * @since 2.0.0 * * @param string $subscriber_state Subscriber State (active|bounced|cancelled|complained|inactive). * @param string $email_address Search susbcribers by email address. This is an exact match search. * @param \DateTime $created_after Filter subscribers who have been created after this date. * @param \DateTime $created_before Filter subscribers who have been created before this date. - * @param \DateTime $added_after Filter subscribers who have been added to the form after this date. - * @param \DateTime $added_before Filter subscribers who have been added to the form before this date. + * @param \DateTime $updated_after Filter subscribers who have been updated after this date. + * @param \DateTime $updated_before Filter subscribers who have been updated before this date. * @param string $sort_field Sort Field (id|updated_at|cancelled_at). * @param string $sort_order Sort Order (asc|desc). * @param string $after_cursor Return results after the given pagination cursor. * @param string $before_cursor Return results before the given pagination cursor. * @param integer $per_page Number of results to return. * + * @since 2.0.0 + * * @see https://developers.convertkit.com/v4.html#list-subscribers * * @return false|mixed @@ -845,8 +845,7 @@ public function get_subscribers( string $after_cursor = '', string $before_cursor = '', int $per_page = 100 - ) - { + ) { // Build parameters. $options = []; @@ -892,20 +891,20 @@ public function get_subscribers( /** * Create a subscriber. - * + * * Behaves as an upsert. If a subscriber with the provided email address does not exist, * it creates one with the specified first name and state. If a subscriber with the provided * email address already exists, it updates the first name. - * - * @since 2.0.0 - * - * @param string $email_address Email Address. - * @param string $first_name First Name. - * @param string $subscriber_state Subscriber State (active|bounced|cancelled|complained|inactive). - * @param array $fields Custom Fields. - * + * + * @param string $email_address Email Address. + * @param string $first_name First Name. + * @param string $subscriber_state Subscriber State (active|bounced|cancelled|complained|inactive). + * @param array $fields Custom Fields. + * + * @since 2.0.0 + * * @see https://developers.convertkit.com/v4.html#create-a-subscriber - * + * * @return mixed */ public function create_subscriber( @@ -913,16 +912,15 @@ public function create_subscriber( string $first_name = '', string $subscriber_state = '', array $fields = [] - ) - { + ) { // Build parameters. $options = []; if (!empty($first_name)) { $options['first_name'] = $first_name; } - if (!empty($state)) { - $options['state'] = $state; + if (!empty($subscriber_state)) { + $options['state'] = $subscriber_state; } if (count($fields)) { $options['fields'] = $fields; @@ -935,9 +933,27 @@ public function create_subscriber( ); } + /** + * Create multiple subscribers. + * + * @param array> $subscribers Subscribers. + * + * @since 2.0.0 + * + * @see https://developers.convertkit.com/v4.html#bulk-create-subscribers + * + * @return mixed + */ public function create_subscribers(array $subscribers) { - // @TODO. + // Build parameters. + $options = ['subscribers' => $subscribers]; + + // Send request. + return $this->post( + endpoint: 'bulk/subscribers', + args: $options + ); } /** @@ -1047,7 +1063,7 @@ public function unsubscribe(string $email) /** * Unsubscribe the given subscriber ID. * - * @param int $subscriber_id Subscriber ID. + * @param integer $subscriber_id Subscriber ID. * * @see https://developers.convertkit.com/v4.html#unsubscribe-subscriber * @@ -1062,6 +1078,9 @@ public function unsubscribe_by_id(int $subscriber_id) * Get a list of the tags for a subscriber. * * @param integer $subscriber_id Subscriber ID. + * @param string $after_cursor Return results after the given pagination cursor. + * @param string $before_cursor Return results before the given pagination cursor. + * @param integer $per_page Number of results to return. * * @see https://developers.convertkit.com/v4.html#list-tags-for-a-subscriber * From 2d9db50a9f849835294c7f49192baffdc76d45eb Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Thu, 21 Mar 2024 15:06:04 +0000 Subject: [PATCH 03/11] Added `callback_url` for bulk add subscribers --- src/ConvertKit_API.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index d831b6d..80c242d 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -936,7 +936,8 @@ public function create_subscriber( /** * Create multiple subscribers. * - * @param array> $subscribers Subscribers. + * @param array> $subscribers Subscribers. + * @param string $callback_url URL to notify for large batch size when async processing complete. * * @since 2.0.0 * @@ -944,11 +945,15 @@ public function create_subscriber( * * @return mixed */ - public function create_subscribers(array $subscribers) + public function create_subscribers(array $subscribers, string $callback_url = '') { // Build parameters. $options = ['subscribers' => $subscribers]; + if (!empty($callback_url)) { + $options['callback_url'] = $callback_url; + } + // Send request. return $this->post( endpoint: 'bulk/subscribers', From 24faea8164127356a4501987c7bede44ff5063df Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Thu, 21 Mar 2024 15:15:38 +0000 Subject: [PATCH 04/11] Started stubbing tests --- tests/ConvertKitAPITest.php | 167 ++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index 9391fcd..4105a8c 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -1592,6 +1592,173 @@ public function testAddSubscriberToFormWithTagID() $this->assertEquals($subscriberTags->tags[0]->id, $_ENV['CONVERTKIT_API_TAG_ID']); } + public function testGetSubscribers() + { + + } + + public function testGetSubscribersByEmailAddress() + { + + } + + public function testGetSubscribersWithBouncedSubscriberState() + { + + } + + public function testGetSubscribersWithAddedAfterParam() + { + + } + + public function testGetSubscribersWithAddedBeforeParam() + { + + } + + public function testGetSubscribersWithUpdatedAfterParam() + { + + } + + public function testGetSubscribersWithUpdatedBeforeParam() + { + + } + + public function testGetSubscibersWithSortFieldParam() + { + + } + + public function testGetSubscibersWithSortOrderParam() + { + + } + + public function testGetSubscribersPagination() + { + + } + + public function testGetSubscribersWithInvalidEmailAddress() + { + + } + + public function testGetSubscribersWithInvalidSubscriberState() + { + + } + + public function testGetSubscribersWithInvalidSortFieldParam() + { + + } + + public function testGetSubscribersWithInvalidSortOrderParam() + { + + } + + public function testGetSubscribersWithInvalidPagination() + { + + } + + /** + * Test that create_subscriber() returns the expected data. + * + * @since 2.0.0 + * + * @return void + */ + public function testCreateSubscriber() + { + + } + + /** + * Test that create_subscriber() returns the expected data + * when a first name is included. + * + * @since 2.0.0 + * + * @return void + */ + public function testCreateSubscriberWithFirstName() + { + + } + + /** + * Test that create_subscriber() returns the expected data + * when a subscriber state is included. + * + * @since 2.0.0 + * + * @return void + */ + public function testCreateSubscriberWithSubscriberState() + { + + } + + /** + * Test that create_subscriber() returns the expected data + * when custom field data is included. + * + * @since 2.0.0 + * + * @return void + */ + public function testCreateSubscriberWithCustomFields() + { + + } + + /** + * Test that create_subscriber() throws a ClientException when an invalid + * email address is specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testCreateSubscriberWithInvalidEmailAddress() + { + + } + + /** + * Test that create_subscriber() throws a ClientException when an invalid + * subscriber state is specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testCreateSubscriberWithInvalidSubscriberState() + { + + } + + public function testCreateSubscribers() + { + + } + + public function testCreateSubscribersWithBlankData() + { + + } + + public function testCreateSubscribersWithInvalidEmailAddresses() + { + + } + /** * Test that get_subscriber_id() returns the expected data. * From 58c96ead03226956cd08cfb17cf03b6066533966 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Fri, 22 Mar 2024 14:52:33 +0000 Subject: [PATCH 05/11] Started writing tests for `get_subscribers` --- src/ConvertKit_API.php | 28 ++++---- tests/ConvertKitAPITest.php | 140 ++++++++++++++++++++++++++++++++++-- 2 files changed, 150 insertions(+), 18 deletions(-) diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index 7735fa3..738b49a 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -1075,20 +1075,6 @@ public function create_subscribers(array $subscribers, string $callback_url = '' ); } - /** - * Get subscriber by id - * - * @param integer $subscriber_id Subscriber ID. - * - * @see https://developers.convertkit.com/v4.html#get-a-subscriber - * - * @return false|integer - */ - public function get_subscriber(int $subscriber_id) - { - return $this->get(sprintf('subscribers/%s', $subscriber_id)); - } - /** * Get the ConvertKit subscriber ID associated with email address if it exists. * Return false if subscriber not found. @@ -1122,6 +1108,20 @@ public function get_subscriber_id(string $email_address) return $subscribers->subscribers[0]->id; } + /** + * Get subscriber by id + * + * @param integer $subscriber_id Subscriber ID. + * + * @see https://developers.convertkit.com/v4.html#get-a-subscriber + * + * @return false|integer + */ + public function get_subscriber(int $subscriber_id) + { + return $this->get(sprintf('subscribers/%s', $subscriber_id)); + } + /** * Updates the information for a single subscriber. * diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index af1e581..d7a82bd 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -2049,44 +2049,176 @@ public function testAddSubscriberToFormByIDWithInvalidSubscriberID() ); } + /** + * Test that get_subscribers() returns the expected data. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribers() { + $result = $this->api->get_subscribers(); + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); } + /** + * Test that get_subscribers() returns the expected data when + * searching by an email address. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribersByEmailAddress() { - + $result = $this->api->get_subscribers( + email_address: $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'] + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + + // Assert correct subscriber returned. + $this->assertEquals( + get_object_vars($result->subscriber)['email_address'], + $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'] + ); } + /** + * Test that get_subscribers() returns the expected data + * when the subscription status is bounced. + * + * @since 1.0.0 + * + * @return void + */ public function testGetSubscribersWithBouncedSubscriberState() { + $result = $this->api->get_subscribers( + subscriber_state: 'bounced' + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + // Check the correct subscribers were returned. + $this->assertEquals($result->subscribers[0]->state, 'bounced'); } + /** + * Test that get_subscribers() returns the expected data + * when the added_after parameter is used. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribersWithAddedAfterParam() { + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_subscribers( + added_after: $date + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + // Check the correct subscribers were returned. + $this->assertGreaterThanOrEqual( + $date->format('Y-m-d'), + date('Y-m-d', strtotime($result->subscribers[0]->added_at)) + ); } + /** + * Test that get_subscribers() returns the expected data + * when the added_before parameter is used. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribersWithAddedBeforeParam() { - + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_subscribers( + added_before: $date + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + + // Check the correct subscribers were returned. + $this->assertLessThanOrEqual( + $date->format('Y-m-d'), + date('Y-m-d', strtotime($result->subscribers[0]->added_at)) + ); } + /** + * Test that get_subscribers() returns the expected data + * when the updated_after parameter is used. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribersWithUpdatedAfterParam() { + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_form_subscriptions( + updated_after: $date + ); + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + + // Check the correct subscribers were returned. + $this->assertGreaterThanOrEqual( + $date->format('Y-m-d'), + date('Y-m-d', strtotime($result->subscribers[0]->created_at)) + ); } + /** + * Test that get_subscribers() returns the expected data + * when the updated_before parameter is used. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribersWithUpdatedBeforeParam() { - + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_form_subscriptions( + updated_before: $date + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + + // Check the correct subscribers were returned. + $this->assertGreaterThanOrEqual( + $date->format('Y-m-d'), + date('Y-m-d', strtotime($result->subscribers[0]->created_at)) + ); } public function testGetSubscibersWithSortFieldParam() { - + } public function testGetSubscibersWithSortOrderParam() From 134f6618ac4c44b4a9c4092d73f8eb747e468d40 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Fri, 22 Mar 2024 15:06:15 +0000 Subject: [PATCH 06/11] Continued tests for `get_subscribers` --- tests/ConvertKitAPITest.php | 135 +++++++++++++++++++++++++++++------- 1 file changed, 109 insertions(+), 26 deletions(-) diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index d7a82bd..eaa72f9 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -2114,17 +2114,17 @@ public function testGetSubscribersWithBouncedSubscriberState() /** * Test that get_subscribers() returns the expected data - * when the added_after parameter is used. + * when the created_after parameter is used. * * @since 2.0.0 * * @return void */ - public function testGetSubscribersWithAddedAfterParam() + public function testGetSubscribersWithCreatedAfterParam() { $date = new \DateTime('2024-01-01'); $result = $this->api->get_subscribers( - added_after: $date + created_after: $date ); // Assert subscribers and pagination exist. @@ -2134,23 +2134,23 @@ public function testGetSubscribersWithAddedAfterParam() // Check the correct subscribers were returned. $this->assertGreaterThanOrEqual( $date->format('Y-m-d'), - date('Y-m-d', strtotime($result->subscribers[0]->added_at)) + date('Y-m-d', strtotime($result->subscribers[0]->created_at)) ); } /** * Test that get_subscribers() returns the expected data - * when the added_before parameter is used. + * when the created_before parameter is used. * * @since 2.0.0 * * @return void */ - public function testGetSubscribersWithAddedBeforeParam() + public function testGetSubscribersWithCreatedBeforeParam() { $date = new \DateTime('2024-01-01'); $result = $this->api->get_subscribers( - added_before: $date + created_before: $date ); // Assert subscribers and pagination exist. @@ -2160,7 +2160,7 @@ public function testGetSubscribersWithAddedBeforeParam() // Check the correct subscribers were returned. $this->assertLessThanOrEqual( $date->format('Y-m-d'), - date('Y-m-d', strtotime($result->subscribers[0]->added_at)) + date('Y-m-d', strtotime($result->subscribers[0]->created_at)) ); } @@ -2175,19 +2175,13 @@ public function testGetSubscribersWithAddedBeforeParam() public function testGetSubscribersWithUpdatedAfterParam() { $date = new \DateTime('2024-01-01'); - $result = $this->api->get_form_subscriptions( + $result = $this->api->get_subscribers( updated_after: $date ); // Assert subscribers and pagination exist. $this->assertDataExists($result, 'subscribers'); $this->assertPaginationExists($result); - - // Check the correct subscribers were returned. - $this->assertGreaterThanOrEqual( - $date->format('Y-m-d'), - date('Y-m-d', strtotime($result->subscribers[0]->created_at)) - ); } /** @@ -2201,34 +2195,123 @@ public function testGetSubscribersWithUpdatedAfterParam() public function testGetSubscribersWithUpdatedBeforeParam() { $date = new \DateTime('2024-01-01'); - $result = $this->api->get_form_subscriptions( + $result = $this->api->get_subscribers( updated_before: $date ); // Assert subscribers and pagination exist. $this->assertDataExists($result, 'subscribers'); $this->assertPaginationExists($result); - - // Check the correct subscribers were returned. - $this->assertGreaterThanOrEqual( - $date->format('Y-m-d'), - date('Y-m-d', strtotime($result->subscribers[0]->created_at)) - ); } - public function testGetSubscibersWithSortFieldParam() + /** + * Test that get_subscribers() returns the expected data + * when the sort_field parameter is used. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSubscribersWithSortFieldParam() { - + $result = $this->api->get_subscribers( + sort_field: 'id' + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + + // Assert sorting is honored by ID in descending (default) order. + $this->assertLessThanOrEqual( + $result->subscribers[0]->id, + $result->subscribers[1]->id + ); } - public function testGetSubscibersWithSortOrderParam() + /** + * Test that get_subscribers() returns the expected data + * when the sort_order parameter is used. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSubscribersWithSortOrderParam() { - + $result = $this->api->get_subscribers( + sort_order: 'asc' + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + + // Assert sorting is honored by ID (default) in ascending order. + $this->assertGreaterThanOrEqual( + $result->subscribers[0]->id, + $result->subscribers[1]->id + ); } + /** + * Test that get_subscribers() returns the expected data + * when pagination parameters and per_page limits are specified. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribersPagination() { + $result = $this->api->get_subscribers( + per_page: 1 + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + + // Assert a single subscriber was returned. + $this->assertCount(1, $result->subscribers); + + // Assert has_previous_page and has_next_page are correct. + $this->assertFalse($result->pagination->has_previous_page); + $this->assertTrue($result->pagination->has_next_page); + + // Use pagination to fetch next page. + $result = $this->api->get_subscribers( + per_page: 1, + after_cursor: $result->pagination->end_cursor + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + + // Assert a single subscriber was returned. + $this->assertCount(1, $result->subscribers); + + // Assert has_previous_page and has_next_page are correct. + $this->assertTrue($result->pagination->has_previous_page); + $this->assertTrue($result->pagination->has_next_page); + + // Use pagination to fetch previous page. + $result = $this->api->get_subscribers( + per_page: 1, + before_cursor: $result->pagination->start_cursor + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + + // Assert a single subscriber was returned. + $this->assertCount(1, $result->subscribers); + // Assert has_previous_page and has_next_page are correct. + $this->assertFalse($result->pagination->has_previous_page); + $this->assertTrue($result->pagination->has_next_page); } public function testGetSubscribersWithInvalidEmailAddress() From f9e515d291b4dab19053640cc1f9613b8a62a6b8 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Fri, 22 Mar 2024 15:10:38 +0000 Subject: [PATCH 07/11] Completed `get_subscribers` tests --- tests/ConvertKitAPITest.php | 92 +++++++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 23 deletions(-) diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index eaa72f9..fb41d20 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -2085,7 +2085,7 @@ public function testGetSubscribersByEmailAddress() // Assert correct subscriber returned. $this->assertEquals( - get_object_vars($result->subscriber)['email_address'], + $result->subscribers[0]->email_address, $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'] ); } @@ -2314,80 +2314,131 @@ public function testGetSubscribersPagination() $this->assertTrue($result->pagination->has_next_page); } + /** + * Test that get_subscribers() throws a ClientException when an invalid + * email address is specified. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribersWithInvalidEmailAddress() { - + $this->expectException(ClientException::class); + $result = $this->api->get_subscribers( + email_address: 'not-an-email-address' + ); } + /** + * Test that get_subscribers() throws a ClientException when an invalid + * subscriber state is specified. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribersWithInvalidSubscriberState() { - + $this->expectException(ClientException::class); + $result = $this->api->get_subscribers( + subscriber_state: 'not-an-valid-state' + ); } + /** + * Test that get_subscribers() throws a ClientException when an invalid + * sort field is specified. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribersWithInvalidSortFieldParam() { - + $this->expectException(ClientException::class); + $result = $this->api->get_subscribers( + sort_field: 'not-a-valid-sort-field' + ); } + /** + * Test that get_subscribers() throws a ClientException when an invalid + * sort order is specified. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribersWithInvalidSortOrderParam() { - + $this->expectException(ClientException::class); + $result = $this->api->get_subscribers( + sort_order: 'not-a-valid-sort-order' + ); } + /** + * Test that get_subscribers() throws a ClientException when an invalid + * pagination parameters are specified. + * + * @since 2.0.0 + * + * @return void + */ public function testGetSubscribersWithInvalidPagination() { - + $this->expectException(ClientException::class); + $result = $this->api->get_subscribers( + after_cursor: 'not-a-valid-cursor' + ); } /** * Test that create_subscriber() returns the expected data. - * + * * @since 2.0.0 - * + * * @return void */ public function testCreateSubscriber() { - } /** * Test that create_subscriber() returns the expected data * when a first name is included. - * + * * @since 2.0.0 - * + * * @return void */ public function testCreateSubscriberWithFirstName() { - } /** * Test that create_subscriber() returns the expected data * when a subscriber state is included. - * + * * @since 2.0.0 - * + * * @return void */ public function testCreateSubscriberWithSubscriberState() { - } /** * Test that create_subscriber() returns the expected data * when custom field data is included. - * + * * @since 2.0.0 - * + * * @return void */ public function testCreateSubscriberWithCustomFields() { - } /** @@ -2400,7 +2451,6 @@ public function testCreateSubscriberWithCustomFields() */ public function testCreateSubscriberWithInvalidEmailAddress() { - } /** @@ -2413,22 +2463,18 @@ public function testCreateSubscriberWithInvalidEmailAddress() */ public function testCreateSubscriberWithInvalidSubscriberState() { - } public function testCreateSubscribers() { - } public function testCreateSubscribersWithBlankData() { - } public function testCreateSubscribersWithInvalidEmailAddresses() { - } /** From 43a23758c9682e8721d7603cc151d156479cb8d5 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Fri, 22 Mar 2024 15:58:15 +0000 Subject: [PATCH 08/11] Started tests for `create_subscriber` --- src/ConvertKit_API.php | 4 +- tests/ConvertKitAPITest.php | 81 +++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index 738b49a..9090fee 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -1028,7 +1028,9 @@ public function create_subscriber( array $fields = [] ) { // Build parameters. - $options = []; + $options = [ + 'email_address' => $email_address, + ]; if (!empty($first_name)) { $options['first_name'] = $first_name; diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index fb41d20..f480247 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -2403,6 +2403,16 @@ public function testGetSubscribersWithInvalidPagination() */ public function testCreateSubscriber() { + $emailAddress = $this->generateEmailAddress(); + $result = $this->api->create_subscriber( + email_address: $emailAddress + ); + + // Assert subscriber exists with correct data. + $this->assertEquals($result->subscriber->email_address, $emailAddress); + + // Unsubscribe to cleanup test. + $this->api->unsubscribe_by_id($result->subscriber->id); } /** @@ -2415,6 +2425,19 @@ public function testCreateSubscriber() */ public function testCreateSubscriberWithFirstName() { + $firstName = 'FirstName'; + $emailAddress = $this->generateEmailAddress(); + $result = $this->api->create_subscriber( + email_address: $emailAddress, + first_name: $firstName + ); + + // Assert subscriber exists with correct data. + $this->assertEquals($result->subscriber->email_address, $emailAddress); + $this->assertEquals($result->subscriber->first_name, $firstName); + + // Unsubscribe to cleanup test. + $this->api->unsubscribe_by_id($result->subscriber->id); } /** @@ -2427,6 +2450,19 @@ public function testCreateSubscriberWithFirstName() */ public function testCreateSubscriberWithSubscriberState() { + $subscriberState = 'inactive'; + $emailAddress = $this->generateEmailAddress(); + $result = $this->api->create_subscriber( + email_address: $emailAddress, + subscriber_state: $subscriberState + ); + + // Assert subscriber exists with correct data. + $this->assertEquals($result->subscriber->email_address, $emailAddress); + $this->assertEquals($result->subscriber->state, $subscriberState); + + // Unsubscribe to cleanup test. + $this->api->unsubscribe_by_id($result->subscriber->id); } /** @@ -2439,6 +2475,21 @@ public function testCreateSubscriberWithSubscriberState() */ public function testCreateSubscriberWithCustomFields() { + $lastName = 'LastName'; + $emailAddress = $this->generateEmailAddress(); + $result = $this->api->create_subscriber( + email_address: $emailAddress, + fields: [ + 'last_name' => $lastName + ] + ); + + // Assert subscriber exists with correct data. + $this->assertEquals($result->subscriber->email_address, $emailAddress); + $this->assertEquals($result->subscriber->fields->last_name, $lastName); + + // Unsubscribe to cleanup test. + $this->api->unsubscribe_by_id($result->subscriber->id); } /** @@ -2451,6 +2502,10 @@ public function testCreateSubscriberWithCustomFields() */ public function testCreateSubscriberWithInvalidEmailAddress() { + $this->expectException(ClientException::class); + $result = $this->api->create_subscriber( + email_address: 'not-an-email-address' + ); } /** @@ -2463,6 +2518,32 @@ public function testCreateSubscriberWithInvalidEmailAddress() */ public function testCreateSubscriberWithInvalidSubscriberState() { + $this->expectException(ClientException::class); + $emailAddress = $this->generateEmailAddress(); + $result = $this->api->create_subscriber( + email_address: $emailAddress, + subscriber_state: 'not-a-valid-state' + ); + } + + /** + * Test that create_subscriber() throws a ClientException when an invalid + * custom field is specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testCreateSubscriberWithInvalidCustomFields() + { + + $emailAddress = $this->generateEmailAddress(); + $result = $this->api->create_subscriber( + email_address: $emailAddress, + fields: [ + 'not_a_custom_field' => 'value' + ] + ); } public function testCreateSubscribers() From c61d362ab9b1692d9e3d9caf2f67c0b3f2279dc6 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Fri, 22 Mar 2024 16:50:04 +0000 Subject: [PATCH 09/11] Completed `create_subscriber` tests --- src/ConvertKit_API.php | 4 +- tests/ConvertKitAPITest.php | 75 ++++++++++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index 9090fee..863752b 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -1028,9 +1028,7 @@ public function create_subscriber( array $fields = [] ) { // Build parameters. - $options = [ - 'email_address' => $email_address, - ]; + $options = ['email_address' => $email_address]; if (!empty($first_name)) { $options['first_name'] = $first_name; diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index f480247..22eeaad 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -2435,7 +2435,7 @@ public function testCreateSubscriberWithFirstName() // Assert subscriber exists with correct data. $this->assertEquals($result->subscriber->email_address, $emailAddress); $this->assertEquals($result->subscriber->first_name, $firstName); - + // Unsubscribe to cleanup test. $this->api->unsubscribe_by_id($result->subscriber->id); } @@ -2460,7 +2460,7 @@ public function testCreateSubscriberWithSubscriberState() // Assert subscriber exists with correct data. $this->assertEquals($result->subscriber->email_address, $emailAddress); $this->assertEquals($result->subscriber->state, $subscriberState); - + // Unsubscribe to cleanup test. $this->api->unsubscribe_by_id($result->subscriber->id); } @@ -2487,7 +2487,7 @@ public function testCreateSubscriberWithCustomFields() // Assert subscriber exists with correct data. $this->assertEquals($result->subscriber->email_address, $emailAddress); $this->assertEquals($result->subscriber->fields->last_name, $lastName); - + // Unsubscribe to cleanup test. $this->api->unsubscribe_by_id($result->subscriber->id); } @@ -2527,8 +2527,8 @@ public function testCreateSubscriberWithInvalidSubscriberState() } /** - * Test that create_subscriber() throws a ClientException when an invalid - * custom field is specified. + * Test that create_subscriber() returns the expected data + * when an invalid custom field is included. * * @since 2.0.0 * @@ -2544,18 +2544,83 @@ public function testCreateSubscriberWithInvalidCustomFields() 'not_a_custom_field' => 'value' ] ); + + // Assert subscriber exists with correct data. + $this->assertEquals($result->subscriber->email_address, $emailAddress); + + // Unsubscribe to cleanup test. + $this->api->unsubscribe_by_id($result->subscriber->id); } + /** + * Test that create_subscribers() returns the expected data. + * + * @since 2.0.0 + * + * @return void + */ public function testCreateSubscribers() { + $subscribers = [ + [ + 'email_address' => str_replace('@convertkit.com', '-1@convertkit.com', $this->generateEmailAddress()), + ], + [ + 'email_address' => str_replace('@convertkit.com', '-2@convertkit.com', $this->generateEmailAddress()), + ], + ]; + $result = $this->api->create_subscribers($subscribers); + + // Assert no failures. + $this->assertCount(0, $result->failures); + + // Assert subscribers exists with correct data. + foreach ($result->subscribers as $i => $subscriber) { + $this->assertEquals($subscriber->email_address, $subscribers[$i]['email_address']); + + // Unsubscribe to cleanup test. + $this->api->unsubscribe_by_id($subscriber->id); + } } + /** + * Test that create_subscribers() throws a ClientException when no data is specified. + * + * @since 2.0.0 + * + * @return void + */ public function testCreateSubscribersWithBlankData() { + $this->expectException(ClientException::class); + $result = $this->api->create_subscribers([ + [], + ]); } + /** + * Test that create_subscribers() returns the expected data when invalid email addresses + * are specified. + * + * @since 2.0.0 + * + * @return void + */ public function testCreateSubscribersWithInvalidEmailAddresses() { + $subscribers = [ + [ + 'email_address' => 'not-an-email-address', + ], + [ + 'email_address' => 'not-an-email-address-again', + ], + ]; + $result = $this->api->create_subscribers($subscribers); + + // Assert no subscribers were added. + $this->assertCount(0, $result->subscribers); + $this->assertCount(2, $result->failures); } /** From d657bfa088fda305ce08572db4d5b0612e2ac777 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Fri, 22 Mar 2024 17:26:58 +0000 Subject: [PATCH 10/11] Completed tests --- src/ConvertKit_API.php | 7 +- tests/ConvertKitAPITest.php | 252 ++++++++++++++++++++++-------------- 2 files changed, 156 insertions(+), 103 deletions(-) diff --git a/src/ConvertKit_API.php b/src/ConvertKit_API.php index 863752b..35a1557 100644 --- a/src/ConvertKit_API.php +++ b/src/ConvertKit_API.php @@ -1094,12 +1094,7 @@ public function get_subscriber_id(string $email_address) ['email_address' => $email_address] ); - if (!$subscribers) { - $this->create_log('No subscribers'); - return false; - } - - if ($subscribers->total_subscribers === 0) { + if (!count($subscribers->subscribers)) { $this->create_log('No subscribers'); return false; } diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index 22eeaad..39037a2 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -2632,8 +2632,6 @@ public function testCreateSubscribersWithInvalidEmailAddresses() */ public function testGetSubscriberID() { - $this->markTestIncomplete(); - $subscriber_id = $this->api->get_subscriber_id($_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL']); $this->assertIsInt($subscriber_id); $this->assertEquals($subscriber_id, (int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID']); @@ -2649,9 +2647,7 @@ public function testGetSubscriberID() */ public function testGetSubscriberIDWithInvalidEmailAddress() { - $this->markTestIncomplete(); - - $this->expectException(InvalidArgumentException::class); + $this->expectException(ClientException::class); $result = $this->api->get_subscriber_id('not-an-email-address'); } @@ -2665,8 +2661,6 @@ public function testGetSubscriberIDWithInvalidEmailAddress() */ public function testGetSubscriberIDWithNotSubscribedEmailAddress() { - $this->markTestIncomplete(); - $result = $this->api->get_subscriber_id('not-a-subscriber@test.com'); $this->assertFalse($result); } @@ -2680,16 +2674,11 @@ public function testGetSubscriberIDWithNotSubscribedEmailAddress() */ public function testGetSubscriber() { - $this->markTestIncomplete(); + $result = $this->api->get_subscriber((int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID']); - $subscriber = $this->api->get_subscriber((int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID']); - $this->assertInstanceOf('stdClass', $subscriber); - $this->assertArrayHasKey('subscriber', get_object_vars($subscriber)); - $this->assertArrayHasKey('id', get_object_vars($subscriber->subscriber)); - $this->assertEquals( - get_object_vars($subscriber->subscriber)['id'], - (int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'] - ); + // Assert subscriber exists with correct data. + $this->assertEquals($result->subscriber->id, $_ENV['CONVERTKIT_API_SUBSCRIBER_ID']); + $this->assertEquals($result->subscriber->email_address, $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL']); } /** @@ -2702,8 +2691,6 @@ public function testGetSubscriber() */ public function testGetSubscriberWithInvalidSubscriberID() { - $this->markTestIncomplete(); - $this->expectException(ClientException::class); $subscriber = $this->api->get_subscriber(12345); } @@ -2717,13 +2704,11 @@ public function testGetSubscriberWithInvalidSubscriberID() */ public function testUpdateSubscriberWithNoChanges() { - $this->markTestIncomplete(); - $result = $this->api->update_subscriber($_ENV['CONVERTKIT_API_SUBSCRIBER_ID']); - $this->assertInstanceOf('stdClass', $result); - $this->assertArrayHasKey('subscriber', get_object_vars($result)); - $this->assertArrayHasKey('id', get_object_vars($result->subscriber)); - $this->assertEquals(get_object_vars($result->subscriber)['id'], $_ENV['CONVERTKIT_API_SUBSCRIBER_ID']); + + // Assert subscriber exists with correct data. + $this->assertEquals($result->subscriber->id, $_ENV['CONVERTKIT_API_SUBSCRIBER_ID']); + $this->assertEquals($result->subscriber->email_address, $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL']); } /** @@ -2735,33 +2720,31 @@ public function testUpdateSubscriberWithNoChanges() */ public function testUpdateSubscriberFirstName() { - $this->markTestIncomplete(); - // Add a subscriber. - $email = $this->generateEmailAddress(); - $result = $this->api->add_subscriber_to_sequence( - sequence_id: $_ENV['CONVERTKIT_API_SEQUENCE_ID'], - email: $email + $firstName = 'FirstName'; + $emailAddress = $this->generateEmailAddress(); + $result = $this->api->create_subscriber( + email_address: $emailAddress ); + // Assert subscriber created with no first name. + $this->assertNull($result->subscriber->first_name); + // Get subscriber ID. - $subscriberID = $result->subscription->subscriber->id; + $subscriberID = $result->subscriber->id; // Update subscriber's first name. $result = $this->api->update_subscriber( subscriber_id: $subscriberID, - first_name: 'First Name' + first_name: $firstName ); - // Confirm the change is reflected in the subscriber. - $this->assertInstanceOf('stdClass', $result); - $this->assertArrayHasKey('subscriber', get_object_vars($result)); - $this->assertArrayHasKey('id', get_object_vars($result->subscriber)); - $this->assertEquals(get_object_vars($result->subscriber)['id'], $subscriberID); - $this->assertEquals(get_object_vars($result->subscriber)['first_name'], 'First Name'); + // Assert changes were made. + $this->assertEquals($result->subscriber->id, $subscriberID); + $this->assertEquals($result->subscriber->first_name, $firstName); - // Unsubscribe. - $this->api->unsubscribe($email); + // Unsubscribe to cleanup test. + $this->api->unsubscribe_by_id($result->subscriber->id); } /** @@ -2773,17 +2756,17 @@ public function testUpdateSubscriberFirstName() */ public function testUpdateSubscriberEmailAddress() { - $this->markTestIncomplete(); - // Add a subscriber. - $email = $this->generateEmailAddress(); - $result = $this->api->add_subscriber_to_sequence( - sequence_id: $_ENV['CONVERTKIT_API_SEQUENCE_ID'], - email: $email + $emailAddress = $this->generateEmailAddress(); + $result = $this->api->create_subscriber( + email_address: $emailAddress ); + // Assert subscriber created. + $this->assertEquals($result->subscriber->email_address, $emailAddress); + // Get subscriber ID. - $subscriberID = $result->subscription->subscriber->id; + $subscriberID = $result->subscriber->id; // Update subscriber's email address. $newEmail = $this->generateEmailAddress(); @@ -2792,15 +2775,12 @@ public function testUpdateSubscriberEmailAddress() email_address: $newEmail ); - // Confirm the change is reflected in the subscriber. - $this->assertInstanceOf('stdClass', $result); - $this->assertArrayHasKey('subscriber', get_object_vars($result)); - $this->assertArrayHasKey('id', get_object_vars($result->subscriber)); - $this->assertEquals(get_object_vars($result->subscriber)['id'], $subscriberID); - $this->assertEquals(get_object_vars($result->subscriber)['email_address'], $newEmail); + // Assert changes were made. + $this->assertEquals($result->subscriber->id, $subscriberID); + $this->assertEquals($result->subscriber->email_address, $newEmail); - // Unsubscribe. - $this->api->unsubscribe($newEmail); + // Unsubscribe to cleanup test. + $this->api->unsubscribe_by_id($result->subscriber->id); } /** @@ -2812,35 +2792,33 @@ public function testUpdateSubscriberEmailAddress() */ public function testUpdateSubscriberCustomFields() { - $this->markTestIncomplete(); - // Add a subscriber. - $email = $this->generateEmailAddress(); - $result = $this->api->add_subscriber_to_sequence( - sequence_id: $_ENV['CONVERTKIT_API_SEQUENCE_ID'], - email: $email + $lastName = 'LastName'; + $emailAddress = $this->generateEmailAddress(); + $result = $this->api->create_subscriber( + email_address: $emailAddress ); + // Assert subscriber created. + $this->assertEquals($result->subscriber->email_address, $emailAddress); + // Get subscriber ID. - $subscriberID = $result->subscription->subscriber->id; + $subscriberID = $result->subscriber->id; - // Update subscriber's email address. + // Update subscriber's custom fields. $result = $this->api->update_subscriber( subscriber_id: $subscriberID, fields: [ - 'last_name' => 'Last Name', + 'last_name' => $lastName, ] ); - // Confirm the change is reflected in the subscriber. - $this->assertInstanceOf('stdClass', $result); - $this->assertArrayHasKey('subscriber', get_object_vars($result)); - $this->assertArrayHasKey('id', get_object_vars($result->subscriber)); - $this->assertEquals(get_object_vars($result->subscriber)['id'], $subscriberID); - $this->assertEquals($result->subscriber->fields->last_name, 'Last Name'); + // Assert changes were made. + $this->assertEquals($result->subscriber->id, $subscriberID); + $this->assertEquals($result->subscriber->fields->last_name, $lastName); - // Unsubscribe. - $this->api->unsubscribe($email); + // Unsubscribe to cleanup test. + $this->api->unsubscribe_by_id($result->subscriber->id); } /** @@ -2853,8 +2831,6 @@ public function testUpdateSubscriberCustomFields() */ public function testUpdateSubscriberWithInvalidSubscriberID() { - $this->markTestIncomplete(); - $this->expectException(ClientException::class); $subscriber = $this->api->update_subscriber(12345); } @@ -2868,23 +2844,14 @@ public function testUpdateSubscriberWithInvalidSubscriberID() */ public function testUnsubscribe() { - $this->markTestIncomplete(); - // Add a subscriber. - $email = $this->generateEmailAddress(); - $result = $this->api->add_subscriber_to_sequence( - sequence_id: $_ENV['CONVERTKIT_API_SEQUENCE_ID'], - email: $email + $emailAddress = $this->generateEmailAddress(); + $result = $this->api->create_subscriber( + email_address: $emailAddress ); // Unsubscribe. - $result = $this->api->unsubscribe($email); - - // Confirm the change is reflected in the subscriber. - $this->assertInstanceOf('stdClass', $result); - $this->assertArrayHasKey('subscriber', get_object_vars($result)); - $this->assertEquals($result->subscriber->email_address, $email); - $this->assertEquals($result->subscriber->state, 'cancelled'); + $this->assertNull($this->api->unsubscribe($emailAddress)); } /** @@ -2897,8 +2864,6 @@ public function testUnsubscribe() */ public function testUnsubscribeWithNotSubscribedEmailAddress() { - $this->markTestIncomplete(); - $this->expectException(ClientException::class); $subscriber = $this->api->unsubscribe('not-subscribed@convertkit.com'); } @@ -2913,12 +2878,43 @@ public function testUnsubscribeWithNotSubscribedEmailAddress() */ public function testUnsubscribeWithInvalidEmailAddress() { - $this->markTestIncomplete(); - $this->expectException(ClientException::class); $subscriber = $this->api->unsubscribe('invalid-email'); } + /** + * Test that unsubscribe() works with a valid subscriber ID. + * + * @since 2.0.0 + * + * @return void + */ + public function testUnsubscribeByID() + { + // Add a subscriber. + $emailAddress = $this->generateEmailAddress(); + $result = $this->api->create_subscriber( + email_address: $emailAddress + ); + + // Unsubscribe. + $this->assertNull($this->api->unsubscribe_by_id($result->subscriber->id)); + } + + /** + * Test that unsubscribe() throws a ClientException when an invalid + * subscriber ID is specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testUnsubscribeByIDWithInvalidSubscriberID() + { + $this->expectException(ClientException::class); + $subscriber = $this->api->unsubscribe_by_id(12345); + } + /** * Test that get_subscriber_tags() returns the expected data. * @@ -2928,11 +2924,11 @@ public function testUnsubscribeWithInvalidEmailAddress() */ public function testGetSubscriberTags() { - $this->markTestIncomplete(); + $result = $this->api->get_subscriber_tags((int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID']); - $subscriber = $this->api->get_subscriber_tags((int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID']); - $this->assertInstanceOf('stdClass', $subscriber); - $this->assertArrayHasKey('tags', get_object_vars($subscriber)); + // Assert tags and pagination exist. + $this->assertDataExists($result, 'tags'); + $this->assertPaginationExists($result); } /** @@ -2945,12 +2941,74 @@ public function testGetSubscriberTags() */ public function testGetSubscriberTagsWithInvalidSubscriberID() { - $this->markTestIncomplete(); - $this->expectException(ClientException::class); $subscriber = $this->api->get_subscriber_tags(12345); } + /** + * Test that get_subscriber_tags() returns the expected data + * when a valid Subscriber ID is specified and pagination parameters + * and per_page limits are specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSubscriberTagsPagination() + { + $result = $this->api->get_subscriber_tags( + subscriber_id: (int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'], + per_page: 1 + ); + + // Assert tags and pagination exist. + $this->assertDataExists($result, 'tags'); + $this->assertPaginationExists($result); + + // Assert a single tag was returned. + $this->assertCount(1, $result->tags); + + // Assert has_previous_page and has_next_page are correct. + $this->assertFalse($result->pagination->has_previous_page); + $this->assertTrue($result->pagination->has_next_page); + + // Use pagination to fetch next page. + $result = $this->api->get_subscriber_tags( + subscriber_id: (int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'], + per_page: 1, + after_cursor: $result->pagination->end_cursor + ); + + // Assert tags and pagination exist. + $this->assertDataExists($result, 'tags'); + $this->assertPaginationExists($result); + + // Assert a single tag was returned. + $this->assertCount(1, $result->tags); + + // Assert has_previous_page and has_next_page are correct. + $this->assertTrue($result->pagination->has_previous_page); + $this->assertTrue($result->pagination->has_next_page); + + // Use pagination to fetch previous page. + $result = $this->api->get_subscriber_tags( + subscriber_id: (int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'], + per_page: 1, + before_cursor: $result->pagination->start_cursor + ); + + // Assert tags and pagination exist. + $this->assertDataExists($result, 'tags'); + $this->assertPaginationExists($result); + + // Assert a single tag was returned. + $this->assertCount(1, $result->tags); + + // Assert has_previous_page and has_next_page are correct. + $this->assertFalse($result->pagination->has_previous_page); + $this->assertTrue($result->pagination->has_next_page); + } + /** * Test that create_broadcast(), update_broadcast() and destroy_broadcast() works * when specifying valid published_at and send_at values. From 099a8b473909f6fd8af9c50229e3afdbe613d762 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 25 Mar 2024 14:22:26 +0000 Subject: [PATCH 11/11] testCreateSubscriberWithSubscriberState: Use `cancelled` state for test --- tests/ConvertKitAPITest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index 39037a2..83e4be9 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -2450,7 +2450,7 @@ public function testCreateSubscriberWithFirstName() */ public function testCreateSubscriberWithSubscriberState() { - $subscriberState = 'inactive'; + $subscriberState = 'cancelled'; $emailAddress = $this->generateEmailAddress(); $result = $this->api->create_subscriber( email_address: $emailAddress,