From 035136167bc065bffb1418455a06f585a255b83e Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Fri, 19 Apr 2024 15:26:35 +0100 Subject: [PATCH 1/5] Added tests --- tests/wpunit/APITest.php | 664 ++++++++++++++++++++++++++++++++------- 1 file changed, 542 insertions(+), 122 deletions(-) diff --git a/tests/wpunit/APITest.php b/tests/wpunit/APITest.php index 936a561..2d4b886 100644 --- a/tests/wpunit/APITest.php +++ b/tests/wpunit/APITest.php @@ -845,140 +845,560 @@ public function testGetLandingPagesNoData() } /** - * Test that the `get_sequences()` function returns expected data. - * - * @since 1.0.0 - */ - public function testGetSequences() - { - $this->markTestIncomplete(); - - $result = $this->api->get_sequences(); - $this->assertNotInstanceOf(WP_Error::class, $result); - $this->assertIsArray($result); - $this->assertArrayHasKey('id', reset($result)); - $this->assertArrayHasKey('name', reset($result)); - } + * Test that get_sequences() returns the expected data. + * + * @since 1.0.0 + * + * @return void + */ + public function testGetSequences() + { + $result = $this->api->get_sequences(); + + // Assert sequences and pagination exist. + $this->assertDataExists($result, 'sequences'); + $this->assertPaginationExists($result); + + // Check first sequence in resultset has expected data. + $sequence = $result['sequences'][0]; + $this->assertArrayHasKey('id', $sequence); + $this->assertArrayHasKey('name', $sequence); + $this->assertArrayHasKey('hold', $sequence); + $this->assertArrayHasKey('repeat', $sequence); + $this->assertArrayHasKey('created_at', $sequence); + } + + /** + * Test that get_sequences() returns the expected data + * when the total count is included. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequencesWithTotalCount() + { + $result = $this->api->get_sequences(true); + + // Assert sequences and pagination exist. + $this->assertDataExists($result, 'sequences'); + $this->assertPaginationExists($result); + + // Assert total count is included. + $this->assertArrayHasKey('total_count', $result['pagination']); + $this->assertGreaterThan(0, $result['pagination']['total_count']); + } + + /** + * Test that get_sequences() returns the expected data when + * pagination parameters and per_page limits are specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequencesPagination() + { + // Return one sequence. + $result = $this->api->get_sequences(false, '', '', 1); + + // Assert sequences and pagination exist. + $this->assertDataExists($result, 'sequences'); + $this->assertPaginationExists($result); - /** - * Test that the `get_sequences()` function returns a blank array when no data - * exists on the ConvertKit account. - * - * @since 1.0.0 - */ - public function testGetSequencesNoData() - { - $this->markTestIncomplete(); + // Assert a single sequence was returned. + $this->assertCount(1, $result['sequences']); - $result = $this->api_no_data->get_sequences(); - $this->assertNotInstanceOf(WP_Error::class, $result); - $this->assertIsArray($result); - $this->assertCount(0, $result); - } + // 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 the `sequence_subscribe()` function returns expected data - * when valid parameters are provided. - * - * @since 1.0.0 - */ - public function testSequenceSubscribe() - { - $this->markTestIncomplete(); + // Use pagination to fetch next page. + $result = $this->api->get_sequences(false, $result['pagination']['end_cursor'], '', 1); - $result = $this->api->sequence_subscribe( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], - $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'], - 'First', - array( - 'last_name' => 'Last', - 'phone_number' => '123-456-7890', - ) - ); - $this->assertNotInstanceOf(WP_Error::class, $result); - $this->assertIsArray($result); - $this->assertArrayHasKey('subscription', $result); - } + // Assert sequences and pagination exist. + $this->assertDataExists($result, 'sequences'); + $this->assertPaginationExists($result); - /** - * Test that the `sequence_subscribe()` function returns a WP_Error - * when an invalid $sequence_id parameter is provided. - * - * @since 1.0.0 - */ - public function testSequenceSubscribeWithInvalidSequenceID() - { - $this->markTestIncomplete(); + // Assert a single sequence was returned. + $this->assertCount(1, $result['sequences']); - $result = $this->api->sequence_subscribe(12345, $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'], 'First'); - $this->assertInstanceOf(WP_Error::class, $result); - $this->assertEquals($result->get_error_code(), $this->errorCode); - $this->assertEquals('Course not found: ', $result->get_error_message()); - } + // Assert has_previous_page and has_next_page are correct. + $this->assertTrue($result['pagination']['has_previous_page']); + $this->assertFalse($result['pagination']['has_next_page']); - /** - * Test that the `sequence_subscribe()` function returns a WP_Error - * when an empty $sequence_id parameter is provided. - * - * @since 1.0.0 - */ - public function testSequenceSubscribeWithEmptySequenceID() - { - $this->markTestIncomplete(); + // Use pagination to fetch previous page. + $result = $this->api->get_sequences(false, '', $result['pagination']['start_cursor'], 1); - $result = $this->api->sequence_subscribe('', $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'], 'First'); - $this->assertInstanceOf(WP_Error::class, $result); - $this->assertEquals($result->get_error_code(), $this->errorCode); - $this->assertEquals('sequence_subscribe(): the sequence_id parameter is empty.', $result->get_error_message()); - } + // Assert sequences and pagination exist. + $this->assertDataExists($result, 'sequences'); + $this->assertPaginationExists($result); - /** - * Test that the `sequence_subscribe()` function returns a WP_Error - * when an empty $email parameter is provided. - * - * @since 1.0.0 - */ - public function testSequenceSubscribeWithEmptyEmail() - { - $this->markTestIncomplete(); + // Assert a single sequence was returned. + $this->assertCount(1, $result['sequences']); - $result = $this->api->sequence_subscribe( $_ENV['CONVERTKIT_API_SEQUENCE_ID'], '', 'First'); - $this->assertInstanceOf(WP_Error::class, $result); - $this->assertEquals($result->get_error_code(), $this->errorCode); - $this->assertEquals('sequence_subscribe(): the email parameter is empty.', $result->get_error_message()); - } + // 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 add_subscriber_to_sequence_by_email() returns the expected data. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceByEmail() + { + // Create subscriber. + $emailAddress = $this->generateEmailAddress(); + $subscriber = $this->api->create_subscriber($emailAddress); + $this->assertNotInstanceOf(WP_Error::class, $result); + $this->assertIsArray($result); - /** - * Test that the `sequence_subscribe()` function returns a WP_Error - * when the $email parameter only consists of spaces. - * - * @since 1.0.0 - */ - public function testSequenceSubscribeWithSpacesInEmail() - { - $this->markTestIncomplete(); + // Set subscriber_id to ensure subscriber is unsubscribed after test. + $this->subscriber_ids[] = $subscriber['subscriber']['id']; - $result = $this->api->sequence_subscribe($_ENV['CONVERTKIT_API_SEQUENCE_ID'], ' ', 'First'); - $this->assertInstanceOf(WP_Error::class, $result); + // Add subscriber to sequence. + $result = $this->api->add_subscriber_to_sequence_by_email( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + $emailAddress + ); + $this->assertNotInstanceOf(WP_Error::class, $result); + $this->assertIsArray($result); + $this->assertArrayHasKey('subscriber', $result); + $this->assertArrayHasKey('id', $result['subscriber']); + $this->assertEquals( + $result['subscriber']['email_address'], + $emailAddress + ); + } + + /** + * Test that add_subscriber_to_sequence_by_email() returns a WP_Error when an invalid + * sequence is specified. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceByEmailWithInvalidSequenceID() + { + $result = $this->api->add_subscriber_to_sequence_by_email( + 12345, + $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'] + ); + $this->assertInstanceOf(WP_Error::class, $result); $this->assertEquals($result->get_error_code(), $this->errorCode); - $this->assertEquals('sequence_subscribe(): the email parameter is empty.', $result->get_error_message()); - } + } + + /** + * Test that add_subscriber_to_sequence_by_email() returns a WP_Error when an invalid + * email address is specified. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceByEmailWithInvalidEmailAddress() + { + $result = $this->api->add_subscriber_to_sequence_by_email( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + 'not-an-email-address' + ); + $this->assertInstanceOf(WP_Error::class, $result); + $this->assertEquals($result->get_error_code(), $this->errorCode); + } + + /** + * Test that add_subscriber_to_sequence() returns the expected data. + * + * @since 2.0.0 + * + * @return void + */ + public function testAddSubscriberToSequence() + { + // Create subscriber. + $subscriber = $this->api->create_subscriber( + $this->generateEmailAddress() + ); + + $this->assertNotInstanceOf(WP_Error::class, $result); + $this->assertIsArray($result); - /** - * Test that the `sequence_subscribe()` function returns a WP_Error - * when an invalid $email parameter is provided. - * - * @since 1.0.0 - */ - public function testSequenceSubscribeWithInvalidEmail() - { - $this->markTestIncomplete(); + // Set subscriber_id to ensure subscriber is unsubscribed after test. + $this->subscriber_ids[] = $subscriber['subscriber']['id']; - $result = $this->api->sequence_subscribe($_ENV['CONVERTKIT_API_SEQUENCE_ID'], 'invalid-email-address', 'First'); - $this->assertInstanceOf(WP_Error::class, $result); + // Add subscriber to sequence. + $result = $this->api->add_subscriber_to_sequence( + (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + $subscriber['subscriber']['id'] + ); + $this->assertNotInstanceOf(WP_Error::class, $result); + $this->assertIsArray($result); + $this->assertArrayHasKey('subscriber', $result); + $this->assertArrayHasKey('id', $result['subscriber']); + $this->assertEquals($result['subscriber']['id'], $subscriber['subscriber']['id']); + } + + /** + * Test that add_subscriber_to_sequence() returns a WP_Error when an invalid + * sequence ID is specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceWithInvalidSequenceID() + { + $result = $this->api->add_subscriber_to_sequence( + 12345, + $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'] + ); + $this->assertInstanceOf(WP_Error::class, $result); $this->assertEquals($result->get_error_code(), $this->errorCode); - $this->assertEquals('Error updating subscriber: Email address is invalid', $result->get_error_message()); - } + } + + /** + * Test that add_subscriber_to_sequence() returns a WP_Error when an invalid + * email address is specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceWithInvalidSubscriberID() + { + $result = $this->api->add_subscriber_to_sequence( + $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'], + 12345 + ); + $this->assertInstanceOf(WP_Error::class, $result); + $this->assertEquals($result->get_error_code(), $this->errorCode); + } + + /** + * Test that get_sequence_subscriptions() returns the expected data. + * + * @since 1.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptions() + { + $result = $this->api->get_sequence_subscriptions($_ENV['CONVERTKIT_API_SEQUENCE_ID']); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + } + + /** + * Test that get_sequence_subscriptions() returns the expected data + * when the total count is included. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithTotalCount() + { + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + null, // Added after. + null, // Added before. + true // Include total count. + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + + // Assert total count is included. + $this->assertArrayHasKey('total_count', $result['pagination']); + $this->assertGreaterThan(0, $result['pagination']['total_count']); + } + + /** + * Test that get_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and the subscription status + * is cancelled. + * + * @since 1.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithBouncedSubscriberState() + { + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'bounced' // Subscriber state. + ); + + // 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_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and the added_after parameter + * is used. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithAddedAfterParam() + { + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + $date // Added after. + ); + + // 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_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and the added_before parameter + * is used. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithAddedBeforeParam() + { + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + null, // Added after. + $date // Added before. + ); + + // 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_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and the created_after parameter + * is used. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithCreatedAfterParam() + { + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + $date // Created after. + ); + + // 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_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and the created_before parameter + * is used. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithCreatedBeforeParam() + { + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + $date // Created before. + ); + + // 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]['created_at'])) + ); + } + + /** + * Test that get_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and pagination parameters + * and per_page limits are specified. + * + * @since 1.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsPagination() + { + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + null, // Added after. + null, // Added before. + false, // Include total count. + '', // After cursor. + '', // Before cursor. + 1 // Per page. + ); + + // 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_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + null, // Added after. + null, // Added before. + false, // Include total count. + $result['pagination']['end_cursor'], // After cursor. + '', // Before cursor. + 1 // Per page. + ); + + // 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_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + null, // Added after. + null, // Added before. + false, // Include total count. + '', // After cursor. + $result['pagination']['start_cursor'], // Before cursor. + 1 // Per page. + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + } + + /** + * Test that get_sequence_subscriptions() returns a WP_Error when an invalid + * Sequence ID is specified. + * + * @since 1.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithInvalidSequenceID() + { + $result = $this->api->get_sequence_subscriptions(12345); + $this->assertInstanceOf(WP_Error::class, $result); + $this->assertEquals($result->get_error_code(), $this->errorCode); + } + + /** + * Test that get_sequence_subscriptions() returns a WP_Error when an invalid + * subscriber state is specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithInvalidSubscriberState() + { + $result = $this->api->get_sequence_subscriptions( + (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + 'not-a-valid-state' + ); + $this->assertInstanceOf(WP_Error::class, $result); + $this->assertEquals($result->get_error_code(), $this->errorCode); + } + + /** + * Test that get_sequence_subscriptions() returns a WP_Error when invalid + * pagination parameters are specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithInvalidPagination() + { + $result = $this->api->get_sequence_subscriptions( + (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + 'not-a-valid-cursor' + ); + $this->assertInstanceOf(WP_Error::class, $result); + $this->assertEquals($result->get_error_code(), $this->errorCode); + } /** * Test that the `get_tags()` function returns expected data. @@ -1678,7 +2098,7 @@ public function testGetBroadcast() } /** - * Test that get_broadcast() throws a ClientException when an invalid + * Test that get_broadcast() returns a WP_Error when an invalid * broadcast ID is specified. * * @since 2.0.0 @@ -1715,7 +2135,7 @@ public function testGetBroadcastStats() } /** - * Test that get_broadcast_stats() throws a ClientException when an invalid + * Test that get_broadcast_stats() returns a WP_Error when an invalid * broadcast ID is specified. * * @since 2.0.0 @@ -1729,7 +2149,7 @@ public function testGetBroadcastStatsWithInvalidBroadcastID() } /** - * Test that update_broadcast() throws a ClientException when an invalid + * Test that update_broadcast() returns a WP_Error when an invalid * broadcast ID is specified. * * @since 1.0.0 @@ -1743,7 +2163,7 @@ public function testUpdateBroadcastWithInvalidBroadcastID() } /** - * Test that delete_broadcast() throws a ClientException when an invalid + * Test that delete_broadcast() returns a WP_Error when an invalid * broadcast ID is specified. * * @since 1.0.0 From b0833dcf559762e808f99e9b2b61327d5c5a34ad Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Fri, 19 Apr 2024 15:26:54 +0100 Subject: [PATCH 2/5] Coding standards --- tests/wpunit/APITest.php | 996 +++++++++++++++++++-------------------- 1 file changed, 498 insertions(+), 498 deletions(-) diff --git a/tests/wpunit/APITest.php b/tests/wpunit/APITest.php index 2d4b886..6f52fed 100644 --- a/tests/wpunit/APITest.php +++ b/tests/wpunit/APITest.php @@ -845,60 +845,60 @@ public function testGetLandingPagesNoData() } /** - * Test that get_sequences() returns the expected data. - * - * @since 1.0.0 - * - * @return void - */ - public function testGetSequences() - { - $result = $this->api->get_sequences(); - - // Assert sequences and pagination exist. - $this->assertDataExists($result, 'sequences'); - $this->assertPaginationExists($result); - - // Check first sequence in resultset has expected data. - $sequence = $result['sequences'][0]; - $this->assertArrayHasKey('id', $sequence); - $this->assertArrayHasKey('name', $sequence); - $this->assertArrayHasKey('hold', $sequence); - $this->assertArrayHasKey('repeat', $sequence); - $this->assertArrayHasKey('created_at', $sequence); - } - - /** - * Test that get_sequences() returns the expected data - * when the total count is included. - * - * @since 2.0.0 - * - * @return void - */ - public function testGetSequencesWithTotalCount() - { - $result = $this->api->get_sequences(true); - - // Assert sequences and pagination exist. - $this->assertDataExists($result, 'sequences'); - $this->assertPaginationExists($result); - - // Assert total count is included. - $this->assertArrayHasKey('total_count', $result['pagination']); - $this->assertGreaterThan(0, $result['pagination']['total_count']); - } - - /** - * Test that get_sequences() returns the expected data when - * pagination parameters and per_page limits are specified. - * - * @since 2.0.0 - * - * @return void - */ - public function testGetSequencesPagination() - { + * Test that get_sequences() returns the expected data. + * + * @since 1.0.0 + * + * @return void + */ + public function testGetSequences() + { + $result = $this->api->get_sequences(); + + // Assert sequences and pagination exist. + $this->assertDataExists($result, 'sequences'); + $this->assertPaginationExists($result); + + // Check first sequence in resultset has expected data. + $sequence = $result['sequences'][0]; + $this->assertArrayHasKey('id', $sequence); + $this->assertArrayHasKey('name', $sequence); + $this->assertArrayHasKey('hold', $sequence); + $this->assertArrayHasKey('repeat', $sequence); + $this->assertArrayHasKey('created_at', $sequence); + } + + /** + * Test that get_sequences() returns the expected data + * when the total count is included. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequencesWithTotalCount() + { + $result = $this->api->get_sequences(true); + + // Assert sequences and pagination exist. + $this->assertDataExists($result, 'sequences'); + $this->assertPaginationExists($result); + + // Assert total count is included. + $this->assertArrayHasKey('total_count', $result['pagination']); + $this->assertGreaterThan(0, $result['pagination']['total_count']); + } + + /** + * Test that get_sequences() returns the expected data when + * pagination parameters and per_page limits are specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequencesPagination() + { // Return one sequence. $result = $this->api->get_sequences(false, '', '', 1); @@ -940,465 +940,465 @@ public function testGetSequencesPagination() // 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 add_subscriber_to_sequence_by_email() returns the expected data. - * - * @since 1.0.0 - * - * @return void - */ - public function testAddSubscriberToSequenceByEmail() - { - // Create subscriber. - $emailAddress = $this->generateEmailAddress(); - $subscriber = $this->api->create_subscriber($emailAddress); - $this->assertNotInstanceOf(WP_Error::class, $result); + } + + /** + * Test that add_subscriber_to_sequence_by_email() returns the expected data. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceByEmail() + { + // Create subscriber. + $emailAddress = $this->generateEmailAddress(); + $subscriber = $this->api->create_subscriber($emailAddress); + $this->assertNotInstanceOf(WP_Error::class, $result); $this->assertIsArray($result); - // Set subscriber_id to ensure subscriber is unsubscribed after test. - $this->subscriber_ids[] = $subscriber['subscriber']['id']; + // Set subscriber_id to ensure subscriber is unsubscribed after test. + $this->subscriber_ids[] = $subscriber['subscriber']['id']; - // Add subscriber to sequence. - $result = $this->api->add_subscriber_to_sequence_by_email( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], - $emailAddress - ); - $this->assertNotInstanceOf(WP_Error::class, $result); + // Add subscriber to sequence. + $result = $this->api->add_subscriber_to_sequence_by_email( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + $emailAddress + ); + $this->assertNotInstanceOf(WP_Error::class, $result); $this->assertIsArray($result); - $this->assertArrayHasKey('subscriber', $result); - $this->assertArrayHasKey('id', $result['subscriber']); - $this->assertEquals( - $result['subscriber']['email_address'], - $emailAddress - ); - } - - /** - * Test that add_subscriber_to_sequence_by_email() returns a WP_Error when an invalid - * sequence is specified. - * - * @since 1.0.0 - * - * @return void - */ - public function testAddSubscriberToSequenceByEmailWithInvalidSequenceID() - { - $result = $this->api->add_subscriber_to_sequence_by_email( - 12345, - $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'] - ); - $this->assertInstanceOf(WP_Error::class, $result); + $this->assertArrayHasKey('subscriber', $result); + $this->assertArrayHasKey('id', $result['subscriber']); + $this->assertEquals( + $result['subscriber']['email_address'], + $emailAddress + ); + } + + /** + * Test that add_subscriber_to_sequence_by_email() returns a WP_Error when an invalid + * sequence is specified. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceByEmailWithInvalidSequenceID() + { + $result = $this->api->add_subscriber_to_sequence_by_email( + 12345, + $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'] + ); + $this->assertInstanceOf(WP_Error::class, $result); $this->assertEquals($result->get_error_code(), $this->errorCode); - } - - /** - * Test that add_subscriber_to_sequence_by_email() returns a WP_Error when an invalid - * email address is specified. - * - * @since 1.0.0 - * - * @return void - */ - public function testAddSubscriberToSequenceByEmailWithInvalidEmailAddress() - { - $result = $this->api->add_subscriber_to_sequence_by_email( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], - 'not-an-email-address' - ); - $this->assertInstanceOf(WP_Error::class, $result); + } + + /** + * Test that add_subscriber_to_sequence_by_email() returns a WP_Error when an invalid + * email address is specified. + * + * @since 1.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceByEmailWithInvalidEmailAddress() + { + $result = $this->api->add_subscriber_to_sequence_by_email( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + 'not-an-email-address' + ); + $this->assertInstanceOf(WP_Error::class, $result); $this->assertEquals($result->get_error_code(), $this->errorCode); - } - - /** - * Test that add_subscriber_to_sequence() returns the expected data. - * - * @since 2.0.0 - * - * @return void - */ - public function testAddSubscriberToSequence() - { - // Create subscriber. - $subscriber = $this->api->create_subscriber( - $this->generateEmailAddress() - ); - - $this->assertNotInstanceOf(WP_Error::class, $result); + } + + /** + * Test that add_subscriber_to_sequence() returns the expected data. + * + * @since 2.0.0 + * + * @return void + */ + public function testAddSubscriberToSequence() + { + // Create subscriber. + $subscriber = $this->api->create_subscriber( + $this->generateEmailAddress() + ); + + $this->assertNotInstanceOf(WP_Error::class, $result); $this->assertIsArray($result); - // Set subscriber_id to ensure subscriber is unsubscribed after test. - $this->subscriber_ids[] = $subscriber['subscriber']['id']; + // Set subscriber_id to ensure subscriber is unsubscribed after test. + $this->subscriber_ids[] = $subscriber['subscriber']['id']; - // Add subscriber to sequence. - $result = $this->api->add_subscriber_to_sequence( - (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'], - $subscriber['subscriber']['id'] - ); - $this->assertNotInstanceOf(WP_Error::class, $result); + // Add subscriber to sequence. + $result = $this->api->add_subscriber_to_sequence( + (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + $subscriber['subscriber']['id'] + ); + $this->assertNotInstanceOf(WP_Error::class, $result); $this->assertIsArray($result); - $this->assertArrayHasKey('subscriber', $result); - $this->assertArrayHasKey('id', $result['subscriber']); - $this->assertEquals($result['subscriber']['id'], $subscriber['subscriber']['id']); - } - - /** - * Test that add_subscriber_to_sequence() returns a WP_Error when an invalid - * sequence ID is specified. - * - * @since 2.0.0 - * - * @return void - */ - public function testAddSubscriberToSequenceWithInvalidSequenceID() - { - $result = $this->api->add_subscriber_to_sequence( - 12345, - $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'] - ); - $this->assertInstanceOf(WP_Error::class, $result); + $this->assertArrayHasKey('subscriber', $result); + $this->assertArrayHasKey('id', $result['subscriber']); + $this->assertEquals($result['subscriber']['id'], $subscriber['subscriber']['id']); + } + + /** + * Test that add_subscriber_to_sequence() returns a WP_Error when an invalid + * sequence ID is specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceWithInvalidSequenceID() + { + $result = $this->api->add_subscriber_to_sequence( + 12345, + $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'] + ); + $this->assertInstanceOf(WP_Error::class, $result); $this->assertEquals($result->get_error_code(), $this->errorCode); - } - - /** - * Test that add_subscriber_to_sequence() returns a WP_Error when an invalid - * email address is specified. - * - * @since 2.0.0 - * - * @return void - */ - public function testAddSubscriberToSequenceWithInvalidSubscriberID() - { - $result = $this->api->add_subscriber_to_sequence( - $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'], - 12345 - ); - $this->assertInstanceOf(WP_Error::class, $result); + } + + /** + * Test that add_subscriber_to_sequence() returns a WP_Error when an invalid + * email address is specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testAddSubscriberToSequenceWithInvalidSubscriberID() + { + $result = $this->api->add_subscriber_to_sequence( + $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'], + 12345 + ); + $this->assertInstanceOf(WP_Error::class, $result); $this->assertEquals($result->get_error_code(), $this->errorCode); - } - - /** - * Test that get_sequence_subscriptions() returns the expected data. - * - * @since 1.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptions() - { - $result = $this->api->get_sequence_subscriptions($_ENV['CONVERTKIT_API_SEQUENCE_ID']); - - // Assert subscribers and pagination exist. - $this->assertDataExists($result, 'subscribers'); - $this->assertPaginationExists($result); - } - - /** - * Test that get_sequence_subscriptions() returns the expected data - * when the total count is included. - * - * @since 2.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptionsWithTotalCount() - { - $result = $this->api->get_sequence_subscriptions( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. - 'active', // Subscriber state. - null, // Created after. - null, // Created before. - null, // Added after. - null, // Added before. - true // Include total count. - ); - - // Assert subscribers and pagination exist. - $this->assertDataExists($result, 'subscribers'); - $this->assertPaginationExists($result); - - // Assert total count is included. - $this->assertArrayHasKey('total_count', $result['pagination']); - $this->assertGreaterThan(0, $result['pagination']['total_count']); - } - - /** - * Test that get_sequence_subscriptions() returns the expected data - * when a valid Sequence ID is specified and the subscription status - * is cancelled. - * - * @since 1.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptionsWithBouncedSubscriberState() - { - $result = $this->api->get_sequence_subscriptions( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. - 'bounced' // Subscriber state. - ); - - // 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_sequence_subscriptions() returns the expected data - * when a valid Sequence ID is specified and the added_after parameter - * is used. - * - * @since 2.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptionsWithAddedAfterParam() - { - $date = new \DateTime('2024-01-01'); - $result = $this->api->get_sequence_subscriptions( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. - 'active', // Subscriber state. - null, // Created after. - null, // Created before. - $date // Added after. - ); - - // 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_sequence_subscriptions() returns the expected data - * when a valid Sequence ID is specified and the added_before parameter - * is used. - * - * @since 2.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptionsWithAddedBeforeParam() - { - $date = new \DateTime('2024-01-01'); - $result = $this->api->get_sequence_subscriptions( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. - 'active', // Subscriber state. - null, // Created after. - null, // Created before. - null, // Added after. - $date // Added before. - ); - - // 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_sequence_subscriptions() returns the expected data - * when a valid Sequence ID is specified and the created_after parameter - * is used. - * - * @since 2.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptionsWithCreatedAfterParam() - { - $date = new \DateTime('2024-01-01'); - $result = $this->api->get_sequence_subscriptions( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. - 'active', // Subscriber state. - $date // Created after. - ); - - // 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_sequence_subscriptions() returns the expected data - * when a valid Sequence ID is specified and the created_before parameter - * is used. - * - * @since 2.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptionsWithCreatedBeforeParam() - { - $date = new \DateTime('2024-01-01'); - $result = $this->api->get_sequence_subscriptions( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. - 'active', // Subscriber state. - null, // Created after. - $date // Created before. - ); - - // 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]['created_at'])) - ); - } - - /** - * Test that get_sequence_subscriptions() returns the expected data - * when a valid Sequence ID is specified and pagination parameters - * and per_page limits are specified. - * - * @since 1.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptionsPagination() - { - $result = $this->api->get_sequence_subscriptions( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. - 'active', // Subscriber state. - null, // Created after. - null, // Created before. - null, // Added after. - null, // Added before. - false, // Include total count. - '', // After cursor. - '', // Before cursor. - 1 // Per page. - ); - - // 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_sequence_subscriptions( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. - 'active', // Subscriber state. - null, // Created after. - null, // Created before. - null, // Added after. - null, // Added before. - false, // Include total count. - $result['pagination']['end_cursor'], // After cursor. - '', // Before cursor. - 1 // Per page. - ); - - // 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_sequence_subscriptions( - $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. - 'active', // Subscriber state. - null, // Created after. - null, // Created before. - null, // Added after. - null, // Added before. - false, // Include total count. - '', // After cursor. - $result['pagination']['start_cursor'], // Before cursor. - 1 // Per page. - ); - - // Assert subscribers and pagination exist. - $this->assertDataExists($result, 'subscribers'); - $this->assertPaginationExists($result); - } - - /** - * Test that get_sequence_subscriptions() returns a WP_Error when an invalid - * Sequence ID is specified. - * - * @since 1.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptionsWithInvalidSequenceID() - { - $result = $this->api->get_sequence_subscriptions(12345); - $this->assertInstanceOf(WP_Error::class, $result); + } + + /** + * Test that get_sequence_subscriptions() returns the expected data. + * + * @since 1.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptions() + { + $result = $this->api->get_sequence_subscriptions($_ENV['CONVERTKIT_API_SEQUENCE_ID']); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + } + + /** + * Test that get_sequence_subscriptions() returns the expected data + * when the total count is included. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithTotalCount() + { + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + null, // Added after. + null, // Added before. + true // Include total count. + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + + // Assert total count is included. + $this->assertArrayHasKey('total_count', $result['pagination']); + $this->assertGreaterThan(0, $result['pagination']['total_count']); + } + + /** + * Test that get_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and the subscription status + * is cancelled. + * + * @since 1.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithBouncedSubscriberState() + { + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'bounced' // Subscriber state. + ); + + // 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_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and the added_after parameter + * is used. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithAddedAfterParam() + { + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + $date // Added after. + ); + + // 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_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and the added_before parameter + * is used. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithAddedBeforeParam() + { + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + null, // Added after. + $date // Added before. + ); + + // 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_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and the created_after parameter + * is used. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithCreatedAfterParam() + { + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + $date // Created after. + ); + + // 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_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and the created_before parameter + * is used. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithCreatedBeforeParam() + { + $date = new \DateTime('2024-01-01'); + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + $date // Created before. + ); + + // 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]['created_at'])) + ); + } + + /** + * Test that get_sequence_subscriptions() returns the expected data + * when a valid Sequence ID is specified and pagination parameters + * and per_page limits are specified. + * + * @since 1.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsPagination() + { + $result = $this->api->get_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + null, // Added after. + null, // Added before. + false, // Include total count. + '', // After cursor. + '', // Before cursor. + 1 // Per page. + ); + + // 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_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + null, // Added after. + null, // Added before. + false, // Include total count. + $result['pagination']['end_cursor'], // After cursor. + '', // Before cursor. + 1 // Per page. + ); + + // 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_sequence_subscriptions( + $_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID. + 'active', // Subscriber state. + null, // Created after. + null, // Created before. + null, // Added after. + null, // Added before. + false, // Include total count. + '', // After cursor. + $result['pagination']['start_cursor'], // Before cursor. + 1 // Per page. + ); + + // Assert subscribers and pagination exist. + $this->assertDataExists($result, 'subscribers'); + $this->assertPaginationExists($result); + } + + /** + * Test that get_sequence_subscriptions() returns a WP_Error when an invalid + * Sequence ID is specified. + * + * @since 1.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithInvalidSequenceID() + { + $result = $this->api->get_sequence_subscriptions(12345); + $this->assertInstanceOf(WP_Error::class, $result); $this->assertEquals($result->get_error_code(), $this->errorCode); - } - - /** - * Test that get_sequence_subscriptions() returns a WP_Error when an invalid - * subscriber state is specified. - * - * @since 2.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptionsWithInvalidSubscriberState() - { - $result = $this->api->get_sequence_subscriptions( - (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'], - 'not-a-valid-state' - ); - $this->assertInstanceOf(WP_Error::class, $result); + } + + /** + * Test that get_sequence_subscriptions() returns a WP_Error when an invalid + * subscriber state is specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithInvalidSubscriberState() + { + $result = $this->api->get_sequence_subscriptions( + (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + 'not-a-valid-state' + ); + $this->assertInstanceOf(WP_Error::class, $result); $this->assertEquals($result->get_error_code(), $this->errorCode); - } - - /** - * Test that get_sequence_subscriptions() returns a WP_Error when invalid - * pagination parameters are specified. - * - * @since 2.0.0 - * - * @return void - */ - public function testGetSequenceSubscriptionsWithInvalidPagination() - { - $result = $this->api->get_sequence_subscriptions( - (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'], - 'not-a-valid-cursor' - ); - $this->assertInstanceOf(WP_Error::class, $result); + } + + /** + * Test that get_sequence_subscriptions() returns a WP_Error when invalid + * pagination parameters are specified. + * + * @since 2.0.0 + * + * @return void + */ + public function testGetSequenceSubscriptionsWithInvalidPagination() + { + $result = $this->api->get_sequence_subscriptions( + (int) $_ENV['CONVERTKIT_API_SEQUENCE_ID'], + 'not-a-valid-cursor' + ); + $this->assertInstanceOf(WP_Error::class, $result); $this->assertEquals($result->get_error_code(), $this->errorCode); - } + } /** * Test that the `get_tags()` function returns expected data. From 0cb1ca8f9a9e55cabfcb4309638e0debe9d8b0c9 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 22 Apr 2024 15:03:43 +0100 Subject: [PATCH 3/5] Add method to build error message --- src/class-convertkit-api.php | 68 ++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/src/class-convertkit-api.php b/src/class-convertkit-api.php index f9407f2..1504a4c 100644 --- a/src/class-convertkit-api.php +++ b/src/class-convertkit-api.php @@ -1196,20 +1196,8 @@ public function request( $endpoint, $method = 'get', $params = array(), $retry_i // Return the API error message as a WP_Error if the HTTP response code is a 4xx code. if ( $http_response_code >= 400 ) { - // Define the error description. - $error = ''; - if ( array_key_exists( 'errors', $response ) ) { - $error = implode( "\n", $response['errors'] ); - } elseif ( array_key_exists( 'error_description', $response ) ) { - $error = $response['error_description']; - } elseif ( array_key_exists( 'error', $response ) ) { - // The 'error' key is present when exchanging an API Key and Secret for an Access Token - // and something went wrong e.g. invalid API credentials. - $error = $response['error']; - if ( array_key_exists( 'message', $response ) ) { - $error .= ': ' . $response['message']; - } - } + // Define the error message. + $error = $this->get_error_message_string( $response ); $this->log( 'API: Error: ' . $error ); @@ -1259,6 +1247,58 @@ public function request( $endpoint, $method = 'get', $params = array(), $retry_i } + /** + * Inspects the given API response for errors, returning them as a string. + * + * @since 2.0.0 + * + * @param array $response API Response. + * @return string Error Message(s). + */ + private function get_error_message_string( $response ) { + + // Most API responses contain the `errors` key. + if ( array_key_exists( 'errors', $response ) ) { + $error_message = ''; + + // For sequences, each item in the `errors` key is an array. + // For other API endpoints, each item in the `errors` key is a string. + foreach ( $response['errors'] as $error ) { + if ( is_array( $error ) ) { + $error_message .= implode( "\n", $error ); + continue; + } + + // Error is a string. + $error_message .= "\n" . $error; + } + + return $error_message; + } + + // Some might provide an `error_description`. + if ( array_key_exists( 'error_description', $response ) ) { + return $response['error_description']; + } + + // The `error` key is present when exchanging an API Key and Secret for an Access Token + // and something went wrong e.g. invalid API credentials. + if ( array_key_exists( 'error', $response ) ) { + $error_message = $response['error']; + + // There might be additional information we can return. + if ( array_key_exists( 'message', $response ) ) { + $error_message .= ': ' . $response['message']; + } + + return $error_message; + } + + // If here, no error was detected. + return ''; + + } + /** * Returns the headers to use in an API request. * From 11d644422babf31e74054908fd59a0118bb887a3 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 22 Apr 2024 15:03:49 +0100 Subject: [PATCH 4/5] Coding standards for tests --- tests/wpunit/APITest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/wpunit/APITest.php b/tests/wpunit/APITest.php index 2887031..2f13b52 100644 --- a/tests/wpunit/APITest.php +++ b/tests/wpunit/APITest.php @@ -977,12 +977,12 @@ public function testAddSubscriberToSequenceByEmail() { // Create subscriber. $emailAddress = $this->generateEmailAddress(); - $subscriber = $this->api->create_subscriber($emailAddress); + $result = $this->api->create_subscriber($emailAddress); $this->assertNotInstanceOf(WP_Error::class, $result); $this->assertIsArray($result); // Set subscriber_id to ensure subscriber is unsubscribed after test. - $this->subscriber_ids[] = $subscriber['subscriber']['id']; + $this->subscriber_ids[] = $result['subscriber']['id']; // Add subscriber to sequence. $result = $this->api->add_subscriber_to_sequence_by_email( @@ -1049,8 +1049,8 @@ public function testAddSubscriberToSequence() $this->generateEmailAddress() ); - $this->assertNotInstanceOf(WP_Error::class, $result); - $this->assertIsArray($result); + $this->assertNotInstanceOf(WP_Error::class, $subscriber); + $this->assertIsArray($subscriber); // Set subscriber_id to ensure subscriber is unsubscribed after test. $this->subscriber_ids[] = $subscriber['subscriber']['id']; From 7a70977e5aeb979be453d736dfb9cdac8e4d6ff4 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 22 Apr 2024 15:10:36 +0100 Subject: [PATCH 5/5] Trim errant newlines from error message --- src/class-convertkit-api.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/class-convertkit-api.php b/src/class-convertkit-api.php index 1504a4c..2a56b99 100644 --- a/src/class-convertkit-api.php +++ b/src/class-convertkit-api.php @@ -1273,7 +1273,8 @@ private function get_error_message_string( $response ) { $error_message .= "\n" . $error; } - return $error_message; + // Remove errant newlines and return. + return trim( $error_message ); } // Some might provide an `error_description`.