From f8d42d75207b6193327cbaa73bb71b3bab2745a5 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 8 Dec 2025 11:10:15 +0800 Subject: [PATCH 1/2] Tests: Add Resource Integration Tests --- .../ResourceCustomFieldsNoDataTest.php | 162 ++++++++++++ .../Integration/ResourceCustomFieldsTest.php | 242 ++++++++++++++++++ tests/Integration/ResourceTagsNoDataTest.php | 162 ++++++++++++ tests/Integration/ResourceTagsTest.php | 236 +++++++++++++++++ 4 files changed, 802 insertions(+) create mode 100644 tests/Integration/ResourceCustomFieldsNoDataTest.php create mode 100644 tests/Integration/ResourceCustomFieldsTest.php create mode 100644 tests/Integration/ResourceTagsNoDataTest.php create mode 100644 tests/Integration/ResourceTagsTest.php diff --git a/tests/Integration/ResourceCustomFieldsNoDataTest.php b/tests/Integration/ResourceCustomFieldsNoDataTest.php new file mode 100644 index 0000000..112e253 --- /dev/null +++ b/tests/Integration/ResourceCustomFieldsNoDataTest.php @@ -0,0 +1,162 @@ +settings = new \ConvertKit_MM_Settings(); + update_option( + $this->settings::SETTINGS_NAME, + [ + 'access_token' => $_ENV['CONVERTKIT_OAUTH_ACCESS_TOKEN_NO_DATA'], + 'refresh_token' => $_ENV['CONVERTKIT_OAUTH_REFRESH_TOKEN_NO_DATA'], + ] + ); + + // Initialize the resource class we want to test. + $this->resource = new \ConvertKit_MM_Resource_Custom_Fields(); + + // Confirm initialization didn't result in an error. + $this->assertNotInstanceOf(\WP_Error::class, $this->resource->resources); + + // Initialize the resource class, fetching resources from the API and caching them in the options table. + $result = $this->resource->init(); + + // Confirm calling init() didn't result in an error. + $this->assertNotInstanceOf(\WP_Error::class, $result); + } + + /** + * Performs actions after each test. + * + * @since 1.3.7 + */ + public function tearDown(): void + { + // Delete Credentials and Resources from Plugin's settings. + delete_option($this->settings::SETTINGS_NAME); + delete_option($this->resource->settings_name); + delete_option($this->resource->settings_name . '_last_queried'); + + // Destroy the resource class we tested. + unset($this->resource); + + // Deactivate Plugin. + deactivate_plugins('convertkit/wp-convertkit.php'); + + parent::tearDown(); + } + + /** + * Test that the refresh() function performs as expected. + * + * @since 1.3.7 + */ + public function testRefresh() + { + // Confirm that no resources exist in the stored options table data. + $result = $this->resource->refresh(); + $this->assertNotInstanceOf(\WP_Error::class, $result); + $this->assertIsArray($result); + $this->assertCount(0, $result); + } + + /** + * Test that the expiry timestamp is set and returns the expected value. + * + * @since 1.3.7 + */ + public function testExpiry() + { + // Define the expected expiry date based on the resource class' $cache_duration setting. + $expectedExpiryDate = date('Y-m-d', time() + $this->resource->cache_duration); + + // Fetch the actual expiry date set when the resource class was initialized. + $expiryDate = date('Y-m-d', $this->resource->last_queried + $this->resource->cache_duration); + + // Confirm both dates match. + $this->assertEquals($expectedExpiryDate, $expiryDate); + } + + /** + * Test that the get() function performs as expected. + * + * @since 1.3.7 + */ + public function testGet() + { + // Confirm that no resources exist in the stored options table data. + $result = $this->resource->get(); + $this->assertNotInstanceOf(\WP_Error::class, $result); + $this->assertIsArray($result); + $this->assertCount(0, $result); + } + + /** + * Test that the count() function returns the number of resources. + * + * @since 1.3.7 + */ + public function testCount() + { + $result = $this->resource->get(); + $this->assertEquals($this->resource->count(), count($result)); + } + + /** + * Test that the exist() function performs as expected. + * + * @since 1.3.7 + */ + public function testExist() + { + // Confirm that the function returns false, because resources do not exist. + $result = $this->resource->exist(); + $this->assertSame($result, false); + } +} diff --git a/tests/Integration/ResourceCustomFieldsTest.php b/tests/Integration/ResourceCustomFieldsTest.php new file mode 100644 index 0000000..db22ec0 --- /dev/null +++ b/tests/Integration/ResourceCustomFieldsTest.php @@ -0,0 +1,242 @@ +settings = new \ConvertKit_MM_Settings(); + update_option( + $this->settings::SETTINGS_NAME, + [ + 'access_token' => $_ENV['CONVERTKIT_OAUTH_ACCESS_TOKEN'], + 'refresh_token' => $_ENV['CONVERTKIT_OAUTH_REFRESH_TOKEN'], + ] + ); + + // Initialize the resource class we want to test. + $this->resource = new \ConvertKit_MM_Resource_Custom_Fields(); + + // Confirm initialization didn't result in an error. + $this->assertNotInstanceOf(\WP_Error::class, $this->resource->resources); + + // Initialize the resource class, fetching resources from the API and caching them in the options table. + $result = $this->resource->init(); + + // Confirm calling init() didn't result in an error. + $this->assertNotInstanceOf(\WP_Error::class, $result); + } + + /** + * Performs actions after each test. + * + * @since 1.3.7 + */ + public function tearDown(): void + { + // Delete Credentials and Resources from Plugin's settings. + delete_option($this->settings::SETTINGS_NAME); + delete_option($this->resource->settings_name); + delete_option($this->resource->settings_name . '_last_queried'); + + // Destroy the resource class we tested. + unset($this->resource); + + // Deactivate Plugin. + deactivate_plugins('convertkit/wp-convertkit.php'); + + parent::tearDown(); + } + + /** + * Test that the refresh() function performs as expected. + * + * @since 1.3.7 + */ + public function testRefresh() + { + // Confirm that the data is stored in the options table and includes some expected keys. + $result = $this->resource->refresh(); + $this->assertIsArray($result); + $this->assertArrayHasKey('id', reset($result)); + $this->assertArrayHasKey('name', reset($result)); + } + + /** + * Test that the expiry timestamp is set and returns the expected value. + * + * @since 1.3.7 + */ + public function testExpiry() + { + // Define the expected expiry date based on the resource class' $cache_duration setting. + $expectedExpiryDate = date('Y-m-d', time() + $this->resource->cache_duration); + + // Fetch the actual expiry date set when the resource class was initialized. + $expiryDate = date('Y-m-d', $this->resource->last_queried + $this->resource->cache_duration); + + // Confirm both dates match. + $this->assertEquals($expectedExpiryDate, $expiryDate); + } + + /** + * Tests that the get() function returns resources in alphabetical ascending order + * by default. + * + * @since 1.3.7 + */ + public function testGet() + { + // Call resource class' get() function. + $result = $this->resource->get(); + + // Assert result is an array. + $this->assertIsArray($result); + + // Assert top level array keys are preserved. + $this->assertArrayHasKey(array_key_first($this->resource->resources), $result); + $this->assertArrayHasKey(array_key_last($this->resource->resources), $result); + + // Assert resource within results has expected array keys. + $this->assertArrayHasKey('id', reset($result)); + $this->assertArrayHasKey('name', reset($result)); + $this->assertArrayHasKey('key', reset($result)); + $this->assertArrayHasKey('label', reset($result)); + + // Assert order of data is in ascending alphabetical order. + $this->assertEquals('Billing Address', reset($result)[ $this->resource->order_by ]); + $this->assertEquals('URL', end($result)[ $this->resource->order_by ]); + } + + /** + * Tests that the get() function returns resources in alphabetical descending order + * when a valid order_by and order properties are defined. + * + * @since 1.3.7 + */ + public function testGetWithValidOrderByAndOrder() + { + // Define order_by and order. + $this->resource->order_by = 'key'; + $this->resource->order = 'desc'; + + // Call resource class' get() function. + $result = $this->resource->get(); + + // Assert result is an array. + $this->assertIsArray($result); + + // Assert top level array keys are preserved. + $this->assertArrayHasKey(array_key_first($this->resource->resources), $result); + $this->assertArrayHasKey(array_key_last($this->resource->resources), $result); + + // Assert resource within results has expected array keys. + $this->assertArrayHasKey('id', reset($result)); + $this->assertArrayHasKey('name', reset($result)); + $this->assertArrayHasKey('key', reset($result)); + $this->assertArrayHasKey('label', reset($result)); + + // Assert order of data is in descending alphabetical order. + $this->assertEquals('url', reset($result)[ $this->resource->order_by ]); + $this->assertEquals('billing_address', end($result)[ $this->resource->order_by ]); + } + + /** + * Tests that the get() function returns resources in their original order + * when populated with Forms and an invalid order_by value is specified. + * + * @since 1.3.7 + */ + public function testGetWithInvalidOrderBy() + { + // Define order_by with an invalid value (i.e. an array key that does not exist). + $this->resource->order_by = 'invalid_key'; + + // Call resource class' get() function. + $result = $this->resource->get(); + + // Assert result is an array. + $this->assertIsArray($result); + + // Assert top level array keys are preserved. + $this->assertArrayHasKey(array_key_first($this->resource->resources), $result); + $this->assertArrayHasKey(array_key_last($this->resource->resources), $result); + + // Assert resource within results has expected array keys. + $this->assertArrayHasKey('id', reset($result)); + $this->assertArrayHasKey('name', reset($result)); + $this->assertArrayHasKey('key', reset($result)); + $this->assertArrayHasKey('label', reset($result)); + + // Assert order of data has not changed. + $this->assertEquals('URL', reset($result)['label']); + $this->assertEquals('Notes', end($result)['label']); + } + + /** + * Test that the count() function returns the number of resources. + * + * @since 1.3.7 + */ + public function testCount() + { + $result = $this->resource->get(); + $this->assertEquals($this->resource->count(), count($result)); + } + + /** + * Test that the exist() function performs as expected. + * + * @since 1.3.7 + */ + public function testExist() + { + // Confirm that the function returns true, because resources exist. + $result = $this->resource->exist(); + $this->assertSame($result, true); + } +} diff --git a/tests/Integration/ResourceTagsNoDataTest.php b/tests/Integration/ResourceTagsNoDataTest.php new file mode 100644 index 0000000..7ded369 --- /dev/null +++ b/tests/Integration/ResourceTagsNoDataTest.php @@ -0,0 +1,162 @@ +settings = new \ConvertKit_MM_Settings(); + update_option( + $this->settings::SETTINGS_NAME, + [ + 'access_token' => $_ENV['CONVERTKIT_OAUTH_ACCESS_TOKEN_NO_DATA'], + 'refresh_token' => $_ENV['CONVERTKIT_OAUTH_REFRESH_TOKEN_NO_DATA'], + ] + ); + + // Initialize the resource class we want to test. + $this->resource = new \ConvertKit_MM_Resource_Tags(); + + // Confirm initialization didn't result in an error. + $this->assertNotInstanceOf(\WP_Error::class, $this->resource->resources); + + // Initialize the resource class, fetching resources from the API and caching them in the options table. + $result = $this->resource->init(); + + // Confirm calling init() didn't result in an error. + $this->assertNotInstanceOf(\WP_Error::class, $result); + } + + /** + * Performs actions after each test. + * + * @since 1.3.7 + */ + public function tearDown(): void + { + // Delete Credentials and Resources from Plugin's settings. + delete_option($this->settings::SETTINGS_NAME); + delete_option($this->resource->settings_name); + delete_option($this->resource->settings_name . '_last_queried'); + + // Destroy the resource class we tested. + unset($this->resource); + + // Deactivate Plugin. + deactivate_plugins('convertkit/wp-convertkit.php'); + + parent::tearDown(); + } + + /** + * Test that the refresh() function performs as expected. + * + * @since 1.3.7 + */ + public function testRefresh() + { + // Confirm that the data is stored in the options table and includes some expected keys. + $result = $this->resource->refresh(); + $this->assertNotInstanceOf(\WP_Error::class, $result); + $this->assertIsArray($result); + $this->assertCount(0, $result); + } + + /** + * Test that the expiry timestamp is set and returns the expected value. + * + * @since 1.3.7 + */ + public function testExpiry() + { + // Define the expected expiry date based on the resource class' $cache_duration setting. + $expectedExpiryDate = date('Y-m-d', time() + $this->resource->cache_duration); + + // Fetch the actual expiry date set when the resource class was initialized. + $expiryDate = date('Y-m-d', $this->resource->last_queried + $this->resource->cache_duration); + + // Confirm both dates match. + $this->assertEquals($expectedExpiryDate, $expiryDate); + } + + /** + * Test that the get() function performs as expected. + * + * @since 1.3.7 + */ + public function testGet() + { + // Confirm that the data is fetched from the options table when using get(), and includes some expected keys. + $result = $this->resource->get(); + $this->assertNotInstanceOf(\WP_Error::class, $result); + $this->assertIsArray($result); + $this->assertCount(0, $result); + } + + /** + * Test that the count() function returns the number of resources. + * + * @since 1.3.7 + */ + public function testCount() + { + $result = $this->resource->get(); + $this->assertEquals($this->resource->count(), count($result)); + } + + /** + * Test that the exist() function performs as expected. + * + * @since 1.3.7 + */ + public function testExist() + { + // Confirm that the function returns true, because resources exist. + $result = $this->resource->exist(); + $this->assertSame($result, false); + } +} diff --git a/tests/Integration/ResourceTagsTest.php b/tests/Integration/ResourceTagsTest.php new file mode 100644 index 0000000..a5a0806 --- /dev/null +++ b/tests/Integration/ResourceTagsTest.php @@ -0,0 +1,236 @@ +settings = new \ConvertKit_MM_Settings(); + update_option( + $this->settings::SETTINGS_NAME, + [ + 'access_token' => $_ENV['CONVERTKIT_OAUTH_ACCESS_TOKEN'], + 'refresh_token' => $_ENV['CONVERTKIT_OAUTH_REFRESH_TOKEN'], + ] + ); + + // Initialize the resource class we want to test. + $this->resource = new \ConvertKit_MM_Resource_Tags(); + + // Confirm initialization didn't result in an error. + $this->assertNotInstanceOf(\WP_Error::class, $this->resource->resources); + + // Initialize the resource class, fetching resources from the API and caching them in the options table. + $result = $this->resource->init(); + + // Confirm calling init() didn't result in an error. + $this->assertNotInstanceOf(\WP_Error::class, $result); + } + + /** + * Performs actions after each test. + * + * @since 1.3.7 + */ + public function tearDown(): void + { + // Delete Credentials and Resources from Plugin's settings. + delete_option($this->settings::SETTINGS_NAME); + delete_option($this->resource->settings_name); + delete_option($this->resource->settings_name . '_last_queried'); + + // Destroy the resource class we tested. + unset($this->resource); + + // Deactivate Plugin. + deactivate_plugins('convertkit/wp-convertkit.php'); + + parent::tearDown(); + } + + /** + * Test that the refresh() function performs as expected. + * + * @since 1.3.7 + */ + public function testRefresh() + { + // Confirm that the data is stored in the options table and includes some expected keys. + $result = $this->resource->refresh(); + $this->assertIsArray($result); + $this->assertArrayHasKey('id', reset($result)); + $this->assertArrayHasKey('name', reset($result)); + } + + /** + * Test that the expiry timestamp is set and returns the expected value. + * + * @since 1.3.7 + */ + public function testExpiry() + { + // Define the expected expiry date based on the resource class' $cache_duration setting. + $expectedExpiryDate = date('Y-m-d', time() + $this->resource->cache_duration); + + // Fetch the actual expiry date set when the resource class was initialized. + $expiryDate = date('Y-m-d', $this->resource->last_queried + $this->resource->cache_duration); + + // Confirm both dates match. + $this->assertEquals($expectedExpiryDate, $expiryDate); + } + + /** + * Tests that the get() function returns resources in alphabetical ascending order + * by default. + * + * @since 1.3.7 + */ + public function testGet() + { + // Call resource class' get() function. + $result = $this->resource->get(); + + // Assert result is an array. + $this->assertIsArray($result); + + // Assert top level array keys are preserved. + $this->assertArrayHasKey(array_key_first($this->resource->resources), $result); + $this->assertArrayHasKey(array_key_last($this->resource->resources), $result); + + // Assert resource within results has expected array keys. + $this->assertArrayHasKey('id', reset($result)); + $this->assertArrayHasKey('name', reset($result)); + + // Assert order of data is in ascending alphabetical order. + $this->assertEquals('gravityforms-tag-1', reset($result)[ $this->resource->order_by ]); + $this->assertEquals('wpforms', end($result)[ $this->resource->order_by ]); + } + + /** + * Tests that the get() function returns resources in alphabetical descending order + * when a valid order_by and order properties are defined. + * + * @since 1.3.7 + */ + public function testGetWithValidOrderByAndOrder() + { + // Define order_by and order. + $this->resource->order_by = 'name'; + $this->resource->order = 'desc'; + + // Call resource class' get() function. + $result = $this->resource->get(); + + // Assert result is an array. + $this->assertIsArray($result); + + // Assert top level array keys are preserved. + $this->assertArrayHasKey(array_key_first($this->resource->resources), $result); + $this->assertArrayHasKey(array_key_last($this->resource->resources), $result); + + // Assert resource within results has expected array keys. + $this->assertArrayHasKey('id', reset($result)); + $this->assertArrayHasKey('name', reset($result)); + + // Assert order of data is in ascending alphabetical order. + $this->assertEquals('wpforms', reset($result)[ $this->resource->order_by ]); + $this->assertEquals('gravityforms-tag-1', end($result)[ $this->resource->order_by ]); + } + + /** + * Tests that the get() function returns resources in their original order + * when populated with Forms and an invalid order_by value is specified. + * + * @since 1.3.7 + */ + public function testGetWithInvalidOrderBy() + { + // Define order_by with an invalid value (i.e. an array key that does not exist). + $this->resource->order_by = 'invalid_key'; + + // Call resource class' get() function. + $result = $this->resource->get(); + + // Assert result is an array. + $this->assertIsArray($result); + + // Assert top level array keys are preserved. + $this->assertArrayHasKey(array_key_first($this->resource->resources), $result); + $this->assertArrayHasKey(array_key_last($this->resource->resources), $result); + + // Assert resource within results has expected array keys. + $this->assertArrayHasKey('id', reset($result)); + $this->assertArrayHasKey('name', reset($result)); + + // Assert order of data has not changed. + $this->assertEquals('wpforms', reset($result)['name']); + $this->assertEquals('wordpress', end($result)['name']); + } + + /** + * Test that the count() function returns the number of resources. + * + * @since 1.3.7 + */ + public function testCount() + { + $result = $this->resource->get(); + $this->assertEquals($this->resource->count(), count($result)); + } + + /** + * Test that the exist() function performs as expected. + * + * @since 1.3.7 + */ + public function testExist() + { + // Confirm that the function returns true, because resources exist. + $result = $this->resource->exist(); + $this->assertSame($result, true); + } +} From 449effdaf455d3fa7a577354e987725733ccb444 Mon Sep 17 00:00:00 2001 From: Tim Carr Date: Mon, 8 Dec 2025 11:14:20 +0800 Subject: [PATCH 2/2] Remove WPForms Reference in Docblocks --- admin/class-convertkit-mm-admin.php | 3 +-- includes/class-convertkit-mm-api.php | 8 ++++---- includes/class-convertkit-mm-resource-tags.php | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/admin/class-convertkit-mm-admin.php b/admin/class-convertkit-mm-admin.php index 6d81ac4..d46cd54 100644 --- a/admin/class-convertkit-mm-admin.php +++ b/admin/class-convertkit-mm-admin.php @@ -203,8 +203,7 @@ private function check_credentials() { // Remove from settings. $this->settings->delete_credentials(); - // Redirect to General screen, which will now show the ConvertKit_Settings_OAuth screen, because - // the Plugin has no access token. + // Reload settings screen, to reflect no credentials exist. wp_safe_redirect( add_query_arg( array( diff --git a/includes/class-convertkit-mm-api.php b/includes/class-convertkit-mm-api.php index a80d00e..510cca9 100644 --- a/includes/class-convertkit-mm-api.php +++ b/includes/class-convertkit-mm-api.php @@ -1,15 +1,15 @@