Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions classes/Visualizer/Module/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,8 @@ public function enqueueSettingsScripts( string $hook_suffix ): void {
}
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'wp-color-picker' );

do_action( 'themeisle_internal_page', VISUALIZER_DIRNAME, 'settings' );
}

/**
Expand Down
33 changes: 33 additions & 0 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ function () {
);
}
);
add_filter( 'visualizer_support_hub_metadata', 'visualizer_support_hub_metadata' );
add_filter(
'visualizer_ai_connect_metadata',
function () {
Expand Down Expand Up @@ -274,6 +275,38 @@ function visualizer_action_scheduler_store_class( $class_name ) {
return 'ActionScheduler_DBStore' === $class_name ? 'Visualizer_ActionScheduler_Store' : $class_name;
}

/**
* Opts into the SDK Support Hub: one Help button on the plugin's own screens
* and the deactivation window.
*
* Visualizer Pro registers nothing here: it has no admin screens of its own
* and the SDK shows one Help button per screen, so the free plugin owns the
* hub for both and tags the message as pro from the Pro license status.
*
* The plugin screens need no `pages` entry: each one fires
* `themeisle_internal_page`, which the SDK already treats as a product screen.
*
* @return array{is_pro: bool, license_namespace: string, links: array<int, array{icon: string, text: string, url: string}>}
*/
function visualizer_support_hub_metadata() {
return array(
'is_pro' => Visualizer_Module::is_pro(),
'license_namespace' => 'visualizer',
'links' => array(
array(
'icon' => 'book-alt',
'text' => __( 'Docs', 'visualizer' ),
'url' => VISUALIZER_MAIN_DOC,
),
array(
'icon' => 'groups',
'text' => __( 'Forum', 'visualizer' ),
'url' => 'https://wordpress.org/support/plugin/visualizer/',
),
),
);
}

/**
* Registers with the SDK
*
Expand Down
84 changes: 84 additions & 0 deletions tests/test-support-hub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php
/**
* WordPress unit test plugin.
*
* @package visualizer
* @subpackage Tests
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
*/

/**
* Test the metadata Visualizer hands to the Themeisle SDK Support Hub.
*/
class Test_Visualizer_Support_Hub extends WP_UnitTestCase {

/**
* The filter is registered and returns the keys the SDK reads.
*/
public function test_metadata_has_the_contract_keys() {
$this->assertNotFalse( has_filter( 'visualizer_support_hub_metadata', 'visualizer_support_hub_metadata' ) );

$data = apply_filters( 'visualizer_support_hub_metadata', array() );

$this->assertIsArray( $data );
$this->assertArrayHasKey( 'is_pro', $data );
$this->assertIsBool( $data['is_pro'] );
$this->assertArrayNotHasKey( 'setup_complete', $data, 'The setup nudge stays off for now.' );
$this->assertArrayNotHasKey( 'pages', $data, 'Screens are declared through themeisle_internal_page, not pages.' );
$this->assertArrayNotHasKey( 'primary_color', $data, 'The hub keeps the shared SDK accent.' );
}

/**
* Every footer link has an icon, a text and a URL.
*/
public function test_links_are_complete() {
$data = apply_filters( 'visualizer_support_hub_metadata', array() );

$this->assertNotEmpty( $data['links'] );
$this->assertLessThanOrEqual( 6, count( $data['links'] ) );
foreach ( $data['links'] as $link ) {
$this->assertNotEmpty( $link['icon'] );
$this->assertNotEmpty( $link['text'] );
$this->assertNotFalse( filter_var( $link['url'], FILTER_VALIDATE_URL ) );
}
$this->assertSame( VISUALIZER_MAIN_DOC, $data['links'][0]['url'] );
}

/**
* `is_pro` follows the `visualizer_is_pro` filter Pro answers from its license.
*/
public function test_is_pro_follows_the_license_filter() {
$this->assertFalse( apply_filters( 'visualizer_support_hub_metadata', array() )['is_pro'] );

add_filter( 'visualizer_is_pro', '__return_true' );
$this->assertTrue( apply_filters( 'visualizer_support_hub_metadata', array() )['is_pro'] );
remove_filter( 'visualizer_is_pro', '__return_true' );
}

/**
* The Settings screen declares itself a product screen like the Library and Support screens.
*/
public function test_settings_screen_fires_internal_page() {
wp_set_current_user( 1 );
set_current_screen( 'dashboard' );

$admin = Visualizer_Plugin::instance()->getModule( Visualizer_Module_Admin::NAME );
$admin->registerAdminMenu();

$fired = array();
add_action(
'themeisle_internal_page',
function ( $product, $page ) use ( &$fired ) {
$fired[] = array( $product, $page );
},
10,
2
);

// The suffix add_submenu_page() returned, whatever menu state earlier tests left behind.
$admin->enqueueSettingsScripts( get_plugin_page_hookname( 'viz-settings', Visualizer_Plugin::NAME ) );
$admin->enqueueSettingsScripts( 'edit-post' );

$this->assertSame( array( array( VISUALIZER_DIRNAME, 'settings' ) ), $fired );
}
}
Loading