diff --git a/src/Testing/Concerns/ElevatesSessions.php b/src/Testing/Concerns/ElevatesSessions.php new file mode 100644 index 0000000000..335fbf15f1 --- /dev/null +++ b/src/Testing/Concerns/ElevatesSessions.php @@ -0,0 +1,31 @@ +actingAs($user)->withElevatedSession($time); + } + + protected function withElevatedSession(?Carbon $time = null) + { + return $this->session(['statamic_elevated_session' => ($time ?? now())->timestamp]); + } + + protected function addElevatedSessionMacros() + { + TestResponse::macro('assertRedirectToConfirmPasswordForElevatedSession', function () { + return $this->assertRedirect(route('statamic.cp.confirm-password')); + }); + + TestResponse::macro('assertElevatedSessionRequiredJsonResponse', function () { + return $this->assertJson(['message' => 'Requires an elevated session.'])->assertStatus(403); + }); + } +} diff --git a/src/Testing/Concerns/FakesRoles.php b/src/Testing/Concerns/FakesRoles.php new file mode 100644 index 0000000000..0f7da84eea --- /dev/null +++ b/src/Testing/Concerns/FakesRoles.php @@ -0,0 +1,56 @@ +mapWithKeys(function ($permissions, $handle) { + $handle = is_string($permissions) ? $permissions : $handle; + $permissions = is_string($permissions) ? [] : $permissions; + + return [$handle => $permissions]; + }) + ->map(function ($permissions, $handle) { + return $permissions instanceof FileRole + ? $permissions->handle($handle) + : Role::make()->handle($handle)->addPermission($permissions); + }); + + $fake = new class($roles) extends RoleRepository + { + protected $roles; + + public function __construct($roles) + { + $this->roles = $roles; + } + + public function all(): Collection + { + return $this->roles; + } + }; + + app()->instance(RepositoryContract::class, $fake); + Role::swap($fake); + } + + protected function setTestRole(string $handle, array $permissions) + { + $this->setTestRoles(array_merge( + Role::all()->mapWithKeys(function ($role) { + return [$role->handle() => $role->permissions()]; + })->toArray(), + [$handle => $permissions] + )); + } +} diff --git a/src/Testing/Concerns/FakesUserGroups.php b/src/Testing/Concerns/FakesUserGroups.php new file mode 100644 index 0000000000..f13fc0048b --- /dev/null +++ b/src/Testing/Concerns/FakesUserGroups.php @@ -0,0 +1,46 @@ +mapWithKeys(function ($roles, $handle) { + $handle = is_string($roles) ? $roles : $handle; + $roles = is_string($roles) ? [] : $roles; + + return [$handle => $roles]; + }) + ->map(function ($roles, $handle) { + return $roles instanceof FileUserGroup + ? $roles->handle($handle) + : UserGroup::make()->handle($handle)->roles($roles); + }); + + $fake = new class($groups) extends UserGroupRepository + { + protected $groups; + + public function __construct($groups) + { + $this->groups = $groups; + } + + public function all(): Collection + { + return $this->groups; + } + }; + + app()->instance(RepositoryContract::class, $fake); + UserGroup::swap($fake); + } +} diff --git a/src/Testing/Concerns/FakesViews.php b/src/Testing/Concerns/FakesViews.php new file mode 100644 index 0000000000..a37766a11d --- /dev/null +++ b/src/Testing/Concerns/FakesViews.php @@ -0,0 +1,61 @@ +app['view']; + + $this->fakeView = app(FakeViewEngine::class); + $this->fakeViewFinder = new FakeViewFinder($this->app['files'], config('view.paths')); + + $this->fakeViewFactory = new FakeViewFactory($this->app['view.engine.resolver'], $this->fakeViewFinder, $this->app['events']); + $this->fakeViewFactory->setFakeEngine($this->fakeView); + foreach (array_reverse($originalFactory->getExtensions()) as $ext => $engine) { + $this->fakeViewFactory->addExtension($ext, $engine); + } + + $this->app->instance('view.finder', $this->fakeViewFinder); + $this->app->instance('view', $this->fakeViewFactory); + } + + public function withStandardFakeViews() + { + $this->withFakeViews(); + + $this->viewShouldReturnRaw('layout', '{{ template_content }}'); + $this->viewShouldReturnRaw('default', '{{ content }}'); + } + + public function withStandardFakeErrorViews() + { + $this->withFakeViews(); + + $this->viewShouldReturnRaw('errors.layout', '{{ template_content }}'); + $this->viewShouldReturnRaw('errors.404', 'The 404 template.'); + } + + public function viewShouldReturnRaw($view, $contents, $extension = 'antlers.html') + { + $this->fakeView->rawContents["$view.$extension"] = $contents; + $this->fakeViewFinder->fakeViews[$view] = $view; + $this->fakeViewFactory->fileExtensions[$view] = $extension; + } + + public function viewShouldReturnRendered($view, $contents, $extension = 'antlers.html') + { + $this->fakeView->renderedContents["$view.$extension"] = $contents; + $this->fakeViewFinder->fakeViews[$view] = $view; + $this->fakeViewFactory->fileExtensions[$view] = $extension; + } +} diff --git a/src/Testing/FakeViewEngine.php b/src/Testing/FakeViewEngine.php new file mode 100644 index 0000000000..dad1b21e42 --- /dev/null +++ b/src/Testing/FakeViewEngine.php @@ -0,0 +1,40 @@ +renderedContents[$path])) { + return $this->renderedContents[$path]; + } + + if (Str::endsWith($path, '.blade.php')) { + return Blade::render($this->rawContents[$path], $data); + } + + return parent::get($path, $data); + } + + protected function getContents($path) + { + if (isset($this->rawContents[$path])) { + return $this->rawContents[$path]; + } + + return parent::getContents($path); + } + + public function exists($path) + { + return app('view.finder')->exists($path); + } +} diff --git a/src/Testing/FakeViewFactory.php b/src/Testing/FakeViewFactory.php new file mode 100644 index 0000000000..42fff0997b --- /dev/null +++ b/src/Testing/FakeViewFactory.php @@ -0,0 +1,36 @@ +fakeEngine = $engine; + + return $this; + } + + public function make($view, $data = [], $mergeData = []) + { + $ext = $this->fileExtensions[$view] ?? 'antlers.html'; + + if ($this->fakeEngine->exists($view)) { + return new View($this, $this->fakeEngine, $view, "{$view}.{$ext}", $data); + } + + return parent::make($view, $data, $mergeData); + } + + public function exists($view) + { + return $this->fakeEngine->exists($view); + } +} diff --git a/src/Testing/FakeViewFinder.php b/src/Testing/FakeViewFinder.php new file mode 100644 index 0000000000..b9ca9e85e6 --- /dev/null +++ b/src/Testing/FakeViewFinder.php @@ -0,0 +1,24 @@ +fakeViews[$view])) { + return $this->fakeViews[$view]; + } + + return parent::find($view); + } + + public function exists($path) + { + return isset($this->fakeViews[$path]); + } +} diff --git a/tests/ElevatesSessions.php b/tests/ElevatesSessions.php index a7895a8ee7..aa09793b5e 100644 --- a/tests/ElevatesSessions.php +++ b/tests/ElevatesSessions.php @@ -2,30 +2,9 @@ namespace Tests; -use Carbon\Carbon; -use Illuminate\Contracts\Auth\Authenticatable; -use Illuminate\Testing\TestResponse; +use Statamic\Testing\Concerns\ElevatesSessions as BaseElevatesSessions; trait ElevatesSessions { - protected function actingAsWithElevatedSession(Authenticatable $user, ?Carbon $time = null) - { - return $this->actingAs($user)->withElevatedSession($time); - } - - protected function withElevatedSession(?Carbon $time = null) - { - return $this->session(['statamic_elevated_session' => ($time ?? now())->timestamp]); - } - - protected function addElevatedSessionMacros() - { - TestResponse::macro('assertRedirectToConfirmPasswordForElevatedSession', function () { - return $this->assertRedirect(route('statamic.cp.confirm-password')); - }); - - TestResponse::macro('assertElevatedSessionRequiredJsonResponse', function () { - return $this->assertJson(['message' => 'Requires an elevated session.'])->assertStatus(403); - }); - } + use BaseElevatesSessions; } diff --git a/tests/FakesRoles.php b/tests/FakesRoles.php index 2184e4e13a..67b03f2fba 100644 --- a/tests/FakesRoles.php +++ b/tests/FakesRoles.php @@ -2,55 +2,9 @@ namespace Tests; -use Illuminate\Support\Collection; -use Statamic\Auth\File\Role as FileRole; -use Statamic\Auth\File\RoleRepository; -use Statamic\Contracts\Auth\RoleRepository as RepositoryContract; -use Statamic\Facades\Role; +use Statamic\Testing\Concerns\FakesRoles as BaseFakesRoles; trait FakesRoles { - protected function setTestRoles($roles) - { - $roles = collect($roles) - ->mapWithKeys(function ($permissions, $handle) { - $handle = is_string($permissions) ? $permissions : $handle; - $permissions = is_string($permissions) ? [] : $permissions; - - return [$handle => $permissions]; - }) - ->map(function ($permissions, $handle) { - return $permissions instanceof FileRole - ? $permissions->handle($handle) - : Role::make()->handle($handle)->addPermission($permissions); - }); - - $fake = new class($roles) extends RoleRepository - { - protected $roles; - - public function __construct($roles) - { - $this->roles = $roles; - } - - public function all(): Collection - { - return $this->roles; - } - }; - - app()->instance(RepositoryContract::class, $fake); - Role::swap($fake); - } - - protected function setTestRole(string $handle, array $permissions) - { - $this->setTestRoles(array_merge( - Role::all()->mapWithKeys(function ($role) { - return [$role->handle() => $role->permissions()]; - })->toArray(), - [$handle => $permissions] - )); - } + use BaseFakesRoles; } diff --git a/tests/FakesUserGroups.php b/tests/FakesUserGroups.php index 43087d18a0..b73e5833f6 100644 --- a/tests/FakesUserGroups.php +++ b/tests/FakesUserGroups.php @@ -2,45 +2,9 @@ namespace Tests; -use Illuminate\Support\Collection; -use Statamic\Auth\File\UserGroup as FileUserGroup; -use Statamic\Auth\File\UserGroupRepository; -use Statamic\Contracts\Auth\UserGroupRepository as RepositoryContract; -use Statamic\Facades\UserGroup; +use Statamic\Testing\Concerns\FakesUserGroups as BaseFakesUserGroups; trait FakesUserGroups { - private function setTestUserGroups($groups) - { - $groups = collect($groups) - ->mapWithKeys(function ($roles, $handle) { - $handle = is_string($roles) ? $roles : $handle; - $roles = is_string($roles) ? [] : $roles; - - return [$handle => $roles]; - }) - ->map(function ($roles, $handle) { - return $roles instanceof FileUserGroup - ? $roles->handle($handle) - : UserGroup::make()->handle($handle)->roles($roles); - }); - - $fake = new class($groups) extends UserGroupRepository - { - protected $groups; - - public function __construct($groups) - { - $this->groups = $groups; - } - - public function all(): Collection - { - return $this->groups; - } - }; - - app()->instance(RepositoryContract::class, $fake); - UserGroup::swap($fake); - } + use BaseFakesUserGroups; } diff --git a/tests/FakesViews.php b/tests/FakesViews.php index 549797093a..209e3ff99e 100644 --- a/tests/FakesViews.php +++ b/tests/FakesViews.php @@ -2,135 +2,9 @@ namespace Tests; -use Illuminate\Support\Facades\Blade; -use Illuminate\Support\Str; -use Illuminate\View\Factory; -use Illuminate\View\View; +use Statamic\Testing\Concerns\FakesViews as BaseFakesViews; trait FakesViews { - protected $fakeView; - protected $fakeViewFinder; - protected $fakeViewFactory; - - public function withFakeViews() - { - $originalFactory = $this->app['view']; - - $this->fakeView = app(FakeViewEngine::class); - $this->fakeViewFinder = new FakeViewFinder($this->app['files'], config('view.paths')); - - $this->fakeViewFactory = new FakeViewFactory($this->app['view.engine.resolver'], $this->fakeViewFinder, $this->app['events']); - foreach (array_reverse($originalFactory->getExtensions()) as $ext => $engine) { - $this->fakeViewFactory->addExtension($ext, $engine); - } - - $this->app->instance('FakeViewEngine', $this->fakeView); - $this->app->instance('view.finder', $this->fakeViewFinder); - $this->app->instance('view', $this->fakeViewFactory); - } - - public function withStandardFakeViews() - { - $this->withFakeViews(); - - $this->viewShouldReturnRaw('layout', '{{ template_content }}'); - $this->viewShouldReturnRaw('default', '{{ content }}'); - } - - public function withStandardFakeErrorViews() - { - $this->withFakeViews(); - - $this->viewShouldReturnRaw('errors.layout', '{{ template_content }}'); - $this->viewShouldReturnRaw('errors.404', 'The 404 template.'); - } - - public function viewShouldReturnRaw($view, $contents, $extension = 'antlers.html') - { - $this->fakeView->rawContents["$view.$extension"] = $contents; - $this->fakeViewFinder->fakeViews[$view] = $view; - $this->fakeViewFactory->fileExtensions[$view] = $extension; - } - - public function viewShouldReturnRendered($view, $contents, $extension = 'antlers.html') - { - $this->fakeView->renderedContents["$view.$extension"] = $contents; - $this->fakeViewFinder->fakeViews[$view] = $view; - $this->fakeViewFactory->fileExtensions[$view] = $extension; - } -} - -class FakeViewFactory extends Factory -{ - public $fileExtensions = []; - - public function make($view, $data = [], $mergeData = []) - { - $engine = app('FakeViewEngine'); - $ext = $this->fileExtensions[$view] ?? 'antlers.html'; - - if ($engine->exists($view)) { - return new View($this, $engine, $view, "{$view}.{$ext}", $data); - } - - return parent::make($view, $data, $mergeData); - } - - public function exists($view) - { - return app('FakeViewEngine')->exists($view); - } -} - -class FakeViewEngine extends \Statamic\View\Antlers\Engine -{ - public $rawContents = []; - public $renderedContents = []; - - public function get($path, array $data = []) - { - if (isset($this->renderedContents[$path])) { - return $this->renderedContents[$path]; - } - - if (Str::endsWith($path, '.blade.php')) { - return Blade::render($this->rawContents[$path], $data); - } - - return parent::get($path, $data); - } - - protected function getContents($path) - { - if (isset($this->rawContents[$path])) { - return $this->rawContents[$path]; - } - - return parent::getContents($path); - } - - public function exists($path) - { - return app('view.finder')->exists($path); - } -} - -class FakeViewFinder extends \Illuminate\View\FileViewFinder -{ - public $fakeViews = []; - - public function find($view) - { - if (isset($this->fakeViews[$view])) { - return $this->fakeViews[$view]; - } - - return parent::find($view); - } - - public function exists($path) - { - return isset($this->fakeViews[$path]); - } + use BaseFakesViews; }