From 210431c8e33cb2a820467c8b3dc785a2d99c2f42 Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Thu, 16 Jan 2020 14:07:11 +0200 Subject: [PATCH 1/5] Custom routes --- .../Controllers/RepositoryStoreController.php | 8 -- src/Repositories/Crudable.php | 19 +++ src/Repositories/Repository.php | 29 +++++ src/RestifyServiceProvider.php | 38 ++++-- tests/Fixtures/RepositoryWithRoutes.php | 27 ++++ tests/IntegrationTest.php | 16 ++- tests/RepositoryWithRoutesTest.php | 122 ++++++++++++++++++ 7 files changed, 232 insertions(+), 27 deletions(-) create mode 100644 tests/Fixtures/RepositoryWithRoutes.php create mode 100644 tests/RepositoryWithRoutesTest.php diff --git a/src/Http/Controllers/RepositoryStoreController.php b/src/Http/Controllers/RepositoryStoreController.php index a91f71b2b..f14aa555f 100644 --- a/src/Http/Controllers/RepositoryStoreController.php +++ b/src/Http/Controllers/RepositoryStoreController.php @@ -32,14 +32,6 @@ public function handle(RepositoryStoreRequest $request) */ $repository = $request->repository(); - $repository::authorizeToCreate($request); - - $validator = $repository::validatorForStoring($request); - - if ($validator->fails()) { - return $this->response()->invalid()->errors($validator->errors()->toArray())->respond(); - } - return $request->newRepositoryWith($repository::newModel())->store($request); } } diff --git a/src/Repositories/Crudable.php b/src/Repositories/Crudable.php index 71885da2a..d497c9936 100644 --- a/src/Repositories/Crudable.php +++ b/src/Repositories/Crudable.php @@ -54,9 +54,13 @@ public function show(RestifyRequest $request, $repositoryId) /** * @param RestifyRequest $request * @return JsonResponse + * @throws ValidationException + * @throws \Illuminate\Auth\Access\AuthorizationException */ public function store(RestifyRequest $request) { + $this->allowToStore($request); + $model = DB::transaction(function () use ($request) { $model = self::fillWhenStore( $request, self::newModel() @@ -127,6 +131,21 @@ public function allowToUpdate(RestifyRequest $request) $validator->validate(); } + /** + * @param RestifyRequest $request + * @return mixed + * @throws \Illuminate\Auth\Access\AuthorizationException + * @throws ValidationException + */ + public function allowToStore(RestifyRequest $request) + { + self::authorizeToCreate($request); + + $validator = self::validatorForStoring($request); + + $validator->validate(); + } + /** * @param RestifyRequest $request * @throws \Illuminate\Auth\Access\AuthorizationException diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index fb5c69f06..be0dc1a91 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -10,6 +10,7 @@ use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; +use Illuminate\Routing\Router; use Illuminate\Support\Collection; use Illuminate\Support\Str; @@ -158,4 +159,32 @@ public static function resolveWith($model) return $self->withResource($model); } + + /** + * Handle dynamic static method calls into the method. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public static function __callStatic($method, $parameters) + { + return (new static)->$method(...$parameters); + } + + /** + * Defining custom roues. + * The prefix of this route is the uriKey (e.g. 'restify-api/orders'), + * The namespace is Http/Controllers + * Middlewares are the same from config('restify.middleware') + * + * However all options could be customized by passing an $options argument + * + * @param Router $router + * @param $options + */ + public static function routes(Router $router, $options = []) + { + // override for custom routes + } } diff --git a/src/RestifyServiceProvider.php b/src/RestifyServiceProvider.php index 0dcc9dcd9..8eebe0f4b 100644 --- a/src/RestifyServiceProvider.php +++ b/src/RestifyServiceProvider.php @@ -2,9 +2,9 @@ namespace Binaryk\LaravelRestify; -use Illuminate\Support\Arr; use Illuminate\Support\Facades\Route; use Illuminate\Support\ServiceProvider; +use ReflectionClass; /** * This provider is injected in console context by the main provider or by the RestifyInjector @@ -34,27 +34,37 @@ protected function registerRoutes() 'middleware' => config('restify.middleware', []), ]; - $this->customDefinitions($config) + $this->customDefinitions() ->defaultRoutes($config); } /** - * @param $config * @return RestifyServiceProvider */ - public function customDefinitions($config) + public function customDefinitions() { - collect(Restify::$repositories)->filter(function ($repository) { - return isset($repository::$middleware) || isset($repository::$prefix); - }) - ->each(function ($repository) use ($config) { - $config['middleware'] = array_merge(config('restify.middleware', []), Arr::wrap($repository::$middleware)); - $config['prefix'] = Restify::path($repository::$prefix); + collect(Restify::$repositories)->each(function ($repository) { + $config = [ + 'namespace' => trim(app()->getNamespace(), '\\') . '\Http\Controllers', + 'as' => '', + 'prefix' => Restify::path($repository::uriKey()), + 'middleware' => config('restify.middleware', []), + ]; + + $reflector = new ReflectionClass($repository); + + $method = $reflector->getMethod('routes'); - Route::group($config, function () { - $this->loadRoutesFrom(__DIR__.'/../routes/api.php'); - }); + $parameters = $method->getParameters(); + + if (count($parameters) === 2 && $parameters[1] instanceof \ReflectionParameter) { + $config = array_merge($config, $parameters[1]->getDefaultValue()); + } + + Route::group($config, function ($router) use ($repository) { + $repository::routes($router); }); + }); return $this; } @@ -66,7 +76,7 @@ public function customDefinitions($config) public function defaultRoutes($config) { Route::group($config, function () { - $this->loadRoutesFrom(__DIR__.'/../routes/api.php'); + $this->loadRoutesFrom(__DIR__ . '/../routes/api.php'); }); return $this; diff --git a/tests/Fixtures/RepositoryWithRoutes.php b/tests/Fixtures/RepositoryWithRoutes.php new file mode 100644 index 000000000..ecdb86a04 --- /dev/null +++ b/tests/Fixtures/RepositoryWithRoutes.php @@ -0,0 +1,27 @@ + + */ +class RepositoryWithRoutes extends Repository +{ + public static function routes(Router $router, $options = []) + { + $router->get('testing', function () { + return response()->json([ + 'success' => true, + ]); + })->name('testing.route'); + } + + public static function uriKey() + { + return 'posts'; + } +} diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 910fc60fa..c7a9c6ba4 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -5,6 +5,7 @@ use Binaryk\LaravelRestify\LaravelRestifyServiceProvider; use Binaryk\LaravelRestify\Restify; use Binaryk\LaravelRestify\Tests\Fixtures\PostRepository; +use Binaryk\LaravelRestify\Tests\Fixtures\RepositoryWithRoutes; use Binaryk\LaravelRestify\Tests\Fixtures\User; use Binaryk\LaravelRestify\Tests\Fixtures\UserRepository; use Illuminate\Contracts\Translation\Translator; @@ -34,11 +35,7 @@ protected function setUp(): void $this->loadRoutes(); $this->withFactories(__DIR__.'/Factories'); $this->injectTranslator(); - - Restify::repositories([ - UserRepository::class, - PostRepository::class, - ]); + $this->loadRepositories(); } protected function getPackageProviders($app) @@ -152,4 +149,13 @@ public function lastQuery() return end($queries); } + + public function loadRepositories() + { + Restify::repositories([ + UserRepository::class, + PostRepository::class, + RepositoryWithRoutes::class, + ]); + } } diff --git a/tests/RepositoryWithRoutesTest.php b/tests/RepositoryWithRoutesTest.php new file mode 100644 index 000000000..b6cad1f46 --- /dev/null +++ b/tests/RepositoryWithRoutesTest.php @@ -0,0 +1,122 @@ + + */ +class RepositoryWithRoutesTest extends IntegrationTest +{ + protected function setUp(): void + { + $this->loadRepositories(); + + Restify::repositories([ + WithCustomPrefix::class, + WithCustomMiddleware::class, + WithCustomNamespace::class, + ]); + + parent::setUp(); + } + + public function test_can_add_custom_routes() + { + $this->get(Restify::path(RepositoryWithRoutes::uriKey()) . '/testing')->assertStatus(200) + ->assertJson([ + 'success' => true, + ]); + + $this->get(route('testing.route'))->assertStatus(200) + ->assertJson([ + 'success' => true, + ]); + } + + public function test_can_use_custom_prefix() + { + $this->get('/custom-prefix/testing')->assertStatus(200) + ->assertJson([ + 'success' => true, + ]); + } + + public function test_can_use_custom_middleware() + { + $this->get(route('middleware.failing.route'))->assertStatus(403); + } + + public function test_can_use_custom_namespace() + { + $this->getJson(route('namespace.route')) + ->assertStatus(200) + ->assertJson([ + 'meta' => [ + 'message' => 'From the sayHello method', + ], + ]); + } + +} + +class WithCustomPrefix extends RepositoryWithRoutes +{ + public static function routes(Router $router, $options = ['prefix' => 'custom-prefix']) + { + $router->get('testing', function () { + return response()->json([ + 'success' => true, + ]); + })->name('custom.testing.route'); + } +} + +class MiddlewareFail +{ + public function handle($request, $next) + { + if (true) { + return abort(403); + } + } +} + +class WithCustomMiddleware extends RepositoryWithRoutes +{ + public static function routes(Router $router, $options = ['middleware' => [MiddlewareFail::class]]) + { + $router->get('with-middleware', function () { + return response()->json([ + 'success' => true, + ]); + })->name('middleware.failing.route'); + } +} + +class WithCustomNamespace extends RepositoryWithRoutes +{ + public static function routes(Router $router, $options = [ + 'namespace' => 'Binaryk\LaravelRestify\Tests', + ]) + { + $router->get('custom-namespace', 'HandleController@sayHello')->name('namespace.route'); + } +} + +class HandleController extends RestController { + /** + * Just saying hello + * + * @return \Binaryk\LaravelRestify\Controllers\RestResponse + */ + public function sayHello() + { + return $this->response()->message('From the sayHello method'); + } +} From 1a62452037beb7828c4aa2e569612cf0bb18586f Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Thu, 16 Jan 2020 14:07:32 +0200 Subject: [PATCH 2/5] Apply fixes from StyleCI (#91) --- src/Repositories/Repository.php | 2 +- src/RestifyServiceProvider.php | 4 ++-- tests/Fixtures/RepositoryWithRoutes.php | 1 - tests/RepositoryWithRoutesTest.php | 9 ++++----- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index be0dc1a91..3a2bc64cd 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -176,7 +176,7 @@ public static function __callStatic($method, $parameters) * Defining custom roues. * The prefix of this route is the uriKey (e.g. 'restify-api/orders'), * The namespace is Http/Controllers - * Middlewares are the same from config('restify.middleware') + * Middlewares are the same from config('restify.middleware'). * * However all options could be customized by passing an $options argument * diff --git a/src/RestifyServiceProvider.php b/src/RestifyServiceProvider.php index 8eebe0f4b..464ecd55e 100644 --- a/src/RestifyServiceProvider.php +++ b/src/RestifyServiceProvider.php @@ -45,7 +45,7 @@ public function customDefinitions() { collect(Restify::$repositories)->each(function ($repository) { $config = [ - 'namespace' => trim(app()->getNamespace(), '\\') . '\Http\Controllers', + 'namespace' => trim(app()->getNamespace(), '\\').'\Http\Controllers', 'as' => '', 'prefix' => Restify::path($repository::uriKey()), 'middleware' => config('restify.middleware', []), @@ -76,7 +76,7 @@ public function customDefinitions() public function defaultRoutes($config) { Route::group($config, function () { - $this->loadRoutesFrom(__DIR__ . '/../routes/api.php'); + $this->loadRoutesFrom(__DIR__.'/../routes/api.php'); }); return $this; diff --git a/tests/Fixtures/RepositoryWithRoutes.php b/tests/Fixtures/RepositoryWithRoutes.php index ecdb86a04..421536851 100644 --- a/tests/Fixtures/RepositoryWithRoutes.php +++ b/tests/Fixtures/RepositoryWithRoutes.php @@ -6,7 +6,6 @@ use Illuminate\Routing\Router; /** - * @package Binaryk\LaravelRestify\Tests\Fixtures; * @author Eduard Lupacescu */ class RepositoryWithRoutes extends Repository diff --git a/tests/RepositoryWithRoutesTest.php b/tests/RepositoryWithRoutesTest.php index b6cad1f46..b8b8eda6f 100644 --- a/tests/RepositoryWithRoutesTest.php +++ b/tests/RepositoryWithRoutesTest.php @@ -8,7 +8,6 @@ use Illuminate\Routing\Router; /** - * @package Binaryk\LaravelRestify\Tests; * @author Eduard Lupacescu */ class RepositoryWithRoutesTest extends IntegrationTest @@ -28,7 +27,7 @@ protected function setUp(): void public function test_can_add_custom_routes() { - $this->get(Restify::path(RepositoryWithRoutes::uriKey()) . '/testing')->assertStatus(200) + $this->get(Restify::path(RepositoryWithRoutes::uriKey()).'/testing')->assertStatus(200) ->assertJson([ 'success' => true, ]); @@ -62,7 +61,6 @@ public function test_can_use_custom_namespace() ], ]); } - } class WithCustomPrefix extends RepositoryWithRoutes @@ -109,9 +107,10 @@ public static function routes(Router $router, $options = [ } } -class HandleController extends RestController { +class HandleController extends RestController +{ /** - * Just saying hello + * Just saying hello. * * @return \Binaryk\LaravelRestify\Controllers\RestResponse */ From aa682c554d1f161421f6bbc8aba7f57be5b93798 Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Thu, 16 Jan 2020 17:04:49 +0200 Subject: [PATCH 3/5] Documented custom routes --- .../repository-pattern/repository-pattern.md | 147 ++++++++++++++++++ src/Repositories/Repository.php | 3 +- tests/Fixtures/RepositoryWithRoutes.php | 4 + 3 files changed, 153 insertions(+), 1 deletion(-) diff --git a/docs/docs/repository-pattern/repository-pattern.md b/docs/docs/repository-pattern/repository-pattern.md index f3571d21e..2a0e6e5a9 100644 --- a/docs/docs/repository-pattern/repository-pattern.md +++ b/docs/docs/repository-pattern/repository-pattern.md @@ -264,3 +264,150 @@ public function serializeIndex($request, $serialized) } ``` +## Custom routes + +Laravel Restify has its own "CRUD" routes, however you're able to define your own routes right from your Repository class: + +```php +/** + * Defining custom routes + * + * The default prefix of this route is the uriKey (e.g. 'restify-api/posts'), + * + * The default namespace is AppNamespace/Http/Controllers + * + * The default middlewares are the same from config('restify.middleware') + * + * However all options could be overrided by passing an $options argument + * + * @param \Illuminate\Routing\Router $router + * @param $options + */ +public static function routes(\Illuminate\Routing\Router $router, $options = []) +{ + $router->get('hello-world', function () { + return 'Hello World'; + }); +} +``` + +Let's diving into a more "real life" example. Let's take the Post repository we had above: + +```php +use Illuminate\Routing\Router; +use Binaryk\LaravelRestify\Repositories\Repository; + +class Post extends Repository +{ + /* + * @param \Illuminate\Routing\Router $router + * @param $options + */ + public static function routes(Router $router, $options = []) + { + $router->get('/{id}/kpi', 'PostController@kpi'); + } + + public static function uriKey() + { + return 'posts'; + } +} +``` + +At this moment Restify built the new route as a child of the `posts`, so it has the route: + +```http request +GET: /restify-api/posts/{id}/kpi +``` + +This route is pointing to the `PostsController`, let's define it: + +```php +response(); + } +} +``` + +### Custom prefix + +As we noticed in the example above, the route is generated as a child of the current repository `uriKey` route, +however sometimes you may want to have a separate prefix, which doesn't depends of the URI of the current repository. +Restify provide you an easy of doing that, by adding default value `prefix` for the second `$options` argument: + +```php +/** + * @param \Illuminate\Routing\Router $router + * @param $options + */ +public static function routes(Router $router, $options = ['prefix' => 'api',]) +{ + $router->get('hello-world', function () { + return 'Hello World'; + }); +} +```` + +Now the generated route will look like this: + +```http request +GET: '/api/hello-world +``` + +With `api` as a custom prefix. + + +### Custom middleware + +All routes declared in the `routes` method, will have the same middelwares defined in your `restify.middleware` configuration file. +Overriding default middlewares is a breeze with Restify: + +```php +/** + * @param \Illuminate\Routing\Router $router + * @param $options + */ +public static function routes(Router $router, $options = ['middleware' => [CustomMiddleware::class],]) +{ + $router->get('hello-world', function () { + return 'Hello World'; + }); +} +```` + +In that case, the single middleware of the route will be defined by the `CustomMiddleware` class. + +### Custom Namespace + +By default each route defined in the `routes` method, will have the namespace `AppRootNamespace\Http\Controllers`. +You can override it easily by using `namespace` configuration key: + +```php +/** + * @param \Illuminate\Routing\Router $router + * @param $options + */ +public static function routes(Router $router, $options = ['namespace' => 'App\Services',]) +{ + $router->get('hello-world', 'WorldController@hello'); +} +```` diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index be0dc1a91..0154cf5d8 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -173,7 +173,8 @@ public static function __callStatic($method, $parameters) } /** - * Defining custom roues. + * Defining custom routes. + * * The prefix of this route is the uriKey (e.g. 'restify-api/orders'), * The namespace is Http/Controllers * Middlewares are the same from config('restify.middleware') diff --git a/tests/Fixtures/RepositoryWithRoutes.php b/tests/Fixtures/RepositoryWithRoutes.php index ecdb86a04..4f0098c27 100644 --- a/tests/Fixtures/RepositoryWithRoutes.php +++ b/tests/Fixtures/RepositoryWithRoutes.php @@ -11,6 +11,10 @@ */ class RepositoryWithRoutes extends Repository { + /** + * @param Router $router + * @param array $options + */ public static function routes(Router $router, $options = []) { $router->get('testing', function () { From 40011dd0949bbd23aa1966895ce20c4609e616ed Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Thu, 16 Jan 2020 18:24:50 +0200 Subject: [PATCH 4/5] Adapt store integration test --- src/Repositories/Crudable.php | 19 +++++++++++--- src/Traits/AuthorizableModels.php | 4 +-- .../RepositoryStoreControllerTest.php | 20 +++++++++++++- tests/Fixtures/PostPolicy.php | 26 +++++++++++++++++++ tests/Fixtures/PostRepository.php | 5 ++-- tests/IntegrationTest.php | 26 +++++++++++++++++-- 6 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 tests/Fixtures/PostPolicy.php diff --git a/src/Repositories/Crudable.php b/src/Repositories/Crudable.php index d497c9936..1317b5d5a 100644 --- a/src/Repositories/Crudable.php +++ b/src/Repositories/Crudable.php @@ -3,10 +3,13 @@ namespace Binaryk\LaravelRestify\Repositories; use Binaryk\LaravelRestify\Controllers\RestResponse; +use Binaryk\LaravelRestify\Exceptions\UnauthorizedException; use Binaryk\LaravelRestify\Http\Requests\RestifyRequest; use Binaryk\LaravelRestify\Restify; +use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Contracts\Pagination\Paginator; use Illuminate\Http\JsonResponse; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; use Illuminate\Validation\ValidationException; @@ -54,12 +57,20 @@ public function show(RestifyRequest $request, $repositoryId) /** * @param RestifyRequest $request * @return JsonResponse - * @throws ValidationException - * @throws \Illuminate\Auth\Access\AuthorizationException */ public function store(RestifyRequest $request) { - $this->allowToStore($request); + try { + $this->allowToStore($request); + } catch (AuthorizationException|UnauthorizedException $e) { + return $this->response()->setData([ + 'errors' => Arr::wrap($e->getMessage()) + ])->setStatusCode(RestResponse::REST_RESPONSE_FORBIDDEN_CODE); + } catch (ValidationException $e) { + return $this->response()->setData([ + 'errors' => $e->errors(), + ])->setStatusCode(RestResponse::REST_RESPONSE_INVALID_CODE); + } $model = DB::transaction(function () use ($request) { $model = self::fillWhenStore( @@ -74,7 +85,7 @@ public function store(RestifyRequest $request) return (new static ($model)) ->response() ->setStatusCode(RestResponse::REST_RESPONSE_CREATED_CODE) - ->header('Location', Restify::path().'/'.static::uriKey().'/'.$model->id); + ->header('Location', Restify::path() . '/' . static::uriKey() . '/' . $model->id); } /** diff --git a/src/Traits/AuthorizableModels.php b/src/Traits/AuthorizableModels.php index bd7d3836b..6d251bec7 100644 --- a/src/Traits/AuthorizableModels.php +++ b/src/Traits/AuthorizableModels.php @@ -107,7 +107,7 @@ public function authorizedToView(Request $request) */ public static function authorizeToCreate(Request $request) { - throw_unless(static::authorizedToCreate($request), AuthorizationException::class); + throw_unless(static::authorizedToCreate($request), AuthorizationException::class, "Unauthorized to create."); } /** @@ -119,7 +119,7 @@ public static function authorizeToCreate(Request $request) public static function authorizedToCreate(Request $request) { if (static::authorizable()) { - return Gate::check('create', get_class(static::newModel())); + return Gate::check('create', static::$model); } return true; diff --git a/tests/Controllers/RepositoryStoreControllerTest.php b/tests/Controllers/RepositoryStoreControllerTest.php index bc82b7b30..ac5b2a9c6 100644 --- a/tests/Controllers/RepositoryStoreControllerTest.php +++ b/tests/Controllers/RepositoryStoreControllerTest.php @@ -2,7 +2,10 @@ namespace Binaryk\LaravelRestify\Tests\Controllers; +use Binaryk\LaravelRestify\Tests\Fixtures\Post; +use Binaryk\LaravelRestify\Tests\Fixtures\PostPolicy; use Binaryk\LaravelRestify\Tests\IntegrationTest; +use Illuminate\Support\Facades\Gate; /** * @author Eduard Lupacescu @@ -12,6 +15,7 @@ class RepositoryStoreControllerTest extends IntegrationTest protected function setUp(): void { parent::setUp(); + $this->authenticate(); } public function test_basic_validation_works() @@ -23,10 +27,24 @@ public function test_basic_validation_works() ->assertJson([ 'errors' => [ 'description' => [ - 'Description field is required bro.', + 'Description field is required', ], ], ]); + + } + + public function test_unauthorized_store() + { + $_SERVER['restify.user.creatable'] = false; + + Gate::policy(Post::class, PostPolicy::class); + + $this->withExceptionHandling()->post('/restify-api/posts', [ + 'title' => 'Title', + 'description' => 'Title', + ])->assertStatus(403) + ->assertJson(['errors' => ['Unauthorized to create.']]); } public function test_success_storing() diff --git a/tests/Fixtures/PostPolicy.php b/tests/Fixtures/PostPolicy.php new file mode 100644 index 000000000..87a2c0df0 --- /dev/null +++ b/tests/Fixtures/PostPolicy.php @@ -0,0 +1,26 @@ + + */ +class PostPolicy +{ + /** + * Determine if the given user can view resources. + */ + public function viewAny($user) + { + return $_SERVER['restify.user.viewAnyable'] ?? true; + } + + /** + * Determine if users can be created. + */ + public function create($user) + { + return $_SERVER['restify.user.creatable'] ?? true; + } +} diff --git a/tests/Fixtures/PostRepository.php b/tests/Fixtures/PostRepository.php index d7f45312c..b9884065f 100644 --- a/tests/Fixtures/PostRepository.php +++ b/tests/Fixtures/PostRepository.php @@ -31,10 +31,11 @@ public function fields(RestifyRequest $request) { return [ Field::make('title')->storingRules('required')->messages([ - 'required' => 'This field is required bro.', + 'required' => 'This field is required', ]), + Field::make('description')->storingRules('required')->messages([ - 'required' => 'Description field is required bro.', + 'required' => 'Description field is required', ]), ]; } diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index c7a9c6ba4..193caaede 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -8,10 +8,12 @@ use Binaryk\LaravelRestify\Tests\Fixtures\RepositoryWithRoutes; use Binaryk\LaravelRestify\Tests\Fixtures\User; use Binaryk\LaravelRestify\Tests\Fixtures\UserRepository; +use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Translation\Translator; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Route; +use Mockery; use Orchestra\Testbench\TestCase; /** @@ -20,6 +22,12 @@ abstract class IntegrationTest extends TestCase { use InteractWithModels; + + /** + * @var mixed + */ + protected $authenticatedAs; + /** * @var mixed */ @@ -33,7 +41,7 @@ protected function setUp(): void $this->repositoryMock(); $this->loadMigrations(); $this->loadRoutes(); - $this->withFactories(__DIR__.'/Factories'); + $this->withFactories(__DIR__ . '/Factories'); $this->injectTranslator(); $this->loadRepositories(); } @@ -66,7 +74,7 @@ protected function loadMigrations() { $this->loadMigrationsFrom([ '--database' => 'sqlite', - '--realpath' => realpath(__DIR__.'/Migrations'), + '--realpath' => realpath(__DIR__ . '/Migrations'), ]); } @@ -158,4 +166,18 @@ public function loadRepositories() RepositoryWithRoutes::class, ]); } + + /** + * Authenticate as an anonymous user. + * + */ + protected function authenticate() + { + $this->actingAs($this->authenticatedAs = Mockery::mock(Authenticatable::class)); + + $this->authenticatedAs->shouldReceive('getAuthIdentifier')->andReturn(1); + $this->authenticatedAs->shouldReceive('getKey')->andReturn(1); + + return $this; + } } From b4a72355c6c317a5f1bec12fdea6b6e496f4e8fd Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Thu, 16 Jan 2020 18:25:06 +0200 Subject: [PATCH 5/5] Apply fixes from StyleCI (#93) --- src/Repositories/Crudable.php | 6 +++--- src/Traits/AuthorizableModels.php | 2 +- tests/Controllers/RepositoryStoreControllerTest.php | 1 - tests/Fixtures/PostPolicy.php | 1 - tests/Fixtures/PostRepository.php | 2 +- tests/IntegrationTest.php | 5 ++--- 6 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Repositories/Crudable.php b/src/Repositories/Crudable.php index 1317b5d5a..225499f1c 100644 --- a/src/Repositories/Crudable.php +++ b/src/Repositories/Crudable.php @@ -62,9 +62,9 @@ public function store(RestifyRequest $request) { try { $this->allowToStore($request); - } catch (AuthorizationException|UnauthorizedException $e) { + } catch (AuthorizationException | UnauthorizedException $e) { return $this->response()->setData([ - 'errors' => Arr::wrap($e->getMessage()) + 'errors' => Arr::wrap($e->getMessage()), ])->setStatusCode(RestResponse::REST_RESPONSE_FORBIDDEN_CODE); } catch (ValidationException $e) { return $this->response()->setData([ @@ -85,7 +85,7 @@ public function store(RestifyRequest $request) return (new static ($model)) ->response() ->setStatusCode(RestResponse::REST_RESPONSE_CREATED_CODE) - ->header('Location', Restify::path() . '/' . static::uriKey() . '/' . $model->id); + ->header('Location', Restify::path().'/'.static::uriKey().'/'.$model->id); } /** diff --git a/src/Traits/AuthorizableModels.php b/src/Traits/AuthorizableModels.php index 6d251bec7..6639d513e 100644 --- a/src/Traits/AuthorizableModels.php +++ b/src/Traits/AuthorizableModels.php @@ -107,7 +107,7 @@ public function authorizedToView(Request $request) */ public static function authorizeToCreate(Request $request) { - throw_unless(static::authorizedToCreate($request), AuthorizationException::class, "Unauthorized to create."); + throw_unless(static::authorizedToCreate($request), AuthorizationException::class, 'Unauthorized to create.'); } /** diff --git a/tests/Controllers/RepositoryStoreControllerTest.php b/tests/Controllers/RepositoryStoreControllerTest.php index ac5b2a9c6..1aac732dc 100644 --- a/tests/Controllers/RepositoryStoreControllerTest.php +++ b/tests/Controllers/RepositoryStoreControllerTest.php @@ -31,7 +31,6 @@ public function test_basic_validation_works() ], ], ]); - } public function test_unauthorized_store() diff --git a/tests/Fixtures/PostPolicy.php b/tests/Fixtures/PostPolicy.php index 87a2c0df0..87cc4e15f 100644 --- a/tests/Fixtures/PostPolicy.php +++ b/tests/Fixtures/PostPolicy.php @@ -3,7 +3,6 @@ namespace Binaryk\LaravelRestify\Tests\Fixtures; /** - * @package Binaryk\LaravelRestify\Tests\Fixtures; * @author Eduard Lupacescu */ class PostPolicy diff --git a/tests/Fixtures/PostRepository.php b/tests/Fixtures/PostRepository.php index b9884065f..04201be69 100644 --- a/tests/Fixtures/PostRepository.php +++ b/tests/Fixtures/PostRepository.php @@ -33,7 +33,7 @@ public function fields(RestifyRequest $request) Field::make('title')->storingRules('required')->messages([ 'required' => 'This field is required', ]), - + Field::make('description')->storingRules('required')->messages([ 'required' => 'Description field is required', ]), diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 193caaede..eb3dc801d 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -41,7 +41,7 @@ protected function setUp(): void $this->repositoryMock(); $this->loadMigrations(); $this->loadRoutes(); - $this->withFactories(__DIR__ . '/Factories'); + $this->withFactories(__DIR__.'/Factories'); $this->injectTranslator(); $this->loadRepositories(); } @@ -74,7 +74,7 @@ protected function loadMigrations() { $this->loadMigrationsFrom([ '--database' => 'sqlite', - '--realpath' => realpath(__DIR__ . '/Migrations'), + '--realpath' => realpath(__DIR__.'/Migrations'), ]); } @@ -169,7 +169,6 @@ public function loadRepositories() /** * Authenticate as an anonymous user. - * */ protected function authenticate() {