diff --git a/.env.dist.testing b/.env.dist.testing
index 19caaa5..0ceb7d2 100644
--- a/.env.dist.testing
+++ b/.env.dist.testing
@@ -7,7 +7,7 @@ TEST_SITE_TABLE_PREFIX=wp_
TEST_SITE_ADMIN_USERNAME=admin
TEST_SITE_ADMIN_PASSWORD=password
TEST_SITE_WP_ADMIN_PATH=/wp-admin
-WP_ROOT_FOLDER="/home/runner/work/convertkit-wordpress-libraries/convertkit-wordpress-libraries/wordpress"
+WP_ROOT_FOLDER="/var/www/html"
WP_ENVIRONMENT_TYPE=local
TEST_DB_NAME=test
TEST_DB_HOST=localhost
@@ -17,7 +17,7 @@ TEST_TABLE_PREFIX=wp_
TEST_SITE_WP_URL=http://127.0.0.1
TEST_SITE_WP_DOMAIN=127.0.0.1
TEST_SITE_ADMIN_EMAIL=wordpress@convertkit.local
-TEST_SITE_CONFIG_FILE="/home/runner/work/convertkit-wordpress-libraries/convertkit-wordpress-libraries/wordpress/wp-content/plugins/convertkit-wordpress-libraries/tests/_support/WpunitTesterConfig.php"
+TEST_SITE_CONFIG_FILE="/var/www/html/wp-content/plugins/convertkit-wordpress-libraries/tests/_support/WpunitTesterConfig.php"
CONVERTKIT_API_BROADCAST_ID="8697158"
CONVERTKIT_API_CUSTOM_FIELD_ID="258240"
CONVERTKIT_API_FORM_ID="2765139"
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index ded4e07..fa5fba9 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -17,15 +17,15 @@ jobs:
# Virtual Environment to use.
# @see: https://github.com/actions/virtual-environments
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
# Environment Variables.
# Accessible by using ${{ env.NAME }}
# Use ${{ secrets.NAME }} to include any GitHub Secrets in ${{ env.NAME }}
# The base folder will always be /home/runner/work/github-repo-name/github-repo-name
env:
- ROOT_DIR: /home/runner/work/convertkit-wordpress-libraries/convertkit-wordpress-libraries/wordpress
- PLUGIN_DIR: /home/runner/work/convertkit-wordpress-libraries/convertkit-wordpress-libraries/wordpress/wp-content/plugins/convertkit-wordpress-libraries
+ ROOT_DIR: /var/www/html
+ PLUGIN_DIR: /var/www/html/wp-content/plugins/convertkit-wordpress-libraries
DB_NAME: test
DB_USER: root
DB_PASS: root
@@ -51,6 +51,13 @@ jobs:
# Steps to install, configure and run tests
steps:
+ # Checkout Plugin to /home/runner/work/convertkit-wordpress-libraries/convertkit-wordpress-libraries/convertkit-wordpress-libraries
+ # We cannot checkout to ${{ env.PLUGIN_DIR }} as GitHub Actions require it be first placed in /home/runner/work/repo/repo
+ - name: Checkout Plugin
+ uses: actions/checkout@v4
+ with:
+ path: /home/runner/work/convertkit-wordpress-libraries/convertkit-wordpress-libraries/convertkit-wordpress-libraries
+
- name: Start MySQL
run: sudo systemctl start mysql.service
@@ -65,17 +72,15 @@ jobs:
# Some workflows checkout WordPress from GitHub, but that seems to bring a bunch of uncompiled files with it.
# Instead download from wordpress.org stable.
- - name: Download WordPress
- run: wget https://wordpress.org/wordpress-${{ matrix.wp-versions }}.tar.gz
-
- - name: Extract WordPress
- run: tar xfz wordpress-${{ matrix.wp-versions }}.tar.gz
-
- # Checkout (copy) this repository's Plugin to this VM.
- - name: Checkout Plugin
- uses: actions/checkout@v4
- with:
- path: ${{ env.PLUGIN_DIR }}
+ - name: Download and Extract WordPress
+ run: |
+ sudo chown -R runner:docker /var/www/html
+ ls -la /var/www/html
+ cd /var/www/html
+ wget https://wordpress.org/wordpress-${{ matrix.wp-versions }}.tar.gz
+ tar xfz wordpress-${{ matrix.wp-versions }}.tar.gz
+ mv wordpress/* .
+ rm -rf wordpress wordpress-${{ matrix.wp-versions }}.tar.gz
# We install WP-CLI, as it provides useful commands to setup and install WordPress through the command line.
- name: Install WP-CLI
@@ -97,6 +102,10 @@ jobs:
working-directory: ${{ env.ROOT_DIR }}
run: wp-cli plugin install ${{ env.INSTALL_PLUGINS }}
+ # Move Plugin
+ - name: Move Plugin
+ run: mv /home/runner/work/convertkit-wordpress-libraries/convertkit-wordpress-libraries/convertkit-wordpress-libraries ${{ env.PLUGIN_DIR }}
+
# Install PHP version to run tests against.
- name: Install PHP
uses: shivammathur/setup-php@v2
diff --git a/phpcs.xml b/phpcs.xml
index 1e875f4..11ae28a 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -14,8 +14,8 @@
class-convertkit-api-traits.php
-
-
+
+
+
-
-
-
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 7dc6e9e..2cf5ef8 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -16,11 +16,11 @@ parameters:
# Location of WordPress Plugins for PHPStan to scan, building symbols.
scanDirectories:
- - /home/runner/work/convertkit-wordpress-libraries/convertkit-wordpress-libraries/wordpress/wp-content/plugins
+ - /var/www/html/wp-content/plugins
# Location of constants for PHPStan to scan, building symbols.
scanFiles:
- - /home/runner/work/convertkit-wordpress-libraries/convertkit-wordpress-libraries/wordpress/wp-config.php
+ - /var/www/html/wp-config.php
# Don't report unmatched ignored errors on older PHP versions (7.2, 7.3)
reportUnmatchedIgnoredErrors: false
diff --git a/src/class-convertkit-api-v4.php b/src/class-convertkit-api-v4.php
index cfde53e..3b72f5b 100644
--- a/src/class-convertkit-api-v4.php
+++ b/src/class-convertkit-api-v4.php
@@ -492,6 +492,7 @@ public function get_access_token_by_api_key_and_secret( $api_key, $api_secret )
array(
'api_key' => $api_key,
'api_secret' => $api_secret,
+ 'client_id' => $this->client_id,
)
);
diff --git a/tests/wpunit/APITest.php b/tests/wpunit/APITest.php
index 27f2d03..b7531a9 100644
--- a/tests/wpunit/APITest.php
+++ b/tests/wpunit/APITest.php
@@ -604,6 +604,38 @@ public function testGetAccessTokenByInvalidAPIKeyAndSecret()
$this->assertEquals('Authorization Failed: API Secret not valid', $result->get_error_message());
}
+ /**
+ * Test that fetching an Access Token using an invalid client ID returns a WP_Error.
+ *
+ * @since 2.0.7
+ */
+ public function testGetAccessTokenByAPIKeyAndSecretWithInvalidClientID()
+ {
+ $api = new ConvertKit_API_V4( 'invalidClientID', $_ENV['CONVERTKIT_OAUTH_REDIRECT_URI'] );
+ $result = $api->get_access_token_by_api_key_and_secret(
+ $_ENV['CONVERTKIT_API_KEY'],
+ $_ENV['CONVERTKIT_API_SECRET']
+ );
+ $this->assertInstanceOf(WP_Error::class, $result);
+ $this->assertEquals($result->get_error_code(), $this->errorCode);
+ }
+
+ /**
+ * Test that fetching an Access Token using a blank client ID returns a WP_Error.
+ *
+ * @since 2.0.7
+ */
+ public function testGetAccessTokenByAPIKeyAndSecretWithBlankClientID()
+ {
+ $api = new ConvertKit_API_V4( '', $_ENV['CONVERTKIT_OAUTH_REDIRECT_URI'] );
+ $result = $api->get_access_token_by_api_key_and_secret(
+ $_ENV['CONVERTKIT_API_KEY'],
+ $_ENV['CONVERTKIT_API_SECRET']
+ );
+ $this->assertInstanceOf(WP_Error::class, $result);
+ $this->assertEquals($result->get_error_code(), $this->errorCode);
+ }
+
/**
* Test that supplying valid API credentials to the API class returns the expected account information.
*
@@ -756,8 +788,9 @@ public function testGetGrowthStatsWithStartDate()
$this->assertArrayHasKey('ending', $result['stats']);
// Assert start and end dates were honored.
- $this->assertEquals($result['stats']['starting'], $starting->format('Y-m-d') . 'T00:00:00-05:00');
- $this->assertEquals($result['stats']['ending'], $ending->format('Y-m-d') . 'T23:59:59-05:00');
+ $timezone = ( new DateTime() )->setTimezone(new DateTimeZone('America/New_York'))->format('P'); // Gets timezone offset for New York (-04:00 during DST, -05:00 otherwise).
+ $this->assertEquals($result['stats']['starting'], $starting->format('Y-m-d') . 'T00:00:00' . $timezone);
+ $this->assertEquals($result['stats']['ending'], $ending->format('Y-m-d') . 'T23:59:59' . $timezone);
}
/**
@@ -790,8 +823,9 @@ public function testGetGrowthStatsWithEndDate()
$this->assertArrayHasKey('ending', $result['stats']);
// Assert start and end dates were honored.
- $this->assertEquals($result['stats']['starting'], $starting->format('Y-m-d') . 'T00:00:00-05:00');
- $this->assertEquals($result['stats']['ending'], $ending->format('Y-m-d') . 'T23:59:59-05:00');
+ $timezone = ( new DateTime() )->setTimezone(new DateTimeZone('America/New_York'))->format('P'); // Gets timezone offset for New York (-04:00 during DST, -05:00 otherwise).
+ $this->assertEquals($result['stats']['starting'], $starting->format('Y-m-d') . 'T00:00:00' . $timezone);
+ $this->assertEquals($result['stats']['ending'], $ending->format('Y-m-d') . 'T23:59:59' . $timezone);
}
/**
@@ -1249,7 +1283,7 @@ public function testGetFormSubscriptionsWithBouncedSubscriberState()
*/
public function testGetFormSubscriptionsWithAddedAfterParam()
{
- $date = new \DateTime('2024-01-01');
+ $date = new \DateTime('2022-01-01');
$result = $this->api->get_form_subscriptions(
(int) $_ENV['CONVERTKIT_API_FORM_ID'], // Form ID.
'active', // Subscriber state.
@@ -1312,7 +1346,7 @@ public function testGetFormSubscriptionsWithAddedBeforeParam()
*/
public function testGetFormSubscriptionsWithCreatedAfterParam()
{
- $date = new \DateTime('2024-01-01');
+ $date = new \DateTime('2022-01-01');
$result = $this->api->get_form_subscriptions(
(int) $_ENV['CONVERTKIT_API_FORM_ID'], // Form ID.
'active', // Subscriber state.
@@ -2272,7 +2306,7 @@ public function testGetSequenceSubscriptionsWithBouncedSubscriberState()
*/
public function testGetSequenceSubscriptionsWithAddedAfterParam()
{
- $date = new \DateTime('2024-01-01');
+ $date = new \DateTime('2022-01-01');
$result = $this->api->get_sequence_subscriptions(
$_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID.
'active', // Subscriber state.
@@ -2335,7 +2369,7 @@ public function testGetSequenceSubscriptionsWithAddedBeforeParam()
*/
public function testGetSequenceSubscriptionsWithCreatedAfterParam()
{
- $date = new \DateTime('2024-01-01');
+ $date = new \DateTime('2022-01-01');
$result = $this->api->get_sequence_subscriptions(
$_ENV['CONVERTKIT_API_SEQUENCE_ID'], // Sequence ID.
'active', // Subscriber state.
@@ -2441,7 +2475,7 @@ public function testGetSequenceSubscriptionsPagination()
// Assert has_previous_page and has_next_page are correct.
$this->assertTrue($result['pagination']['has_previous_page']);
- $this->assertTrue($result['pagination']['has_next_page']);
+ $this->assertFalse($result['pagination']['has_next_page']);
// Use pagination to fetch previous page.
$result = $this->api->get_sequence_subscriptions(
@@ -2654,7 +2688,7 @@ public function testCreateTagBlank()
}
/**
- * Test that create_tag() returns a WP_Error when creating
+ * Test that create_tag() returns the expected data when creating
* a tag that already exists.
*
* @since 1.0.0
@@ -2664,8 +2698,12 @@ public function testCreateTagBlank()
public function testCreateTagThatExists()
{
$result = $this->api->create_tag($_ENV['CONVERTKIT_API_TAG_NAME']);
- $this->assertInstanceOf(WP_Error::class, $result);
- $this->assertEquals($result->get_error_code(), $this->errorCode);
+
+ // Assert response contains correct data.
+ $this->assertArrayHasKey('id', $result['tag']);
+ $this->assertArrayHasKey('name', $result['tag']);
+ $this->assertArrayHasKey('created_at', $result['tag']);
+ $this->assertEquals($result['tag']['name'], $_ENV['CONVERTKIT_API_TAG_NAME']);
}
/**
@@ -2734,8 +2772,8 @@ public function testCreateTagsBlank()
}
/**
- * Test that create_tags() returns a WP_Error when creating
- * tags that already exists.
+ * Test that create_tags() returns the expected data when creating
+ * tags that already exist.
*
* @since 2.0.0
*
@@ -2750,8 +2788,10 @@ public function testCreateTagsThatExist()
]
);
- // Assert failures.
- $this->assertCount(2, $result['failures']);
+ // Assert existing tags are returned.
+ $this->assertCount(2, $result['tags']);
+ $this->assertEquals($result['tags'][1]['name'], $_ENV['CONVERTKIT_API_TAG_NAME']);
+ $this->assertEquals($result['tags'][0]['name'], $_ENV['CONVERTKIT_API_TAG_NAME_2']);
}
/**
@@ -3127,7 +3167,7 @@ public function testGetTagSubscriptionsWithBouncedSubscriberState()
*/
public function testGetTagSubscriptionsWithTaggedAfterParam()
{
- $date = new \DateTime('2024-01-01');
+ $date = new \DateTime('2022-01-01');
$result = $this->api->get_tag_subscriptions(
(int) $_ENV['CONVERTKIT_API_TAG_ID'], // Tag ID.
'active', // Subscriber state.
@@ -3190,7 +3230,7 @@ public function testGetTagSubscriptionsWithTaggedBeforeParam()
*/
public function testGetTagSubscriptionsWithCreatedAfterParam()
{
- $date = new \DateTime('2024-01-01');
+ $date = new \DateTime('2022-01-01');
$result = $this->api->get_tag_subscriptions(
(int) $_ENV['CONVERTKIT_API_TAG_ID'], // Tag ID.
'active', // Subscriber state.
@@ -3450,7 +3490,7 @@ public function testGetSubscribersWithBouncedSubscriberState()
*/
public function testGetSubscribersWithCreatedAfterParam()
{
- $date = new \DateTime('2024-01-01');
+ $date = new \DateTime('2022-01-01');
$result = $this->api->get_subscribers(
'active', // Subscriber state.
'', // Email address.
@@ -3507,7 +3547,7 @@ public function testGetSubscribersWithCreatedBeforeParam()
*/
public function testGetSubscribersWithUpdatedAfterParam()
{
- $date = new \DateTime('2024-01-01');
+ $date = new \DateTime('2022-01-01');
$result = $this->api->get_subscribers(
'active', // Subscriber state.
'', // Email address.