Skip to content

Commit 200c6fe

Browse files
committed
uploaded file
1 parent 4169c8f commit 200c6fe

File tree

2 files changed

+127
-2
lines changed

2 files changed

+127
-2
lines changed

src/Illuminate/Foundation/Http/TypedFormRequestFactory.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
use ReflectionParameter;
3232
use ReflectionType;
3333
use ReflectionUnionType;
34-
use SplFileInfo;
3534
use stdClass;
3635

3736
use function Illuminate\Support\enum_value;
@@ -648,7 +647,7 @@ protected function isDateObjectType(string $name): bool
648647
*/
649648
protected function isFile(string $name): bool
650649
{
651-
return is_a($name, SplFileInfo::class, true);
650+
return is_a($name, UploadedFile::class, true);
652651
}
653652

654653
/**

tests/Integration/Http/TypedRequestTest.php

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Illuminate\Foundation\Http\Attributes\WithoutInferringRules;
1515
use Illuminate\Foundation\Http\TypedFormRequest;
1616
use Illuminate\Http\Request;
17+
use Illuminate\Http\UploadedFile;
1718
use Illuminate\Support\Collection;
1819
use Illuminate\Validation\Rule;
1920
use Illuminate\Validation\ValidationException;
@@ -1436,6 +1437,103 @@ public function testStopOnFirstFailureAttributeReportsOnlyOneError()
14361437
$this->assertArrayNotHasKey('age', $e->errors());
14371438
}
14381439
}
1440+
1441+
public function testUploadedFileTypeAcceptsValidFile()
1442+
{
1443+
$file = UploadedFile::fake()->create('document.pdf', 100);
1444+
1445+
$request = Request::create('', 'POST', ['title' => 'My Doc'], files: ['attachment' => $file]);
1446+
$this->app->instance('request', $request);
1447+
1448+
$actual = $this->app->make(FileUploadRequest::class);
1449+
1450+
$this->assertSame('My Doc', $actual->title);
1451+
$this->assertInstanceOf(UploadedFile::class, $actual->attachment);
1452+
$this->assertSame('document.pdf', $actual->attachment->getClientOriginalName());
1453+
}
1454+
1455+
public function testUploadedFileTypeRejectsNonFileInput()
1456+
{
1457+
$request = Request::create('', 'POST', [
1458+
'title' => 'My Doc',
1459+
'attachment' => 'not-a-file',
1460+
]);
1461+
$this->app->instance('request', $request);
1462+
1463+
try {
1464+
$this->app->make(FileUploadRequest::class);
1465+
self::fail('No exception thrown!');
1466+
} catch (ValidationException $e) {
1467+
$this->assertArrayHasKey('attachment', $e->errors());
1468+
}
1469+
}
1470+
1471+
public function testUploadedFileTypeMissingRequiredFileFails()
1472+
{
1473+
$request = Request::create('', 'POST', ['title' => 'My Doc']);
1474+
$this->app->instance('request', $request);
1475+
1476+
try {
1477+
$this->app->make(FileUploadRequest::class);
1478+
self::fail('No exception thrown!');
1479+
} catch (ValidationException $e) {
1480+
$this->assertArrayHasKey('attachment', $e->errors());
1481+
}
1482+
}
1483+
1484+
public function testNullableUploadedFileAcceptsNull()
1485+
{
1486+
$request = Request::create('', 'POST', [
1487+
'title' => 'My Doc',
1488+
'attachment' => null,
1489+
]);
1490+
$this->app->instance('request', $request);
1491+
1492+
$actual = $this->app->make(NullableFileUploadRequest::class);
1493+
1494+
$this->assertInstanceOf(NullableFileUploadRequest::class, $actual);
1495+
$this->assertSame('My Doc', $actual->title);
1496+
$this->assertNull($actual->attachment);
1497+
}
1498+
1499+
public function testOptionalUploadedFileUsesDefaultWhenOmitted()
1500+
{
1501+
$request = Request::create('', 'POST', ['title' => 'My Doc']);
1502+
$this->app->instance('request', $request);
1503+
1504+
$actual = $this->app->make(NullableFileUploadRequest::class);
1505+
1506+
$this->assertInstanceOf(NullableFileUploadRequest::class, $actual);
1507+
$this->assertNull($actual->attachment);
1508+
}
1509+
1510+
public function testUploadedFileMapFromUseMappedFieldName()
1511+
{
1512+
$file = UploadedFile::fake()->create('photo.jpg', 200);
1513+
1514+
$request = Request::create('', 'POST', ['title' => 'My Photo'], files: ['user_avatar' => $file]);
1515+
$this->app->instance('request', $request);
1516+
1517+
$actual = $this->app->make(MappedFileUploadRequest::class);
1518+
1519+
$this->assertInstanceOf(MappedFileUploadRequest::class, $actual);
1520+
$this->assertInstanceOf(UploadedFile::class, $actual->avatar);
1521+
$this->assertSame('photo.jpg', $actual->avatar->getClientOriginalName());
1522+
}
1523+
1524+
public function testUploadedFileMapFromMissingFileUsesMappedValidationKey()
1525+
{
1526+
$request = Request::create('', 'POST', ['title' => 'My Photo']);
1527+
$this->app->instance('request', $request);
1528+
1529+
try {
1530+
$this->app->make(MappedFileUploadRequest::class);
1531+
self::fail('No exception thrown!');
1532+
} catch (ValidationException $e) {
1533+
$this->assertArrayHasKey('user_avatar', $e->errors());
1534+
$this->assertArrayNotHasKey('avatar', $e->errors());
1535+
}
1536+
}
14391537
}
14401538

14411539
class MyTypedForm extends TypedFormRequest
@@ -1992,3 +2090,31 @@ public function __construct(
19922090
) {
19932091
}
19942092
}
2093+
2094+
class FileUploadRequest extends TypedFormRequest
2095+
{
2096+
public function __construct(
2097+
public string $title,
2098+
public UploadedFile $attachment,
2099+
) {
2100+
}
2101+
}
2102+
2103+
class NullableFileUploadRequest extends TypedFormRequest
2104+
{
2105+
public function __construct(
2106+
public string $title,
2107+
public ?UploadedFile $attachment = null,
2108+
) {
2109+
}
2110+
}
2111+
2112+
class MappedFileUploadRequest extends TypedFormRequest
2113+
{
2114+
public function __construct(
2115+
public string $title,
2116+
#[MapFrom('user_avatar')]
2117+
public UploadedFile $avatar,
2118+
) {
2119+
}
2120+
}

0 commit comments

Comments
 (0)