diff --git a/composer.json b/composer.json index b2f56476..9e008ee7 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ }, "require-dev": { "mockery/mockery": "^1.0", - "orchestra/testbench": "^6.0|^7.0|^8.0", + "orchestra/testbench": "^6.34|^7.31|^8.11", "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.3" }, @@ -33,9 +33,11 @@ }, "autoload-dev": { "psr-4": { - "App\\Models\\": "tests/Fixtures/Models", - "Laravel\\Fortify\\Tests\\": "tests/" - } + "Laravel\\Fortify\\Tests\\": "tests/", + "App\\": "workbench/app/", + "Database\\Factories\\": "workbench/database/factories/" + }, + "classmap": ["stubs/"] }, "extra": { "branch-alias": { @@ -51,5 +53,11 @@ "sort-packages": true }, "minimum-stability": "dev", - "prefer-stable": true + "prefer-stable": true, + "scripts": { + "post-autoload-dump": "@prepare", + "prepare": "@php vendor/bin/testbench package:discover --ansi", + "lint": "@php vendor/bin/phpstan analyse", + "test": "@php vendor/bin/phpunit" + } } diff --git a/testbench.yaml b/testbench.yaml new file mode 100644 index 00000000..b544006c --- /dev/null +++ b/testbench.yaml @@ -0,0 +1,5 @@ +providers: + - Laravel\Fortify\FortifyServiceProvider + +migrations: + - database/migrations diff --git a/tests/AuthenticatedSessionControllerTest.php b/tests/AuthenticatedSessionControllerTest.php index fe40e1cf..fe99c6b3 100644 --- a/tests/AuthenticatedSessionControllerTest.php +++ b/tests/AuthenticatedSessionControllerTest.php @@ -5,6 +5,7 @@ use Illuminate\Cache\RateLimiter; use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Foundation\Auth\User; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Event; @@ -12,7 +13,6 @@ use Laravel\Fortify\Contracts\LoginViewResponse; use Laravel\Fortify\Events\TwoFactorAuthenticationChallenged; use Laravel\Fortify\Features; -use Laravel\Fortify\FortifyServiceProvider; use Laravel\Fortify\LoginRateLimiter; use Laravel\Fortify\TwoFactorAuthenticatable; use Mockery; @@ -20,6 +20,8 @@ class AuthenticatedSessionControllerTest extends OrchestraTestCase { + use RefreshDatabase; + public function test_the_login_view_is_returned() { $this->mock(LoginViewResponse::class) @@ -34,8 +36,6 @@ public function test_the_login_view_is_returned() public function test_user_can_authenticate() { - $this->loadLaravelMigrations(['--database' => 'testbench']); - TestAuthenticationSessionUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -56,12 +56,6 @@ public function test_user_is_redirected_to_challenge_when_using_two_factor_authe app('config')->set('auth.providers.users.model', TestTwoFactorAuthenticationSessionUser::class); - $this->loadLaravelMigrations(['--database' => 'testbench']); - - Schema::table('users', function ($table) { - $table->text('two_factor_secret')->nullable(); - }); - TestTwoFactorAuthenticationSessionUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -89,12 +83,6 @@ public function test_user_is_not_redirected_to_challenge_when_using_two_factor_a Features::twoFactorAuthentication(['confirm' => true]), ]); - $this->loadLaravelMigrations(['--database' => 'testbench']); - - Schema::table('users', function ($table) { - $table->text('two_factor_secret')->nullable(); - }); - TestTwoFactorAuthenticationSessionUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -120,10 +108,7 @@ public function test_user_is_redirected_to_challenge_when_using_two_factor_authe Features::twoFactorAuthentication(['confirm' => true]), ]); - $this->loadLaravelMigrations(['--database' => 'testbench']); - Schema::table('users', function ($table) { - $table->text('two_factor_secret')->nullable(); $table->timestamp('two_factor_confirmed_at')->nullable(); }); @@ -153,12 +138,6 @@ public function test_user_can_authenticate_when_two_factor_challenge_is_disabled app('config')->set('fortify.features', $features); - $this->loadLaravelMigrations(['--database' => 'testbench']); - - Schema::table('users', function ($table) { - $table->text('two_factor_secret')->nullable(); - }); - TestTwoFactorAuthenticationSessionUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -176,8 +155,6 @@ public function test_user_can_authenticate_when_two_factor_challenge_is_disabled public function test_validation_exception_returned_on_failure() { - $this->loadLaravelMigrations(['--database' => 'testbench']); - TestAuthenticationSessionUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -271,9 +248,6 @@ public function test_two_factor_challenge_can_be_passed_via_code() { app('config')->set('auth.providers.users.model', TestTwoFactorAuthenticationSessionUser::class); - $this->loadLaravelMigrations(['--database' => 'testbench']); - $this->artisan('migrate', ['--database' => 'testbench'])->run(); - $tfaEngine = app(Google2FA::class); $userSecret = $tfaEngine->generateSecretKey(); $validOtp = $tfaEngine->getCurrentOtp($userSecret); @@ -302,12 +276,6 @@ public function test_two_factor_authentication_preserves_remember_me_selection() app('config')->set('auth.providers.users.model', TestTwoFactorAuthenticationSessionUser::class); - $this->loadLaravelMigrations(['--database' => 'testbench']); - - Schema::table('users', function ($table) { - $table->text('two_factor_secret')->nullable(); - }); - TestTwoFactorAuthenticationSessionUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -334,9 +302,6 @@ public function test_two_factor_challenge_fails_for_old_otp_and_zero_window() Features::twoFactorAuthentication(['window' => 0]), ]); - $this->loadLaravelMigrations(['--database' => 'testbench']); - $this->artisan('migrate', ['--database' => 'testbench'])->run(); - $tfaEngine = app(Google2FA::class); $userSecret = $tfaEngine->generateSecretKey(); $currentTs = $tfaEngine->getTimestamp(); @@ -365,9 +330,6 @@ public function test_two_factor_challenge_can_be_passed_via_recovery_code() { app('config')->set('auth.providers.users.model', TestTwoFactorAuthenticationSessionUser::class); - $this->loadLaravelMigrations(['--database' => 'testbench']); - $this->artisan('migrate', ['--database' => 'testbench'])->run(); - $user = TestTwoFactorAuthenticationSessionUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -392,9 +354,6 @@ public function test_two_factor_challenge_can_fail_via_recovery_code() { app('config')->set('auth.providers.users.model', TestTwoFactorAuthenticationSessionUser::class); - $this->loadLaravelMigrations(['--database' => 'testbench']); - $this->artisan('migrate', ['--database' => 'testbench'])->run(); - $user = TestTwoFactorAuthenticationSessionUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -419,9 +378,6 @@ public function test_two_factor_challenge_requires_a_challenged_user() { app('config')->set('auth.providers.users.model', TestTwoFactorAuthenticationSessionUser::class); - $this->loadLaravelMigrations(['--database' => 'testbench']); - $this->artisan('migrate', ['--database' => 'testbench'])->run(); - $response = $this->withSession([])->withoutExceptionHandling()->get('/two-factor-challenge'); $response->assertRedirect('/login'); @@ -432,8 +388,6 @@ public function test_case_insensitive_usernames_can_be_used() { app('config')->set('fortify.lowercase_usernames', true); - $this->loadLaravelMigrations(['--database' => 'testbench']); - TestAuthenticationSessionUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -448,23 +402,12 @@ public function test_case_insensitive_usernames_can_be_used() $response->assertRedirect('/home'); } - protected function getPackageProviders($app) + protected function defineEnvironment($app) { - return [FortifyServiceProvider::class]; - } - - protected function getEnvironmentSetUp($app) - { - $app['migrator']->path(__DIR__.'/../database/migrations'); - - $app['config']->set('auth.providers.users.model', TestAuthenticationSessionUser::class); - - $app['config']->set('database.default', 'testbench'); + parent::defineEnvironment($app); - $app['config']->set('database.connections.testbench', [ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => '', + $app['config']->set([ + 'auth.providers.users.model' => TestAuthenticationSessionUser::class, ]); } } diff --git a/tests/ConfirmablePasswordControllerTest.php b/tests/ConfirmablePasswordControllerTest.php index 1f2deb81..ec9ae430 100644 --- a/tests/ConfirmablePasswordControllerTest.php +++ b/tests/ConfirmablePasswordControllerTest.php @@ -3,26 +3,27 @@ namespace Laravel\Fortify\Tests; use Illuminate\Foundation\Auth\User; +use Illuminate\Foundation\Testing\RefreshDatabase; use Laravel\Fortify\Contracts\ConfirmPasswordViewResponse; use Laravel\Fortify\Fortify; class ConfirmablePasswordControllerTest extends OrchestraTestCase { + use RefreshDatabase; + protected $user; protected function setUp(): void { - parent::setUp(); - - $this->loadLaravelMigrations(['--database' => 'testbench']); - - $this->artisan('migrate', ['--database' => 'testbench'])->run(); + $this->afterApplicationCreated(function () { + $this->user = TestConfirmPasswordUser::forceCreate([ + 'name' => 'Taylor Otwell', + 'email' => 'taylor@laravel.com', + 'password' => bcrypt('secret'), + ]); + }); - $this->user = TestConfirmPasswordUser::forceCreate([ - 'name' => 'Taylor Otwell', - 'email' => 'taylor@laravel.com', - 'password' => bcrypt('secret'), - ]); + parent::setUp(); } public function test_the_confirm_password_view_is_returned() @@ -147,18 +148,12 @@ public function test_password_confirmation_can_fail_with_json() $response->assertJsonValidationErrors('password'); } - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { - $app['migrator']->path(__DIR__.'/../database/migrations'); - - $app['config']->set('auth.providers.users.model', TestConfirmPasswordUser::class); - - $app['config']->set('database.default', 'testbench'); + parent::defineEnvironment($app); - $app['config']->set('database.connections.testbench', [ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => '', + $app['config']->set([ + 'auth.providers.users.model' => TestConfirmPasswordUser::class, ]); } } diff --git a/tests/OrchestraTestCase.php b/tests/OrchestraTestCase.php index f26c4678..29628306 100644 --- a/tests/OrchestraTestCase.php +++ b/tests/OrchestraTestCase.php @@ -2,19 +2,24 @@ namespace Laravel\Fortify\Tests; -use Laravel\Fortify\FortifyServiceProvider; -use Mockery; +use Laravel\Fortify\Features; +use Orchestra\Testbench\Concerns\WithLaravelMigrations; +use Orchestra\Testbench\Concerns\WithWorkbench; use Orchestra\Testbench\TestCase; abstract class OrchestraTestCase extends TestCase { - public function tearDown(): void + use WithLaravelMigrations, WithWorkbench; + + protected function defineEnvironment($app) { - Mockery::close(); + $app['config']->set(['database.default' => 'testing']); } - protected function getPackageProviders($app) + protected function withConfirmedTwoFactorAuthentication($app) { - return [FortifyServiceProvider::class]; + $app['config']->set('fortify.features', [ + Features::twoFactorAuthentication(['confirm' => true]), + ]); } } diff --git a/tests/PasswordControllerTest.php b/tests/PasswordControllerTest.php index 675bae7e..20a72721 100644 --- a/tests/PasswordControllerTest.php +++ b/tests/PasswordControllerTest.php @@ -3,16 +3,18 @@ namespace Laravel\Fortify\Tests; use App\Actions\Fortify\UpdateUserPassword; -use App\Models\User; +use Database\Factories\UserFactory; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Validation\ValidationException; use Laravel\Fortify\Contracts\UpdatesUserPasswords; -use Mockery; class PasswordControllerTest extends OrchestraTestCase { + use RefreshDatabase; + public function test_passwords_can_be_updated() { - $user = Mockery::mock(User::class); + $user = UserFactory::new()->create(); $this->mock(UpdatesUserPasswords::class) ->shouldReceive('update') @@ -29,10 +31,7 @@ public function test_passwords_can_be_updated() public function test_passwords_cannot_be_updated_without_current_password() { - $user = Mockery::mock(User::class); - - require_once __DIR__.'/../stubs/PasswordValidationRules.php'; - require_once __DIR__.'/../stubs/UpdateUserPassword.php'; + $user = UserFactory::new()->create(); try { (new UpdateUserPassword())->update($user, [ @@ -49,10 +48,7 @@ public function test_passwords_cannot_be_updated_without_current_password() public function test_passwords_cannot_be_updated_without_current_password_confirmation() { - $user = Mockery::mock(User::class); - - require_once __DIR__.'/../stubs/PasswordValidationRules.php'; - require_once __DIR__.'/../stubs/UpdateUserPassword.php'; + $user = UserFactory::new()->create(); try { (new UpdateUserPassword())->update($user, [ diff --git a/tests/RecoveryCodeControllerTest.php b/tests/RecoveryCodeControllerTest.php index fddc207f..76b9d72b 100644 --- a/tests/RecoveryCodeControllerTest.php +++ b/tests/RecoveryCodeControllerTest.php @@ -3,19 +3,18 @@ namespace Laravel\Fortify\Tests; use Illuminate\Foundation\Auth\User; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Event; use Laravel\Fortify\Events\RecoveryCodesGenerated; -use Laravel\Fortify\FortifyServiceProvider; class RecoveryCodeControllerTest extends OrchestraTestCase { + use RefreshDatabase; + public function test_new_recovery_codes_can_be_generated() { Event::fake(); - $this->loadLaravelMigrations(['--database' => 'testbench']); - $this->artisan('migrate', ['--database' => 'testbench'])->run(); - $user = TestTwoFactorRecoveryCodeUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -35,24 +34,6 @@ public function test_new_recovery_codes_can_be_generated() $this->assertNotNull($user->two_factor_recovery_codes); $this->assertIsArray(json_decode(decrypt($user->two_factor_recovery_codes), true)); } - - protected function getPackageProviders($app) - { - return [FortifyServiceProvider::class]; - } - - protected function getEnvironmentSetUp($app) - { - $app['migrator']->path(__DIR__.'/../database/migrations'); - - $app['config']->set('database.default', 'testbench'); - - $app['config']->set('database.connections.testbench', [ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => '', - ]); - } } class TestTwoFactorRecoveryCodeUser extends User diff --git a/tests/TwoFactorAuthenticationControllerTest.php b/tests/TwoFactorAuthenticationControllerTest.php index 396dc5d1..60310373 100644 --- a/tests/TwoFactorAuthenticationControllerTest.php +++ b/tests/TwoFactorAuthenticationControllerTest.php @@ -3,24 +3,22 @@ namespace Laravel\Fortify\Tests; use Illuminate\Foundation\Auth\User; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Event; use Laravel\Fortify\Events\TwoFactorAuthenticationConfirmed; use Laravel\Fortify\Events\TwoFactorAuthenticationDisabled; use Laravel\Fortify\Events\TwoFactorAuthenticationEnabled; -use Laravel\Fortify\Features; -use Laravel\Fortify\FortifyServiceProvider; use Laravel\Fortify\TwoFactorAuthenticatable; use PragmaRX\Google2FA\Google2FA; class TwoFactorAuthenticationControllerTest extends OrchestraTestCase { + use RefreshDatabase; + public function test_two_factor_authentication_can_be_enabled() { Event::fake(); - $this->loadLaravelMigrations(['--database' => 'testbench']); - $this->artisan('migrate', ['--database' => 'testbench'])->run(); - $user = TestTwoFactorAuthenticationUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -48,9 +46,6 @@ public function test_two_factor_authentication_secret_key_can_be_retrieved() { Event::fake(); - $this->loadLaravelMigrations(['--database' => 'testbench']); - $this->artisan('migrate', ['--database' => 'testbench'])->run(); - $user = TestTwoFactorAuthenticationUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -67,17 +62,13 @@ public function test_two_factor_authentication_secret_key_can_be_retrieved() $this->assertEquals('foo', $response->original['secretKey']); } + /** + * @define-env withConfirmedTwoFactorAuthentication + */ public function test_two_factor_authentication_can_be_confirmed() { Event::fake(); - app('config')->set('fortify.features', [ - Features::twoFactorAuthentication(['confirm' => true]), - ]); - - $this->loadLaravelMigrations(['--database' => 'testbench']); - $this->artisan('migrate', ['--database' => 'testbench'])->run(); - $tfaEngine = app(Google2FA::class); $userSecret = $tfaEngine->generateSecretKey(); $validOtp = $tfaEngine->getCurrentOtp($userSecret); @@ -109,17 +100,13 @@ public function test_two_factor_authentication_can_be_confirmed() $this->assertFalse($user->hasEnabledTwoFactorAuthentication()); } + /** + * @define-env withConfirmedTwoFactorAuthentication + */ public function test_two_factor_authentication_can_not_be_confirmed_with_invalid_code() { Event::fake(); - app('config')->set('fortify.features', [ - Features::twoFactorAuthentication(['confirm' => true]), - ]); - - $this->loadLaravelMigrations(['--database' => 'testbench']); - $this->artisan('migrate', ['--database' => 'testbench'])->run(); - $tfaEngine = app(Google2FA::class); $userSecret = $tfaEngine->generateSecretKey(); @@ -148,9 +135,6 @@ public function test_two_factor_authentication_can_be_disabled() { Event::fake(); - $this->loadLaravelMigrations(['--database' => 'testbench']); - $this->artisan('migrate', ['--database' => 'testbench'])->run(); - $user = TestTwoFactorAuthenticationUser::forceCreate([ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', @@ -172,24 +156,6 @@ public function test_two_factor_authentication_can_be_disabled() $this->assertNull($user->two_factor_secret); $this->assertNull($user->two_factor_recovery_codes); } - - protected function getPackageProviders($app) - { - return [FortifyServiceProvider::class]; - } - - protected function getEnvironmentSetUp($app) - { - $app['migrator']->path(__DIR__.'/../database/migrations'); - - $app['config']->set('database.default', 'testbench'); - - $app['config']->set('database.connections.testbench', [ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => '', - ]); - } } class TestTwoFactorAuthenticationUser extends User diff --git a/tests/Fixtures/Models/User.php b/workbench/app/Models/User.php similarity index 100% rename from tests/Fixtures/Models/User.php rename to workbench/app/Models/User.php diff --git a/workbench/database/factories/UserFactory.php b/workbench/database/factories/UserFactory.php new file mode 100644 index 00000000..c4209e17 --- /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 + */ + protected $model = User::class; +}