From da28a533751ad28d637f28c6301efe317595d616 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Thu, 27 Jan 2022 19:36:14 +0100 Subject: [PATCH] [8.x] Fix autoresolving model name from factory (#40616) * Fix autoresolving model name from factory * Reverse change to fallback factory * Add test --- .../Database/Eloquent/Factories/Factory.php | 8 ++++++-- .../Database/DatabaseEloquentFactoryTest.php | 13 +++++++++++++ .../Fixtures/Factories/Money/PriceFactory.php | 15 +++++++++++++++ .../Database/Fixtures/Models/Money/Price.php | 19 +++++++++++++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tests/Database/Fixtures/Factories/Money/PriceFactory.php create mode 100644 tests/Database/Fixtures/Models/Money/Price.php diff --git a/src/Illuminate/Database/Eloquent/Factories/Factory.php b/src/Illuminate/Database/Eloquent/Factories/Factory.php index 0735b8c0270b..56826e765a52 100644 --- a/src/Illuminate/Database/Eloquent/Factories/Factory.php +++ b/src/Illuminate/Database/Eloquent/Factories/Factory.php @@ -686,12 +686,16 @@ public function newModel(array $attributes = []) public function modelName() { $resolver = static::$modelNameResolver ?: function (self $factory) { + $namespacedFactoryBasename = Str::replaceLast( + 'Factory', '', Str::replaceFirst(static::$namespace, '', get_class($factory)) + ); + $factoryBasename = Str::replaceLast('Factory', '', class_basename($factory)); $appNamespace = static::appNamespace(); - return class_exists($appNamespace.'Models\\'.$factoryBasename) - ? $appNamespace.'Models\\'.$factoryBasename + return class_exists($appNamespace.'Models\\'.$namespacedFactoryBasename) + ? $appNamespace.'Models\\'.$namespacedFactoryBasename : $appNamespace.$factoryBasename; }; diff --git a/tests/Database/DatabaseEloquentFactoryTest.php b/tests/Database/DatabaseEloquentFactoryTest.php index 3b7e28217b49..52b6971ad3f5 100644 --- a/tests/Database/DatabaseEloquentFactoryTest.php +++ b/tests/Database/DatabaseEloquentFactoryTest.php @@ -12,6 +12,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\Sequence; use Illuminate\Database\Eloquent\Model as Eloquent; +use Illuminate\Tests\Database\Fixtures\Models\Money\Price; use Mockery; use PHPUnit\Framework\TestCase; @@ -469,6 +470,18 @@ public function test_resolve_nested_model_factories() } } + public function test_resolve_nested_model_name_from_factory() + { + Container::getInstance()->instance(Application::class, $app = Mockery::mock(Application::class)); + $app->shouldReceive('getNamespace')->andReturn('Illuminate\\Tests\\Database\\Fixtures\\'); + + Factory::useNamespace('Illuminate\\Tests\\Database\\Fixtures\\Factories\\'); + + $factory = Price::factory(); + + $this->assertSame(Price::class, $factory->modelName()); + } + public function test_resolve_non_app_nested_model_factories() { Container::getInstance()->instance(Application::class, $app = Mockery::mock(Application::class)); diff --git a/tests/Database/Fixtures/Factories/Money/PriceFactory.php b/tests/Database/Fixtures/Factories/Money/PriceFactory.php new file mode 100644 index 000000000000..bf49e8be2176 --- /dev/null +++ b/tests/Database/Fixtures/Factories/Money/PriceFactory.php @@ -0,0 +1,15 @@ + $this->faker->name, + ]; + } +} diff --git a/tests/Database/Fixtures/Models/Money/Price.php b/tests/Database/Fixtures/Models/Money/Price.php new file mode 100644 index 000000000000..7fd74460736d --- /dev/null +++ b/tests/Database/Fixtures/Models/Money/Price.php @@ -0,0 +1,19 @@ +