diff --git a/.github/workflows/test-php.yml b/.github/workflows/test-php.yml index 05a8b9eb6..3fdd05842 100644 --- a/.github/workflows/test-php.yml +++ b/.github/workflows/test-php.yml @@ -33,30 +33,18 @@ jobs: - name: Run PHPCS run: composer run lint - phpunit: - name: Phpunit + phpstan: + name: PHPStan runs-on: ubuntu-latest if: github.event.pull_request.draft == false && github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name - services: - mysql: - image: mysql:5.7 - env: - MYSQL_ROOT_PASSWORD: root - ports: - - 3306/tcp - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - name: Setup PHP version - uses: shivammathur/setup-php@v1 + uses: shivammathur/setup-php@v2 with: - php-version: '7.2' + php-version: '7.4' extensions: simplexml, mysql - tools: phpunit:7.5.15 - name: Checkout source code uses: actions/checkout@v2 - - name: Install WordPress Test Suite - run: | - bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1:${{ job.services.mysql.ports['3306'] }} - name: Get Composer Cache Directory id: composer-cache run: | @@ -70,33 +58,55 @@ jobs: ${{ runner.os }}-composer- - name: Install composer run: composer install --prefer-dist --no-progress --no-suggest - - name: Run phpunit - run: phpunit + - name: PHPStan Static Analysis + run: composer phpstan - phpstan: - name: PHPStan + unit: + name: UnitTests runs-on: ubuntu-latest if: github.event.pull_request.draft == false && github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name steps: - - name: Setup PHP version - uses: shivammathur/setup-php@v2 - with: - php-version: '7.4' - extensions: simplexml, mysql - - name: Checkout source code - uses: actions/checkout@v2 + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + - name: Get Composer Cache Directory id: composer-cache run: | echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Setup Composer cache - uses: actions/cache@v1 + + # setup the composer cache (vendor) with github actions cache and the cache dir defined in the previous step + - uses: actions/cache@v1 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: | ${{ runner.os }}-composer- + + # run composer install - name: Install composer run: composer install --prefer-dist --no-progress --no-suggest - - name: PHPStan Static Analysis - run: composer phpstan + + - name: Create License File + run: | + printf "{\"key\":\"${{ secrets.OTTER_PRO_LICENSE }}\"}" > license.json + + # setup the node cache (node_modules) with github actions cache + - name: Cache Node - npm + uses: actions/cache@v1 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-cache- + + - name: npm ci + run: | + npm ci + + - name: Setup WP Env + run: | + npm run test:unit:php:setup + + - name: Run PHP Unit Tests + run: | + npm run test:unit:php:base diff --git a/.gitignore b/.gitignore index 01f932c40..b9b0f397c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ artifacts *.results.json trace.json license.json +.phpunit.result.cache .fleet diff --git a/inc/plugins/class-block-conditions.php b/inc/plugins/class-block-conditions.php index 146cd6008..d49c10cdd 100644 --- a/inc/plugins/class-block-conditions.php +++ b/inc/plugins/class-block-conditions.php @@ -42,38 +42,49 @@ public function init() { */ public function render_blocks( $block_content, $block ) { if ( ! is_admin() && ! ( defined( 'REST_REQUEST' ) && REST_REQUEST ) && isset( $block['attrs']['otterConditions'] ) ) { - $display = true; + $display = $this->evaluate_condition_collection( $block['attrs']['otterConditions'] ); - foreach ( $block['attrs']['otterConditions'] as $group ) { - if ( 0 === count( $group ) ) { - continue; - } + if ( false === $display ) { + return; + } + } - $visibility = true; + return $block_content; + } - foreach ( $group as $condition ) { - if ( ! $this->evaluate_condition( $condition ) ) { - $visibility = false; - } - } + /** + * Evaluate conditions + * + * @param array $collection The conditions collection to evaluate. + * @return bool Whether the conditions are met. + */ + public function evaluate_condition_collection( $collection ) { + $display = true; - if ( true === $visibility ) { - $display = true; - break; - } + foreach ( $collection as $group ) { + if ( 0 === count( $group ) ) { + continue; + } + $visibility = true; - if ( false === $visibility ) { - $display = false; + foreach ( $group as $condition ) { + if ( ! $this->evaluate_condition( $condition ) ) { + $visibility = false; } } - if ( false === $display ) { - return; + if ( true === $visibility ) { + $display = true; + break; + } + + if ( false === $visibility ) { + $display = false; } } - return $block_content; + return $display; } /** diff --git a/inc/plugins/class-dynamic-content.php b/inc/plugins/class-dynamic-content.php index 9a4124747..2212842c6 100644 --- a/inc/plugins/class-dynamic-content.php +++ b/inc/plugins/class-dynamic-content.php @@ -43,10 +43,49 @@ public function apply_dynamic_content( $content ) { return $content; } + $matches = array(); + $num = self::parse_dynamic_content_query( $content, $matches ); + + if ( isset( $num ) && 0 === $num ) { + return $content; + } + + foreach ( $matches as $match ) { + $replacement = $this->apply_data( $match ); + $string_to_replace = $match[0]; + $position = strstr( $content, $string_to_replace, true ); + + if ( false === $position ) { + continue; + } + + $position = strlen( $position ); + $content = substr_replace( $content, $replacement, $position, strlen( $string_to_replace ) ); + } + + return $content; + } + + /** + * Get the Dynamic Content regex. + * + * @return string + */ + public static function dynamic_content_regex() { // Todo: Improve this Regex, it can't go on for like this. Soon it will be longer than the available space in the universe!!! - $re = '/[^"\'<>]+)["\']|data-id=["\'](?P[^"\'<>]+)["\']|data-before=["\'](?P[^"\'<>]+)["\']|data-after=["\'](?P[^"\'<>]+)["\']|data-length=["\'](?P[^"\'<>]+)["\']|data-date-type=["\'](?P[^"\'<>]+)["\']|data-date-format=["\'](?P[^"\'<>]+)["\']|data-date-custom=["\'](?P[^"\'<>]+)["\']|data-time-type=["\'](?P[^"\'<>]+)["\']|data-time-format=["\'](?P[^"\'<>]+)["\']|data-time-custom=["\'](?P[^"\'<>]+)["\']|data-term-type=["\'](?P[^"\'<>]+)["\']|data-term-separator=["\'](?P[^"\'<>]+)["\']|data-meta-key=["\'](?P[^"\'<>]+)["\']|data-parameter=["\'](?P[^"\'<>]+)["\']|data-format=["\'](?P[^"\'<>]+)["\']|data-context=["\'](?P[^"\'<>]+)["\']|data-taxonomy=["\'](?P[^"\'<>]+)["\']|[a-zA-Z-]+=["\'][^"\'<>]+["\']))*\s*>(?[^ $].*?)<\s*\/\s*o-dynamic>/'; + return '/[^"\'<>]+)["\']|data-id=["\'](?P[^"\'<>]+)["\']|data-before=["\'](?P[^"\'<>]+)["\']|data-after=["\'](?P[^"\'<>]+)["\']|data-length=["\'](?P[^"\'<>]+)["\']|data-date-type=["\'](?P[^"\'<>]+)["\']|data-date-format=["\'](?P[^"\'<>]+)["\']|data-date-custom=["\'](?P[^"\'<>]+)["\']|data-time-type=["\'](?P[^"\'<>]+)["\']|data-time-format=["\'](?P[^"\'<>]+)["\']|data-time-custom=["\'](?P[^"\'<>]+)["\']|data-term-type=["\'](?P[^"\'<>]+)["\']|data-term-separator=["\'](?P[^"\'<>]+)["\']|data-meta-key=["\'](?P[^"\'<>]+)["\']|data-parameter=["\'](?P[^"\'<>]+)["\']|data-format=["\'](?P[^"\'<>]+)["\']|data-context=["\'](?P[^"\'<>]+)["\']|data-taxonomy=["\'](?P[^"\'<>]+)["\']|[a-zA-Z-]+=["\'][^"\'<>]+["\']))*\s*>(?[^ $].*?)<\s*\/\s*o-dynamic>/'; + } - return preg_replace_callback( $re, array( $this, 'apply_data' ), $content ); + /** + * Parse dynamic content query. + * + * @param string $content The content to parse. + * @param array $matches The matches. + * @return mixed + */ + public static function parse_dynamic_content_query( $content, &$matches ) { + $re = self::dynamic_content_regex(); + return preg_match_all( $re, $content, $matches, PREG_SET_ORDER, 0 ); } /** diff --git a/inc/plugins/class-stripe-api.php b/inc/plugins/class-stripe-api.php index 6fcb73de8..7babe4236 100644 --- a/inc/plugins/class-stripe-api.php +++ b/inc/plugins/class-stripe-api.php @@ -7,6 +7,7 @@ namespace ThemeIsle\GutenbergBlocks\Plugins; +use Stripe\Collection; use Stripe\StripeClient; /** @@ -108,7 +109,7 @@ public function build_error_response( $error ) { * @param string $path Request path. * @param array|string $args Request arguments. * - * @return mixed + * @return mixed|\WP_Error|Collection * @access public */ public function create_request( $path, $args = array() ) { @@ -237,7 +238,7 @@ public function save_customer_data( $session_id ) { array_push( $data, $object ); - if ( defined( 'COOKIEPATH' ) && defined( 'COOKIE_DOMAIN' ) && ! $user_id ) { + if ( defined( 'COOKIEPATH' ) && defined( 'COOKIE_DOMAIN' ) && ! headers_sent() && ! $user_id ) { setcookie( 'o_stripe_data', wp_json_encode( $data ), strtotime( '+1 week' ), COOKIEPATH, COOKIE_DOMAIN, false ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.cookies_setcookie return; } diff --git a/package.json b/package.json index 1d05dc4c9..23aeb680b 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,18 @@ "test:e2e:blockId": "wp-scripts test-e2e uniq-id-checking.spec.js", "test:e2e:playwright": "npx playwright test --config src/blocks/test/e2e/playwright.config.js", "test:e2e:playwright-ui": "npx playwright test --config src/blocks/test/e2e/playwright.config.js --ui", + "test:unit:php:setup": "wp-env start", + "test:unit:php:setup:debug": "wp-env start --xdebug", + "test:unit:php:base": "wp-env run --env-cwd='wp-content/plugins/otter-blocks' tests-wordpress vendor/bin/phpunit -c phpunit.xml --verbose", + "test:unit:php": "npm-run-all test:unit:php:setup test:unit:php:base", + "test:unit:php:debug": "npm-run-all test:unit:php:setup:debug test:unit:php:base", + "test:unit:php:multisite:base": "wp-env run --env-cwd='wp-content/plugins/otter-blocks' tests-wordpress vendor/bin/phpunit -c phpunit/multisite.xml --verbose", + "test:unit:php:multisite": "npm-run-all test:unit:php:setup test:unit:php:multisite:base", + "test:unit:php:multisite:debug": "npm-run-all test:unit:php:setup:debug test:unit:php:multisite:base", + "test:php": "npm-run-all lint:php test:unit:php", + "test:php:watch": "wp-env run --env-cwd='wp-content/plugins/otter-blocks' tests-cli composer run-script test:watch", + "lint:php": "wp-env run --env-cwd='wp-content/plugins/otter-blocks' cli composer run-script lint", + "format:php": "wp-env run --env-cwd='wp-content/plugins/otter-blocks' cli composer run-script format", "wp-env": "wp-env" }, "repository": { diff --git a/tests/bootstrap.php b/tests/bootstrap.php index deff6ffd3..96ff47338 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -21,7 +21,16 @@ // Start up the WP testing environment. require $_tests_dir . '/includes/bootstrap.php'; +if ( ! defined( 'OTTER_BLOCKS_VERSION' ) ) { + define('OTTER_BLOCKS_VERSION', '1.0.0'); +} + +require dirname( dirname( __FILE__ ) ) . '/tests/stripe-http-client-mock.php'; require dirname( dirname( __FILE__ ) ) . '/inc/css/class-css-utility.php'; +require dirname( dirname( __FILE__ ) ) . '/inc/plugins/class-block-conditions.php'; +require dirname( dirname( __FILE__ ) ) . '/inc/plugins/class-dynamic-content.php'; +require dirname( dirname( __FILE__ ) ) . '/plugins/otter-pro/inc/plugins/class-block-conditions.php'; +require dirname( dirname( __FILE__ ) ) . '/plugins/otter-pro/inc/plugins/class-dynamic-content.php'; global $current_user; $current_user = new WP_User( 1 ); diff --git a/tests/stripe-http-client-mock.php b/tests/stripe-http-client-mock.php new file mode 100644 index 000000000..7604c3f30 --- /dev/null +++ b/tests/stripe-http-client-mock.php @@ -0,0 +1,225 @@ +mockProductsList(), 200, null); + } + + if (preg_match('#^/v1/products/\w+$#', $path)) { + return array($this->mockSingleProduct(), 200, null); + } + + if ($path === '/v1/prices') { + return array($this->mockPricesList(), 200, null); + } + + if (preg_match('#^/v1/prices/\w+$#', $path)) { + return array($this->mockSinglePrice($path), 200, null); + } + + if ($path === '/v1/checkout/sessions') { + return array($this->mockCreateSession(), 200, null); + } + + if (preg_match('#^/v1/checkout/sessions/\w+/line_items$#', $path)) { + return array($this->mockSessionItems($path), 200, null); + } + + if (preg_match('#^/v1/checkout/sessions/\w+$#', $path)) { + return array($this->mockGetSession($path), 200, null); + } + + if (preg_match('#^/v1/subscriptions/\w+$#', $path)) { + return array($this->mockGetSubscription($path), 200, null); + } + + return [ + $this->mockProductsList(), + '200', + null + ]; + } + + private function mockProductsList() + { + return json_encode( + [ + 'object' => 'list', + 'data' => [ + [ + 'id' => 'prod_1', + 'name' => 'Laptop', + 'description' => 'High-performance laptop', + 'price' => 1200, + 'currency' => 'USD', + 'active' => true + ], + [ + 'id' => 'prod_2', + 'name' => 'Smartphone', + 'description' => 'Latest model smartphone', + 'price' => 800, + 'currency' => 'USD', + 'active' => true + ], + [ + 'id' => 'prod_3', + 'name' => 'Headphones', + 'description' => 'Noise-cancelling headphones', + 'price' => 300, + 'currency' => 'USD', + 'active' => false + ] + ], + 'has_more' => false + ] + ); + } + + private function mockSingleProduct() + { + return json_encode( + [ + 'id' => 'prod_1', + 'name' => 'Laptop', + 'description' => 'High-performance laptop', + 'price' => 1200, + 'currency' => 'USD', + 'active' => true, + 'object' => 'product' + ] + ); + } + + private function mockPricesList() + { + return json_encode( + [ + 'object' => 'list', + 'data' => [ + [ + 'id' => 'price_1', + 'product' => 'prod_1', + 'unit_amount' => 1000 + ], + [ + 'id' => 'price_2', + 'product' => 'prod_2', + 'unit_amount' => 2000 + ] + ] + ] + ); + } + + private function mockSinglePrice() + { + return json_encode( + [ + 'id' => 'price_1', + 'product' => 'prod_1', + 'unit_amount' => 1000, + 'currency' => 'USD', + 'object' => 'price', + 'active' => true, + 'billing_scheme' => 'per_unit', + ] + ); + } + + private function mockCreateSession() + { + return json_encode( + [ + 'object' => 'object', + 'data' => [ + 'id' => 'sess_1', + 'status' => 'created' + ] + ] + ); + } + + private function mockGetSession() + { + return json_encode( + [ + 'id' => 'sess_1', + 'status' => 'complete', + 'customer' => 'cus_1', + 'customer_details' => [ + 'email' => 'test@test.com' + ], + 'mode' => 'payment', + 'payment_status' => 'paid', + 'payment_intent' => 'pi_1', + 'object' => 'checkout.session', + 'success_url' => 'https://example.com/success?product_id=prod_1', + 'complete' => true + ] + ); + } + + private function mockSessionItems() + { + return json_encode( + [ + 'object' => 'list', + 'data' => [ + [ + 'id' => 'item_1', + 'quantity' => 1, + 'object' => 'item', + 'price' => [ + 'id' => 'price_1', + 'product' => 'prod_1', + 'unit_amount' => 1000, + 'currency' => 'USD', + 'object' => 'price', + 'active' => true, + 'billing_scheme' => 'per_unit', + ] + ], + [ + 'id' => 'item_2', + 'quantity' => 2, + 'object' => 'item', + 'price' => [ + 'id' => 'price_1', + 'product' => 'prod_1', + 'unit_amount' => 1000, + 'currency' => 'USD', + 'object' => 'price', + 'active' => true, + 'billing_scheme' => 'per_unit', + ] + ] + ] + ] + ); + } + + private function mockGetSubscription() + { + return json_encode(array( + 'id' => 'sub_1', + 'status' => 'active' + )); + } +} + diff --git a/tests/test-block-conditions.php b/tests/test-block-conditions.php new file mode 100644 index 000000000..db0489eca --- /dev/null +++ b/tests/test-block-conditions.php @@ -0,0 +1,485 @@ +block_conditions = new Block_Conditions(); + $this->otter_pro_blocks_conditions = new \ThemeIsle\OtterPro\Plugins\Block_Conditions(); + $this->user_id = wp_create_user( 'test_user_deletion', 'userlogin', 'test@userrecover.com' ); + + $this->block_conditions->init(); + + /** + * Create a test post. + */ + $this->post_id = $this->factory()->post->create(); + $this->category_slug = 'test-category'; + $this->category_id = $this->factory()->category->create( + array( + 'name' => 'Test Category', + 'slug' => $this->category_slug, + ) + ); + + wp_update_post( + array( + 'ID' => $this->post_id, + 'post_author' => $this->user_id, + 'post_type' => 'post', + 'post_category' => array( $this->category_id ), + ) + ); + + // Add some meta values to the post. + update_post_meta( $this->post_id, 'test_meta', 'test' ); + + // Add some meta to the user. + update_user_meta( $this->user_id, 'test_meta', 'test' ); + + // Set the post as the current post. + $this->go_to( get_permalink( $this->post_id ) ); + } + + public function tear_down() + { + wp_delete_user( $this->user_id, true ); + wp_delete_post( $this->post_id, true ); + wp_delete_term( $this->category_id, 'category' ); + parent::tear_down(); + } + + /** + * Test logged-in user when user is logged in. + */ + public function test_logged_in_user_on_login() { + wp_set_current_user( $this->user_id ); + + $condition = array( + 'type' => 'loggedInUser', + ); + + $result = $this->block_conditions->evaluate_condition( $condition ); + + $this->assertTrue( $result ); + } + + /** + * Test logged-in user when user is not logged in. + */ + public function test_logged_in_user_on_logout() { + + $condition = array( + 'type' => 'loggedInUser', + ); + + wp_set_current_user( 0 ); + + $result = $this->block_conditions->evaluate_condition( $condition ); + + $this->assertFalse( $result ); + } + + /** + * Test logged-out user when user is logged in. + */ + public function test_logged_out_user_on_login() { + wp_set_current_user( $this->user_id ); + + $condition = array( + 'type' => 'loggedOutUser', + ); + + $result = $this->block_conditions->evaluate_condition( $condition ); + + $this->assertFalse( $result ); + } + + /** + * Test logged-out user when user is not logged in. + */ + public function test_logged_out_user_on_logout() { + + $condition = array( + 'type' => 'loggedOutUser', + ); + + wp_set_current_user( 0 ); + + $result = $this->block_conditions->evaluate_condition( $condition ); + + $this->assertTrue( $result ); + } + + /** + * Test user roles when user has the role. + */ + public function test_user_roles_has_role() { + wp_set_current_user( $this->user_id ); + $user = wp_get_current_user(); + $user->set_role( 'administrator' ); + + $condition = array( + 'type' => 'userRoles', + 'roles' => array( 'administrator' ), + ); + + $result = $this->block_conditions->evaluate_condition( $condition ); + + $this->assertTrue( $result ); + } + + /** + * Test user roles when user does not have the role. + */ + public function test_user_roles_does_not_have_role() { + wp_set_current_user( $this->user_id ); + $user = wp_get_current_user(); + $user->set_role( 'administrator' ); + + $condition = array( + 'type' => 'userRoles', + 'roles' => array( 'editor' ), + ); + + $result = $this->block_conditions->evaluate_condition( $condition ); + + $this->assertFalse( $result ); + } + + /** + * Test the post type condition. + */ + public function test_post_type() { + + $condition = array( + 'type' => 'postType', + 'post_types' => array( 'post' ), + ); + + $result = $this->block_conditions->evaluate_condition( $condition ); + + $this->assertTrue( $result ); + } + + /** + * Test the post type condition on invalid post type. + */ + public function test_post_type_on_invalid() { + + $condition = array( + 'type' => 'postType', + 'post_types' => array( 'test' ), + ); + + $result = $this->block_conditions->evaluate_condition( $condition ); + + $this->assertFalse( $result ); + } + + /** + * Test the post category condition. + */ + public function test_post_category() { + + $condition = array( + 'type' => 'postCategory', + 'categories' => array( $this->category_slug ), + ); + + $result = $this->block_conditions->evaluate_condition( $condition ); + + $this->assertTrue( $result ); + } + + /** + * Test the post category condition on invalid category. + */ + public function test_post_category_on_invalid() { + + $condition = array( + 'type' => 'postCategory', + 'categories' => array( 'invalid' ), + ); + + $result = $this->block_conditions->evaluate_condition( $condition ); + + $this->assertFalse( $result ); + } + + /** + * Test logged in user meta. + */ + public function test_logged_in_user_meta() { + wp_set_current_user( $this->user_id ); + + $condition = array( + 'type' => 'loggedInUserMeta', + 'meta_key' => 'test_meta', + 'meta_compare' => 'is_true', + ); + + $result = $this->otter_pro_blocks_conditions->evaluate_condition( true, $condition, true ); + + $this->assertTrue( $result ); + } + + /** + * Test logged in user meta. + */ + public function test_logged_in_user_meta_invalid() { + wp_set_current_user( $this->user_id ); + + $condition = array( + 'type' => 'loggedInUserMeta', + 'meta_key' => 'test_', + 'meta_compare' => 'is_true', + ); + + $result = $this->otter_pro_blocks_conditions->evaluate_condition( true, $condition, true ); + + $this->assertFalse( $result ); + } + + /** + * Test post meta. + */ + public function test_post_meta() { + wp_set_current_user( $this->user_id ); + + $condition = array( + 'type' => 'postMeta', + 'meta_key' => 'test_meta', + 'meta_compare' => 'is_true', + ); + + $result = $this->otter_pro_blocks_conditions->evaluate_condition( true, $condition, true ); + + $this->assertTrue( $result ); + } + + /** + * Test post meta. + */ + public function test_post_meta_invalid() { + wp_set_current_user( $this->user_id ); + + $condition = array( + 'type' => 'postMeta', + 'meta_key' => 'test_', + 'meta_compare' => 'is_true', + ); + + $result = $this->otter_pro_blocks_conditions->evaluate_condition( true, $condition, true ); + + $this->assertFalse( $result ); + } + + /** + * Test data range. + */ + public function test_date_range() { + + $condition = array( + 'type' => 'dateRange', + 'start_date' => '2020-01-01', + 'end_date' => '2030-12-31', + ); + + $result = $this->otter_pro_blocks_conditions->evaluate_condition( true, $condition, true ); + + $this->assertTrue( $result ); + } + + /** + * Test data range. + */ + public function test_date_range_invalid() { + + $condition = array( + 'type' => 'dateRange', + 'start_date' => '2020-01-01', + 'end_date' => '2020-12-31', + ); + + $result = $this->otter_pro_blocks_conditions->evaluate_condition( true, $condition, true ); + + $this->assertFalse( $result ); + } + + /** + * Test the date reccuring condition. + */ + public function test_date_recurring() { + $condition = array( + 'type' => 'dateRecurring', + 'days' => array( 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday' ), + ); + + $result = $this->otter_pro_blocks_conditions->evaluate_condition( true, $condition, true ); + + $this->assertTrue( $result ); + } + + /** + * Test multiple conditions. + */ + public function test_multiple_conditions() { + + $this->go_to( get_permalink( $this->post_id ) ); + wp_set_current_user( $this->user_id ); + + $collection = array( + array( + array( + 'type' => 'loggedInUser', + ), + array( + 'type' => 'postType', + 'post_types' => array( 'post' ), + ), + ) + ); + + $result = $this->block_conditions->evaluate_condition_collection( $collection ); + + $this->assertTrue( $result ); + } + + + /** + * Test multiple conditions. + */ + public function test_multiple_conditions__with_one_invalid() { + $this->go_to( get_permalink( $this->post_id ) ); + wp_set_current_user( 0 ); + + $collection = array( + array( + array( + 'type' => 'loggedInUser', + ), + array( + 'type' => 'postType', + 'post_types' => array( 'post' ), + ), + ), + ); + + $result = $this->block_conditions->evaluate_condition_collection( $collection ); + + $this->assertFalse( $result ); + } + + /** + * Test multiple conditions. + */ + public function test_multiple_conditions_with_all_invalid() { + $this->go_to( get_permalink( $this->post_id ) ); + wp_set_current_user( 0 ); + + $collection = array( + array( + array( + 'type' => 'loggedInUser', + ), + array( + 'type' => 'postType', + 'post_types' => array( 'test_17' ), + ), + ), + ); + + $result = $this->block_conditions->evaluate_condition_collection( $collection ); + + $this->assertFalse( $result ); + } + + /** + * Test OR collection. + */ + public function test_or_collection() { + $this->go_to( get_permalink( $this->post_id ) ); + + $collection = array( + array( + array( + 'type' => 'postType', + 'post_types' => array( 'post' ), + ), + ), + array( + array( + 'type' => 'postType', + 'post_types' => array( 'test_17' ), + ), + ), + ); + + $result = $this->block_conditions->evaluate_condition_collection( $collection ); + + $this->assertTrue( $result ); + } + + /** + * Test OR collection. All invalid + */ + public function test_or_collection_invalid() { + $this->go_to( get_permalink( $this->post_id ) ); + + $collection = array( + array( + array( + 'type' => 'postType', + 'post_types' => array( 'post_42' ), + ), + ), + array( + array( + 'type' => 'postType', + 'post_types' => array( 'test_17' ), + ), + ), + ); + + $result = $this->block_conditions->evaluate_condition_collection( $collection ); + + $this->assertFalse( $result ); + } +} diff --git a/tests/test-dynamic-content.php b/tests/test-dynamic-content.php new file mode 100644 index 000000000..8b008c72a --- /dev/null +++ b/tests/test-dynamic-content.php @@ -0,0 +1,687 @@ +dynamic_content = new Dynamic_Content(); + $this->dynamic_content_pro = new \ThemeIsle\OtterPro\Plugins\Dynamic_Content(); + $this->user_id = wp_create_user( 'test_user_deletion', 'userlogin', 'test@userrecover.com' ); + + + /** + * Create a test post. + */ + $this->post_id = $this->factory()->post->create(); + $this->category_slug = 'test-category'; + $this->category_id = $this->factory()->category->create( + array( + 'name' => 'Test Category', + 'slug' => $this->category_slug, + ) + ); + + wp_update_post( + array( + 'ID' => $this->post_id, + 'post_author' => $this->user_id, + 'post_type' => 'post', + 'post_category' => array( $this->category_id ), + 'post_title' => 'Test', + 'post_content' => 'Test', + 'post_status' => 'publish', + 'post_excerpt' => 'Test', + ) + ); + + // Add some meta values to the post. + update_post_meta( $this->post_id, 'test_meta', 'test' ); + + // Add some meta to the user. + update_user_meta( $this->user_id, 'test_meta', 'test' ); + + // Set the post as the current post. + $this->go_to( get_permalink( $this->post_id ) ); + } + + /** + * Tear down the test. + */ + public function tear_down() { + wp_delete_user( $this->user_id, true ); + wp_delete_post( $this->post_id, true ); + wp_delete_term( $this->category_id, 'category' ); + parent::tear_down(); + } + + /** + * Test the Post ID query. + */ + public function test_post_id() { + + $post_id_query = '

