diff --git a/.wordpress-org/banner-772x250.png b/.wordpress-org/banner-772x250.png index 0193c68..e4eceba 100644 Binary files a/.wordpress-org/banner-772x250.png and b/.wordpress-org/banner-772x250.png differ diff --git a/.wordpress-org/icon-128x128.png b/.wordpress-org/icon-128x128.png new file mode 100644 index 0000000..d914e92 Binary files /dev/null and b/.wordpress-org/icon-128x128.png differ diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 8c80419..a80920a 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -17,7 +17,7 @@ The Betterlytics plugin stores all settings in a single WordPress option (`bette "track_404": { "enabled": false }, "track_search": { "enabled": false }, "track_downloads": { "enabled": false }, - "track_css_events": { "enabled": false } + "track_custom_html_attribute": { "enabled": false } } ``` @@ -27,7 +27,7 @@ Configure the plugin directly from your deployment scripts: ```bash # Set all options at once (JSON) -wp option update betterlytics_options '{"site_id":"abc123","server_url":"https://analytics.example.com/track","script_url":"https://analytics.example.com/analytics.js","enabled":true}' --format=json +wp option update betterlytics_options '{"site_id":"abc123","server_url":"https://analytics.example.com/event","script_url":"https://analytics.example.com/analytics.js","enabled":true}' --format=json # Or pipe from a config file wp option update betterlytics_options --format=json < betterlytics-config.json @@ -61,12 +61,10 @@ add_action( 'init', function() { } update_option( 'betterlytics_options', [ - 'site_id' => $site_id, - 'server_url' => getenv( 'BETTERLYTICS_SERVER_URL' ) ?: 'https://betterlytics.io/event', - 'script_url' => getenv( 'BETTERLYTICS_SCRIPT_URL' ) ?: 'https://betterlytics.io/analytics.js', - 'enabled' => filter_var( getenv( 'BETTERLYTICS_ENABLED' ) ?: 'true', FILTER_VALIDATE_BOOLEAN ), - 'track_logged_in' => filter_var( getenv( 'BETTERLYTICS_TRACK_LOGGED_IN' ) ?: 'false', FILTER_VALIDATE_BOOLEAN ), - 'hooks' => [], + 'site_id' => $site_id, + 'server_url' => getenv( 'BETTERLYTICS_SERVER_URL' ) ?: 'https://betterlytics.io/event', + 'script_url' => getenv( 'BETTERLYTICS_SCRIPT_URL' ) ?: 'https://betterlytics.io/analytics.js', + 'enabled' => filter_var( getenv( 'BETTERLYTICS_ENABLED' ) ?: 'true', FILTER_VALIDATE_BOOLEAN ), ]); update_option( 'betterlytics_configured_by_env', true ); @@ -81,10 +79,9 @@ services: wordpress: environment: BETTERLYTICS_SITE_ID: "your-site-id" - BETTERLYTICS_SERVER_URL: "https://analytics.example.com/track" + BETTERLYTICS_SERVER_URL: "https://analytics.example.com/event" BETTERLYTICS_SCRIPT_URL: "https://analytics.example.com/analytics.js" BETTERLYTICS_ENABLED: "true" - BETTERLYTICS_TRACK_LOGGED_IN: "false" ``` ## Config File Approach @@ -94,7 +91,7 @@ Keep a `betterlytics-config.json` in your deployment repo for reproducible confi ```json { "site_id": "production-site-id", - "server_url": "https://analytics.example.com/track", + "server_url": "https://analytics.example.com/event", "script_url": "https://analytics.example.com/analytics.js", "enabled": true } diff --git a/Dockerfile.test b/Dockerfile.test index e486ec7..c63733c 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -6,7 +6,6 @@ RUN apt-get update && apt-get install -y \ unzip \ libzip-dev \ default-mysql-client \ - subversion \ && docker-php-ext-install mysqli pdo pdo_mysql zip \ && rm -rf /var/lib/apt/lists/* diff --git a/README.md b/README.md index 7defc56..bff0d61 100644 --- a/README.md +++ b/README.md @@ -20,19 +20,18 @@ Official WordPress plugin for [Betterlytics](https://betterlytics.io) - privacy- ### General Settings -| Setting | Description | -| ------------------------- | ---------------------------------------------------------------------- | -| **Enable Tracking** | Toggle tracking on/off | -| **Site ID** | Your unique Site ID from the Betterlytics dashboard | -| **Server URL** | Tracking endpoint (default: `https://betterlytics.io/event`) | -| **Script URL** | Analytics script URL (default: `https://betterlytics.io/analytics.js`) | -| **Track Logged-in Users** | Include/exclude logged-in users from analytics | +| Setting | Description | +| ------------------- | ---------------------------------------------------------------------- | +| **Enable Tracking** | Toggle tracking on/off | +| **Site ID** | Your unique Site ID from the Betterlytics dashboard | +| **Server URL** | Tracking endpoint (default: `https://betterlytics.io/event`) | +| **Script URL** | Analytics script URL (default: `https://betterlytics.io/analytics.js`) | ### Self-Hosting If you're self-hosting Betterlytics, update the Server URL and Script URL to point to your instance: -- **Server URL**: `https://your-instance.com/track` +- **Server URL**: `https://your-instance.com/event` - **Script URL**: `https://your-instance.com/analytics.js` ### Automated Configuration (CI/CD) @@ -104,7 +103,7 @@ if ( Betterlytics_Options::is_tracking_enabled() ) { ```php $options = Betterlytics_Options::get_options(); -// Returns: site_id, server_url, script_url, enabled, track_logged_in, hooks +// Returns: site_id, server_url, script_url, enabled, track_outbound, etc. // Get a single option $site_id = Betterlytics_Options::get( 'site_id' ); @@ -112,7 +111,7 @@ $site_id = Betterlytics_Options::get( 'site_id' ); ## Requirements -- WordPress 6.0+ +- WordPress 5.0+ - PHP 7.4+ - pnpm 9.0+ (for developers) diff --git a/admin/class-betterlytics-admin.php b/admin/class-betterlytics-admin.php index a6320cf..6e40cf5 100644 --- a/admin/class-betterlytics-admin.php +++ b/admin/class-betterlytics-admin.php @@ -97,11 +97,14 @@ public function sanitize_options( $input ) { $page = isset( $_POST['option_page'] ) ? sanitize_text_field( wp_unslash( $_POST['option_page'] ) ) : ''; if ( 'betterlytics_settings' === $page ) { - $options['enabled'] = ! empty( $input['enabled'] ); - $options['site_id'] = sanitize_text_field( $input['site_id'] ?? '' ); - $options['server_url'] = esc_url_raw( $input['server_url'] ?? 'https://betterlytics.io/event' ); + $options['enabled'] = ! empty( $input['enabled'] ); + $options['site_id'] = sanitize_text_field( $input['site_id'] ?? '' ); + + // Only update URLs if explicitly provided. + if ( ! empty( $input['server_url'] ) ) { + $options['server_url'] = esc_url_raw( $input['server_url'] ); + } - // Allow script_url to be updated programmatically (e.g. config.json) even if hidden in UI. if ( ! empty( $input['script_url'] ) ) { $options['script_url'] = esc_url_raw( $input['script_url'] ); } @@ -109,10 +112,10 @@ public function sanitize_options( $input ) { $options['track_web_vitals'] = ! empty( $input['track_web_vitals'] ); $checkbox_keys = [ - 'track_404' => [ 'enabled' ], - 'track_search' => [ 'enabled', 'include_query' ], - 'track_downloads' => [ 'enabled' ], - 'track_css_events' => [ 'enabled' ], + 'track_404' => [ 'enabled' ], + 'track_search' => [ 'enabled', 'include_query' ], + 'track_downloads' => [ 'enabled' ], + 'track_custom_html_attribute' => [ 'enabled' ], ]; foreach ( $checkbox_keys as $key => $subkeys ) { diff --git a/admin/components/views/settings/betterlytics-page.php b/admin/components/views/settings/betterlytics-page.php index 855f412..f3279ef 100644 --- a/admin/components/views/settings/betterlytics-page.php +++ b/admin/components/views/settings/betterlytics-page.php @@ -162,13 +162,13 @@ Betterlytics_Admin_Controller::render_component( 'ui/setting-row', [ - 'label' => __( 'CSS Class Events', 'betterlytics' ), - 'name' => 'betterlytics_options[track_css_events][enabled]', - 'checked' => ! empty( $betterlytics_options['track_css_events']['enabled'] ), + 'label' => __( 'Custom HTML Attribute Events', 'betterlytics' ), + 'name' => 'betterlytics_options[track_custom_html_attribute][enabled]', + 'checked' => ! empty( $betterlytics_options['track_custom_html_attribute']['enabled'] ), 'description' => sprintf( - /* translators: %s: CSS class example */ - __( 'Track clicks on elements with %s class', 'betterlytics' ), - 'betterlytics-event-name=YourEvent' + /* translators: %s: HTML attribute example */ + __( 'Track clicks on elements with %s attribute', 'betterlytics' ), + 'data-betterlytics-event="some-event-name"' ), 'help_path' => 'integration/custom-events', ] diff --git a/betterlytics.php b/betterlytics.php index 9e5c5c4..868891f 100644 --- a/betterlytics.php +++ b/betterlytics.php @@ -4,7 +4,7 @@ * * @package Betterlytics * @author Betterlytics - * @copyright 2024 Betterlytics + * @copyright 2026 Betterlytics * @license GPL-2.0-or-later * * @wordpress-plugin @@ -12,7 +12,7 @@ * Plugin URI: https://github.com/betterlytics/betterlytics-wordpress * Description: Privacy-first analytics for WordPress. Automatically adds the Betterlytics tracking script and provides easy WordPress action hooks integration. * Version: 1.0.0 - * Requires at least: 6.0 + * Requires at least: 5.0 * Requires PHP: 7.4 * Author: Betterlytics * Author URI: https://betterlytics.io @@ -67,12 +67,9 @@ function betterlytics_plugin_action_links( $links ) { $settings_link = '' . __( 'Settings', 'betterlytics' ) . ''; array_unshift( $links, $settings_link ); - // Add dashboard link if site_id is configured. - $options = get_option( 'betterlytics_options', [] ); - if ( ! empty( $options['site_id'] ) ) { - $dashboard_link = '' . __( 'Dashboard', 'betterlytics' ) . ''; - array_unshift( $links, $dashboard_link ); - } + // Add dashboard link. + $dashboard_link = '' . __( 'Dashboard', 'betterlytics' ) . ''; + array_unshift( $links, $dashboard_link ); return $links; } diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 8c6f14c..6558f78 100644 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -27,20 +27,18 @@ if [ ! -f "$WP_TESTS_DIR/includes/functions.php" ]; then curl --progress-bar https://wordpress.org/latest.tar.gz | tar xz -C "$WP_CORE_DIR" --strip-components=1 echo " Done!" - # Download test suite - echo "[2/4] Downloading test suite includes..." - svn export --force --ignore-externals https://develop.svn.wordpress.org/tags/6.7/tests/phpunit/includes/ "$WP_TESTS_DIR/includes" + # Download test suite from GitHub mirror (more reliable than SVN) + echo "[2/4] Downloading test suite from GitHub..." + WP_DEVELOP_DIR=$(mktemp -d) + git clone --depth=1 --branch=6.7 https://github.com/WordPress/wordpress-develop.git "$WP_DEVELOP_DIR" + cp -r "$WP_DEVELOP_DIR/tests/phpunit/includes" "$WP_TESTS_DIR/includes" + cp -r "$WP_DEVELOP_DIR/tests/phpunit/data" "$WP_TESTS_DIR/data" + cp "$WP_DEVELOP_DIR/wp-tests-config-sample.php" "$WP_TESTS_DIR/wp-tests-config.php" + rm -rf "$WP_DEVELOP_DIR" echo " Done!" - echo "[3/4] Downloading test suite data..." - svn export --force --ignore-externals https://develop.svn.wordpress.org/tags/6.7/tests/phpunit/data/ "$WP_TESTS_DIR/data" - echo " Done!" - - # Download wp-tests-config.php - echo "[4/4] Configuring test environment..." - curl -s https://develop.svn.wordpress.org/tags/6.7/wp-tests-config-sample.php > "$WP_TESTS_DIR/wp-tests-config.php" - # Configure wp-tests-config.php + echo "[3/4] Configuring test environment..." sed -i "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR/wp-tests-config.php" sed -i "s:__DIR__ . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR/wp-tests-config.php" sed -i "s/youremptytestdbnamehere/$WORDPRESS_DB_NAME/" "$WP_TESTS_DIR/wp-tests-config.php" diff --git a/demo/config.json b/demo/config.json index 79e6154..840bf2f 100644 --- a/demo/config.json +++ b/demo/config.json @@ -1,13 +1,13 @@ { - "site_id": "betterlytics-wp-mklt1198", + "site_id": "", "server_url": "http://localhost:3001/event", "script_url": "http://localhost:3006/analytics.js", - "enabled": true, + "enabled": false, "track_web_vitals": false, "track_404": { "enabled": true }, "track_search": { "enabled": true }, "track_outbound": { "mode": "domain" }, "track_downloads": { "enabled": true }, - "track_css_events": { "enabled": true } + "track_custom_html_attribute": { "enabled": true } } diff --git a/demo/mu-plugins/betterlytics-demo.php b/demo/mu-plugins/betterlytics-demo.php index 5434858..c6a0b85 100644 --- a/demo/mu-plugins/betterlytics-demo.php +++ b/demo/mu-plugins/betterlytics-demo.php @@ -156,6 +156,17 @@ function betterlytics_demo_render_test_page( $content ) {

+

HTML Attribute Testing

+
+

Click these buttons to fire custom HTML attributed Betterlytics events:

+ + +
+

WordPress Hook Testing

Post a comment to trigger the comment_post hook:

diff --git a/docker-compose.yml b/docker-compose.yml index 9bcc373..a412cbb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,6 +15,7 @@ services: volumes: - wordpress_data:/var/www/html - .:/var/www/html/wp-content/plugins/betterlytics + - ./demo/mu-plugins:/var/www/html/wp-content/mu-plugins depends_on: db: condition: service_healthy @@ -214,6 +215,11 @@ services: sh -c ' echo "Setting up demo environment..." && + # Enable pretty permalinks + echo "Enabling pretty permalinks..." && + wp rewrite structure "/%postname%/" --hard && + wp rewrite flush --hard && + # Create a demo page for testing custom events if ! wp post list --post_type=page --name=betterlytics-test --format=ids | grep -q .; then echo "Creating test page..." && diff --git a/includes/class-betterlytics-options.php b/includes/class-betterlytics-options.php index bec3ff2..09a2ad2 100644 --- a/includes/class-betterlytics-options.php +++ b/includes/class-betterlytics-options.php @@ -25,29 +25,29 @@ class Betterlytics_Options { * @var array */ const DEFAULTS = [ - 'site_id' => '', - 'server_url' => 'https://betterlytics.io/event', - 'script_url' => 'https://betterlytics.io/analytics.js', - 'enabled' => false, - 'track_web_vitals' => false, - 'track_404' => [ + 'site_id' => '', + 'server_url' => 'https://betterlytics.io/event', + 'script_url' => 'https://betterlytics.io/analytics.js', + 'enabled' => false, + 'track_web_vitals' => false, + 'track_404' => [ 'enabled' => false, 'metadata' => [], ], - 'track_search' => [ + 'track_search' => [ 'enabled' => false, 'include_query' => false, 'metadata' => [], ], - 'track_outbound' => [ + 'track_outbound' => [ 'mode' => 'domain', 'metadata' => [], ], - 'track_downloads' => [ + 'track_downloads' => [ 'enabled' => false, 'metadata' => [], ], - 'track_css_events' => [ + 'track_custom_html_attribute' => [ 'enabled' => false, 'metadata' => [], ], @@ -68,7 +68,7 @@ public static function get_options() { 'track_404', 'track_search', 'track_downloads', - 'track_css_events', + 'track_custom_html_attribute', ]; foreach ( $event_keys as $key ) { diff --git a/public/class-betterlytics-public.php b/public/class-betterlytics-public.php index 7fba7cf..0e7fbd0 100644 --- a/public/class-betterlytics-public.php +++ b/public/class-betterlytics-public.php @@ -106,7 +106,7 @@ public function enqueue_event_scripts() { } $options = Betterlytics_Options::get_options(); - $needs_js = ! empty( $options['track_downloads']['enabled'] ) || ! empty( $options['track_css_events']['enabled'] ); + $needs_js = ! empty( $options['track_downloads']['enabled'] ) || ! empty( $options['track_custom_html_attribute']['enabled'] ); if ( ! $needs_js ) { return; @@ -120,14 +120,14 @@ public function enqueue_event_scripts() { true ); - wp_localize_script( - 'betterlytics-events', - 'betterlyticsEvents', - [ - 'trackDownloads' => ! empty( $options['track_downloads'] ), - 'trackCssEvents' => ! empty( $options['track_css_events'] ), - ] - ); + wp_localize_script( + 'betterlytics-events', + 'betterlyticsEvents', + [ + 'trackDownloads' => ! empty( $options['track_downloads']['enabled'] ), + 'trackCustomHtmlAttr' => ! empty( $options['track_custom_html_attribute']['enabled'] ), + ] + ); } /** @@ -145,7 +145,7 @@ public function output_queued_events() { echo "\n"; diff --git a/public/js/betterlytics-events.js b/public/js/betterlytics-events.js index 769536b..f78209f 100644 --- a/public/js/betterlytics-events.js +++ b/public/js/betterlytics-events.js @@ -1,37 +1,40 @@ -(function() { - 'use strict'; +(function () { + "use strict"; - var config = window.betterlyticsEvents || {}; + var config = window.betterlyticsEvents || {}; - // File download tracking - if (config.trackDownloads) { - var downloadExtensions = /\.(pdf|zip|doc|docx|xls|xlsx|ppt|pptx|exe|dmg|tar|gz|rar)$/i; - document.addEventListener('click', function(e) { - var link = e.target.closest('a[href]'); - if (!link) return; + // File download tracking + if (config.trackDownloads) { + var downloadExtensions = + /\.(pdf|zip|doc|docx|xls|xlsx|ppt|pptx|exe|dmg|tar|gz|rar)$/i; + document.addEventListener("click", function (e) { + var link = e.target.closest("a[href]"); + if (!link) return; - if (downloadExtensions.test(link.href)) { - window.betterlytics && betterlytics.event('file-download', { - url: link.href, - filename: link.href.split('/').pop() - }); - } - }); - } + if (downloadExtensions.test(link.href)) { + window.betterlytics && + betterlytics.event("file-download", { + url: link.href, + filename: link.href.split("/").pop(), + }); + } + }); + } - // CSS class event tracking (data-betterlytics-event attribute) - if (config.trackCssEvents) { - document.addEventListener('click', function(e) { - var element = e.target.closest('[data-betterlytics-event]'); - if (!element) return; + // Custom HTML attribute event tracking (data-betterlytics-event attribute) + if (config.trackCustomHtmlAttr) { + document.addEventListener("click", function (e) { + var element = e.target.closest("[data-betterlytics-event]"); + if (!element) return; - var eventName = element.getAttribute('data-betterlytics-event'); - if (eventName) { - window.betterlytics && betterlytics.event(eventName, { - element: element.tagName.toLowerCase(), - text: element.innerText.substring(0, 100) - }); - } - }); - } + var eventName = element.getAttribute("data-betterlytics-event"); + if (eventName) { + window.betterlytics && + betterlytics.event(eventName, { + element: element.tagName.toLowerCase(), + text: element.innerText.substring(0, 100), + }); + } + }); + } })(); diff --git a/readme.txt b/readme.txt index 02cfa4d..a86698e 100644 --- a/readme.txt +++ b/readme.txt @@ -1,7 +1,7 @@ === Betterlytics === Contributors: betterlytics Tags: analytics, privacy, gdpr, cookieless, statistics -Requires at least: 6.0 +Requires at least: 5.0 Tested up to: 6.7 Stable tag: 1.0.0 Requires PHP: 7.4 @@ -20,7 +20,6 @@ This plugin helps you quickly set up Betterlytics on your WordPress site without * **Easy Setup** — Add your Site ID and start tracking in seconds * **No Code Required** — Automatically injects the lightweight tracking script -* **Privacy Controls** — Option to exclude logged-in users from tracking * **WordPress Hooks Integration** — Map WordPress actions to custom analytics events * **Self-Hosting Support** — Works with both Betterlytics Cloud and self-hosted instances @@ -70,10 +69,6 @@ Yes. Betterlytics does not collect personally identifiable information and does Yes. Betterlytics is open source. You can configure the plugin to point to your own self-hosted instance by updating the Server URL and Script URL in the settings. -= Can I exclude logged-in users from tracking? = - -Yes. There's a setting to exclude logged-in WordPress users from being tracked. - == External Services == This plugin connects to the Betterlytics analytics service to track website visits. @@ -105,7 +100,6 @@ By enabling tracking, you consent to data being sent to Betterlytics servers (or * Initial release * Automatic tracking script injection * WordPress hooks integration -* Privacy controls for logged-in users == Upgrade Notice == diff --git a/tests/class-betterlytics-test-case.php b/tests/class-betterlytics-test-case.php index 82a37d3..ff1ebff 100644 --- a/tests/class-betterlytics-test-case.php +++ b/tests/class-betterlytics-test-case.php @@ -37,12 +37,10 @@ public function tear_down() { */ protected function set_options( $options ) { $defaults = array( - 'site_id' => '', - 'server_url' => 'https://betterlytics.io/event', - 'script_url' => 'https://betterlytics.io/analytics.js', - 'enabled' => false, - 'track_logged_in' => true, - 'hooks' => array(), + 'site_id' => '', + 'server_url' => 'https://betterlytics.io/event', + 'script_url' => 'https://betterlytics.io/analytics.js', + 'enabled' => false, ); update_option( 'betterlytics_options', wp_parse_args( $options, $defaults ) ); diff --git a/tests/test-admin.php b/tests/test-admin.php index da95dae..3aea076 100644 --- a/tests/test-admin.php +++ b/tests/test-admin.php @@ -79,7 +79,51 @@ public function test_sanitize_options_enabled_checkbox() { $this->assertFalse( $result_disabled['enabled'] ); } + /** + * Test sanitize_options preserves valid track_outbound modes. + */ + public function test_sanitize_options_track_outbound_valid_modes() { + $valid_modes = array( 'off', 'domain', 'full' ); + + foreach ( $valid_modes as $mode ) { + $input = array( + 'track_outbound' => array( 'mode' => $mode ), + ); + + $result = $this->admin->sanitize_options( $input ); + + $this->assertSame( $mode, $result['track_outbound']['mode'] ); + } + } + + /** + * Test sanitize_options falls back to default for invalid track_outbound mode. + */ + public function test_sanitize_options_track_outbound_invalid_mode() { + $input = array( + 'track_outbound' => array( 'mode' => 'invalid_mode' ), + ); + + $result = $this->admin->sanitize_options( $input ); + + // Should fall back to default 'domain' mode. + $this->assertSame( 'domain', $result['track_outbound']['mode'] ); + } + + /** + * Test sanitize_options handles track_web_vitals checkbox. + */ + public function test_sanitize_options_web_vitals_checkbox() { + $input_enabled = array( + 'track_web_vitals' => '1', + ); + $input_disabled = array(); + $result_enabled = $this->admin->sanitize_options( $input_enabled ); + $result_disabled = $this->admin->sanitize_options( $input_disabled ); + $this->assertTrue( $result_enabled['track_web_vitals'] ); + $this->assertFalse( $result_disabled['track_web_vitals'] ); + } } diff --git a/tests/test-configuration-md.php b/tests/test-configuration-md.php index d718e67..cc3c081 100644 --- a/tests/test-configuration-md.php +++ b/tests/test-configuration-md.php @@ -32,7 +32,7 @@ public function test_full_json_configuration() { ), 'track_outbound' => array( 'mode' => 'domain' ), 'track_downloads' => array( 'enabled' => false ), - 'track_css_events' => array( 'enabled' => false ), + 'track_custom_html_attribute' => array( 'enabled' => false ), ); // Simulate applying this configuration via update_option @@ -81,19 +81,18 @@ public function test_variable_update_flow() { public function test_environment_variables_logic() { // Simulate variables being available (via local vars instead of getenv for test stability) $mock_env = array( - 'BETTERLYTICS_SITE_ID' => 'env-site-id', - 'BETTERLYTICS_SERVER_URL' => 'https://env-server.com', - 'BETTERLYTICS_SCRIPT_URL' => 'https://env-server.com/js', - 'BETTERLYTICS_ENABLED' => 'true', - 'BETTERLYTICS_TRACK_LOGGED_IN' => 'true', + 'BETTERLYTICS_SITE_ID' => 'env-site-id', + 'BETTERLYTICS_SERVER_URL' => 'https://env-server.com', + 'BETTERLYTICS_SCRIPT_URL' => 'https://env-server.com/js', + 'BETTERLYTICS_ENABLED' => 'true', ); // The logic from CONFIGURATION.md adapted for test $config = array( - 'site_id' => $mock_env['BETTERLYTICS_SITE_ID'], - 'server_url' => $mock_env['BETTERLYTICS_SERVER_URL'], - 'script_url' => $mock_env['BETTERLYTICS_SCRIPT_URL'], - 'enabled' => filter_var( $mock_env['BETTERLYTICS_ENABLED'], FILTER_VALIDATE_BOOLEAN ), + 'site_id' => $mock_env['BETTERLYTICS_SITE_ID'], + 'server_url' => $mock_env['BETTERLYTICS_SERVER_URL'], + 'script_url' => $mock_env['BETTERLYTICS_SCRIPT_URL'], + 'enabled' => filter_var( $mock_env['BETTERLYTICS_ENABLED'], FILTER_VALIDATE_BOOLEAN ), ); update_option( 'betterlytics_options', $config ); diff --git a/tests/test-hooks.php b/tests/test-hooks.php index 71726b9..3279573 100644 --- a/tests/test-hooks.php +++ b/tests/test-hooks.php @@ -27,7 +27,7 @@ public function test_404_page_event() { array( 'enabled' => true, 'site_id' => 'test-site', - 'track_404' => true, + 'track_404' => array( 'enabled' => true ), ) ); diff --git a/tests/test-options.php b/tests/test-options.php index bfef8c8..ff25986 100644 --- a/tests/test-options.php +++ b/tests/test-options.php @@ -75,7 +75,7 @@ public function test_get_nonexistent_option_returns_default() { public function test_update_options() { $options = array( 'site_id' => 'updated-site', - 'server_url' => 'https://custom.example.com/track', + 'server_url' => 'https://custom.example.com/event', 'script_url' => 'https://custom.example.com/analytics.js', 'enabled' => true, ); @@ -84,7 +84,7 @@ public function test_update_options() { $this->assertTrue( $result ); $this->assertSame( 'updated-site', Betterlytics_Options::get( 'site_id' ) ); - $this->assertSame( 'https://custom.example.com/track', Betterlytics_Options::get( 'server_url' ) ); + $this->assertSame( 'https://custom.example.com/event', Betterlytics_Options::get( 'server_url' ) ); } /** diff --git a/tests/test-public.php b/tests/test-public.php index a32f972..709f276 100644 --- a/tests/test-public.php +++ b/tests/test-public.php @@ -71,7 +71,7 @@ public function test_script_output_when_configured() { array( 'enabled' => true, 'site_id' => 'my-test-site', - 'server_url' => 'https://analytics.example.com/track', + 'server_url' => 'https://analytics.example.com/event', 'script_url' => 'https://analytics.example.com/script.js', ) ); @@ -83,7 +83,7 @@ public function test_script_output_when_configured() { // Check that the script contains expected elements. $this->assertStringContainsString( 'window.betterlytics', $output ); $this->assertStringContainsString( 'data-site-id="my-test-site"', $output ); - $this->assertStringContainsString( 'data-server-url="https://analytics.example.com/track"', $output ); + $this->assertStringContainsString( 'data-server-url="https://analytics.example.com/event"', $output ); $this->assertStringContainsString( 'src="https://analytics.example.com/script.js"', $output ); $this->assertStringContainsString( 'async', $output ); } @@ -169,4 +169,99 @@ public function test_multiple_queued_events_output() { $this->assertStringContainsString( "betterlytics.event('event-one'", $output ); $this->assertStringContainsString( "betterlytics.event('event-two'", $output ); } + + /** + * Test that web vitals attribute is output correctly when enabled. + */ + public function test_web_vitals_enabled() { + $this->set_options( + array( + 'enabled' => true, + 'site_id' => 'test-site', + 'track_web_vitals' => true, + ) + ); + + ob_start(); + $this->public->inject_tracking_script(); + $output = ob_get_clean(); + + $this->assertStringContainsString( 'data-web-vitals="true"', $output ); + } + + /** + * Test that web vitals attribute is output correctly when disabled. + */ + public function test_web_vitals_disabled() { + $this->set_options( + array( + 'enabled' => true, + 'site_id' => 'test-site', + 'track_web_vitals' => false, + ) + ); + + ob_start(); + $this->public->inject_tracking_script(); + $output = ob_get_clean(); + + $this->assertStringContainsString( 'data-web-vitals="false"', $output ); + } + + /** + * Test track_outbound mode 'domain' outputs correctly. + */ + public function test_outbound_links_domain_mode() { + $this->set_options( + array( + 'enabled' => true, + 'site_id' => 'test-site', + 'track_outbound' => array( 'mode' => 'domain' ), + ) + ); + + ob_start(); + $this->public->inject_tracking_script(); + $output = ob_get_clean(); + + $this->assertStringContainsString( 'data-outbound-links="domain"', $output ); + } + + /** + * Test track_outbound mode 'full' outputs correctly. + */ + public function test_outbound_links_full_mode() { + $this->set_options( + array( + 'enabled' => true, + 'site_id' => 'test-site', + 'track_outbound' => array( 'mode' => 'full' ), + ) + ); + + ob_start(); + $this->public->inject_tracking_script(); + $output = ob_get_clean(); + + $this->assertStringContainsString( 'data-outbound-links="full"', $output ); + } + + /** + * Test track_outbound mode 'off' outputs correctly. + */ + public function test_outbound_links_off_mode() { + $this->set_options( + array( + 'enabled' => true, + 'site_id' => 'test-site', + 'track_outbound' => array( 'mode' => 'off' ), + ) + ); + + ob_start(); + $this->public->inject_tracking_script(); + $output = ob_get_clean(); + + $this->assertStringContainsString( 'data-outbound-links="off"', $output ); + } }