'aCV.txt', 'type' => 'application/octet-stream', 'tmp_name' => '/private/var/tmp/phpzTQbqP', 'error' => 0, 'size' => 3471 ]; $fileField->setValue($fileFieldValue); $this->assertTrue($form->validationResult()->isValid()); } /** * Test that FileField::validate() is run on FileFields with both single and multi-file syntax * By default FileField::validate() will return true early if the $_FILES super-global does not contain the * corresponding FileField::name. This early return means the files was not fully run through FileField::validate() * So for this test we create an invalid file upload on purpose and test that false was returned which means that * the file was run through FileField::validate() function */ public function testMultiFileSyntaxUploadIsValidated() { $names = [ 'single_file_syntax', 'multi_file_syntax_a[]', 'multi_file_syntax_b[0]', 'multi_file_syntax_c[key]' ]; foreach ($names as $name) { $form = new Form( Controller::curr(), 'Form', new FieldList($fileField = new FileField($name, 'My desc')), new FieldList() ); $fileData = $this->createInvalidUploadedFileData($name, "FileFieldTest.txt"); // FileFields with multi_file_syntax[] files will appear in the $_FILES super-global // with the [] brackets trimmed e.g. $_FILES[multi_file_syntax] $_FILES = [preg_replace('#\[(.*?)\]#', '', $name) => $fileData]; $fileField->setValue($fileData); $validator = $form->getValidator(); $isValid = $fileField->validate($validator); $this->assertFalse($isValid, "$name was run through the validate() function"); } } protected function createInvalidUploadedFileData($name, $tmpFileName): array { $tmpFilePath = TEMP_PATH . DIRECTORY_SEPARATOR . $tmpFileName; // multi_file_syntax if (strpos($name ?? '', '[') !== false) { $key = 0; if (preg_match('#\[(.+?)\]#', $name ?? '', $m)) { $key = $m[1]; } return [ 'name' => [$key => $tmpFileName], 'type' => [$key => 'text/plaintext'], 'size' => [$key => 0], 'tmp_name' => [$key => $tmpFilePath], 'error' => [$key => UPLOAD_ERR_NO_FILE], ]; } // single_file_syntax return [ 'name' => $tmpFileName, 'type' => 'text/plaintext', 'size' => 0, 'tmp_name' => $tmpFilePath, 'error' => UPLOAD_ERR_NO_FILE, ]; } /** * @skipUpgrade */ public function testGetAcceptFileTypes() { $field = new FileField('image', 'Image'); $field->setAllowedExtensions('jpg', 'png'); $method = new ReflectionMethod($field, 'getAcceptFileTypes'); $method->setAccessible(true); $allowed = $method->invoke($field); $expected = ['.jpg', '.png', 'image/jpeg', 'image/png']; foreach ($expected as $extensionOrMime) { $this->assertContains($extensionOrMime, $allowed); } } /** * Test different scenarii for a failed upload : an error occurred, no files where provided * @skipUpgrade */ public function testUploadMissingRequiredFile() { $form = new Form( Controller::curr(), 'Form', new FieldList( $fileField = new FileField('cv', 'Upload your CV') ), new FieldList(), new RequiredFields('cv') ); // All fields are filled but for some reason an error occurred when uploading the file => fails $fileFieldValue = [ 'name' => 'aCV.txt', 'type' => 'application/octet-stream', 'tmp_name' => '/private/var/tmp/phpzTQbqP', 'error' => 1, 'size' => 3471 ]; $fileField->setValue($fileFieldValue); $this->assertFalse( $form->validationResult()->isValid(), 'An error occurred when uploading a file, but the validator returned true' ); // We pass an empty set of parameters for the uploaded file => fails $fileFieldValue = []; $fileField->setValue($fileFieldValue); $this->assertFalse( $form->validationResult()->isValid(), 'An empty array was passed as parameter for an uploaded file, but the validator returned true' ); // We pass an null value for the uploaded file => fails $fileFieldValue = null; $fileField->setValue($fileFieldValue); $this->assertFalse( $form->validationResult()->isValid(), 'A null value was passed as parameter for an uploaded file, but the validator returned true' ); } }