Post ID

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $post_id_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'postID', $result['type'] ); + } + + /** + * Test the Post Type query. + */ + public function test_post_type() { + $post_type_query = '

Post Type

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $post_type_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'postType', $result['type'] ); + } + + /** + * Test the Post Title query. + */ + public function test_post_title() { + $post_title_query = '

Post Title

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $post_title_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'postTitle', $result['type'] ); + } + + /** + * Test the Post Status query. + */ + public function test_post_status() { + $post_status_query = '

Post Status

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $post_status_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'postStatus', $result['type'] ); + } + + /** + * Test the Post Content query. + */ + public function test_post_content() { + $post_content_query = '

Post Content

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $post_content_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'postContent', $result['type'] ); + } + + /** + * Test the Post Excerpt query. + */ + public function test_post_excerpt() { + $post_excerpt_query = '

Advanced Custom Fields

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $post_excerpt_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'postExcerpt', $result['type'] ); + $this->assertEquals( '500', $result['length'] ); + $this->assertEquals( 'before', $result['before'] ); + $this->assertEquals( 'after', $result['after'] ); + } + + /** + * Test the Post Date query. + */ + public function test_post_date() { + $post_date_query = '

Post Date

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $post_date_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'postDate', $result['type'] ); + } + + /** + * Test the Post Time query. + */ + public function test_post_time() { + $post_time_query = '

Post Time

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $post_time_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'postTime', $result['type'] ); + $this->assertEquals( 'modified', $result['timeType'] ); + $this->assertEquals( 'custom', $result['timeFormat'] ); + $this->assertEquals( 'H:i', $result['timeCustom'] ); + } + + /** + * Test the Post Terms query. + */ + public function test_post_terms() { + $post_terms_query = '

Post Terms

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $post_terms_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'postTerms', $result['type'] ); + $this->assertEquals( 'custom', $result['termType'] ); + $this->assertEquals( 'categories', $result['taxonomy'] ); + $this->assertEquals( '-', $result['termSeparator'] ); + $this->assertEquals( 'before', $result['before'] ); + $this->assertEquals( 'after', $result['after'] ); + } + + /** + * Test the Post Meta query. + */ + public function test_post_meta() { + $post_meta_query = '

Post Custom Field

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $post_meta_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'postMeta', $result['type'] ); + $this->assertEquals( 'test', $result['metaKey'] ); + $this->assertEquals( 'before', $result['before'] ); + $this->assertEquals( 'after', $result['after'] ); + } + + /** + * Test the Advanced Custom Fields query. + */ + public function test_acf() { + $acf_query = '

Advanced Custom Fields

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $acf_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'acf', $result['type'] ); + $this->assertEquals( 'field_646f643a407bf', $result['metaKey'] ); + $this->assertEquals( 'before', $result['before'] ); + $this->assertEquals( 'after', $result['after'] ); + } + + /** + * Test the Site Title query. + */ + public function test_site_title() { + $site_title_query = '

Site Title

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $site_title_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'siteTitle', $result['type'] ); + } + + /** + * Test the Site Tagline query. + */ + public function test_site_tagline() { + $site_tagline_query = '

Site Tagline

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $site_tagline_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'siteTagline', $result['type'] ); + } + + /** + * Test the Author Name query. + */ + public function test_author_name() { + $author_name_query = '

Author Name

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $author_name_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'authorName', $result['type'] ); + } + + /** + * Test the Author Description query. + */ + public function test_author_description() { + $author_description_query = '

Author Description

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $author_description_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'authorDescription', $result['type'] ); + } + + /** + * Test the Author Meta query. + */ + public function test_author_meta() { + $author_meta_query = '

Author Meta

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $author_meta_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'authorMeta', $result['type'] ); + $this->assertEquals( 'display_name', $result['metaKey'] ); + } + + /** + * Test the Logged In User Name query. + */ + public function test_logged_in_user_name() { + $logged_in_user_name_query = '

Logged In User Name

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $logged_in_user_name_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'loggedInUserName', $result['type'] ); + } + + /** + * Test the Logged In User Description query. + */ + public function test_logged_in_user_description() { + $logged_in_user_description_query = '

Logged In User Description

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $logged_in_user_description_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'loggedInUserDescription', $result['type'] ); + } + + /** + * Test for the Logged In User Email query. + */ + public function test_logged_in_user_email() { + $logged_in_user_email_query = '

Logged In User Email

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $logged_in_user_email_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'loggedInUserEmail', $result['type'] ); + } + + /** + * Test the Logged In User Meta query. + */ + public function test_logged_in_user_meta() { + $logged_in_user_meta_query = '

Logged In User Meta

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $logged_in_user_meta_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'loggedInUserMeta', $result['type'] ); + $this->assertEquals( 'description', $result['metaKey'] ); + } + + /** + * Test the Archive Title query. + */ + public function test_archive_title() { + $archive_title_query = '

Archive Title

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $archive_title_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'archiveTitle', $result['type'] ); + } + + /** + * Test the Archive Description query. + */ + public function test_archive_description() { + $archive_description_query = '

Archive Description

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $archive_description_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'archiveDescription', $result['type'] ); + } + + /** + * Test the Date query. + */ + public function test_date() { + $date_query = '

Date

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $date_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'date', $result['type'] ); + $this->assertEquals( 'custom', $result['dateFormat'] ); + $this->assertEquals( 'l, F j, Y', $result['dateCustom'] ); + } + + /** + * Test the Time query. + */ + public function test_time() { + $time_query = '

Time

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $time_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'time', $result['type'] ); + $this->assertEquals( 'custom', $result['timeFormat'] ); + $this->assertEquals( 'H:i', $result['timeCustom'] ); + } + + /** + * Test the Query String query. + */ + public function test_query_string() { + $query_string_query = '

Query String

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $query_string_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'queryString', $result['type'] ); + $this->assertEquals( 'capitalize', $result['format'] ); + $this->assertEquals( 'action', $result['parameter'] ); + } + + /** + * Test the Country query. + */ + public function test_country() { + $country_query = '

Country

'; + + $result = array(); + $num = Dynamic_Content::parse_dynamic_content_query( $country_query, $result ); + $this->assertTrue( boolval( $num ) ); + $result = $result[0]; + + $this->assertEquals( 'country', $result['type'] ); + } + + /** + * Test the Post Id evaluation. + */ + public function test_post_id_evaluation() { + // Set the post as the current post. + $this->go_to( get_permalink( $this->post_id ) ); + + $post_id_query = '

Post ID

'; + $result = $this->dynamic_content->apply_dynamic_content( $post_id_query ); + + $this->assertEquals( '

' . $this->post_id . '

', $result ); + } + + /** + * Test the Post Type evaluation. + */ + public function test_post_type_evaluation() { + // Set the post as the current post. + $this->go_to( get_permalink( $this->post_id ) ); + + $post_type_query = '

Post Type

'; + $result = $this->dynamic_content->apply_dynamic_content( $post_type_query ); + + $this->assertEquals( '

post

', $result ); + } + + /** + * Test the Post Title evaluation. + */ + public function test_post_title_evaluation() { + // Set the post as the current post. + $this->go_to( get_permalink( $this->post_id ) ); + + $post_title_query = '

Post Title

'; + $result = $this->dynamic_content->apply_dynamic_content( $post_title_query ); + + $this->assertEquals( '

Test

', $result ); + } + + /** + * Test the Post Status evaluation. + */ + public function test_post_status_evaluation() { + // Set the post as the current post. + $this->go_to( get_permalink( $this->post_id ) ); + + $post_status_query = '

Post Status

'; + $result = $this->dynamic_content->apply_dynamic_content( $post_status_query ); + + $this->assertEquals( '

publish

', $result ); + } + + /** + * Test the Post Content evaluation. + */ + public function test_post_content_evaluation() { + // Set the post as the current post. + $this->go_to( get_permalink( $this->post_id ) ); + + $post_content_query = '

Post Content

'; + $result = $this->dynamic_content->apply_dynamic_content( $post_content_query ); + + $this->assertStringContainsString( '

Test

', $result ); + } + + /** + * Test the Post Excerpt evaluation. + */ + public function test_post_excerpt_evaluation() { + // Set the post as the current post. + $this->go_to( get_permalink( $this->post_id ) ); + + $post_excerpt_query = '

Advanced Custom Fields

'; + $result = $this->dynamic_content->apply_dynamic_content( $post_excerpt_query ); + + $this->assertEquals( '

before-Test…-after

', $result ); + } + + /** + * Test the Logger In User Name evaluation. + */ + public function test_logged_in_user_name_evaluation() { + // Set the user as the current user. + wp_set_current_user( $this->user_id ); + + $logged_in_user_name_query = '

Logged In User Name

'; + $result = $this->dynamic_content->apply_dynamic_content( $logged_in_user_name_query ); + + $this->assertEquals( '

test_user_deletion

', $result ); + } + + /** + * Test the Logger In User Description evaluation. + */ + public function test_logged_in_user_description_evaluation() { + // Set the user as the current user. + wp_set_current_user( $this->user_id ); + + $logged_in_user_description_query = '

Logged In User Description

'; + $result = $this->dynamic_content->apply_dynamic_content( $logged_in_user_description_query ); + + $this->assertEquals( '

', $result ); + } + + /** + * Test the Logger In User Email evaluation. + */ + public function test_logged_in_user_email_evaluation() { + // Set the user as the current user. + wp_set_current_user( $this->user_id ); + + $logged_in_user_email_query = '

Logged In User Email

'; + $result = $this->dynamic_content->apply_dynamic_content( $logged_in_user_email_query ); + + $this->assertEquals( '

test@userrecover.com

', $result ); + } + + /** + * Test he Date evaluation. + */ + public function test_date_evaluation() { + // Set the user as the current user. + wp_set_current_user( $this->user_id ); + + $date_query = '

Date

'; + $result = $this->dynamic_content->apply_dynamic_content( $date_query ); + + $this->assertEquals( '

' . date( 'l, F j, Y' ) . '

', $result ); + } + + /** + * Test the Time evaluation. + */ + public function test_time_evaluation() { + // Set the user as the current user. + wp_set_current_user( $this->user_id ); + + $time_query = '

Time

'; + $result = $this->dynamic_content->apply_dynamic_content( $time_query ); + + $this->assertEquals( '

' . date( 'H:i' ) . '

', $result ); + } + + /** + * Test the Author Name evaluation. + */ + public function test_author_name_evaluation() { + // Set the user as the current user. + wp_set_current_user( $this->user_id ); + + $author_name_query = '

Author Name

'; + $result = $this->dynamic_content->apply_dynamic_content( $author_name_query ); + + $this->assertEquals( '

test_user_deletion

', $result ); + } + + /** + * Test the Author Description evaluation. + */ + public function test_author_description_evaluation() { + // Set the user as the current user. + wp_set_current_user( $this->user_id ); + + $author_description_query = '

Author Description

'; + $result = $this->dynamic_content->apply_dynamic_content( $author_description_query ); + + $this->assertEquals( '

', $result ); + } + + /** + * Test multiple dynamic content queries. + */ + public function test_multiple_dynamic_content_queries() { + // Set the post as the current post. + $this->go_to( get_permalink( $this->post_id ) ); + + $multiple_queries = '

This is Post ID

Post Type

'; + $result = $this->dynamic_content->apply_dynamic_content( $multiple_queries ); + + $this->assertEquals( '

This is ' . $this->post_id . '

post

', $result ); + } + + /** + * Test multiple dynamic content queries on a very long content. + */ + public function test_multiple_dynamic_content_queries_on_long_content() { + // Set the post as the current post. + $this->go_to( get_permalink( $this->post_id ) ); + + $padding = str_repeat( ' ', 10000 ); + $multiple_queries = '

This is Post ID' . $padding . '

Post Type

'; + $long_content = str_repeat( $multiple_queries, 100 ); + $result = $this->dynamic_content->apply_dynamic_content( $long_content ); + + $this->assertStringContainsString( '

This is ' . $this->post_id . $padding . '

post

', $result ); + } +} diff --git a/tests/test-patterns-class.php b/tests/test-patterns-class.php new file mode 100644 index 000000000..84089a020 --- /dev/null +++ b/tests/test-patterns-class.php @@ -0,0 +1,44 @@ + get_site_url(), + 'license_id' => $array_data['key'], + 'cache' => gmdate( 'u' ), + ), + 'https://api.themeisle.com/templates-cloud/otter-patterns' + ); + + $response = wp_remote_get( $url ); + $response = wp_remote_retrieve_body( $response ); + + $this->assertTrue( 2000 < strlen( $response ) ); + + $response = json_decode( $response, true ); + + $this->assertIsArray( $response ); + + $this->assertArrayHasKey( 'slug', $response[0] ); + } +} diff --git a/tests/test-stripe-api-class.php b/tests/test-stripe-api-class.php new file mode 100644 index 000000000..be8e62ee2 --- /dev/null +++ b/tests/test-stripe-api-class.php @@ -0,0 +1,112 @@ +stripe_api = new Stripe_API(); + } + + + /** + * Test Stripe products retrieval. + */ + public function test_retrieve_products() { + $products = $this->stripe_api->create_request( + 'products', + array( + 'active' => true, + 'limit' => 50, + ) + ); + + $this->assertIsArray( $products->data ); + } + + /** + * Test Stripe prices retrieval. + */ + public function test_retrieve_prices() { + $prices = $this->stripe_api->create_request( + 'prices', + array( + 'active' => true, + 'limit' => 50, + ) + ); + + $this->assertIsArray( $prices->data ); + } + + /** + * Test Stripe product retrieval. + */ + public function test_retrieve_product() { + $product = $this->stripe_api->create_request('product', 'prod_1' ); + + $this->assertTrue( 'prod_1' === $product['id'] ); + } + + /** + * Test Stripe price retrieval. + */ + public function test_retrieve_price() { + $price = $this->stripe_api->create_request('price', 'price_1' ); + + $this->assertTrue( 'price_1' === $price['id'] ); + } + + /** + * Test get customer email from session. + */ + public function test_retrieve_session_email() { + $this->assertTrue( 'test@test.com' === $this->stripe_api->get_session_email( 'sess_1' ) ); + } + + /** + * Test user purchase. + */ + public function test_user_purchase() { + wp_set_current_user( 1 ); + $this->stripe_api->save_customer_data( 'sess_1' ); + $data = $this->stripe_api->get_customer_data(); + + $this->assertFalse( empty( $data[0]['id'] ) ); + } + + /** + * Test status for price id. + */ + public function test_status_for_price_id() { + $status = $this->stripe_api->get_status_for_price_id( 'sess_1','price_1' ); + + $this->assertTrue( 'success' === $status ); + } +}