diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f64afb62a99a..d2a186904407 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,6 +11,10 @@ jobs: runs-on: ubuntu-latest services: + memcached: + image: memcached:1.6-alpine + ports: + - 11211:11211 mysql: image: mysql:5.7 env: @@ -44,9 +48,6 @@ jobs: tools: composer:v2 coverage: none - - name: Setup Memcached - uses: niden/actions-memcached@v7 - - name: Setup problem matchers run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" diff --git a/CHANGELOG-6.x.md b/CHANGELOG-6.x.md index ae564658b926..7586408424bb 100644 --- a/CHANGELOG-6.x.md +++ b/CHANGELOG-6.x.md @@ -1,6 +1,13 @@ # Release Notes for 6.x -## [Unreleased](https://github.com/laravel/framework/compare/v6.20.5...6.x) +## [Unreleased](https://github.com/laravel/framework/compare/v6.20.6...6.x) + + +## [v6.20.6 (2020-12-01)](https://github.com/laravel/framework/compare/v6.20.5...v6.20.6) + +### Fixed +- Backport Redis context option ([#35370](https://github.com/laravel/framework/pull/35370)) +- Fixed validating image/jpeg images after Symfony/Mime update ([#35419](https://github.com/laravel/framework/pull/35419)) ## [v6.20.5 (2020-11-24)](https://github.com/laravel/framework/compare/v6.20.4...v6.20.5) diff --git a/docker-compose.yml b/docker-compose.yml index dc02296a48b4..4b129f911cfc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: memcached: - image: memcached:1.5-alpine + image: memcached:1.6-alpine ports: - "11211:11211" restart: always diff --git a/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php b/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php index 92c3758e15f9..c48bd22a54f4 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php +++ b/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php @@ -233,7 +233,7 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null // If the type value is null it is probably safe to assume we're eager loading // the relationship. In this case we'll just pass in a dummy query where we // need to remove any eager loads that may already be defined on a model. - return empty($class = $this->{$type}) + return is_null($class = $this->{$type}) || $class === '' ? $this->morphEagerTo($name, $type, $id, $ownerKey) : $this->morphInstanceTo($class, $name, $type, $id, $ownerKey); } diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index 9632e9b31b64..451a0120b177 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -31,7 +31,7 @@ class Application extends Container implements ApplicationContract, HttpKernelIn * * @var string */ - const VERSION = '6.20.6'; + const VERSION = '6.20.7'; /** * The base path for the Laravel installation. diff --git a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php index 6f566ce09f37..a7a6071ab5b5 100644 --- a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php @@ -1206,6 +1206,10 @@ public function validateMimes($attribute, $value, $parameters) return false; } + if (in_array('jpg', $parameters) || in_array('jpeg', $parameters)) { + $parameters = array_unique(array_merge($parameters, ['jpg', 'jpeg'])); + } + return $value->getPath() !== '' && in_array($value->guessExtension(), $parameters); } diff --git a/tests/Database/DatabaseConnectionTest.php b/tests/Database/DatabaseConnectionTest.php index 7baf935716dc..31273656e56a 100755 --- a/tests/Database/DatabaseConnectionTest.php +++ b/tests/Database/DatabaseConnectionTest.php @@ -153,9 +153,8 @@ public function testTransactionLevelNotIncrementedOnTransactionException() public function testBeginTransactionMethodRetriesOnFailure() { $pdo = $this->createMock(DatabaseConnectionTestMockPDO::class); - $pdo->expects($this->at(0)) - ->method('beginTransaction') - ->will($this->throwException(new ErrorException('server has gone away'))); + $pdo->method('beginTransaction') + ->willReturnOnConsecutiveCalls($this->throwException(new ErrorException('server has gone away'))); $connection = $this->getMockConnection(['reconnect'], $pdo); $connection->expects($this->once())->method('reconnect'); $connection->beginTransaction(); diff --git a/tests/Database/DatabaseEloquentMorphToTest.php b/tests/Database/DatabaseEloquentMorphToTest.php index 5f9049b4a4a5..c01dfd8b924f 100644 --- a/tests/Database/DatabaseEloquentMorphToTest.php +++ b/tests/Database/DatabaseEloquentMorphToTest.php @@ -90,6 +90,16 @@ public function testMorphToWithArrayDefault() $this->assertSame('taylor', $result->username); } + public function testMorphToWithZeroMorphType() + { + $parent = $this->getMockBuilder(EloquentMorphToModelStub::class)->setMethods(['getAttribute', 'morphEagerTo', 'morphInstanceTo'])->getMock(); + $parent->method('getAttribute')->with('relation_type')->willReturn(0); + $parent->expects($this->once())->method('morphInstanceTo'); + $parent->expects($this->never())->method('morphEagerTo'); + + $parent->relation(); + } + public function testMorphToWithSpecifiedClassDefault() { $parent = new EloquentMorphToModelStub; diff --git a/tests/Validation/ValidationValidatorTest.php b/tests/Validation/ValidationValidatorTest.php index 3a968b894c02..b6c6ab2281ae 100755 --- a/tests/Validation/ValidationValidatorTest.php +++ b/tests/Validation/ValidationValidatorTest.php @@ -1787,14 +1787,14 @@ public function testValidateMax() $this->assertFalse($v->passes()); $file = $this->getMockBuilder(UploadedFile::class)->setMethods(['isValid', 'getSize'])->setConstructorArgs([__FILE__, basename(__FILE__)])->getMock(); - $file->expects($this->any())->method('isValid')->willReturn(true); - $file->expects($this->at(1))->method('getSize')->willReturn(3072); + $file->method('isValid')->willReturn(true); + $file->method('getSize')->willReturn(3072); $v = new Validator($trans, ['photo' => $file], ['photo' => 'Max:10']); $this->assertTrue($v->passes()); $file = $this->getMockBuilder(UploadedFile::class)->setMethods(['isValid', 'getSize'])->setConstructorArgs([__FILE__, basename(__FILE__)])->getMock(); - $file->expects($this->at(0))->method('isValid')->willReturn(true); - $file->expects($this->at(1))->method('getSize')->willReturn(4072); + $file->method('isValid')->willReturn(true); + $file->method('getSize')->willReturn(4072); $v = new Validator($trans, ['photo' => $file], ['photo' => 'Max:2']); $this->assertFalse($v->passes()); @@ -2665,49 +2665,49 @@ public function testValidateImage() $file = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); $file->expects($this->any())->method('guessExtension')->willReturn('php'); $file->expects($this->any())->method('getClientOriginalExtension')->willReturn('php'); - $v = new Validator($trans, ['x' => $file], ['x' => 'Image']); + $v = new Validator($trans, ['x' => $file], ['x' => 'image']); $this->assertFalse($v->passes()); $file2 = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); - $file2->expects($this->any())->method('guessExtension')->willReturn('jpeg'); + $file2->expects($this->any())->method('guessExtension')->willReturn('jpg'); $file2->expects($this->any())->method('getClientOriginalExtension')->willReturn('jpeg'); - $v = new Validator($trans, ['x' => $file2], ['x' => 'Image']); + $v = new Validator($trans, ['x' => $file2], ['x' => 'image']); + $this->assertTrue($v->passes()); + + $file2 = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); + $file2->expects($this->any())->method('guessExtension')->willReturn('jpg'); + $file2->expects($this->any())->method('getClientOriginalExtension')->willReturn('jpg'); + $v = new Validator($trans, ['x' => $file2], ['x' => 'image']); $this->assertTrue($v->passes()); $file3 = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); $file3->expects($this->any())->method('guessExtension')->willReturn('gif'); $file3->expects($this->any())->method('getClientOriginalExtension')->willReturn('gif'); - $v = new Validator($trans, ['x' => $file3], ['x' => 'Image']); + $v = new Validator($trans, ['x' => $file3], ['x' => 'image']); $this->assertTrue($v->passes()); $file4 = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); $file4->expects($this->any())->method('guessExtension')->willReturn('bmp'); $file4->expects($this->any())->method('getClientOriginalExtension')->willReturn('bmp'); - $v = new Validator($trans, ['x' => $file4], ['x' => 'Image']); + $v = new Validator($trans, ['x' => $file4], ['x' => 'image']); $this->assertTrue($v->passes()); $file5 = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); $file5->expects($this->any())->method('guessExtension')->willReturn('png'); $file5->expects($this->any())->method('getClientOriginalExtension')->willReturn('png'); - $v = new Validator($trans, ['x' => $file5], ['x' => 'Image']); + $v = new Validator($trans, ['x' => $file5], ['x' => 'image']); $this->assertTrue($v->passes()); $file6 = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); $file6->expects($this->any())->method('guessExtension')->willReturn('svg'); $file6->expects($this->any())->method('getClientOriginalExtension')->willReturn('svg'); - $v = new Validator($trans, ['x' => $file6], ['x' => 'Image']); + $v = new Validator($trans, ['x' => $file6], ['x' => 'image']); $this->assertTrue($v->passes()); $file7 = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); $file7->expects($this->any())->method('guessExtension')->willReturn('webp'); $file7->expects($this->any())->method('getClientOriginalExtension')->willReturn('webp'); - $v = new Validator($trans, ['x' => $file7], ['x' => 'Image']); - $this->assertTrue($v->passes()); - - $file2 = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); - $file2->expects($this->any())->method('guessExtension')->willReturn('jpg'); - $file2->expects($this->any())->method('getClientOriginalExtension')->willReturn('jpg'); - $v = new Validator($trans, ['x' => $file2], ['x' => 'Image']); + $v = new Validator($trans, ['x' => $file7], ['x' => 'image']); $this->assertTrue($v->passes()); } @@ -2719,7 +2719,7 @@ public function testValidateImageDoesNotAllowPhpExtensionsOnImageMime() $file = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); $file->expects($this->any())->method('guessExtension')->willReturn('jpeg'); $file->expects($this->any())->method('getClientOriginalExtension')->willReturn('php'); - $v = new Validator($trans, ['x' => $file], ['x' => 'Image']); + $v = new Validator($trans, ['x' => $file], ['x' => 'image']); $this->assertFalse($v->passes()); } @@ -2832,20 +2832,25 @@ public function testValidateImageDimensions() $this->assertFalse($v->passes()); } - /** - * @requires extension fileinfo - */ - public function testValidatePhpMimetypes() + public function testValidateMimetypes() { $trans = $this->getIlluminateArrayTranslator(); - $uploadedFile = [__DIR__.'/ValidationRuleTest.php', '', null, null, null, true]; - - $file = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); - $file->expects($this->any())->method('guessExtension')->willReturn('rtf'); - $file->expects($this->any())->method('getClientOriginalExtension')->willReturn('rtf'); + $uploadedFile = [__FILE__, '', null, null, null, true]; + $file = $this->getMockBuilder(UploadedFile::class)->setMethods(['getMimeType'])->setConstructorArgs($uploadedFile)->getMock(); + $file->expects($this->any())->method('getMimeType')->willReturn('text/rtf'); $v = new Validator($trans, ['x' => $file], ['x' => 'mimetypes:text/*']); $this->assertTrue($v->passes()); + + $file = $this->getMockBuilder(UploadedFile::class)->setMethods(['getMimeType'])->setConstructorArgs($uploadedFile)->getMock(); + $file->expects($this->any())->method('getMimeType')->willReturn('application/pdf'); + $v = new Validator($trans, ['x' => $file], ['x' => 'mimetypes:text/rtf']); + $this->assertFalse($v->passes()); + + $file = $this->getMockBuilder(UploadedFile::class)->setMethods(['getMimeType'])->setConstructorArgs($uploadedFile)->getMock(); + $file->expects($this->any())->method('getMimeType')->willReturn('image/jpeg'); + $v = new Validator($trans, ['x' => $file], ['x' => 'mimetypes:image/jpeg']); + $this->assertTrue($v->passes()); } public function testValidateMime() @@ -2864,6 +2869,18 @@ public function testValidateMime() $file2->expects($this->any())->method('isValid')->willReturn(false); $v = new Validator($trans, ['x' => $file2], ['x' => 'mimes:pdf']); $this->assertFalse($v->passes()); + + $file = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); + $file->expects($this->any())->method('guessExtension')->willReturn('jpg'); + $file->expects($this->any())->method('getClientOriginalExtension')->willReturn('jpg'); + $v = new Validator($trans, ['x' => $file], ['x' => 'mimes:jpeg']); + $this->assertTrue($v->passes()); + + $file = $this->getMockBuilder(UploadedFile::class)->setMethods(['guessExtension', 'getClientOriginalExtension'])->setConstructorArgs($uploadedFile)->getMock(); + $file->expects($this->any())->method('guessExtension')->willReturn('jpg'); + $file->expects($this->any())->method('getClientOriginalExtension')->willReturn('jpeg'); + $v = new Validator($trans, ['x' => $file], ['x' => 'mimes:jpg']); + $this->assertTrue($v->passes()); } public function testValidateMimeEnforcesPhpCheck()