diff --git a/CHANGELOG.md b/CHANGELOG.md index e3257b06..465e8fd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Latest * [#241](https://github.com/cleverage/process-bundle/issues/241) Fix CsvWriterTask: a non-array input throws the documented `\UnexpectedValueException` instead of a `TypeError` when `headers` is `null`, and the CSV tasks release their file on `finalize()` so that the task can be executed again. Update documentation, add tests. * [#240](https://github.com/cleverage/process-bundle/issues/240) Fix FileMoverTask: with `autoincrement`, the suffix was computed on the whole path (a dot in a directory name was taken as the extension, making the move fail for a file without extension) and an existing numeric suffix of the file name was replaced (`report-2024.csv` became `report-1.csv`). The suffix is now appended to the file name only (`report-2024-1.csv`, `file-1`, `.env-1`). Update documentation, add tests. * [#243](https://github.com/cleverage/process-bundle/issues/243) Fix RecursivePropertySetterTransformer: a `\stdClass` item without the property was replaced by a copy in the output, so the input object was not modified; the property is now added to the item itself. Update documentation, add tests. +* [#242](https://github.com/cleverage/process-bundle/issues/242) Fix InputFileReaderTask: an input that is not a non-empty string (e.g. `null`) throws an explicit `\UnexpectedValueException` (`No file path given as input`) instead of a PHP warning followed by a `TypeError`. Update documentation, add tests. v5.1 ----- diff --git a/docs/reference/tasks/input_file_reader_task.md b/docs/reference/tasks/input_file_reader_task.md index 39e5e06b..ac9413f9 100644 --- a/docs/reference/tasks/input_file_reader_task.md +++ b/docs/reference/tasks/input_file_reader_task.md @@ -12,8 +12,8 @@ Task reference Accepted inputs --------------- -`string`: path of the file to read. An `\UnexpectedValueException` is thrown if the file does not exist or is not -readable. +`string`: path of the file to read. An `\UnexpectedValueException` is thrown if the input is not a non-empty string +(e.g. `null`, `''`), or if the file does not exist or is not readable. Possible outputs ---------------- diff --git a/src/Task/File/InputFileReaderTask.php b/src/Task/File/InputFileReaderTask.php index b2b36178..9d002370 100644 --- a/src/Task/File/InputFileReaderTask.php +++ b/src/Task/File/InputFileReaderTask.php @@ -21,6 +21,13 @@ */ class InputFileReaderTask extends FileReaderTask { + #[\Override] + public function initialize(ProcessState $state): void + { + // Only validate the options: the file path comes from the input + parent::getOptions($state); + } + /** * @return array */ @@ -28,9 +35,11 @@ class InputFileReaderTask extends FileReaderTask protected function getOptions(ProcessState $state): array { $options = parent::getOptions($state); - if (null !== $state->getInput()) { - $options['filename'] = $state->getInput(); + $filename = $state->getInput(); + if (!\is_string($filename) || '' === $filename) { + throw new \UnexpectedValueException('No file path given as input'); } + $options['filename'] = $filename; return $options; } diff --git a/tests/Task/File/InputFileReaderTaskTest.php b/tests/Task/File/InputFileReaderTaskTest.php index 96551daf..bcbd10da 100644 --- a/tests/Task/File/InputFileReaderTaskTest.php +++ b/tests/Task/File/InputFileReaderTaskTest.php @@ -107,6 +107,29 @@ public function testThrowsWhenInputFileIsNotReadable(): void $this->read($task, $state, $filename); } + /** + * @return iterable + */ + public static function invalidInputProvider(): iterable + { + yield 'null' => [null]; + yield 'empty string' => ['']; + yield 'array' => [['a.txt']]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('invalidInputProvider')] + public function testThrowsWhenNoFilePathIsGivenAsInput(mixed $input): void + { + $task = new InputFileReaderTask(); + $state = $this->createState([]); + $task->initialize($state); + + $this->expectException(\UnexpectedValueException::class); + $this->expectExceptionMessage('No file path given as input'); + + $this->read($task, $state, $input); + } + public function testRejectsFilenameOption(): void { $task = new InputFileReaderTask();