diff --git a/tests/phpunit/tests/image/site_icon.php b/tests/phpunit/tests/image/site_icon.php
new file mode 100644
index 0000000000..703b089680
--- /dev/null
+++ b/tests/phpunit/tests/image/site_icon.php
@@ -0,0 +1,178 @@
+wp_site_icon = $GLOBALS['wp_site_icon'];
+ }
+
+ function tearDown() {
+ $this->site_icon = null;
+ $this->remove_added_uploads();
+ parent::tearDown();
+ }
+
+ function test_intermediate_image_sizes() {
+ $image_sizes = $this->wp_site_icon->intermediate_image_sizes( array() );
+
+ $sizes = array();
+ foreach ( $this->wp_site_icon->site_icon_sizes as $size ) {
+ $sizes[] = 'site_icon-' . $size;
+ }
+
+ $this->assertEquals( $sizes, $image_sizes );
+ }
+
+ function test_intermediate_image_sizes_with_filter() {
+ add_filter( 'site_icon_image_sizes', array( $this, '_custom_test_sizes' ) );
+ $image_sizes = $this->wp_site_icon->intermediate_image_sizes( array() );
+
+ $sizes = array();
+ foreach ( $this->wp_site_icon->site_icon_sizes as $size ) {
+ $sizes[] = 'site_icon-' . $size;
+ }
+
+ // Is our custom icon size there?
+ $this->assertContains( 'site_icon-321', $image_sizes );
+
+ // All icon sizes should be part of the array, including sizes added through the filter.
+ $this->assertEquals( $sizes, $image_sizes );
+
+ // Remove custom size.
+ unset( $this->wp_site_icon->site_icon_sizes[ array_search( 321, $this->wp_site_icon->site_icon_sizes ) ] );
+ // Remove the filter we added
+ remove_filter( 'site_icon_image_sizes', array( $this, '_custom_test_sizes' ) );
+ }
+
+ function test_additional_sizes() {
+ $image_sizes = $this->wp_site_icon->additional_sizes( array() );
+
+ $sizes = array();
+ foreach ( $this->wp_site_icon->site_icon_sizes as $size ) {
+ $sizes[ 'site_icon-' . $size ] = array(
+ 'width ' => $size,
+ 'height' => $size,
+ 'crop' => true,
+ );
+ }
+
+ $this->assertEquals( $sizes, $image_sizes );
+ }
+
+ function test_additional_sizes_with_filter() {
+ add_filter( 'site_icon_image_sizes', array( $this, '_custom_test_sizes' ) );
+ $image_sizes = $this->wp_site_icon->additional_sizes( array() );
+
+ $sizes = array();
+ foreach ( $this->wp_site_icon->site_icon_sizes as $size ) {
+ $sizes[ 'site_icon-' . $size ] = array(
+ 'width ' => $size,
+ 'height' => $size,
+ 'crop' => true,
+ );
+ }
+
+ // Is our custom icon size there?
+ $this->assertArrayHasKey( 'site_icon-321', $image_sizes );
+
+ // All icon sizes should be part of the array, including sizes added through the filter.
+ $this->assertEquals( $sizes, $image_sizes );
+
+ // Remove custom size.
+ unset( $this->wp_site_icon->site_icon_sizes[ array_search( 321, $this->wp_site_icon->site_icon_sizes ) ] );
+ }
+
+ function test_create_attachment_object() {
+ $attachment_id = $this->_insert_attachment();
+ $parent_url = get_post( $attachment_id )->guid;
+ $cropped = str_replace( basename( $parent_url ), 'cropped-test-image.jpg', $parent_url );
+
+ $object = $this->wp_site_icon->create_attachment_object( $cropped, $attachment_id );
+
+ $this->assertEquals( $object['post_title'], 'cropped-test-image.jpg' );
+ $this->assertEquals( $object['context'], 'site-icon' );
+ $this->assertEquals( $object['post_mime_type'], 'image/jpeg' );
+ $this->assertEquals( $object['post_content'], $cropped );
+ $this->assertEquals( $object['guid'], $cropped );
+ }
+
+ function test_insert_cropped_attachment() {
+ $attachment_id = $this->_insert_attachment();
+ $parent_url = get_post( $attachment_id )->guid;
+ $cropped = str_replace( basename( $parent_url ), 'cropped-test-image.jpg', $parent_url );
+
+ $object = $this->wp_site_icon->create_attachment_object( $cropped, $attachment_id );
+ $cropped_id = $this->wp_site_icon->insert_attachment( $object, $cropped );
+
+ $this->assertInternalType( 'int', $cropped_id );
+ $this->assertGreaterThan( 0, $cropped_id );
+ }
+
+ function test_delete_site_icon() {
+ $attachment_id = $this->_insert_attachment();
+ update_option( 'site_icon', $attachment_id );
+
+ $this->wp_site_icon->delete_site_icon();
+
+ $this->assertFalse( get_option( 'site_icon', false ) );
+ }
+
+ function test_delete_attachment_data() {
+ $attachment_id = $this->_insert_attachment();
+ update_option( 'site_icon', $attachment_id );
+
+ wp_delete_attachment( $attachment_id, true );
+
+ $this->assertFalse( get_option( 'site_icon', false ) );
+ }
+
+ function _custom_test_sizes( $sizes ) {
+ $sizes[] = 321;
+
+ return $sizes;
+ }
+
+ function _insert_attachment() {
+ if ( $this->attachment_id ) {
+ return $this->attachment_id;
+ }
+
+ $filename = DIR_TESTDATA . '/images/test-image.jpg';
+ $contents = file_get_contents( $filename );
+
+ $upload = wp_upload_bits( basename( $filename ), null, $contents );
+ $type = '';
+ if ( ! empty( $upload['type'] ) ) {
+ $type = $upload['type'];
+ } else {
+ $mime = wp_check_filetype( $upload['file'] );
+ if ( $mime ) {
+ $type = $mime['type'];
+ }
+ }
+
+ $attachment = array(
+ 'post_title' => basename( $upload['file'] ),
+ 'post_content' => $upload['url'],
+ 'post_type' => 'attachment',
+ 'post_mime_type' => $type,
+ 'guid' => $upload['url'],
+ );
+
+ // Save the data
+ $this->attachment_id = wp_insert_attachment( $attachment, $upload['file'] );
+ wp_update_attachment_metadata( $this->attachment_id, wp_generate_attachment_metadata( $this->attachment_id, $upload['file'] ) );
+
+ return $this->attachment_id;
+ }
+}
diff --git a/tests/phpunit/tests/template/general.php b/tests/phpunit/tests/template/general.php
new file mode 100644
index 0000000000..d2cb586bbc
--- /dev/null
+++ b/tests/phpunit/tests/template/general.php
@@ -0,0 +1,155 @@
+wp_site_icon = $GLOBALS['wp_site_icon'];
+ }
+
+ /**
+ * @group site_icon
+ */
+ function test_get_site_icon_url() {
+ $this->assertEmpty( get_site_icon_url() );
+
+ $this->_set_site_icon();
+ $this->assertEquals( $this->site_icon_url, get_site_icon_url() );
+
+ $this->_remove_site_icon();
+ $this->assertEmpty( get_site_icon_url() );
+ }
+
+ /**
+ * @group site_icon
+ */
+ function test_site_icon_url() {
+ $this->expectOutputString( '' );
+ site_icon_url();
+
+ $this->_set_site_icon();
+ $this->expectOutputString( $this->site_icon_url );
+ site_icon_url();
+ $this->_remove_site_icon();
+ }
+
+ /**
+ * @group site_icon
+ */
+ function test_has_site_icon() {
+ $this->assertFalse( has_site_icon() );
+
+ $this->_set_site_icon();
+ $this->assertTrue( has_site_icon() );
+
+ $this->_remove_site_icon();
+ $this->assertFalse( has_site_icon() );
+ }
+
+ /**
+ * @group site_icon
+ */
+ function test_wp_site_icon() {
+ $this->expectOutputString( '' );
+ wp_site_icon();
+
+ $this->_set_site_icon();
+ $output = array(
+ sprintf( '', esc_url( get_site_icon_url( null, 32 ) ) ),
+ sprintf( '', esc_url( get_site_icon_url( null, 180 ) ) ),
+ sprintf( '', esc_url( get_site_icon_url( null, 270 ) ) ),
+ '',
+ );
+ $output = implode( "\n", $output );
+
+ $this->expectOutputString( $output );
+ wp_site_icon();
+
+ $this->_remove_site_icon();
+ }
+
+ /**
+ * @group site_icon
+ */
+ function test_wp_site_icon_with_filter() {
+ $this->expectOutputString( '' );
+ wp_site_icon();
+
+ $this->_set_site_icon();
+ $output = array(
+ sprintf( '', esc_url( get_site_icon_url( null, 32 ) ) ),
+ sprintf( '', esc_url( get_site_icon_url( null, 180 ) ) ),
+ sprintf( '', esc_url( get_site_icon_url( null, 270 ) ) ),
+ sprintf( '', esc_url( get_site_icon_url( null, 150 ) ) ),
+ '',
+ );
+ $output = implode( "\n", $output );
+
+ $this->expectOutputString( $output );
+ add_filter( 'site_icon_meta_tags', array( $this, '_custom_site_icon_meta_tag' ) );
+ wp_site_icon();
+ remove_filter( 'site_icon_meta_tags', array( $this, '_custom_site_icon_meta_tag' ) );
+
+ $this->_remove_site_icon();
+ }
+
+ function _custom_site_icon_meta_tag( $meta_tags ) {
+ $meta_tags[] = sprintf( '', esc_url( get_site_icon_url( null, 150 ) ) );
+
+ return $meta_tags;
+ }
+
+ function _set_site_icon() {
+ if ( ! $this->site_icon_id ) {
+ add_filter( 'intermediate_image_sizes_advanced', array( $this->wp_site_icon, 'additional_sizes' ) );
+ $this->_insert_attachment();
+ remove_filter( 'intermediate_image_sizes_advanced', array( $this->wp_site_icon, 'additional_sizes' ) );
+ }
+
+ update_option( 'site_icon', $this->site_icon_id );
+ }
+
+ function _remove_site_icon() {
+ delete_option( 'site_icon' );
+ }
+
+ function _insert_attachment() {
+ $filename = DIR_TESTDATA . '/images/test-image.jpg';
+ $contents = file_get_contents( $filename );
+
+ $upload = wp_upload_bits( basename( $filename ), null, $contents );
+ $type = '';
+ if ( ! empty( $upload['type'] ) ) {
+ $type = $upload['type'];
+ } else {
+ $mime = wp_check_filetype( $upload['file'] );
+ if ( $mime ) {
+ $type = $mime['type'];
+ }
+ }
+
+ $attachment = array(
+ 'post_title' => basename( $upload['file'] ),
+ 'post_content' => $upload['url'],
+ 'post_type' => 'attachment',
+ 'post_mime_type' => $type,
+ 'guid' => $upload['url'],
+ );
+
+ // Save the data
+ $this->site_icon_url = $upload['url'];
+ $this->site_icon_id = wp_insert_attachment( $attachment, $upload['file'] );
+ wp_update_attachment_metadata( $this->site_icon_id, wp_generate_attachment_metadata( $this->site_icon_id, $upload['file'] ) );
+ }
+}