From 5e9e4b8da8ea5c2d23bb7b119f634f57df770561 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Wed, 20 Sep 2023 21:58:30 +0800 Subject: [PATCH] Test Improvements (#1688) * Test Improvements Signed-off-by: Mior Muhammad Zaki * wip Signed-off-by: Mior Muhammad Zaki --------- Signed-off-by: Mior Muhammad Zaki --- composer.json | 10 ++- testbench.yaml | 5 ++ tests/Feature/AccessTokenControllerTest.php | 83 +++++++------------- tests/Feature/ActingAsTest.php | 20 ++--- tests/Feature/KeysCommandTest.php | 10 --- tests/Feature/PassportTestCase.php | 59 +++++--------- workbench/app/Models/User.php | 42 ++++++++++ workbench/database/factories/UserFactory.php | 20 +++++ 8 files changed, 129 insertions(+), 120 deletions(-) create mode 100644 testbench.yaml create mode 100644 workbench/app/Models/User.php create mode 100644 workbench/database/factories/UserFactory.php diff --git a/composer.json b/composer.json index 2b8b77602..9516d6d87 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ }, "require-dev": { "mockery/mockery": "^1.0", - "orchestra/testbench": "^7.0|^8.0", + "orchestra/testbench": "^7.31|^8.11", "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.3" }, @@ -46,7 +46,9 @@ }, "autoload-dev": { "psr-4": { - "Laravel\\Passport\\Tests\\": "tests/" + "Laravel\\Passport\\Tests\\": "tests/", + "Workbench\\App\\": "workbench/app/", + "Workbench\\Database\\Factories\\": "workbench/database/factories/" } }, "extra": { @@ -62,6 +64,10 @@ "config": { "sort-packages": true }, + "scripts": { + "post-autoload-dump": "@prepare", + "prepare": "@php vendor/bin/testbench package:discover --ansi" + }, "minimum-stability": "dev", "prefer-stable": true } diff --git a/testbench.yaml b/testbench.yaml new file mode 100644 index 000000000..7d0c53214 --- /dev/null +++ b/testbench.yaml @@ -0,0 +1,5 @@ +providers: + - Laravel\Passport\PassportServiceProvider + +migrations: true + diff --git a/tests/Feature/AccessTokenControllerTest.php b/tests/Feature/AccessTokenControllerTest.php index 87d31b3a9..92218333c 100644 --- a/tests/Feature/AccessTokenControllerTest.php +++ b/tests/Feature/AccessTokenControllerTest.php @@ -4,50 +4,26 @@ use Carbon\CarbonImmutable; use Illuminate\Contracts\Hashing\Hasher; -use Illuminate\Database\Schema\Blueprint; -use Illuminate\Support\Facades\Schema; use Laravel\Passport\Client; use Laravel\Passport\Database\Factories\ClientFactory; -use Laravel\Passport\HasApiTokens; use Laravel\Passport\Passport; use Laravel\Passport\PersonalAccessTokenFactory; use Laravel\Passport\Token; +use Orchestra\Testbench\Concerns\WithLaravelMigrations; +use Workbench\Database\Factories\UserFactory; class AccessTokenControllerTest extends PassportTestCase { - protected function setUp(): void - { - parent::setUp(); - - Schema::create('users', function (Blueprint $table) { - $table->increments('id'); - $table->string('email')->unique(); - $table->string('password'); - $table->dateTime('created_at'); - $table->dateTime('updated_at'); - }); - } - - protected function tearDown(): void - { - Schema::dropIfExists('users'); - - parent::tearDown(); - } - - protected function getUserClass() - { - return User::class; - } + use WithLaravelMigrations; public function testGettingAccessTokenWithClientCredentialsGrant() { $this->withoutExceptionHandling(); - $user = new User(); - $user->email = 'foo@gmail.com'; - $user->password = $this->app->make(Hasher::class)->make('foobar123'); - $user->save(); + $user = UserFactory::new()->create([ + 'email' => 'foo@gmail.com', + 'password' => $this->app->make(Hasher::class)->make('foobar123'), + ]); /** @var Client $client */ $client = ClientFactory::new()->asClientCredentials()->create(['user_id' => $user->getKey()]); @@ -87,10 +63,10 @@ public function testGettingAccessTokenWithClientCredentialsGrant() public function testGettingAccessTokenWithClientCredentialsGrantInvalidClientSecret() { - $user = new User(); - $user->email = 'foo@gmail.com'; - $user->password = $this->app->make(Hasher::class)->make('foobar123'); - $user->save(); + $user = UserFactory::new()->create([ + 'email' => 'foo@gmail.com', + 'password' => $this->app->make(Hasher::class)->make('foobar123'), + ]); /** @var Client $client */ $client = ClientFactory::new()->asClientCredentials()->create(['user_id' => $user->getKey()]); @@ -131,10 +107,10 @@ public function testGettingAccessTokenWithPasswordGrant() $this->withoutExceptionHandling(); $password = 'foobar123'; - $user = new User(); - $user->email = 'foo@gmail.com'; - $user->password = $this->app->make(Hasher::class)->make($password); - $user->save(); + $user = UserFactory::new()->create([ + 'email' => 'foo@gmail.com', + 'password' => $this->app->make(Hasher::class)->make($password), + ]); /** @var Client $client */ $client = ClientFactory::new()->asPasswordClient()->create(['user_id' => $user->getKey()]); @@ -178,10 +154,10 @@ public function testGettingAccessTokenWithPasswordGrant() public function testGettingAccessTokenWithPasswordGrantWithInvalidPassword() { $password = 'foobar123'; - $user = new User(); - $user->email = 'foo@gmail.com'; - $user->password = $this->app->make(Hasher::class)->make($password); - $user->save(); + $user = UserFactory::new()->create([ + 'email' => 'foo@gmail.com', + 'password' => $this->app->make(Hasher::class)->make($password), + ]); /** @var Client $client */ $client = ClientFactory::new()->asPasswordClient()->create(['user_id' => $user->getKey()]); @@ -221,10 +197,10 @@ public function testGettingAccessTokenWithPasswordGrantWithInvalidPassword() public function testGettingAccessTokenWithPasswordGrantWithInvalidClientSecret() { $password = 'foobar123'; - $user = new User(); - $user->email = 'foo@gmail.com'; - $user->password = $this->app->make(Hasher::class)->make($password); - $user->save(); + $user = UserFactory::new()->create([ + 'email' => 'foo@gmail.com', + 'password' => $this->app->make(Hasher::class)->make($password), + ]); /** @var Client $client */ $client = ClientFactory::new()->asPasswordClient()->create(['user_id' => $user->getKey()]); @@ -268,10 +244,10 @@ public function testGettingCustomResponseType() $this->withoutExceptionHandling(); Passport::$authorizationServerResponseType = new IdTokenResponse('foo_bar_open_id_token'); - $user = new User(); - $user->email = 'foo@gmail.com'; - $user->password = $this->app->make(Hasher::class)->make('foobar123'); - $user->save(); + $user = UserFactory::new()->create([ + 'email' => 'foo@gmail.com', + 'password' => $this->app->make(Hasher::class)->make('foobar123'), + ]); /** @var Client $client */ $client = ClientFactory::new()->asClientCredentials()->create(['user_id' => $user->getKey()]); @@ -294,11 +270,6 @@ public function testGettingCustomResponseType() } } -class User extends \Illuminate\Foundation\Auth\User -{ - use HasApiTokens; -} - class IdTokenResponse extends \League\OAuth2\Server\ResponseTypes\BearerTokenResponse { /** diff --git a/tests/Feature/ActingAsTest.php b/tests/Feature/ActingAsTest.php index bf0b95319..031d5abf4 100644 --- a/tests/Feature/ActingAsTest.php +++ b/tests/Feature/ActingAsTest.php @@ -3,12 +3,11 @@ namespace Laravel\Passport\Tests\Feature; use Illuminate\Contracts\Routing\Registrar; -use Illuminate\Foundation\Auth\User; use Illuminate\Support\Facades\Route; -use Laravel\Passport\HasApiTokens; use Laravel\Passport\Http\Middleware\CheckForAnyScope; use Laravel\Passport\Http\Middleware\CheckScopes; use Laravel\Passport\Passport; +use Workbench\App\Models\User; class ActingAsTest extends PassportTestCase { @@ -23,7 +22,7 @@ public function testActingAsWhenTheRouteIsProtectedByAuthMiddleware() return 'bar'; })->middleware('auth:api'); - Passport::actingAs(new PassportUser()); + Passport::actingAs(new User()); $response = $this->get('/foo'); $response->assertSuccessful(); @@ -41,7 +40,7 @@ public function testActingAsWhenTheRouteIsProtectedByCheckScopesMiddleware() return 'bar'; })->middleware(CheckScopes::class.':admin,footest'); - Passport::actingAs(new PassportUser(), ['admin', 'footest']); + Passport::actingAs(new User(), ['admin', 'footest']); $response = $this->get('/foo'); $response->assertSuccessful(); @@ -59,7 +58,7 @@ public function testActingAsWhenTheRouteIsProtectedByCheckForAnyScopeMiddleware( return 'bar'; })->middleware(CheckForAnyScope::class.':admin,footest'); - Passport::actingAs(new PassportUser(), ['footest']); + Passport::actingAs(new User(), ['footest']); $response = $this->get('/foo'); $response->assertSuccessful(); @@ -76,7 +75,7 @@ public function testActingAsWhenTheRouteIsProtectedByCheckScopesMiddlewareWithIn return 'bar'; }); - Passport::actingAs(new PassportUser(), ['foo', 'baz']); + Passport::actingAs(new User(), ['foo', 'baz']); $response = $this->get('/foo'); $response->assertSuccessful(); @@ -93,17 +92,10 @@ public function testActingAsWhenTheRouteIsProtectedByCheckForAnyScopeMiddlewareW return 'bar'; }); - Passport::actingAs(new PassportUser(), ['foo']); + Passport::actingAs(new User(), ['foo']); $response = $this->get('/foo'); $response->assertSuccessful(); $response->assertSee('bar'); } } - -class PassportUser extends User -{ - use HasApiTokens; - - protected $table = 'users'; -} diff --git a/tests/Feature/KeysCommandTest.php b/tests/Feature/KeysCommandTest.php index e7d528f82..3d2f4b986 100644 --- a/tests/Feature/KeysCommandTest.php +++ b/tests/Feature/KeysCommandTest.php @@ -2,18 +2,8 @@ namespace Laravel\Passport\Tests\Feature; -use Mockery as m; - class KeysCommandTest extends PassportTestCase { - protected function tearDown(): void - { - m::close(); - - @unlink(self::PUBLIC_KEY); - @unlink(self::PRIVATE_KEY); - } - public function testPrivateAndPublicKeysAreGenerated() { $this->assertFileExists(self::PUBLIC_KEY); diff --git a/tests/Feature/PassportTestCase.php b/tests/Feature/PassportTestCase.php index 8daeb4e6c..3ccf02bdc 100644 --- a/tests/Feature/PassportTestCase.php +++ b/tests/Feature/PassportTestCase.php @@ -3,14 +3,15 @@ namespace Laravel\Passport\Tests\Feature; use Illuminate\Contracts\Config\Repository; -use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Foundation\Testing\LazilyRefreshDatabase; use Laravel\Passport\Passport; -use Laravel\Passport\PassportServiceProvider; +use Orchestra\Testbench\Concerns\WithWorkbench; use Orchestra\Testbench\TestCase; +use Workbench\App\Models\User; abstract class PassportTestCase extends TestCase { - use RefreshDatabase; + use LazilyRefreshDatabase, WithWorkbench; const KEYS = __DIR__.'/../keys'; const PUBLIC_KEY = self::KEYS.'/oauth-public.key'; @@ -18,50 +19,32 @@ abstract class PassportTestCase extends TestCase protected function setUp(): void { - parent::setUp(); + $this->afterApplicationCreated(function () { + Passport::loadKeysFrom(self::KEYS); - $this->artisan('migrate:fresh'); + @unlink(self::PUBLIC_KEY); + @unlink(self::PRIVATE_KEY); - Passport::loadKeysFrom(self::KEYS); + $this->artisan('passport:keys'); + }); - @unlink(self::PUBLIC_KEY); - @unlink(self::PRIVATE_KEY); + $this->beforeApplicationDestroyed(function () { + @unlink(self::PUBLIC_KEY); + @unlink(self::PRIVATE_KEY); + }); - $this->artisan('passport:keys'); + parent::setUp(); } - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { $config = $app->make(Repository::class); - $config->set('auth.defaults.provider', 'users'); - - if (($userClass = $this->getUserClass()) !== null) { - $config->set('auth.providers.users.model', $userClass); - } - - $config->set('auth.guards.api', ['driver' => 'passport', 'provider' => 'users']); - - $app['config']->set('database.default', 'testbench'); - - $app['config']->set('database.connections.testbench', [ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => '', + $config->set([ + 'auth.defaults.provider' => 'users', + 'auth.providers.users.model' => User::class, + 'auth.guards.api' => ['driver' => 'passport', 'provider' => 'users'], + 'database.default' => 'testing', ]); } - - protected function getPackageProviders($app) - { - return [PassportServiceProvider::class]; - } - - /** - * Get the Eloquent user model class name. - * - * @return string|null - */ - protected function getUserClass() - { - } } diff --git a/workbench/app/Models/User.php b/workbench/app/Models/User.php new file mode 100644 index 000000000..6987bfb38 --- /dev/null +++ b/workbench/app/Models/User.php @@ -0,0 +1,42 @@ + + */ + protected $fillable = [ + 'name', + 'email', + 'password', + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + 'password', + 'remember_token', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'email_verified_at' => 'datetime', + ]; +} diff --git a/workbench/database/factories/UserFactory.php b/workbench/database/factories/UserFactory.php new file mode 100644 index 000000000..db6dfa3df --- /dev/null +++ b/workbench/database/factories/UserFactory.php @@ -0,0 +1,20 @@ + + */ +class UserFactory extends \Orchestra\Testbench\Factories\UserFactory +{ + /** + * The name of the factory's corresponding model. + * + * @var class-string<\TModel> + */ + protected $model = User::class; +}