diff --git a/src/ConvertKit_API_Traits.php b/src/ConvertKit_API_Traits.php index 136009c..f6bc7b0 100644 --- a/src/ConvertKit_API_Traits.php +++ b/src/ConvertKit_API_Traits.php @@ -602,6 +602,43 @@ public function update_tag_name(int $tag_id, string $name) return $this->put(sprintf('tags/%s', $tag_id), ['name' => $name]); } + /** + * Tags the given subscribers with the given existing Tags. + * + * @param array> $taggings Taggings, in the format: + * [ + * [ + * "tag_id" => 0, + * "subscriber_id" => 0 + * ], + * [ + * "tag_id" => 1, + * "subscriber_id" => 1 + * ], + * ]. + * @param string $callback_url URL to notify for large batch size when async processing complete. + * + * @since 2.2.1 + * + * @see https://developers.kit.com/api-reference/tags/bulk-tag-subscribers + * + * @return false|mixed + */ + public function tag_subscribers(array $taggings, string $callback_url = '') + { + // Build parameters. + $options = ['taggings' => $taggings]; + if (!empty($callback_url)) { + $options['callback_url'] = $callback_url; + } + + // Send request. + return $this->post( + 'bulk/tags/subscribers', + $options + ); + } + /** * Tags a subscriber with the given existing Tag. * diff --git a/tests/ConvertKitAPIKeyTest.php b/tests/ConvertKitAPIKeyTest.php index d6f0b0c..b7c4536 100644 --- a/tests/ConvertKitAPIKeyTest.php +++ b/tests/ConvertKitAPIKeyTest.php @@ -247,8 +247,8 @@ public function testCreateTags() } /** - * Test that create_tags() throws a ClientException when attempting - * to create blank tags, as this is only supported using OAuth. + * Skip this test from ConvertKitAPITest, as testCreateTags() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -256,32 +256,69 @@ public function testCreateTags() */ public function testCreateTagsBlank() { - $this->expectException(ClientException::class); - $result = $this->api->create_tags([ - '', - '', - ]); + $this->markTestSkipped('testCreateTags() above confirms a ClientException is thrown.'); } /** - * Test that create_tags() throws a ClientException when creating - * tags that already exists, as this is only supported using OAuth. + * Skip this test from ConvertKitAPITest, as testCreateTags() above + * confirms a ClientException is thrown. * * @since 2.2.0 * * @return void */ public function testCreateTagsThatExist() + { + $this->markTestSkipped('testCreateTags() above confirms a ClientException is thrown.'); + } + + /** + * Test that tag_subscribers() throws a ClientException when attempting + * to tag subscribers, as this is only supported using OAuth. + * + * @since 2.2.1 + * + * @return void + */ + public function testTagSubscribers() { $this->expectException(ClientException::class); - $result = $this->api->create_tags( + $result = $this->api->tag_subscribers( [ - $_ENV['CONVERTKIT_API_TAG_NAME'], - $_ENV['CONVERTKIT_API_TAG_NAME_2'], + [ + 'tag_id' => (int) $_ENV['CONVERTKIT_API_TAG_ID'], + 'subscriber_id' => (int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'] + ], ] ); } + /** + * Skip this test from ConvertKitAPITest, as testTagSubscribers() above + * confirms a ClientException is thrown. + * + * @since 2.2.1 + * + * @return void + */ + public function testTagSubscribersWithInvalidTagID() + { + $this->markTestSkipped('testTagSubscribers() above confirms a ClientException is thrown.'); + } + + /** + * Skip this test from ConvertKitAPITest, as testTagSubscribers() above + * confirms a ClientException is thrown. + * + * @since 2.2.1 + * + * @return void + */ + public function testTagSubscribersWithInvalidSubscriberID() + { + $this->markTestSkipped('testTagSubscribers() above confirms a ClientException is thrown.'); + } + /** * Test that add_subscribers_to_forms() throws a ClientException when * attempting to add subscribers to forms, as this is only supported @@ -320,9 +357,8 @@ public function testAddSubscribersToForms() } /** - * Test that add_subscribers_to_forms() returns a ClientException - * when a referrer URL is specified, as this is only supported - * using OAuth. + * Skip this test from ConvertKitAPITest, as testAddSubscribersToForms() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -330,38 +366,12 @@ public function testAddSubscribersToForms() */ public function testAddSubscribersToFormsWithReferrer() { - // Create subscriber. - $emailAddress = $this->generateEmailAddress(); - $subscriber = $this->api->create_subscriber( - email_address: $emailAddress - ); - - // Set subscriber_id to ensure subscriber is unsubscribed after test. - $this->subscriber_ids[] = $subscriber->subscriber->id; - - $this->expectException(ClientException::class); - - // Add subscribers to forms. - $result = $this->api->add_subscribers_to_forms( - forms_subscribers_ids: [ - [ - 'form_id' => (int) $_ENV['CONVERTKIT_API_FORM_ID'], - 'subscriber_id' => $subscriber->subscriber->id, - 'referrer' => 'https://mywebsite.com/bfpromo/', - ], - [ - 'form_id' => (int) $_ENV['CONVERTKIT_API_FORM_ID_2'], - 'subscriber_id' => $subscriber->subscriber->id, - 'referrer' => 'https://mywebsite.com/bfpromo/', - ], - ] - ); + $this->markTestSkipped('testAddSubscribersToForms() above confirms a ClientException is thrown.'); } /** - * Test that add_subscribers_to_forms() returns a ClientException - * when a referrer URL with UTM parameters is specified, as this is only - * supported using OAuth. + * Skip this test from ConvertKitAPITest, as testAddSubscribersToForms() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -369,48 +379,12 @@ public function testAddSubscribersToFormsWithReferrer() */ public function testAddSubscribersToFormsWithReferrerUTMParams() { - // Define referrer. - $referrerUTMParams = [ - 'utm_source' => 'facebook', - 'utm_medium' => 'cpc', - 'utm_campaign' => 'black_friday', - 'utm_term' => 'car_owners', - 'utm_content' => 'get_10_off', - ]; - $referrer = 'https://mywebsite.com/bfpromo/?' . http_build_query($referrerUTMParams); - - // Create subscriber. - $emailAddress = $this->generateEmailAddress(); - $subscriber = $this->api->create_subscriber( - email_address: $emailAddress - ); - - // Set subscriber_id to ensure subscriber is unsubscribed after test. - $this->subscriber_ids[] = $subscriber->subscriber->id; - - $this->expectException(ClientException::class); - - // Add subscribers to forms. - $result = $this->api->add_subscribers_to_forms( - forms_subscribers_ids: [ - [ - 'form_id' => (int) $_ENV['CONVERTKIT_API_FORM_ID'], - 'subscriber_id' => $subscriber->subscriber->id, - 'referrer' => $referrer, - ], - [ - 'form_id' => (int) $_ENV['CONVERTKIT_API_FORM_ID_2'], - 'subscriber_id' => $subscriber->subscriber->id, - 'referrer' => $referrer, - ], - ] - ); + $this->markTestSkipped('testAddSubscribersToForms() above confirms a ClientException is thrown.'); } /** - * Test that add_subscribers_to_forms() returns a ClientException - * when invalid Form IDs are specified, as this is only supported - * using OAuth. + * Skip this test from ConvertKitAPITest, as testAddSubscribersToForms() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -418,35 +392,12 @@ public function testAddSubscribersToFormsWithReferrerUTMParams() */ public function testAddSubscribersToFormsWithInvalidFormIDs() { - // Create subscriber. - $emailAddress = $this->generateEmailAddress(); - $subscriber = $this->api->create_subscriber( - email_address: $emailAddress - ); - - // Set subscriber_id to ensure subscriber is unsubscribed after test. - $this->subscriber_ids[] = $subscriber->subscriber->id; - - $this->expectException(ClientException::class); - - // Add subscribers to forms. - $result = $this->api->add_subscribers_to_forms( - forms_subscribers_ids: [ - [ - 'form_id' => 9999999, - 'subscriber_id' => $subscriber->subscriber->id, - ], - [ - 'form_id' => 9999999, - 'subscriber_id' => $subscriber->subscriber->id, - ], - ] - ); + $this->markTestSkipped('testAddSubscribersToForms() above confirms a ClientException is thrown.'); } /** - * Test that add_subscribers_to_forms() returns a ClientException - * when invalid Subscriber IDs are specified, as this is only supported + * Skip this test from ConvertKitAPITest, as testAddSubscribersToForms() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -454,30 +405,7 @@ public function testAddSubscribersToFormsWithInvalidFormIDs() */ public function testAddSubscribersToFormsWithInvalidSubscriberIDs() { - // Create subscriber. - $emailAddress = $this->generateEmailAddress(); - $subscriber = $this->api->create_subscriber( - email_address: $emailAddress - ); - - // Set subscriber_id to ensure subscriber is unsubscribed after test. - $this->subscriber_ids[] = $subscriber->subscriber->id; - - $this->expectException(ClientException::class); - - // Add subscribers to forms. - $result = $this->api->add_subscribers_to_forms( - forms_subscribers_ids: [ - [ - 'form_id' => (int) $_ENV['CONVERTKIT_API_FORM_ID'], - 'subscriber_id' => 999999, - ], - [ - 'form_id' => (int) $_ENV['CONVERTKIT_API_FORM_ID_2'], - 'subscriber_id' => 999999, - ], - ] - ); + $this->markTestSkipped('testAddSubscribersToForms() above confirms a ClientException is thrown.'); } /** @@ -504,7 +432,8 @@ public function testCreateSubscribers() } /** - * Test that create_subscribers() throws a ClientException when no data is specified. + * Skip this test from ConvertKitAPITest, as testCreateSubscribersWithBlankData() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -512,15 +441,12 @@ public function testCreateSubscribers() */ public function testCreateSubscribersWithBlankData() { - $this->expectException(ClientException::class); - $result = $this->api->create_subscribers([ - [], - ]); + $this->markTestSkipped('testCreateSubscribers() above confirms a ClientException is thrown.'); } /** - * Test that create_subscribers() throws a ClientException when invalid email addresses - * are specified, as this is only supported using OAuth. + * Skip this test from ConvertKitAPITest, as testCreateSubscribersWithBlankData() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -528,16 +454,7 @@ public function testCreateSubscribersWithBlankData() */ public function testCreateSubscribersWithInvalidEmailAddresses() { - $this->expectException(ClientException::class); - $subscribers = [ - [ - 'email_address' => 'not-an-email-address', - ], - [ - 'email_address' => 'not-an-email-address-again', - ], - ]; - $result = $this->api->create_subscribers($subscribers); + $this->markTestSkipped('testCreateSubscribers() above confirms a ClientException is thrown.'); } /** @@ -573,9 +490,8 @@ public function testGetPurchases() } /** - * Test that get_purchases() throws a ClientException - * when the total count is included, as this is only - * supported using OAuth. + * Skip this test from ConvertKitAPITest, as testGetPurchases() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -583,16 +499,12 @@ public function testGetPurchases() */ public function testGetPurchasesWithTotalCount() { - $this->expectException(ClientException::class); - $result = $this->api->get_purchases( - include_total_count: true - ); + $this->markTestSkipped('testGetPurchases() above confirms a ClientException is thrown.'); } /** - * Test that get_purchases() throws a ClientException - * when pagination parameters and per_page limits are specified, - * as this is only supported using OAuth. + * Skip this test from ConvertKitAPITest, as testGetPurchases() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -600,10 +512,7 @@ public function testGetPurchasesWithTotalCount() */ public function testGetPurchasesPagination() { - $this->expectException(ClientException::class); - $result = $this->api->get_purchases( - per_page: 1 - ); + $this->markTestSkipped('testGetPurchases() above confirms a ClientException is thrown.'); } /** @@ -622,9 +531,8 @@ public function testGetPurchase() } /** - * Test that get_purchases() throws a ClientException when an invalid - * purchase ID is specified, as this is only supported - * using OAuth. + * Skip this test from ConvertKitAPITest, as testGetPurchase() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -632,8 +540,7 @@ public function testGetPurchase() */ public function testGetPurchaseWithInvalidID() { - $this->expectException(ClientException::class); - $this->api->get_purchase(12345); + $this->markTestSkipped('testGetPurchase() above confirms a ClientException is thrown.'); } /** @@ -683,8 +590,8 @@ public function testCreatePurchase() } /** - * Test that create_purchase() throws a ClientException when an invalid - * email address is specified, as this is only supported using OAuth. + * Skip this test from ConvertKitAPITest, as testCreatePurchase() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -692,27 +599,12 @@ public function testCreatePurchase() */ public function testCreatePurchaseWithInvalidEmailAddress() { - $this->expectException(ClientException::class); - $this->api->create_purchase( - email_address: 'not-an-email-address', - transaction_id: str_shuffle('wfervdrtgsdewrafvwefds'), - currency: 'usd', - products: [ - [ - 'name' => 'Floppy Disk (512k)', - 'sku' => '7890-ijkl', - 'pid' => 9999, - 'lid' => 7777, - 'quantity' => 2, - 'unit_price' => 5.00, - ], - ], - ); + $this->markTestSkipped('testCreatePurchase() above confirms a ClientException is thrown.'); } /** - * Test that create_purchase() throws a ClientException when a blank - * transaction ID is specified, as this is only supported using OAuth. + * Skip this test from ConvertKitAPITest, as testCreatePurchase() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -720,27 +612,12 @@ public function testCreatePurchaseWithInvalidEmailAddress() */ public function testCreatePurchaseWithBlankTransactionID() { - $this->expectException(ClientException::class); - $this->api->create_purchase( - email_address: $this->generateEmailAddress(), - transaction_id: '', - currency: 'usd', - products: [ - [ - 'name' => 'Floppy Disk (512k)', - 'sku' => '7890-ijkl', - 'pid' => 9999, - 'lid' => 7777, - 'quantity' => 2, - 'unit_price' => 5.00, - ], - ], - ); + $this->markTestSkipped('testCreatePurchase() above confirms a ClientException is thrown.'); } /** - * Test that create_purchase() throws a ClientException when no products - * are specified, as this is only supported using OAuth. + * Skip this test from ConvertKitAPITest, as testCreatePurchase() above + * confirms a ClientException is thrown. * * @since 2.2.0 * @@ -748,12 +625,6 @@ public function testCreatePurchaseWithBlankTransactionID() */ public function testCreatePurchaseWithNoProducts() { - $this->expectException(ClientException::class); - $this->api->create_purchase( - email_address: $this->generateEmailAddress(), - transaction_id: str_shuffle('wfervdrtgsdewrafvwefds'), - currency: 'usd', - products: [], - ); + $this->markTestSkipped('testCreatePurchase() above confirms a ClientException is thrown.'); } } diff --git a/tests/ConvertKitAPITest.php b/tests/ConvertKitAPITest.php index 75245a2..70bbf12 100644 --- a/tests/ConvertKitAPITest.php +++ b/tests/ConvertKitAPITest.php @@ -1818,6 +1818,125 @@ public function testGetSubscriberStatsWithInvalidSubscriberID() $result = $this->api->get_subscriber_stats(12345); } + /** + * Test that tag_subscribers() returns the expected data. + * + * @since 2.2.1 + * + * @return void + */ + public function testTagSubscribers() + { + // Create subscribers. + $subscribers = [ + [ + 'email_address' => str_replace('@kit.com', '-1@kit.com', $this->generateEmailAddress()), + ], + [ + 'email_address' => str_replace('@kit.com', '-2@kit.com', $this->generateEmailAddress()), + ], + ]; + $result = $this->api->create_subscribers($subscribers); + + // Set subscriber_id to ensure subscriber is unsubscribed after test. + foreach ($result->subscribers as $i => $subscriber) { + $this->subscriber_ids[] = $subscriber->id; + } + + // Tag subscribers. + $result = $this->api->tag_subscribers( + [ + [ + 'tag_id' => (int) $_ENV['CONVERTKIT_API_TAG_ID'], + 'subscriber_id' => $this->subscriber_ids[0] + ], + [ + 'tag_id' => (int) $_ENV['CONVERTKIT_API_TAG_ID'], + 'subscriber_id' => $this->subscriber_ids[1] + ], + ] + ); + + // Assert no failures. + $this->assertCount(0, $result->failures); + + // Confirm result is an array comprising of each subscriber that was created. + $this->assertIsArray($result->subscribers); + $this->assertCount(2, $result->subscribers); + } + + /** + * Test that tag_subscribers() returns failures when an invalid + * tag ID is specified. + * + * @since 2.2.1 + * + * @return void + */ + public function testTagSubscribersWithInvalidTagID() + { + // Create subscribers. + $subscribers = [ + [ + 'email_address' => str_replace('@kit.com', '-1@kit.com', $this->generateEmailAddress()), + ], + [ + 'email_address' => str_replace('@kit.com', '-2@kit.com', $this->generateEmailAddress()), + ], + ]; + $result = $this->api->create_subscribers($subscribers); + + // Set subscriber_id to ensure subscriber is unsubscribed after test. + foreach ($result->subscribers as $i => $subscriber) { + $this->subscriber_ids[] = $subscriber->id; + } + + // Tag subscribers. + $result = $this->api->tag_subscribers( + [ + [ + 'tag_id' => 12345, + 'subscriber_id' => $this->subscriber_ids[0] + ], + [ + 'tag_id' => 12345, + 'subscriber_id' => $this->subscriber_ids[1] + ], + ] + ); + + // Assert failures. + $this->assertCount(2, $result->failures); + } + + /** + * Test that tag_subscribers() returns failures when an invalid + * subscriber ID is specified. + * + * @since 2.2.1 + * + * @return void + */ + public function testTagSubscribersWithInvalidSubscriberID() + { + // Tag subscribers that do not exist. + $result = $this->api->tag_subscribers( + [ + [ + 'tag_id' => (int) $_ENV['CONVERTKIT_API_TAG_ID'], + 'subscriber_id' => 12345, + ], + [ + 'tag_id' => (int) $_ENV['CONVERTKIT_API_TAG_ID'], + 'subscriber_id' => 67890, + ], + ] + ); + + // Assert failures. + $this->assertCount(2, $result->failures); + } + /** * Test that tag_subscriber_by_email() returns the expected data. *