feat: scaffold plugin foundation
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace WPContentSync\Tests\Unit;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use WPContentSync\Container;
|
||||
|
||||
class ContainerTest extends TestCase {
|
||||
public function test_it_returns_registered_service(): void {
|
||||
$container = new Container();
|
||||
$service = new \stdClass();
|
||||
|
||||
$container->set( 'example', $service );
|
||||
|
||||
self::assertSame( $service, $container->get( 'example' ) );
|
||||
}
|
||||
|
||||
public function test_it_reuses_factory_result(): void {
|
||||
$container = new Container();
|
||||
$calls = 0;
|
||||
|
||||
$container->factory(
|
||||
'example',
|
||||
static function () use ( &$calls ): \stdClass {
|
||||
++$calls;
|
||||
return new \stdClass();
|
||||
}
|
||||
);
|
||||
|
||||
$first = $container->get( 'example' );
|
||||
$second = $container->get( 'example' );
|
||||
|
||||
self::assertSame( $first, $second );
|
||||
self::assertSame( 1, $calls );
|
||||
}
|
||||
|
||||
public function test_it_throws_for_unknown_service(): void {
|
||||
$container = new Container();
|
||||
|
||||
$this->expectException( \InvalidArgumentException::class );
|
||||
$this->expectExceptionMessage( 'Service "missing" is not registered.' );
|
||||
|
||||
$container->get( 'missing' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace WPContentSync\Tests\Unit;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use WPContentSync\Logging\OptionLogger;
|
||||
|
||||
class OptionLoggerTest extends TestCase {
|
||||
protected function setUp(): void {
|
||||
$GLOBALS['wpcs_test_options'] = array();
|
||||
}
|
||||
|
||||
public function test_it_records_log_entries(): void {
|
||||
$logger = new OptionLogger( 10 );
|
||||
|
||||
$logger->warning( 'Connection failed.', array( 'url' => 'https://example.test' ) );
|
||||
|
||||
$entries = get_option( OptionLogger::OPTION_NAME, array() );
|
||||
|
||||
self::assertCount( 1, $entries );
|
||||
self::assertSame( 'warning', $entries[0]['level'] );
|
||||
self::assertSame( 'Connection failed.', $entries[0]['message'] );
|
||||
self::assertSame( 'https://example.test', $entries[0]['context']['url'] );
|
||||
self::assertArrayHasKey( 'timestamp', $entries[0] );
|
||||
}
|
||||
|
||||
public function test_it_redacts_sensitive_context_values(): void {
|
||||
$logger = new OptionLogger( 10 );
|
||||
|
||||
$logger->error(
|
||||
'Authentication failed.',
|
||||
array(
|
||||
'application_password' => 'secret-value',
|
||||
'client_secret' => 'client-secret-value',
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer nested-token',
|
||||
),
|
||||
'token' => 'token-value',
|
||||
'username' => 'admin',
|
||||
)
|
||||
);
|
||||
|
||||
$entries = get_option( OptionLogger::OPTION_NAME, array() );
|
||||
|
||||
self::assertSame( '[redacted]', $entries[0]['context']['application_password'] );
|
||||
self::assertSame( '[redacted]', $entries[0]['context']['client_secret'] );
|
||||
self::assertSame( '[redacted]', $entries[0]['context']['headers']['Authorization'] );
|
||||
self::assertSame( '[redacted]', $entries[0]['context']['token'] );
|
||||
self::assertSame( 'admin', $entries[0]['context']['username'] );
|
||||
}
|
||||
|
||||
public function test_it_limits_retained_entries(): void {
|
||||
$logger = new OptionLogger( 2 );
|
||||
|
||||
$logger->info( 'First' );
|
||||
$logger->info( 'Second' );
|
||||
$logger->info( 'Third' );
|
||||
|
||||
$entries = get_option( OptionLogger::OPTION_NAME, array() );
|
||||
|
||||
self::assertCount( 2, $entries );
|
||||
self::assertSame( 'Second', $entries[0]['message'] );
|
||||
self::assertSame( 'Third', $entries[1]['message'] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace WPContentSync\Tests\Unit;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use WPContentSync\Settings\Settings;
|
||||
|
||||
class SettingsTest extends TestCase {
|
||||
public function test_it_provides_secure_defaults(): void {
|
||||
$settings = Settings::fromArray( array() );
|
||||
|
||||
self::assertSame( array(), $settings->syncPairs() );
|
||||
self::assertSame( 'warning', $settings->loggingLevel() );
|
||||
self::assertTrue( $settings->automaticUrlReplacementEnabled() );
|
||||
self::assertSame( 'last_write_wins', $settings->conflictStrategy() );
|
||||
}
|
||||
|
||||
public function test_it_sanitizes_scalar_settings(): void {
|
||||
$settings = Settings::fromArray(
|
||||
array(
|
||||
'logging_level' => '<b>debug</b>',
|
||||
'conflict_strategy' => "manual_review\n",
|
||||
'automatic_url_replacement' => false,
|
||||
)
|
||||
);
|
||||
|
||||
self::assertSame( 'debug', $settings->loggingLevel() );
|
||||
self::assertSame( 'manual_review', $settings->conflictStrategy() );
|
||||
self::assertFalse( $settings->automaticUrlReplacementEnabled() );
|
||||
}
|
||||
|
||||
public function test_it_rejects_unknown_logging_level(): void {
|
||||
$settings = Settings::fromArray(
|
||||
array(
|
||||
'logging_level' => 'verbose',
|
||||
)
|
||||
);
|
||||
|
||||
self::assertSame( 'warning', $settings->loggingLevel() );
|
||||
}
|
||||
|
||||
public function test_it_normalizes_string_boolean_values(): void {
|
||||
$settings = Settings::fromArray(
|
||||
array(
|
||||
'automatic_url_replacement' => 'false',
|
||||
)
|
||||
);
|
||||
|
||||
self::assertFalse( $settings->automaticUrlReplacementEnabled() );
|
||||
|
||||
$settings = Settings::fromArray(
|
||||
array(
|
||||
'automatic_url_replacement' => '1',
|
||||
)
|
||||
);
|
||||
|
||||
self::assertTrue( $settings->automaticUrlReplacementEnabled() );
|
||||
}
|
||||
|
||||
public function test_it_serializes_to_array(): void {
|
||||
$settings = Settings::fromArray(
|
||||
array(
|
||||
'sync_pairs' => array(
|
||||
array(
|
||||
'name' => 'Staging',
|
||||
'source_url' => 'https://example.test',
|
||||
'destination_url' => 'https://staging.example.test',
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
self::assertSame(
|
||||
array(
|
||||
'sync_pairs' => array(
|
||||
array(
|
||||
'name' => 'Staging',
|
||||
'source_url' => 'https://example.test',
|
||||
'destination_url' => 'https://staging.example.test',
|
||||
),
|
||||
),
|
||||
'logging_level' => 'warning',
|
||||
'automatic_url_replacement' => true,
|
||||
'conflict_strategy' => 'last_write_wins',
|
||||
),
|
||||
$settings->toArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user