From d205b641301f1371163154494c1a1e98113558dc Mon Sep 17 00:00:00 2001 From: James Silver Date: Tue, 14 Nov 2023 09:29:58 +0000 Subject: [PATCH] #1,#2,#3: Separate handlers into Data and Scrub handlers --- README.md | 2 +- src/Contracts/DataHandler.php | 13 +-- src/Contracts/DatabaseHandler.php | 32 +++++++ src/Contracts/DatabaseUpdate.php | 17 ---- src/Contracts/DetectsApplicability.php | 8 ++ src/Contracts/ScrubHandler.php | 29 ++++++ .../ArrayHandler.php | 4 +- .../CallableHandler.php | 4 +- .../FakerHandler.php | 4 +- src/DataHandlers/Handler.php | 48 ++++++++++ .../IntegerHandler.php | 4 +- .../ObjectHandler.php | 4 +- .../StringHandler.php | 4 +- src/Exceptions/InvalidHandler.php | 23 +++++ src/Exceptions/ValueNotFound.php | 26 ------ src/Handlers/Handler.php | 63 ------------- src/ScrubHandlers/Handler.php | 68 ++++++++++++++ src/ScrubHandlers/Update.php | 26 ++++++ src/Scrubber.php | 91 +++++++++++-------- src/Util/ConfigurationParser.php | 73 +++++++++++---- src/Util/HandlerRegistry.php | 60 ------------ src/Util/SelfDetectingHandlerRegistry.php | 85 +++++++++++++++++ tests/Support/Fakes/Database.php | 37 +++++++- tests/Support/Fakes/FakeHandler.php | 4 +- tests/Support/HandlerFactory.php | 5 +- tests/Support/config-delete-matching-rows.php | 11 +++ tests/Support/config-ignore.php | 22 +++++ tests/Support/config-invalid.php | 2 +- tests/Support/config-truncate.php | 9 ++ tests/Support/config.php | 2 +- tests/Unit/Handlers/ArrayHandlerTest.php | 6 +- tests/Unit/Handlers/CallableHandlerTest.php | 6 +- tests/Unit/Handlers/FakerHandlerTest.php | 6 +- tests/Unit/Handlers/IntegerHandlerTest.php | 6 +- tests/Unit/Handlers/ObjectHandlerTest.php | 12 +-- tests/Unit/Handlers/StringHandlerTest.php | 6 +- tests/Unit/ScrubberTest.php | 63 ++++++++++++- tests/Unit/Util/ConfigurationParserTest.php | 32 +++++-- ...p => SelfDetectingHandlerRegistryTest.php} | 33 +++++-- 39 files changed, 653 insertions(+), 297 deletions(-) create mode 100644 src/Contracts/DatabaseHandler.php delete mode 100644 src/Contracts/DatabaseUpdate.php create mode 100644 src/Contracts/DetectsApplicability.php create mode 100644 src/Contracts/ScrubHandler.php rename src/{Handlers => DataHandlers}/ArrayHandler.php (84%) rename src/{Handlers => DataHandlers}/CallableHandler.php (81%) rename src/{Handlers => DataHandlers}/FakerHandler.php (85%) create mode 100644 src/DataHandlers/Handler.php rename src/{Handlers => DataHandlers}/IntegerHandler.php (84%) rename src/{Handlers => DataHandlers}/ObjectHandler.php (91%) rename src/{Handlers => DataHandlers}/StringHandler.php (85%) create mode 100644 src/Exceptions/InvalidHandler.php delete mode 100644 src/Exceptions/ValueNotFound.php delete mode 100644 src/Handlers/Handler.php create mode 100644 src/ScrubHandlers/Handler.php create mode 100644 src/ScrubHandlers/Update.php delete mode 100644 src/Util/HandlerRegistry.php create mode 100644 src/Util/SelfDetectingHandlerRegistry.php create mode 100644 tests/Support/config-delete-matching-rows.php create mode 100644 tests/Support/config-ignore.php create mode 100644 tests/Support/config-truncate.php rename tests/Unit/Util/{HandlerRegistryTest.php => SelfDetectingHandlerRegistryTest.php} (66%) diff --git a/README.md b/README.md index 553a22b..287edbb 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Here is an example configuration used in the unit tests: ```php [ diff --git a/src/Contracts/DataHandler.php b/src/Contracts/DataHandler.php index 193e770..9fdc421 100644 --- a/src/Contracts/DataHandler.php +++ b/src/Contracts/DataHandler.php @@ -4,14 +4,9 @@ interface DataHandler { - public function __construct( - string $table, - string $field, - mixed $input, - ?DatabaseKey $primaryKey = null, - ?string $type = null, - string $seed = 'scrubber', - ); + public static function makeFromConfig( + array $config + ): self; - public function handle(); //phpcs:ignore + public function getValue(): mixed; } diff --git a/src/Contracts/DatabaseHandler.php b/src/Contracts/DatabaseHandler.php new file mode 100644 index 0000000..133835c --- /dev/null +++ b/src/Contracts/DatabaseHandler.php @@ -0,0 +1,32 @@ +input) === false) { throw new RuntimeException( diff --git a/src/Handlers/CallableHandler.php b/src/DataHandlers/CallableHandler.php similarity index 81% rename from src/Handlers/CallableHandler.php rename to src/DataHandlers/CallableHandler.php index eef2b03..06750d9 100644 --- a/src/Handlers/CallableHandler.php +++ b/src/DataHandlers/CallableHandler.php @@ -1,12 +1,12 @@ input) === false) { throw new RuntimeException('CallableHandler input is not callable'); diff --git a/src/Handlers/FakerHandler.php b/src/DataHandlers/FakerHandler.php similarity index 85% rename from src/Handlers/FakerHandler.php rename to src/DataHandlers/FakerHandler.php index e09f80d..7a2d807 100644 --- a/src/Handlers/FakerHandler.php +++ b/src/DataHandlers/FakerHandler.php @@ -1,12 +1,12 @@ input, 'faker.') === false) { throw new RuntimeException('FakerHandler invalid faker input format given'); diff --git a/src/DataHandlers/Handler.php b/src/DataHandlers/Handler.php new file mode 100644 index 0000000..1058920 --- /dev/null +++ b/src/DataHandlers/Handler.php @@ -0,0 +1,48 @@ +input = $input; + $this->type = $type; + $this->faker = Faker::create(); + $this->faker->seed($seed); + } + + public function getType(): ?string + { + return $this->type; + } + + abstract public function getValue(): mixed; + + abstract public static function detect(mixed $value): bool; +} diff --git a/src/Handlers/IntegerHandler.php b/src/DataHandlers/IntegerHandler.php similarity index 84% rename from src/Handlers/IntegerHandler.php rename to src/DataHandlers/IntegerHandler.php index c0e086c..ce09141 100644 --- a/src/Handlers/IntegerHandler.php +++ b/src/DataHandlers/IntegerHandler.php @@ -1,12 +1,12 @@ input) === false) { throw new RuntimeException( diff --git a/src/Handlers/ObjectHandler.php b/src/DataHandlers/ObjectHandler.php similarity index 91% rename from src/Handlers/ObjectHandler.php rename to src/DataHandlers/ObjectHandler.php index 81c3459..34b6398 100644 --- a/src/Handlers/ObjectHandler.php +++ b/src/DataHandlers/ObjectHandler.php @@ -1,12 +1,12 @@ input) === false) { throw new RuntimeException('CallableHandler input is not an object'); diff --git a/src/Handlers/StringHandler.php b/src/DataHandlers/StringHandler.php similarity index 85% rename from src/Handlers/StringHandler.php rename to src/DataHandlers/StringHandler.php index d2003f8..84f1c5c 100644 --- a/src/Handlers/StringHandler.php +++ b/src/DataHandlers/StringHandler.php @@ -1,12 +1,12 @@ input) === false && is_int($this->input) === false) { throw new RuntimeException( diff --git a/src/Exceptions/InvalidHandler.php b/src/Exceptions/InvalidHandler.php new file mode 100644 index 0000000..02323ec --- /dev/null +++ b/src/Exceptions/InvalidHandler.php @@ -0,0 +1,23 @@ +value = $value; + $message = $message !== '' ? $message : 'Invalid handler.'; + + parent::__construct($message, $code, $previous); + } +} diff --git a/src/Exceptions/ValueNotFound.php b/src/Exceptions/ValueNotFound.php deleted file mode 100644 index ec9203c..0000000 --- a/src/Exceptions/ValueNotFound.php +++ /dev/null @@ -1,26 +0,0 @@ -getErrorMessage($table, $field); - - parent::__construct($message, $code, $previous); - } - - private function getErrorMessage(string $table, string $field): string - { - return "The 'value' key was not found for $field on $table in the configuration file"; - } -} diff --git a/src/Handlers/Handler.php b/src/Handlers/Handler.php deleted file mode 100644 index 55edf05..0000000 --- a/src/Handlers/Handler.php +++ /dev/null @@ -1,63 +0,0 @@ -table = $table; - $this->field = $field; - $this->input = $input; - $this->primaryKey = $primaryKey ?? ScrubberDatabaseKey::createFromConfig('id'); - $this->type = $type; - $this->faker = Faker::create(); - $this->faker->seed($seed); - } - - abstract public static function detect(mixed $value): bool; - - public function getTable(): string - { - return $this->table; - } - - public function getField(): string - { - return $this->field; - } - - public function getPrimaryKey(): DatabaseKey - { - return $this->primaryKey; - } - - public function getType(): ?string - { - return $this->type; - } -} diff --git a/src/ScrubHandlers/Handler.php b/src/ScrubHandlers/Handler.php new file mode 100644 index 0000000..0f094bf --- /dev/null +++ b/src/ScrubHandlers/Handler.php @@ -0,0 +1,68 @@ +table = $table; + $this->field = $field; + $this->primaryKey = $primaryKey; + $this->dataHandler = $dataHandler; + $this->type = $type; + } + + public function getTable(): string + { + return $this->table; + } + + public function getField(): string + { + return $this->field; + } + + public function getPrimaryKey(): DatabaseKey + { + return $this->primaryKey; + } + + public function getDataHandler(): DataHandler + { + return $this->dataHandler; + } + + public function getType(): ?string + { + return $this->type; + } + + abstract public static function detect(mixed $value): bool; + + abstract public function scrub( + mixed $primaryKeyValues, + DatabaseHandler $database + ): void; +} diff --git a/src/ScrubHandlers/Update.php b/src/ScrubHandlers/Update.php new file mode 100644 index 0000000..5fb0d29 --- /dev/null +++ b/src/ScrubHandlers/Update.php @@ -0,0 +1,26 @@ +update( + $this->getTable(), + $this->getField(), + $this->dataHandler->getValue(), + $primaryKeyValues, + $this->getPrimaryKey(), + ); + } +} \ No newline at end of file diff --git a/src/Scrubber.php b/src/Scrubber.php index 3471b09..f9a69fe 100644 --- a/src/Scrubber.php +++ b/src/Scrubber.php @@ -2,9 +2,9 @@ namespace ClntDev\Scrubber; -use ClntDev\Scrubber\Contracts\DatabaseUpdate; +use ClntDev\Scrubber\Contracts\DatabaseHandler; use ClntDev\Scrubber\Contracts\Logger; -use ClntDev\Scrubber\Handlers\Handler; +use ClntDev\Scrubber\Contracts\ScrubHandler; use ClntDev\Scrubber\Util\ConfigurationParser; use Throwable; @@ -12,13 +12,13 @@ class Scrubber { private ConfigurationParser $parser; - private DatabaseUpdate $database; + private DatabaseHandler $database; private Logger $logger; public function __construct( string $configPath, - DatabaseUpdate $database, + DatabaseHandler $database, Logger $logger ) { $this->database = $database; @@ -26,18 +26,18 @@ public function __construct( $this->parser = ConfigurationParser::make($configPath); } - public static function make(string $configPath, DatabaseUpdate $database, Logger $logger): self + public static function make(string $configPath, DatabaseHandler $database, Logger $logger): self { return new self($configPath, $database, $logger); } public function run(): bool { - $handlers = $this->parser->parse(); + $scrubHandlers = $this->parser->parse(); try { - foreach ($handlers as $handler) { - $this->runHandler($handler); + foreach ($scrubHandlers as $scrubHandler) { + $this->runHandler($scrubHandler); } } catch (Throwable $exception) { $this->logger->log($exception); @@ -48,10 +48,20 @@ public function run(): bool return true; } + public function getTableList(): array + { + return $this->parser->parseTables(); + } + + public function getIgnoredTableList(): array + { + return $this->parser->parseTables(false); + } + public function getFieldList(string $type = 'pid'): array { return array_values(array_filter(array_map( - static fn (Handler $handler): ?string => $handler->getType() === $type ? $handler->getField() : null, + static fn (ScrubHandler $handler): ?string => $handler->getType() === $type ? $handler->getField() : null, array_values($this->parser->parse()) ))); } @@ -61,37 +71,42 @@ public function getFieldListAsString(string $type = 'pid'): string return implode(',', $this->getFieldList($type)); } - protected function runHandler(Handler $handler): void + protected function runHandler(ScrubHandler $handler): void { - foreach ($this->database->fetch($handler->getTable(), $handler->getPrimaryKey()) as $primaryKeyValues) { - $primaryKey = $handler->getPrimaryKey(); - - if ($primaryKey->isComposite()) { - if (is_array($primaryKeyValues) === false) { - throw new Exceptions\CompositePrimaryKeyError(<<getTable()}.{$handler->getField()} has a composite - primary key. but the database did not return an array ({$primaryKeyValues}). - EOM); - } - - $primaryKeyCount = $primaryKey->count(); - $valueCount = count($primaryKeyValues); - - if ($primaryKeyCount !== $valueCount) { - throw new Exceptions\CompositePrimaryKeyError(<<getTable()}.{$handler->getField()} has a composite - primary key with {$primaryKeyCount} columns, but the database fetched {$valueCount} values. - EOM); - } - } + foreach ($this->database->fetch( + $handler->getTable(), + $handler->getPrimaryKey() + ) as $primaryKeyValues) { + $this->validatePrimaryKeyValues($handler, $primaryKeyValues); + $handler->scrub($primaryKeyValues, $this->database); + } + } + + protected function validatePrimaryKeyValues( + ScrubHandler $handler, + mixed $primaryKeyValues + ): void { + $primaryKey = $handler->getPrimaryKey(); + + if ($primaryKey->isComposite() === false) { + return; + } + + if (is_array($primaryKeyValues) === false) { + throw new Exceptions\CompositePrimaryKeyError(<<getTable()}.{$handler->getField()} has a composite + primary key. but the database did not return an array ({$primaryKeyValues}). + EOM); + } + + $primaryKeyCount = $primaryKey->count(); + $valueCount = count($primaryKeyValues); - $this->database->update( - $handler->getTable(), - $handler->getField(), - $handler->handle(), - $primaryKeyValues, - $handler->getPrimaryKey(), - ); + if ($primaryKeyCount !== $valueCount) { + throw new Exceptions\CompositePrimaryKeyError(<<getTable()}.{$handler->getField()} has a composite + primary key with {$primaryKeyCount} columns, but the database fetched {$valueCount} values. + EOM); } } } diff --git a/src/Util/ConfigurationParser.php b/src/Util/ConfigurationParser.php index 2b88c7d..3c33012 100644 --- a/src/Util/ConfigurationParser.php +++ b/src/Util/ConfigurationParser.php @@ -2,25 +2,54 @@ namespace ClntDev\Scrubber\Util; +use ClntDev\Scrubber\Contracts\DataHandler; +use ClntDev\Scrubber\Contracts\ScrubHandler; use ClntDev\Scrubber\DatabaseKey; -use ClntDev\Scrubber\Exceptions\ValueNotFound; -use ClntDev\Scrubber\Handlers\Handler; +use ClntDev\Scrubber\DataHandlers\ArrayHandler; +use ClntDev\Scrubber\DataHandlers\CallableHandler; +use ClntDev\Scrubber\DataHandlers\FakerHandler; +use ClntDev\Scrubber\DataHandlers\IntegerHandler; +use ClntDev\Scrubber\DataHandlers\ObjectHandler; +use ClntDev\Scrubber\DataHandlers\StringHandler; +use ClntDev\Scrubber\ScrubHandlers\Update; class ConfigurationParser { protected array $config; - protected HandlerRegistry $handlerRegistry; + protected SelfDetectingHandlerRegistry $dataHandlerRegistry; - public function __construct(string $configPath) - { + protected SelfDetectingHandlerRegistry $scrubOperationRegistry; + + public function __construct( + string $configPath, + SelfDetectingHandlerRegistry $dataHandlerRegistry, + SelfDetectingHandlerRegistry $scrubOperationRegistry, + ) { $this->config = include $configPath; - $this->handlerRegistry = new HandlerRegistry; + $this->scrubOperationRegistry = $dataHandlerRegistry; + $this->dataHandlerRegistry = $scrubOperationRegistry; } public static function make(string $configPath): self { - return new self($configPath); + return new self( + $configPath, + SelfDetectingHandlerRegistry::makeForDataHandlers(), + SelfDetectingHandlerRegistry::makeForScrubHandlers() + ); + } + + public function parseTables(bool $includeIgnored = true): array + { + if ($includeIgnored) { + return array_keys($this->config); + } + + return array_map( + fn (DataHandler $handler) => $handler, + $this->parse() + ); } public function parse(): array @@ -35,31 +64,37 @@ public function parse(): array private function mapFields(string $table, array $fields): array { return array_map( - fn (string $field, array $fieldData): Handler => $this->parseFieldDataToHandler($table, $field, $fieldData), + function (string $field, array $fieldData) use ($table): ScrubHandler { + return $this->parseFieldDataToHandler($table, $field, $fieldData); + }, array_keys($fields), array_values($fields) ); } - private function parseFieldDataToHandler(string $table, string $field, array $fieldData): Handler + private function parseFieldDataToHandler(string $table, string $field, array $fieldData): ScrubHandler { - if (isset($fieldData['value']) === false) { - throw new ValueNotFound($table, $field); - } - if (isset($fieldData['handler'])) { - $handler = $fieldData['handler']; + /** @var class-string $dataHandler */ + $dataHandler = $fieldData['handler']; + } else { + /** @var class-string $dataHandler */ + $dataHandler = $this->scrubOperationRegistry->getHandlerClassFromValue($fieldData['value']); } - $handler = $handler ?? $this->handlerRegistry->getHandlerClassFromValue($fieldData['value']); + if (isset($fieldData['scrubHandler'])) { + /** @var class-string $scrubHandler */ + $scrubHandler = $fieldData['scrubHandler']; + } else { + /** @var class-string $scrubHandler */ + $scrubHandler = $this->dataHandlerRegistry->getHandlerClassFromValue($fieldData); + } - return new $handler( + return new $scrubHandler( $table, $field, - $fieldData['value'], DatabaseKey::createFromConfig($fieldData['primary_key'] ?? 'id'), - $fieldData['type'] ?? null, - $fieldData['seed'] ?? 'scrubber' + $dataHandler::makeFromConfig($fieldData), ); } } diff --git a/src/Util/HandlerRegistry.php b/src/Util/HandlerRegistry.php deleted file mode 100644 index 7705d81..0000000 --- a/src/Util/HandlerRegistry.php +++ /dev/null @@ -1,60 +0,0 @@ -handlers = array_merge($this->getAvailableHandlers(), $handlers); - } - - public function addHandler(string $handler): self - { - $this->handlers[] = $handler; - - return $this; - } - - public function getAvailableHandlers(): array - { - return array_merge($this->coreHandlers, $this->additionalHandlers); - } - - public function getHandlers(): array - { - return $this->handlers; - } - - public function getHandlerClassFromValue(mixed $value): string - { - foreach ($this->handlers as $handler) { - if ($handler::detect($value)) { - return $handler; - } - } - - throw new HandlerNotFound($value); - } -} diff --git a/src/Util/SelfDetectingHandlerRegistry.php b/src/Util/SelfDetectingHandlerRegistry.php new file mode 100644 index 0000000..4fe3fef --- /dev/null +++ b/src/Util/SelfDetectingHandlerRegistry.php @@ -0,0 +1,85 @@ +[] $handlers */ + public function __construct(array $handlers = []) + { + array_walk($handlers, [$this, 'validateHandler']); + + $this->handlers = $handlers; + } + + /** @param class-string $handler */ + public function addHandler(string $handler): self + { + $this->validateHandler($handler); + + $this->handlers[] = $handler; + + return $this; + } + + /** @return class-string[] */ + public function getHandlers(): array + { + return $this->handlers; + } + + /** @return class-string */ + public function getHandlerClassFromValue(mixed $value): string + { + foreach ($this->handlers as $handler) { + if ($handler::detect($value)) { + return $handler; + } + } + + throw new HandlerNotFound($value); + } + + private function validateHandler(string $handler): void + { + $class = new \ReflectionClass($handler); + if ($class->implementsInterface(DetectsApplicability::class) === false) { + throw new InvalidHandler($handler); + } + } +} diff --git a/tests/Support/Fakes/Database.php b/tests/Support/Fakes/Database.php index abb0375..0f9550d 100644 --- a/tests/Support/Fakes/Database.php +++ b/tests/Support/Fakes/Database.php @@ -3,11 +3,15 @@ namespace ClntDev\Scrubber\Tests\Support\Fakes; use ClntDev\Scrubber\Contracts\DatabaseKey; -use ClntDev\Scrubber\Contracts\DatabaseUpdate; +use ClntDev\Scrubber\Contracts\DatabaseHandler; -class Database implements DatabaseUpdate +class Database implements DatabaseHandler { - public array $entries; + public array $entries = []; + + public array $deletedEntries = []; + + public array $truncatedEntries = []; public function __construct() { @@ -43,4 +47,31 @@ public function update( return true; } + + public function delete( + string $table, + string $field, + string $value, + array|int|string $primaryKeyValue, + DatabaseKey $primaryKey + ): bool { + $this->deletedEntries[] = [ + 'table' => $table, + 'field' => $field, + 'value' => $value, + 'primaryKeyValue' => $primaryKeyValue, + 'primaryKey' => $primaryKey->getNames(), + ]; + + return true; + } + + public function truncate(string $table): bool + { + $this->truncatedEntries[] = [ + 'table' => $table, + ]; + + return true; + } } diff --git a/tests/Support/Fakes/FakeHandler.php b/tests/Support/Fakes/FakeHandler.php index 9c96732..5f32bab 100644 --- a/tests/Support/Fakes/FakeHandler.php +++ b/tests/Support/Fakes/FakeHandler.php @@ -2,11 +2,11 @@ namespace ClntDev\Scrubber\Tests\Support\Fakes; -use ClntDev\Scrubber\Handlers\Handler; +use ClntDev\Scrubber\DataHandlers\Handler; class FakeHandler extends Handler { - public function handle(): string //phpcs:ignore + public function getValue(): string //phpcs:ignore { return 'fake-handler'; } diff --git a/tests/Support/HandlerFactory.php b/tests/Support/HandlerFactory.php index c51f7c4..8b741c9 100644 --- a/tests/Support/HandlerFactory.php +++ b/tests/Support/HandlerFactory.php @@ -2,12 +2,13 @@ namespace ClntDev\Scrubber\Tests\Support; -use ClntDev\Scrubber\Handlers\Handler; +use ClntDev\Scrubber\DataHandlers\Handler; class HandlerFactory { + /** @param class-string $handlerClass */ public function create(string $handlerClass, mixed $input): Handler { - return new $handlerClass('test_table', 'test_field', $input); + return new $handlerClass($input, null, 'scrubber'); } } diff --git a/tests/Support/config-delete-matching-rows.php b/tests/Support/config-delete-matching-rows.php new file mode 100644 index 0000000..34f6010 --- /dev/null +++ b/tests/Support/config-delete-matching-rows.php @@ -0,0 +1,11 @@ + [ + 'is_admin' => [ + 'primary_key' => 'id', + 'delete_matching_rows' => true, + 'value' => '1', + ], + ], +]; diff --git a/tests/Support/config-ignore.php b/tests/Support/config-ignore.php new file mode 100644 index 0000000..741884b --- /dev/null +++ b/tests/Support/config-ignore.php @@ -0,0 +1,22 @@ + [ + 'foobar' => [ + 'primary_key' => 'id', + 'value' => 'faker.firstName', + 'type' => 'pid', + ], + ], + 'not_ignored2' => [ + 'is_admin' => [ + 'primary_key' => 'id', + 'value' => '1', + ], + ], + 'users' => [ + '*' => [ + 'ignore' => true, + ], + ], +]; diff --git a/tests/Support/config-invalid.php b/tests/Support/config-invalid.php index eab848a..78c8c57 100644 --- a/tests/Support/config-invalid.php +++ b/tests/Support/config-invalid.php @@ -1,6 +1,6 @@ [ diff --git a/tests/Support/config-truncate.php b/tests/Support/config-truncate.php new file mode 100644 index 0000000..9694a38 --- /dev/null +++ b/tests/Support/config-truncate.php @@ -0,0 +1,9 @@ + [ + '*' => [ + 'truncate' => true, + ], + ], +]; diff --git a/tests/Support/config.php b/tests/Support/config.php index 63714b1..9840634 100644 --- a/tests/Support/config.php +++ b/tests/Support/config.php @@ -1,6 +1,6 @@ [ diff --git a/tests/Unit/Handlers/ArrayHandlerTest.php b/tests/Unit/Handlers/ArrayHandlerTest.php index 480b007..c49491d 100644 --- a/tests/Unit/Handlers/ArrayHandlerTest.php +++ b/tests/Unit/Handlers/ArrayHandlerTest.php @@ -2,7 +2,7 @@ namespace ClntDev\Scrubber\Tests\Handlers; -use ClntDev\Scrubber\Handlers\ArrayHandler; +use ClntDev\Scrubber\DataHandlers\ArrayHandler; use ClntDev\Scrubber\Tests\TestCase; use stdClass; use Throwable; @@ -14,7 +14,7 @@ public function the_array_handler_returns_the_expected_value(): void { $handler = $this->handlerFactory->create(ArrayHandler::class, ['one', 'two']); - $this->assertEquals(json_encode(['one', 'two'], JSON_THROW_ON_ERROR), $handler->handle()); + $this->assertEquals(json_encode(['one', 'two'], JSON_THROW_ON_ERROR), $handler->getValue()); } /** @test */ @@ -23,7 +23,7 @@ public function the_array_handler_throws_exception_if_input_is_invalid(): void $handler = $this->handlerFactory->create(ArrayHandler::class, 'string'); try { - $handler->handle(); + $handler->getValue(); } catch (Throwable $exception) { $this->assertEquals('ArrayHandler input is not an array, string given', $exception->getMessage()); return; diff --git a/tests/Unit/Handlers/CallableHandlerTest.php b/tests/Unit/Handlers/CallableHandlerTest.php index d8235ab..d89c7b9 100644 --- a/tests/Unit/Handlers/CallableHandlerTest.php +++ b/tests/Unit/Handlers/CallableHandlerTest.php @@ -2,7 +2,7 @@ namespace ClntDev\Scrubber\Tests\Handlers; -use ClntDev\Scrubber\Handlers\CallableHandler; +use ClntDev\Scrubber\DataHandlers\CallableHandler; use ClntDev\Scrubber\Tests\TestCase; use Closure; use stdClass; @@ -24,7 +24,7 @@ public function the_callable_handler_returns_the_expected_value(): void { $handler = $this->handlerFactory->create(CallableHandler::class, $this->callable); - $this->assertEquals('Test Callable', $handler->handle()); + $this->assertEquals('Test Callable', $handler->getValue()); } /** @test */ @@ -33,7 +33,7 @@ public function the_callable_handler_throws_exception_if_input_is_not_an_object_ $handler = $this->handlerFactory->create(CallableHandler::class, ['one', 'two']); try { - $handler->handle(); + $handler->getValue(); } catch (Throwable $exception) { $this->assertEquals('CallableHandler input is not callable', $exception->getMessage()); return; diff --git a/tests/Unit/Handlers/FakerHandlerTest.php b/tests/Unit/Handlers/FakerHandlerTest.php index 0f470c8..bd76085 100644 --- a/tests/Unit/Handlers/FakerHandlerTest.php +++ b/tests/Unit/Handlers/FakerHandlerTest.php @@ -2,7 +2,7 @@ namespace ClntDev\Scrubber\Tests\Handlers; -use ClntDev\Scrubber\Handlers\FakerHandler; +use ClntDev\Scrubber\DataHandlers\FakerHandler; use ClntDev\Scrubber\Tests\TestCase; use Faker\Factory as Faker; use Faker\Generator as FakerGenerator; @@ -25,7 +25,7 @@ public function the_faker_handler_returns_the_expected_value(): void { $handler = $this->handlerFactory->create(FakerHandler::class, 'faker.sentence'); - $this->assertNotEmpty($handler->handle()); + $this->assertNotEmpty($handler->getValue()); } /** @test */ @@ -34,7 +34,7 @@ public function the_faker_handler_throws_exception_if_input_is_invalid(): void $handler = $this->handlerFactory->create(FakerHandler::class, 'fakerinvalid.string'); try { - $handler->handle(); + $handler->getValue(); } catch (Throwable $exception) { $this->assertEquals('FakerHandler invalid faker input format given', $exception->getMessage()); return; diff --git a/tests/Unit/Handlers/IntegerHandlerTest.php b/tests/Unit/Handlers/IntegerHandlerTest.php index e7053f3..069cb3a 100644 --- a/tests/Unit/Handlers/IntegerHandlerTest.php +++ b/tests/Unit/Handlers/IntegerHandlerTest.php @@ -2,7 +2,7 @@ namespace ClntDev\Scrubber\Tests\Handlers; -use ClntDev\Scrubber\Handlers\IntegerHandler; +use ClntDev\Scrubber\DataHandlers\IntegerHandler; use ClntDev\Scrubber\Tests\TestCase; use Throwable; @@ -13,7 +13,7 @@ public function the_integer_handler_returns_the_expected_value(): void { $handler = $this->handlerFactory->create(IntegerHandler::class, '1'); - $this->assertEquals(1, $handler->handle()); + $this->assertEquals(1, $handler->getValue()); } /** @test */ @@ -22,7 +22,7 @@ public function the_integer_handler_throws_exception_if_input_is_invalid(): void $handler = $this->handlerFactory->create(IntegerHandler::class, ['one', 'two']); try { - $handler->handle(); + $handler->getValue(); } catch (Throwable $exception) { $this->assertEquals('IntegerHandler input is not numeric, array given', $exception->getMessage()); return; diff --git a/tests/Unit/Handlers/ObjectHandlerTest.php b/tests/Unit/Handlers/ObjectHandlerTest.php index 595a74f..76e357f 100644 --- a/tests/Unit/Handlers/ObjectHandlerTest.php +++ b/tests/Unit/Handlers/ObjectHandlerTest.php @@ -2,7 +2,7 @@ namespace ClntDev\Scrubber\Tests\Handlers; -use ClntDev\Scrubber\Handlers\ObjectHandler; +use ClntDev\Scrubber\DataHandlers\ObjectHandler; use ClntDev\Scrubber\Tests\Support\Fakes\CallableTestObject; use ClntDev\Scrubber\Tests\Support\Fakes\HandleTestObject; use ClntDev\Scrubber\Tests\Support\Fakes\InvalidTestObject; @@ -17,7 +17,7 @@ public function the_object_handler_returns_the_expected_handle_test_object_value { $handler = $this->handlerFactory->create(ObjectHandler::class, new HandleTestObject); - $this->assertEquals('handle', $handler->handle()); + $this->assertEquals('handle', $handler->getValue()); } /** @test */ @@ -25,7 +25,7 @@ public function the_object_handler_returns_the_expected_invoke_test_object_value { $handler = $this->handlerFactory->create(ObjectHandler::class, new InvokeTestObject); - $this->assertEquals('__invoke', $handler->handle()); + $this->assertEquals('__invoke', $handler->getValue()); } /** @test */ @@ -33,7 +33,7 @@ public function the_object_handler_can_also_handle_a_callable_value(): void { $handler = $this->handlerFactory->create(ObjectHandler::class, new CallableTestObject); - $this->assertEquals('callable', $handler->handle()); + $this->assertEquals('callable', $handler->getValue()); } /** @test */ @@ -42,7 +42,7 @@ public function the_object_handler_logs_exception_if_input_is_not_an_object_or_o $handler = $this->handlerFactory->create(ObjectHandler::class, ['one', 'two']); try { - $handler->handle(); + $handler->getValue(); } catch (Throwable $exception) { $this->assertEquals('CallableHandler input is not an object', $exception->getMessage()); return; @@ -57,7 +57,7 @@ public function the_object_handler_logs_exception_if_input_does_not_have_expecte $handler = $this->handlerFactory->create(ObjectHandler::class, new InvalidTestObject); try { - $handler->handle(); + $handler->getValue(); } catch (Throwable $exception) { $this->assertEquals( 'CallableHandler __invoke or handle method not found on ' diff --git a/tests/Unit/Handlers/StringHandlerTest.php b/tests/Unit/Handlers/StringHandlerTest.php index a92d557..fd7bde6 100644 --- a/tests/Unit/Handlers/StringHandlerTest.php +++ b/tests/Unit/Handlers/StringHandlerTest.php @@ -2,7 +2,7 @@ namespace ClntDev\Scrubber\Tests\Handlers; -use ClntDev\Scrubber\Handlers\StringHandler; +use ClntDev\Scrubber\DataHandlers\StringHandler; use ClntDev\Scrubber\Tests\TestCase; use Throwable; @@ -13,7 +13,7 @@ public function the_string_handler_returns_the_expected_value(): void { $handler = $this->handlerFactory->create(StringHandler::class, 1); - $this->assertEquals('1', $handler->handle()); + $this->assertEquals('1', $handler->getValue()); } /** @test */ @@ -22,7 +22,7 @@ public function the_string_handler_logs_exception_if_input_is_invalid(): void $handler = $this->handlerFactory->create(StringHandler::class, ['one', 'two']); try { - $handler->handle(); + $handler->getValue(); } catch (Throwable $exception) { $this->assertEquals('StringHandler input is not stringable, array given', $exception->getMessage()); return; diff --git a/tests/Unit/ScrubberTest.php b/tests/Unit/ScrubberTest.php index 9304c2d..6ece342 100644 --- a/tests/Unit/ScrubberTest.php +++ b/tests/Unit/ScrubberTest.php @@ -2,8 +2,8 @@ namespace ClntDev\Scrubber\Tests\Unit; -use ClntDev\Scrubber\Contracts\DatabaseUpdate; -use ClntDev\Scrubber\Exceptions\ValueNotFound; +use ClntDev\Scrubber\Contracts\DatabaseHandler; +use ClntDev\Scrubber\Exceptions\HandlerNotFound; use ClntDev\Scrubber\Scrubber; use ClntDev\Scrubber\Tests\Support\Fakes\Database; use ClntDev\Scrubber\Tests\Support\Fakes\DatabaseThatIgnoresCompositeKeys; @@ -12,7 +12,7 @@ class ScrubberTest extends TestCase { - protected DatabaseUpdate $database; + protected DatabaseHandler $database; protected string $configPath; @@ -189,7 +189,7 @@ public function it_logs_any_errors_thrown_during_runtime(): void /** @test */ public function an_exception_is_thrown_if_the_config_is_invalid_on_run(): void { - $this->expectException(ValueNotFound::class); + $this->expectException(HandlerNotFound::class); Scrubber::make( __DIR__ . '/../Support/config-invalid.php', @@ -256,4 +256,59 @@ public function it_can_get_the_comma_separated_field_list_for_the_given_type(): $scrubber->getFieldListAsString('pid') ); } + + /** @test */ + public function deletes_rows_that_match_field_value(): void + { + $this->markTestSkipped(); + Scrubber::make( + __DIR__ . '/../Support/config-delete-matching-rows.php', + $this->database, + $this->logger + )->run(); + + $this->assertNotEmpty($this->database->deletedEntries); + } + + /** @test */ + public function truncates_table(): void + { + Scrubber::make( + __DIR__ . '/../Support/config-truncate.php', + $this->database, + $this->logger + )->run(); + + $this->assertNotEmpty($this->database->truncatedEntries); + } + + /** @test */ + public function gets_ignored_tables(): void + { + $scrubber = Scrubber::make( + __DIR__ . '/../Support/config-ignore.php', + $this->database, + $this->logger + ); + + $this->assertEquals( + ['users'], + $scrubber->getIgnoredTableList() + ); + } + + /** @test */ + public function gets_all_tables(): void + { + $scrubber = Scrubber::make( + __DIR__ . '/../Support/config-ignore.php', + $this->database, + $this->logger + ); + + $this->assertEquals( + ['not_ignored1', 'not_ignored2', 'users'], + $scrubber->getTableList() + ); + } } diff --git a/tests/Unit/Util/ConfigurationParserTest.php b/tests/Unit/Util/ConfigurationParserTest.php index 873150a..a09ffbd 100644 --- a/tests/Unit/Util/ConfigurationParserTest.php +++ b/tests/Unit/Util/ConfigurationParserTest.php @@ -2,10 +2,13 @@ namespace ClntDev\Scrubber\Tests\Unit\Util; +use ClntDev\Scrubber\Contracts\ScrubHandler; +use ClntDev\Scrubber\Exceptions\HandlerNotFound; use ClntDev\Scrubber\Exceptions\ValueNotFound; -use ClntDev\Scrubber\Handlers\CallableHandler; -use ClntDev\Scrubber\Handlers\FakerHandler; -use ClntDev\Scrubber\Handlers\StringHandler; +use ClntDev\Scrubber\DataHandlers\CallableHandler; +use ClntDev\Scrubber\DataHandlers\FakerHandler; +use ClntDev\Scrubber\DataHandlers\StringHandler; +use ClntDev\Scrubber\ScrubHandlers\Update; use ClntDev\Scrubber\Tests\TestCase; use ClntDev\Scrubber\Util\ConfigurationParser; @@ -29,9 +32,21 @@ public function it_can_create_the_parser_from_a_static_make_method(): void /** @test */ public function it_can_parse_the_test_config_into_the_expected_handlers(): void { + /** @var ScrubHandler[] $result */ $result = $this->parser->parse(); - $expectedHandlers = [ + $expectedScrubHandlers = [ + Update::class, + Update::class, + Update::class, + Update::class, + Update::class, + Update::class, + Update::class, + Update::class, + ]; + + $expectedDataHandlers = [ FakerHandler::class, FakerHandler::class, FakerHandler::class, @@ -44,8 +59,9 @@ public function it_can_parse_the_test_config_into_the_expected_handlers(): void $this->assertCount(9, $result); - for ($i = 0, $iMax = count($expectedHandlers); $i < $iMax; $i++) { //phpcs:ignore - $this->assertInstanceOf($expectedHandlers[$i], $result[$i]); + for ($i = 0, $iMax = count($expectedScrubHandlers); $i < $iMax; $i++) { //phpcs:ignore + $this->assertInstanceOf($expectedScrubHandlers[$i], $result[$i]); + $this->assertInstanceOf($expectedDataHandlers[$i], $result[$i]->getDataHandler()); } } @@ -58,11 +74,11 @@ public function it_returns_an_empty_array_if_parsed_config_is_empty(): void } /** @test */ - public function it_throws_a_value_not_found_exception_if_the_value_key_is_not_defined(): void + public function it_throws_a_handler_not_found_exception_if_the_value_key_is_not_defined(): void { $this->parser = ConfigurationParser::make(__DIR__ . '/../../Support/config-invalid.php'); - $this->expectException(ValueNotFound::class); + $this->expectException(HandlerNotFound::class); $this->parser->parse(); } diff --git a/tests/Unit/Util/HandlerRegistryTest.php b/tests/Unit/Util/SelfDetectingHandlerRegistryTest.php similarity index 66% rename from tests/Unit/Util/HandlerRegistryTest.php rename to tests/Unit/Util/SelfDetectingHandlerRegistryTest.php index be6ee06..3f9ec87 100644 --- a/tests/Unit/Util/HandlerRegistryTest.php +++ b/tests/Unit/Util/SelfDetectingHandlerRegistryTest.php @@ -3,24 +3,25 @@ namespace ClntDev\Scrubber\Tests\Unit\Util; use ClntDev\Scrubber\Exceptions\HandlerNotFound; -use ClntDev\Scrubber\Handlers\ArrayHandler; -use ClntDev\Scrubber\Handlers\CallableHandler; -use ClntDev\Scrubber\Handlers\FakerHandler; -use ClntDev\Scrubber\Handlers\IntegerHandler; -use ClntDev\Scrubber\Handlers\ObjectHandler; -use ClntDev\Scrubber\Handlers\StringHandler; +use ClntDev\Scrubber\DataHandlers\ArrayHandler; +use ClntDev\Scrubber\DataHandlers\CallableHandler; +use ClntDev\Scrubber\DataHandlers\FakerHandler; +use ClntDev\Scrubber\DataHandlers\IntegerHandler; +use ClntDev\Scrubber\DataHandlers\ObjectHandler; +use ClntDev\Scrubber\DataHandlers\StringHandler; +use ClntDev\Scrubber\ScrubHandlers\Update; use ClntDev\Scrubber\Tests\Support\Fakes\FakeHandler; use ClntDev\Scrubber\Tests\Support\Fakes\InvalidTestObject; use ClntDev\Scrubber\Tests\TestCase; -use ClntDev\Scrubber\Util\HandlerRegistry; +use ClntDev\Scrubber\Util\SelfDetectingHandlerRegistry; -class HandlerRegistryTest extends TestCase +class SelfDetectingHandlerRegistryTest extends TestCase { - protected HandlerRegistry $registry; + protected SelfDetectingHandlerRegistry $registry; protected function setUp(): void { - $this->registry = new HandlerRegistry; + $this->registry = SelfDetectingHandlerRegistry::makeForDataHandlers(); parent::setUp(); } @@ -40,6 +41,18 @@ public function it_populates_handlers_with_all_expected_core_handlers(): void $this->assertEquals($expectedHandlers, $this->registry->getHandlers()); } + /** @test */ + public function it_populates_handlers_with_all_expected_scrub_handlers(): void + { + $this->registry = SelfDetectingHandlerRegistry::makeForScrubHandlers(); + + $expectedHandlers = [ + Update::class, + ]; + + $this->assertEquals($expectedHandlers, $this->registry->getHandlers()); + } + /** @test */ public function it_is_possible_to_add_an_additional_handler(): void {