diff --git a/tests/Feature/AdminFunctionTest.php b/tests/Feature/AdminFunctionTest.php
index a9af465..ab2cf43 100644
--- a/tests/Feature/AdminFunctionTest.php
+++ b/tests/Feature/AdminFunctionTest.php
@@ -8,6 +8,7 @@
namespace Alley\WP\WP_SEO\Tests\Feature;
use Alley\WP\WP_SEO\Tests\TestCase;
+use Mantle\Testing\Utils;
class AdminFunctionTest extends TestCase {
/**
@@ -17,11 +18,7 @@ class AdminFunctionTest extends TestCase {
*/
function test_admin_functions_contain( $function, $should, $contain, $args ) {
// Capture the output of the function.
- ob_start();
- $function( ...$args );
- $output = ob_get_clean();
-
- self::assertStringContainsString( $contain, $output, $should );
+ self::assertStringContainsString( $contain, Utils::get_echo( $function, $args ), $should );
}
/**
diff --git a/tests/Feature/MetaboxesTest.php b/tests/Feature/MetaboxesTest.php
index b7d26ea..b85bdae 100644
--- a/tests/Feature/MetaboxesTest.php
+++ b/tests/Feature/MetaboxesTest.php
@@ -8,6 +8,7 @@
namespace Alley\WP\WP_SEO\Tests\Feature;
use Alley\WP\WP_SEO\Tests\TestCase;
+use Mantle\Testing\Utils;
use WP_SEO_Settings;
use WP_SEO;
@@ -72,9 +73,7 @@ function test_post_meta_fields() {
$post = get_post( $post_ID );
// Capture the output of the function.
- ob_start();
- WP_SEO()->post_meta_fields( $post );
- $html = ob_get_clean();
+ $html = Utils::get_echo( [ WP_SEO(), 'post_meta_fields' ], [ $post ] );
self::assertStringContainsString( 'name="seo_meta[title]" value="' . $title . '" size="96"', $html );
self::assertMatchesRegularExpression( '/]+type="hidden"[^>]+name="wp-seo-nonce"/', $html );
@@ -92,9 +91,7 @@ function test_save_post_fields() {
$post = get_post( $post_ID );
// Capture the output of the function.
- ob_start();
- WP_SEO()->post_meta_fields( $post );
- $html = ob_get_clean();
+ $html = Utils::get_echo( [ WP_SEO(), 'post_meta_fields' ], [ $post ] );
// No $_POST.
$this->assertNull( WP_SEO()->save_post_fields( $post_ID ) );
@@ -181,9 +178,7 @@ function test_add_term_boxes() {
*/
function test_add_term_meta_fields() {
// Capture the output of the function.
- ob_start();
- WP_SEO()->add_term_meta_fields( 'category' );
- $html = ob_get_clean();
+ $html = Utils::get_echo( [ WP_SEO(), 'add_term_meta_fields' ], [ 'category' ] );
self::assertMatchesRegularExpression( '/]+type="hidden"[^>]+name="wp-seo-nonce"/', $html );
self::assertStringContainsString( 'name="seo_meta[title]"', $html );
@@ -209,9 +204,7 @@ function test_edit_term_meta_fields() {
);
// Capture the output of the function.
- ob_start();
- WP_SEO()->edit_term_meta_fields( $category, 'category' );
- $html = ob_get_clean();
+ $html = Utils::get_echo( [ WP_SEO(), 'edit_term_meta_fields' ], [ $category, 'category' ] );
self::assertMatchesRegularExpression( '/]+type="hidden"[^>]+name="wp-seo-nonce"/', $html );
self::assertMatchesRegularExpression( "/{$description}<\/textarea>/", $html );
@@ -226,9 +219,7 @@ function test_save_term_fields() {
$category = get_term( $category_ID, 'category' );
// Capture the output of the function.
- ob_start();
- WP_SEO()->edit_term_meta_fields( $category, 'category' );
- $html = ob_get_clean();
+ $html = Utils::get_echo( [ WP_SEO(), 'add_term_meta_fields' ], [ $category, 'category' ] );
// No $_POST.
$this->assertNull( WP_SEO()->save_term_fields( $category_ID, $category->term_taxonomy_id, 'category' ) );
diff --git a/tests/Feature/PropertiesTest.php b/tests/Feature/PropertiesTest.php
new file mode 100644
index 0000000..80ce474
--- /dev/null
+++ b/tests/Feature/PropertiesTest.php
@@ -0,0 +1,52 @@
+set_properties();
+ }
+
+ function tearDown(): void {
+ parent::tearDown();
+ // Leave the place as we found it.
+ remove_filter( 'wp_seo_formatting_tags', [ $this, '_add_mock' ] );
+ remove_filter( 'wp_seo_formatting_tags', [ $this, '_add_illegals' ] );
+ WP_SEO()->set_properties();
+ }
+
+ function _add_mock( $tags ) {
+ $tags['is_a_tag'] = $this->getMockForAbstractClass( 'WP_SEO_Formatting_Tag' );
+
+ return $tags;
+ }
+
+ function _add_illegals( $tags ) {
+ $tags['is_non_object'] = true;
+ $tags['is_wrong_object'] = new \stdClass;
+
+ return $tags;
+ }
+
+ function test_legal_tag() {
+ $this->assertArrayHasKey( 'is_a_tag', WP_SEO()->formatting_tags );
+ }
+
+ function test_illegal_tags() {
+ $this->assertArrayNotHasKey( 'is_non_object', WP_SEO()->formatting_tags );
+ $this->assertArrayNotHasKey( 'is_wrong_object', WP_SEO()->formatting_tags );
+ }
+
+}
diff --git a/tests/Feature/SettingsPageTest.php b/tests/Feature/SettingsPageTest.php
new file mode 100644
index 0000000..1af8532
--- /dev/null
+++ b/tests/Feature/SettingsPageTest.php
@@ -0,0 +1,370 @@
+add_options_page();
+
+ global $submenu;
+ $this->assertContains(
+ [
+ 'SEO',
+ 'manage_options',
+ 'wp-seo',
+ 'WP SEO Settings',
+ ],
+ $submenu['options-general.php']
+ );
+ }
+
+ /**
+ * Make sure we have a help tab.
+ */
+ function test_add_help_tab() {
+ set_current_screen( 'front' );
+ WP_SEO_Settings()->add_help_tab();
+
+ $actual = get_current_screen()->get_help_tab( 'formatting-tags' );
+ // Not all versions we test against include the priority.
+ if ( isset( $actual['priority'] ) ) {
+ unset( $actual['priority'] );
+ }
+
+ $this->assertEquals( $actual, [
+ 'id' => 'formatting-tags',
+ 'title' => 'Formatting Tags',
+ 'content' => '',
+ 'callback' => [ WP_SEO_Settings(), 'view_formatting_tags_help_tab' ],
+ ] );
+ }
+
+ /**
+ * Test that the "example URL" method includes the text and any included link.
+ */
+ function test_example_url() {
+
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_url' ], [ 'Demo text' ] );
+ $this->assertSame( 'Demo text
', $html );
+
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_url' ], [ 'Demo text', 'http://wordpress.org' ] );
+ $this->assertStringContainsString( 'http://wordpress.org
', $html );
+ }
+
+ /**
+ * Test that the example of a Post includes a link to the latest post.
+ */
+ function test_example_permalink() {
+ $post_ID = $this->factory->post->create();
+
+ $section = [ 'id' => 'single_post' ];
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_permalink' ], [ $section ] );
+
+ $this->assertStringContainsString( get_permalink( $post_ID ), $html );
+ }
+
+ /**
+ * Test that the example of a new custom post type displays the fallback string.
+ */
+ function test_example_permalink_no_posts() {
+ register_post_type( 'demo' );
+
+ $section = [ 'id' => 'single_demo' ];
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_permalink' ], [ $section ] );
+
+ $this->assertStringContainsString( 'No posts yet.', $html );
+ }
+
+ /**
+ * Test that the example of a term archive includes a link to the newest term.
+ */
+ function test_example_term_archive() {
+ $category_ID = $this->factory->term->create( [ 'taxonomy' => 'category' ] );
+ wp_set_object_terms( $this->factory->post->create(), $category_ID, 'category' );
+
+ $section = [ 'id' => 'archive_category' ];
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_term_archive' ], [ $section ] );
+
+ $this->assertStringContainsString( get_term_link( $category_ID, 'category' ), $html );
+ }
+
+ /**
+ * Test that the example of a new taxonomy displays the fallback string.
+ */
+ function test_example_term_archive_no_terms() {
+ register_taxonomy( 'demo', 'post' );
+
+ $section = [ 'id' => 'archive_demo' ];
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_term_archive' ], [ $section ] );
+
+ $this->assertStringContainsString( 'No terms yet.', $html );
+ }
+
+ /**
+ * Test that the example of a post type archive includes the right link.
+ */
+ function test_example_post_type_archive() {
+ register_post_type( 'demo', [ 'has_archive' => true ] );
+ $this->factory->post->create( [ 'post_type' => 'demo' ] );
+
+ $section = [ 'id' => 'archive_demo' ];
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_post_type_archive' ], [ $section ] );
+
+ $this->assertStringContainsString( get_post_type_archive_link( 'demo' ), $html );
+ }
+
+ /**
+ * Test that the example of a post type without archive support is blank.
+ */
+ function test_example_post_type_archive_no_support() {
+ register_post_type( 'demo' );
+ $this->factory->post->create( [ 'post_type' => 'demo' ] );
+
+ $section = [ 'id' => 'archive_demo' ];
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_post_type_archive' ], [ $section ] );
+
+ $this->assertEmpty( $html );
+ }
+
+ /**
+ * Test that the example of a date archive includes this year and month.
+ *
+ * Before testing for the current month, remove the current year to avoid a
+ * false positive in January.
+ */
+ function test_example_date_archive() {
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_date_archive' ] );
+
+ $this->assertStringContainsString( date( 'Y' ), $html );
+ $this->assertStringContainsString( date( 'm' ), str_replace( date( 'Y' ), '', $html ) );
+ }
+
+ /**
+ * Test that the example of an author archive includes the URL for this user.
+ */
+ function test_example_author_archive() {
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_author_archive' ] );
+
+ $this->assertStringContainsString( get_author_posts_url( get_current_user_id() ), $html );
+ }
+
+ /**
+ * Test that the example of a search link includes a search query string.
+ */
+ function test_example_search_page() {
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_search_page' ] );
+
+ $this->assertStringContainsString( get_search_link( 'wordpress' ), $html );
+ }
+
+ /**
+ * Test that the example 404 page includes the hashed blog URL.
+ */
+ function test_example_404_page() {
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'example_404_page' ] );
+
+ $this->assertStringContainsString( md5( get_bloginfo( 'url' ) ), $html );
+ }
+
+ /**
+ * Test the various states of the field() helper method.
+ */
+ function test_field() {
+ // No field.
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'field' ], [ [] ] );
+
+ $this->assertEmpty( $html );
+
+ // No type? Use a text field.
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'field' ], [ [ 'field' => 'demo' ] ] );
+ $this->assertMatchesRegularExpression( '/]+type="text"[^>]+name="wp-seo\[demo\]"/', $html );
+
+ // Check that a value is passed.
+ WP_SEO_Settings()->options['demo'] = 'demo value';
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'field' ], [ [ 'field' => 'demo' ] ] );
+
+ $this->assertMatchesRegularExpression( '/]+type="text"[^>]+value="demo value"/', $html );
+
+ // Check the rendered field types.
+ $html = Utils::get_echo( [ WP_SEO_Settings(), 'field' ], [
+ [
+ 'field' => 'demo',
+ 'type' => 'textarea',
+ ]
+ ] );
+
+ $this->assertStringContainsString( '