Skip to content

Commit

Permalink
Added unit and integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Screenfeed committed Feb 3, 2021
1 parent 7ecf9ac commit 9835a87
Show file tree
Hide file tree
Showing 64 changed files with 4,811 additions and 293 deletions.
55 changes: 55 additions & 0 deletions Tests/Fixtures/src/Options/Sanitization.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Screenfeed\AutoWPOptions\Tests\Fixtures\src\Options;

use Screenfeed\AutoWPOptions\Sanitization\SanitizationInterface;

class Sanitization implements SanitizationInterface {

public function get_prefix() {
return 'fixture';
}

public function get_identifier() {
return 'settings';
}

public function get_default_values() {
return [
'the_array' => [],
'the_number' => 0,
'the_text' => 'some text',
];
}

public function get_reset_values() {
return [
'the_array' => [ 2 ],
'the_number' => 2,
'the_text' => 'reset text',
];
}

public function sanitize_and_validate( $key, $value, $default = null ) {
switch ( $key ) {
case 'the_array':
$value = is_array( $value ) ? array_unique( array_map( 'absint', $value ) ) : [];
$value = ! empty( $value ) ? array_combine( $value, $value ) : [];
return $value;
case 'the_number':
return absint( $value );
case 'the_text':
return (string) sanitize_text_field( $value );

default:
return false;
}
}

public function sanitize_and_validate_on_update( array $values ) {
if ( ! empty( $values['the_number'] ) && ! in_array( $values['the_number'], $values['the_array'], true ) ) {
$values['the_number'] = 0;
}
return $values;
}
}
51 changes: 51 additions & 0 deletions Tests/Fixtures/src/Options/Storage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Screenfeed\AutoWPOptions\Tests\Fixtures\src\Options;

use Screenfeed\AutoWPOptions\Storage\StorageInterface;

class Storage implements StorageInterface {
public $values;
public $network_id;

public function __construct( $values = null ) {
if ( ! isset( $values ) ) {
$values = [
'the_unknown' => [ '-7' ],
'the_number' => '-7',
];
}
$this->values = $values;
$this->network_id = ! empty( $args['network_id'] ) && is_numeric( $args['network_id'] ) ? absint( $args['network_id'] ) : get_current_network_id();
}

public function get_type() {
return 'fixture_type';
}

public function get_full_name() {
return 'fixture_settings';
}

public function get_network_id() {
return $this->network_id;
}

public function is_network_option() {
return false;
}

public function get() {
return $this->values;
}

public function set( array $values ) {
$this->values = (array) sanitize_option( $this->get_full_name(), $values );
return true;
}

public function delete() {
$this->values = false;
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Screenfeed\AutoWPOptions\Tests\Fixtures\src\Sanitization\AbstractSanitization;

use Screenfeed\AutoWPOptions\Sanitization\AbstractSanitization;

class Sanitization extends AbstractSanitization {

protected $prefix = 'fixture';

protected $identifier = 'settings';

protected $default_values = [
'the_array' => [],
'the_number' => 0,
'the_text' => 'some text',
];

protected $reset_values = [
'the_array' => [ 2 ],
'the_number' => 2,
'the_text' => 'reset text',
];

protected function sanitize_and_validate_value( $key, $value, $default ) {
switch ( $key ) {
case 'the_array':
$value = is_array( $value ) ? array_unique( array_map( 'absint', $value ) ) : [];
$value = ! empty( $value ) ? array_combine( $value, $value ) : [];
return $value;
case 'the_number':
return absint( $value );
case 'the_text':
return (string) sanitize_text_field( $value );

default:
return false;
}
}

protected function validate_values_on_update( array $values ) {
if ( ! empty( $values['the_number'] ) && ! in_array( $values['the_number'], $values['the_array'], true ) ) {
$values['the_number'] = 0;
}
return $values;
}
}
42 changes: 42 additions & 0 deletions Tests/Integration/HookCallbackTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Screenfeed\AutoWPOptions\Tests\Integration;

trait HookCallbackTrait {

/**
* Asserts that a hook callback has been registered.
* Examples:
* $this->assertHookCallbackRegistered( 'admin_init', 'my_func', 50 );
* $this->assertHookCallbackRegistered( 'admin_init', [ $instance, 'my_method' ], 20 );
* $this->assertHookCallbackRegistered( 'admin_init', [ MyClass::class, 'my_method' ], 5 );
* This last example will also work for an instance method (by the use of `assertInstanceOf()`).
*
* @param string $hook_name Name of the hook.
* @param callable $callable Can be a function name, an anonymous function,
* an array "instance object + method name", an array "class name + method name".
* @param int $priority Hook priority.
* @return void
*/
protected function assertHookCallbackRegistered( $hook_name, $callable, $priority = 10 ) {
global $wp_filter;

$this->assertTrue( has_action( $hook_name ) );

$callbacks = $wp_filter[ $hook_name ]->callbacks;
$registration = current( $callbacks[ $priority ] );

if ( is_array( $callable ) ) {
$this->assertInternalType( 'array', $registration['function'] );

if ( is_string( $callable[0] ) && is_object( $registration['function'][0] ) ) {
$this->assertInstanceOf( $callable[0], $registration['function'][0] );
$this->assertEquals( $callable[1], $registration['function'][1] );
} else {
$this->assertEquals( $callable, $registration['function'] );
}
} else {
$this->assertEquals( $callable, $registration['function'] );
}
}
}
20 changes: 20 additions & 0 deletions Tests/Integration/TestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Screenfeed\AutoWPOptions\Tests\Integration;

use Screenfeed\AutoWPOptions\Tests\Integration\HookCallbackTrait;
use Screenfeed\AutoWPOptions\Tests\TestCaseTrait;
use WP_UnitTestCase;

abstract class TestCase extends WP_UnitTestCase {
use HookCallbackTrait;
use TestCaseTrait;

public function return_true() {
return true;
}

public function return_false() {
return false;
}
}
56 changes: 56 additions & 0 deletions Tests/Integration/bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php
/**
* Bootstraps the AutoWPOptions integration tests
*
* @package Screenfeed\AutoWPOptions\Tests\Integration
*/

namespace Screenfeed\AutoWPOptions\Tests\Integration;

use function Screenfeed\AutoWPOptions\Tests\init_test_suite;

require_once dirname( dirname( __FILE__ ) ) . '/bootstrap-functions.php';

init_test_suite( 'Integration' );

/**
* Get the WordPress' tests suite directory.
*
* @return string Returns The directory path to the WordPress testing environment.
*/
function get_wp_tests_dir() {
$tests_dir = getenv( 'WP_TESTS_DIR' );

// Travis CI & Vagrant SSH tests directory.
if ( empty( $tests_dir ) ) {
$tests_dir = '/tmp/wordpress-tests-lib';
}

// If the tests' includes directory does not exist, try a relative path to Core tests directory.
if ( ! file_exists( $tests_dir . '/includes/' ) ) {
$tests_dir = '../../../../tests/phpunit';
}

// Check it again. If it doesn't exist, stop here and post a message as to why we stopped.
if ( ! file_exists( $tests_dir . '/includes/' ) ) {
trigger_error( 'Unable to run the integration tests, because the WordPress test suite could not be located.', E_USER_ERROR ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error -- Valid use case for our testing suite.
}

// Strip off the trailing directory separator, if it exists.
return rtrim( $tests_dir, DIRECTORY_SEPARATOR );
}

/**
* Bootstraps the integration testing environment with WordPress and AutoWPOptions.
*
* @param string $wp_tests_dir The directory path to the WordPress testing environment.
*/
function bootstrap_integration_suite( $wp_tests_dir ) {
// Give access to tests_add_filter() function.
require_once $wp_tests_dir . '/includes/functions.php';

// Start up the WP testing environment.
require_once $wp_tests_dir . '/includes/bootstrap.php';
}

bootstrap_integration_suite( get_wp_tests_dir() );
21 changes: 21 additions & 0 deletions Tests/Integration/phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
bootstrap="bootstrap.php"
backupGlobals="false"
colors="true"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutTodoAnnotatedTests="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
verbose="true">

<testsuites>
<testsuite name="integration">
<directory suffix=".php">.</directory>
</testsuite>
</testsuites>
</phpunit>
65 changes: 65 additions & 0 deletions Tests/Integration/src/Options/delete.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace Screenfeed\AutoWPOptions\Tests\Integration\src\Options;

use Screenfeed\AutoWPOptions\Options;
use Screenfeed\AutoWPOptions\Tests\Fixtures\src\Options\Sanitization;
use Screenfeed\AutoWPOptions\Tests\Fixtures\src\Options\Storage;
use Screenfeed\AutoWPOptions\Tests\Integration\TestCase;

/**
* Tests for Options::delete().
*
* @covers Options::delete
* @group Options
*/
class Test_Delete extends TestCase {

public function testShouldDeleteOnlyValidValues() {
$storage = new Storage();
$sanitization = new Sanitization();

$result = ( new Options( $storage, $sanitization ) )->delete(
[
'test',
'the_number',
]
);
$expected = [
'the_unknown' => [ '-7' ],
];

$this->assertTrue( $result );
$this->assertSame( $expected, $storage->values );
}

public function testShouldDeleteOption() {
$storage = new Storage( [] );
$sanitization = new Sanitization();

$result = ( new Options( $storage, $sanitization ) )->delete(
[
'test',
'the_number',
]
);
$expected = false;

$this->assertTrue( $result );
$this->assertSame( $expected, $storage->values );
}

public function testShouldNotDelete() {
$storage = new Storage( false );
$sanitization = new Sanitization();

$result = ( new Options( $storage, $sanitization ) )->delete(
[
'test',
'the_number',
]
);

$this->assertFalse( $result );
}
}
27 changes: 27 additions & 0 deletions Tests/Integration/src/Options/delete_all.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Screenfeed\AutoWPOptions\Tests\Integration\src\Options;

use Screenfeed\AutoWPOptions\Options;
use Screenfeed\AutoWPOptions\Tests\Fixtures\src\Options\Sanitization;
use Screenfeed\AutoWPOptions\Tests\Fixtures\src\Options\Storage;
use Screenfeed\AutoWPOptions\Tests\Integration\TestCase;

/**
* Tests for Options::delete_all().
*
* @covers Options::delete_all
* @group Options
*/
class Test_DeleteAll extends TestCase {

public function testShouldDeleteAll() {
$storage = new Storage();
$sanitization = new Sanitization();

$result = ( new Options( $storage, $sanitization ) )->delete_all();

$this->assertTrue( $result );
$this->assertFalse( $storage->values );
}
}
Loading

0 comments on commit 9835a87

Please sign in to comment.