From 7b74ca29ab57f8f319996fe33a3ed4cae1e7a96d Mon Sep 17 00:00:00 2001 From: Eduard Lupacescu Date: Wed, 23 Dec 2020 15:31:05 +0200 Subject: [PATCH 1/6] Custom pivots. --- src/Fields/BelongsToMany.php | 13 +- src/Fields/Field.php | 8 +- src/Repositories/PivotsCollection.php | 17 +++ src/Repositories/Repository.php | 116 ++++++++++++------ .../RepositoryAttachControllerTest.php | 34 ++++- .../RepositoryIndexControllerTest.php | 6 +- tests/Fixtures/Company/Company.php | 1 + tests/Fixtures/Company/CompanyRepository.php | 13 +- tests/Fixtures/Company/CompanyUserPivot.php | 12 ++ 9 files changed, 164 insertions(+), 56 deletions(-) create mode 100644 src/Repositories/PivotsCollection.php create mode 100644 tests/Fixtures/Company/CompanyUserPivot.php diff --git a/src/Fields/BelongsToMany.php b/src/Fields/BelongsToMany.php index 7e0c220d8..dfa1eec9a 100644 --- a/src/Fields/BelongsToMany.php +++ b/src/Fields/BelongsToMany.php @@ -4,6 +4,7 @@ use Binaryk\LaravelRestify\Contracts\RestifySearchable; use Binaryk\LaravelRestify\Fields\Concerns\Attachable; +use Binaryk\LaravelRestify\Repositories\PivotsCollection; use Binaryk\LaravelRestify\Repositories\Repository; use Closure; use Illuminate\Auth\Access\AuthorizationException; @@ -30,8 +31,8 @@ class BelongsToMany extends EagerField public function __construct($attribute, $relation, $parentRepository) { - if (! is_a(app($parentRepository), Repository::class)) { - abort(500, "Invalid parent repository [{$parentRepository}]. Expended instance of ".Repository::class); + if (!is_a(app($parentRepository), Repository::class)) { + abort(500, "Invalid parent repository [{$parentRepository}]. Expended instance of " . Repository::class); } parent::__construct($attribute); @@ -52,10 +53,10 @@ public function resolve($repository, $attribute = null) try { return $this->repositoryClass::resolveWith($item) ->allowToShow(app(Request::class)) - ->withExtraFields( - collect($this->pivotFields)->each(function (Field $field) use ($item) { - return $field->resolveCallback(fn () => $item->pivot->{$field->attribute}); - })->all() + ->withPivots( + PivotsCollection::make($this->pivotFields) + ->map(fn(Field $field) => clone $field) + ->resolveFromPivot($item->pivot) ) ->eagerState(); } catch (AuthorizationException $e) { diff --git a/src/Fields/Field.php b/src/Fields/Field.php index fd42a11b5..ed50c8ad2 100644 --- a/src/Fields/Field.php +++ b/src/Fields/Field.php @@ -446,6 +446,10 @@ public function isSortable() */ public function resolveForShow($repository, $attribute = null) { + if ($this->attribute === 'is_admin') { + dd('foo'); + } + $attribute = $attribute ?? $this->attribute; if ($attribute === 'Computed') { @@ -474,7 +478,7 @@ public function resolveForIndex($repository, $attribute = null) if ($attribute === 'Computed') { $this->value = call_user_func($this->computedCallback, $repository); - return; + return $this; } if (! $this->indexCallback) { @@ -494,7 +498,7 @@ public function resolve($repository, $attribute = null) if ($attribute === 'Computed') { $this->value = call_user_func($this->computedCallback, $repository); - return; + return $this; } if (! $this->resolveCallback) { diff --git a/src/Repositories/PivotsCollection.php b/src/Repositories/PivotsCollection.php new file mode 100644 index 000000000..7fffb3244 --- /dev/null +++ b/src/Repositories/PivotsCollection.php @@ -0,0 +1,17 @@ +map(function (Field $field) use ($pivot) { + return $field->resolveCallback(fn() => $pivot->{$field->attribute}); + }); + } +} diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index 045fc79b0..328904acf 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -162,6 +162,13 @@ abstract class Repository implements RestifySearchable, JsonSerializable */ public $extraFields = []; + /** + * A collection of pivots for the nested relationships. + * + * @var PivotsCollection + */ + private PivotsCollection $pivots; + public function __construct() { $this->bootIfNotBooted(); @@ -251,7 +258,7 @@ public static function newModel(): Model public static function query(RestifyRequest $request) { - if (! $request->isViaRepository()) { + if (!$request->isViaRepository()) { return static::newModel()->query(); } @@ -320,6 +327,20 @@ public function withExtraFields(array $fields): self return $this; } + public function withPivots(PivotsCollection $pivots): self + { + $this->pivots = $pivots; + + return $this; + } + + public function getPivots(): ?PivotsCollection + { + return isset($this->pivots) + ? $this->pivots + : null; + } + public function withResource($resource) { $this->resource = $resource; @@ -404,16 +425,16 @@ public function resolveShowAttributes(RestifyRequest $request) { $fields = $this->collectFields($request) ->forShow($request, $this) - ->filter(fn (Field $field) => $field->authorize($request)) + ->filter(fn(Field $field) => $field->authorize($request)) ->when( - $this->eagerState, + $this->isEagerState(), function ($items) { - return $items->filter(fn (Field $field) => ! $field instanceof EagerField); + return $items->filter(fn(Field $field) => !$field instanceof EagerField); } ) - ->each(fn (Field $field) => $field->resolveForShow($this)) - ->map(fn (Field $field) => $field->serializeToValue($request)) - ->mapWithKeys(fn ($value) => $value) + ->each(fn(Field $field) => $field->resolveForShow($this)) + ->map(fn(Field $field) => $field->serializeToValue($request)) + ->mapWithKeys(fn($value) => $value) ->all(); if ($this instanceof Mergeable) { @@ -431,7 +452,7 @@ function ($items) { return false; } - if (! $field->authorize($request)) { + if (!$field->authorize($request)) { return false; } @@ -454,16 +475,16 @@ public function resolveIndexAttributes($request) $fields = $this ->collectFields($request) ->forIndex($request, $this) - ->filter(fn (Field $field) => $field->authorize($request)) + ->filter(fn(Field $field) => $field->authorize($request)) ->when( $this->eagerState, function ($items) { - return $items->filter(fn (Field $field) => ! $field instanceof EagerField); + return $items->filter(fn(Field $field) => !$field instanceof EagerField); } ) - ->each(fn (Field $field) => $field->resolveForIndex($this)) - ->map(fn (Field $field) => $field->serializeToValue($request)) - ->mapWithKeys(fn ($value) => $value) + ->each(fn(Field $field) => $field->resolveForIndex($this)) + ->map(fn(Field $field) => $field->serializeToValue($request)) + ->mapWithKeys(fn($value) => $value) ->all(); if ($this instanceof Mergeable) { @@ -481,7 +502,7 @@ function ($items) { return false; } - if (! $field->authorize($request)) { + if (!$field->authorize($request)) { return false; } @@ -502,6 +523,25 @@ public function resolveShowMeta($request) ]; } + public function resolveShowPivots(RestifyRequest $request): array + { + if (is_null($pivots = $this->getPivots())) { + return []; + } + + return $pivots + ->filter(fn(Field $field) => $field->authorize($request)) + ->each(fn(Field $field) => $field->resolve($this)) + ->map(fn(Field $field) => $field->serializeToValue($request)) + ->mapWithKeys(fn($value) => $value) + ->all(); + } + + public function resolveIndexPivots(RestifyRequest $request): array + { + return $this->resolveShowPivots($request); + } + /** * Return a list with relationship for the current model. * @@ -535,16 +575,16 @@ public function resolveRelationships($request): array : $this->resource->{$relation}(); collect([ - Builder::class => fn () => $withs->put($relation, (static::$relatedCast)::fromBuilder($request, $paginator, $this)), + Builder::class => fn() => $withs->put($relation, (static::$relatedCast)::fromBuilder($request, $paginator, $this)), - Relation::class => fn () => $withs->put($relation, (static::$relatedCast)::fromRelation($request, $paginator, $this)), + Relation::class => fn() => $withs->put($relation, (static::$relatedCast)::fromRelation($request, $paginator, $this)), - Collection::class => fn () => $withs->put($relation, $paginator), + Collection::class => fn() => $withs->put($relation, $paginator), - Model::class => fn () => fn () => $withs->put($relation, $paginator), + Model::class => fn() => fn() => $withs->put($relation, $paginator), - ])->first(fn ($fn, $class) => $paginator instanceof $class, - fn () => fn () => $withs->put($relation, $paginator) + ])->first(fn($fn, $class) => $paginator instanceof $class, + fn() => fn() => $withs->put($relation, $paginator) )(); }); @@ -598,14 +638,14 @@ public function index(RestifyRequest $request) [ 'meta' => $this->when( $meta = $this->resolveIndexMainMeta( - $request, $models = $items->map(fn (self $repository) => $repository->resource), RepositoryCollection::meta($paginator->toArray()) + $request, $models = $items->map(fn(self $repository) => $repository->resource), RepositoryCollection::meta($paginator->toArray()) ), $meta ), 'links' => $this->when( $links = $this->resolveIndexLinks($request, $models, RepositoryCollection::paginationLinks($paginator->toArray())), $links ), - 'data' => $items->map(fn (self $repository) => $repository->serializeForIndex($request)), + 'data' => $items->map(fn(self $repository) => $repository->serializeForIndex($request)), ] ) ); @@ -655,7 +695,7 @@ public function store(RestifyRequest $request) } } - $fields->each(fn (Field $field) => $field->invokeAfter($request, $this->resource)); + $fields->each(fn(Field $field) => $field->invokeAfter($request, $this->resource)); }); static::stored($this->resource, $request); @@ -686,7 +726,7 @@ public function storeBulk(RepositoryStoreBulkRequest $request) $this->resource->save(); - $fields->each(fn (Field $field) => $field->invokeAfter($request, $this->resource)); + $fields->each(fn(Field $field) => $field->invokeAfter($request, $this->resource)); return $this->resource; }); @@ -713,7 +753,7 @@ public function update(RestifyRequest $request, $repositoryId) return $fields; })->each( - fn (Field $field) => $field->invokeAfter($request, $this->resource) + fn(Field $field) => $field->invokeAfter($request, $this->resource) ); return $this->response() @@ -742,7 +782,7 @@ public function attach(RestifyRequest $request, $repositoryId, Collection $pivot $eagerField = $this->authorizeBelongsToMany($request)->belongsToManyField($request); DB::transaction(function () use ($request, $pivots, $eagerField) { - $fields = $eagerField->collectPivotFields()->filter(fn ($pivotField) => $request->has($pivotField->attribute))->values(); + $fields = $eagerField->collectPivotFields()->filter(fn($pivotField) => $request->has($pivotField->attribute))->values(); $pivots->map(function ($pivot) use ($request, $fields, $eagerField) { static::validatorForAttach($request)->validate(); @@ -775,7 +815,7 @@ public function detach(RestifyRequest $request, $repositoryId, Collection $pivot $deleted = DB::transaction(function () use ($pivots, $eagerField, $request) { return $pivots - ->map(fn ($pivot) => $eagerField->authorizeToDetach($request, $pivot) && $pivot->delete()); + ->map(fn($pivot) => $eagerField->authorizeToDetach($request, $pivot) && $pivot->delete()); }); return $this->response() @@ -807,18 +847,18 @@ public function allowToUpdate(RestifyRequest $request, $payload = null): self public function allowToAttach(RestifyRequest $request, Collection $attachers): self { - $methodGuesser = 'attach'.Str::studly($request->relatedRepository); + $methodGuesser = 'attach' . Str::studly($request->relatedRepository); - $attachers->each(fn ($model) => $this->authorizeToAttach($request, $methodGuesser, $model)); + $attachers->each(fn($model) => $this->authorizeToAttach($request, $methodGuesser, $model)); return $this; } public function allowToDetach(RestifyRequest $request, Collection $attachers): self { - $methodGuesser = 'detach'.Str::studly($request->relatedRepository); + $methodGuesser = 'detach' . Str::studly($request->relatedRepository); - $attachers->each(fn ($model) => $this->authorizeToDetach($request, $methodGuesser, $model)); + $attachers->each(fn($model) => $this->authorizeToDetach($request, $methodGuesser, $model)); return $this; } @@ -908,11 +948,12 @@ public function response($content = '', $status = 200, array $headers = []): Res public function serializeForShow(RestifyRequest $request): array { return $this->filter([ - 'id' => $this->when(optional($this->resource)->id, fn () => $this->getId($request)), + 'id' => $this->when(optional($this->resource)->id, fn() => $this->getId($request)), 'type' => $this->when($type = $this->getType($request), $type), 'attributes' => $request->isShowRequest() ? $this->resolveShowAttributes($request) : $this->resolveIndexAttributes($request), 'relationships' => $this->when(value($related = $this->resolveRelationships($request)), $related), 'meta' => $this->when(value($meta = $request->isShowRequest() ? $this->resolveShowMeta($request) : $this->resolveIndexMeta($request)), $meta), + 'pivots' => $this->when(value($pivots = $this->resolveShowPivots($request)), $pivots), ]); } @@ -921,9 +962,10 @@ public function serializeForIndex(RestifyRequest $request): array return $this->filter([ 'id' => $this->when($id = $this->getId($request), $id), 'type' => $this->when($type = $this->getType($request), $type), - 'attributes' => $this->when((bool) $attrs = $this->resolveIndexAttributes($request), $attrs), + 'attributes' => $this->when((bool)$attrs = $this->resolveIndexAttributes($request), $attrs), 'relationships' => $this->when(value($related = $this->resolveIndexRelationships($request)), $related), 'meta' => $this->when(value($meta = $this->resolveIndexMeta($request)), $meta), + 'pivots' => $this->when(value($pivots = $this->resolveIndexPivots($request)), $pivots), ]); } @@ -934,7 +976,7 @@ protected function getType(RestifyRequest $request): ?string protected function getId(RestifyRequest $request): ?string { - if (! static::$id) { + if (!static::$id) { return null; } @@ -963,7 +1005,7 @@ private function modelAttributes(Request $request = null): Collection */ protected static function fillFields(RestifyRequest $request, Model $model, Collection $fields) { - return $fields->map(fn (Field $field) => $field->fillAttribute($request, $model)); + return $fields->map(fn(Field $field) => $field->fillAttribute($request, $model)); } protected static function fillBulkFields(RestifyRequest $request, Model $model, Collection $fields, int $bulkRow = null) @@ -975,12 +1017,12 @@ protected static function fillBulkFields(RestifyRequest $request, Model $model, public static function uriTo(Model $model) { - return Str::replaceFirst('//', '/', Restify::path().'/'.static::uriKey().'/'.$model->getKey()); + return Str::replaceFirst('//', '/', Restify::path() . '/' . static::uriKey() . '/' . $model->getKey()); } public function availableFilters(RestifyRequest $request) { - return collect($this->filter($this->filters($request)))->each(fn (Filter $filter) => $filter->authorizedToSee($request)) + return collect($this->filter($this->filters($request)))->each(fn(Filter $filter) => $filter->authorizedToSee($request)) ->values(); } diff --git a/tests/Controllers/RepositoryAttachControllerTest.php b/tests/Controllers/RepositoryAttachControllerTest.php index 235fb589f..c99ad83a4 100644 --- a/tests/Controllers/RepositoryAttachControllerTest.php +++ b/tests/Controllers/RepositoryAttachControllerTest.php @@ -15,7 +15,7 @@ public function test_attach_a_user_to_a_company() $user = $this->mockUsers(2)->first(); $company = factory(Company::class)->create(); - $response = $this->postJson('companies/'.$company->id.'/attach/users', [ + $response = $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => $user->id, 'is_admin' => true, ])->assertStatus(201); @@ -32,12 +32,34 @@ public function test_pivot_field_validation() $user = $this->mockUsers(2)->first(); $company = factory(Company::class)->create(); - $this->postJson('companies/'.$company->id.'/attach/users', [ + $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => $user->id, ]) ->assertStatus(400); } + public function test_pivot_field_present_when_show() + { + $company = tap(factory(Company::class)->create(), function (Company $company) { + $company->users()->attach($this->mockUsers()->first()->id, [ + 'is_admin' => true, + ]); + $company->users()->attach($this->mockUsers()->first()->id); + }); + + $response = $this->getJson('companies/' . $company->id . '?related=users') + ->assertOk(); + + $this->assertSame( + true, + $response->json('data.relationships.users.0.pivots.is_admin') + ); + $this->assertSame( + false, + $response->json('data.relationships.users.1.pivots.is_admin') + ); + } + public function test_attach_multiple_users_to_a_company() { $user = $this->mockUsers(2)->first(); @@ -45,7 +67,7 @@ public function test_attach_multiple_users_to_a_company() $usersFromCompany = $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users'); $this->assertCount(0, $usersFromCompany->json('data')); - $response = $this->postJson('companies/'.$company->id.'/attach/users', [ + $response = $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => [1, 2], 'is_admin' => true, ]) @@ -69,7 +91,7 @@ public function test_after_attach_a_user_to_company_number_of_users_increased() $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users') ->assertJsonCount(0, 'data'); - $this->postJson('companies/'.$company->id.'/attach/users', [ + $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => $user->id, 'is_admin' => true, ]); @@ -90,7 +112,7 @@ public function test_policy_to_attach_a_user_to_a_company() $_SERVER['allow_attach_users'] = false; - $this->postJson('companies/'.$company->id.'/attach/users', [ + $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => $user->id, 'is_admin' => true, ]) @@ -98,7 +120,7 @@ public function test_policy_to_attach_a_user_to_a_company() $_SERVER['allow_attach_users'] = true; - $this->postJson('companies/'.$company->id.'/attach/users', [ + $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => $user->id, 'is_admin' => true, ]) diff --git a/tests/Controllers/RepositoryIndexControllerTest.php b/tests/Controllers/RepositoryIndexControllerTest.php index 3c7c1a3b2..56cc7e0aa 100644 --- a/tests/Controllers/RepositoryIndexControllerTest.php +++ b/tests/Controllers/RepositoryIndexControllerTest.php @@ -122,7 +122,11 @@ public function test_using_custom_related_casts() public function test_repository_with_deep_relations() { - CompanyRepository::$related = ['users.posts']; + CompanyRepository::partialMock() + ->expects('related') + ->andReturn([ + 'users.posts' + ]); tap(factory(Company::class)->create(), function (Company $company) { tap($company->users()->create( diff --git a/tests/Fixtures/Company/Company.php b/tests/Fixtures/Company/Company.php index d1ed1dc86..aabb248c8 100644 --- a/tests/Fixtures/Company/Company.php +++ b/tests/Fixtures/Company/Company.php @@ -15,6 +15,7 @@ class Company extends Model public function users() { return $this->belongsToMany(User::class, 'company_user', 'company_id', 'user_id') + ->using(CompanyUserPivot::class) ->withPivot([ 'is_admin', ]) diff --git a/tests/Fixtures/Company/CompanyRepository.php b/tests/Fixtures/Company/CompanyRepository.php index dc6d7a8d3..a172d6596 100644 --- a/tests/Fixtures/Company/CompanyRepository.php +++ b/tests/Fixtures/Company/CompanyRepository.php @@ -12,9 +12,14 @@ class CompanyRepository extends Repository { public static $model = Company::class; - public static $related = [ - 'users', - ]; + public static function related(): array + { + return [ + 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->withPivot( + Field::make('is_admin')->rules('required') + ), + ]; + } public function fields(RestifyRequest $request) { @@ -23,7 +28,7 @@ public function fields(RestifyRequest $request) BelongsToMany::make('users', 'users', UserRepository::class)->withPivot( Field::make('is_admin')->rules('required') - )->canDetach(fn ($request, $pivot) => $_SERVER['roles.canDetach.users']), + )->canDetach(fn($request, $pivot) => $_SERVER['roles.canDetach.users']), ]; } } diff --git a/tests/Fixtures/Company/CompanyUserPivot.php b/tests/Fixtures/Company/CompanyUserPivot.php new file mode 100644 index 000000000..ae053f887 --- /dev/null +++ b/tests/Fixtures/Company/CompanyUserPivot.php @@ -0,0 +1,12 @@ + 'bool', + ]; +} From c4951d659e2705317b0297e69c68f47ca0c36a05 Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Wed, 23 Dec 2020 15:31:30 +0200 Subject: [PATCH 2/6] Apply fixes from StyleCI (#329) --- src/Fields/BelongsToMany.php | 6 +- src/Repositories/PivotsCollection.php | 2 +- src/Repositories/Repository.php | 80 +++++++++---------- .../RepositoryAttachControllerTest.php | 14 ++-- .../RepositoryIndexControllerTest.php | 2 +- tests/Fixtures/Company/CompanyRepository.php | 2 +- 6 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/Fields/BelongsToMany.php b/src/Fields/BelongsToMany.php index dfa1eec9a..4d1adf896 100644 --- a/src/Fields/BelongsToMany.php +++ b/src/Fields/BelongsToMany.php @@ -31,8 +31,8 @@ class BelongsToMany extends EagerField public function __construct($attribute, $relation, $parentRepository) { - if (!is_a(app($parentRepository), Repository::class)) { - abort(500, "Invalid parent repository [{$parentRepository}]. Expended instance of " . Repository::class); + if (! is_a(app($parentRepository), Repository::class)) { + abort(500, "Invalid parent repository [{$parentRepository}]. Expended instance of ".Repository::class); } parent::__construct($attribute); @@ -55,7 +55,7 @@ public function resolve($repository, $attribute = null) ->allowToShow(app(Request::class)) ->withPivots( PivotsCollection::make($this->pivotFields) - ->map(fn(Field $field) => clone $field) + ->map(fn (Field $field) => clone $field) ->resolveFromPivot($item->pivot) ) ->eagerState(); diff --git a/src/Repositories/PivotsCollection.php b/src/Repositories/PivotsCollection.php index 7fffb3244..4ef91e176 100644 --- a/src/Repositories/PivotsCollection.php +++ b/src/Repositories/PivotsCollection.php @@ -11,7 +11,7 @@ class PivotsCollection extends Collection public function resolveFromPivot(Pivot $pivot): self { return $this->map(function (Field $field) use ($pivot) { - return $field->resolveCallback(fn() => $pivot->{$field->attribute}); + return $field->resolveCallback(fn () => $pivot->{$field->attribute}); }); } } diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index 328904acf..8efbbefab 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -258,7 +258,7 @@ public static function newModel(): Model public static function query(RestifyRequest $request) { - if (!$request->isViaRepository()) { + if (! $request->isViaRepository()) { return static::newModel()->query(); } @@ -425,16 +425,16 @@ public function resolveShowAttributes(RestifyRequest $request) { $fields = $this->collectFields($request) ->forShow($request, $this) - ->filter(fn(Field $field) => $field->authorize($request)) + ->filter(fn (Field $field) => $field->authorize($request)) ->when( $this->isEagerState(), function ($items) { - return $items->filter(fn(Field $field) => !$field instanceof EagerField); + return $items->filter(fn (Field $field) => ! $field instanceof EagerField); } ) - ->each(fn(Field $field) => $field->resolveForShow($this)) - ->map(fn(Field $field) => $field->serializeToValue($request)) - ->mapWithKeys(fn($value) => $value) + ->each(fn (Field $field) => $field->resolveForShow($this)) + ->map(fn (Field $field) => $field->serializeToValue($request)) + ->mapWithKeys(fn ($value) => $value) ->all(); if ($this instanceof Mergeable) { @@ -452,7 +452,7 @@ function ($items) { return false; } - if (!$field->authorize($request)) { + if (! $field->authorize($request)) { return false; } @@ -475,16 +475,16 @@ public function resolveIndexAttributes($request) $fields = $this ->collectFields($request) ->forIndex($request, $this) - ->filter(fn(Field $field) => $field->authorize($request)) + ->filter(fn (Field $field) => $field->authorize($request)) ->when( $this->eagerState, function ($items) { - return $items->filter(fn(Field $field) => !$field instanceof EagerField); + return $items->filter(fn (Field $field) => ! $field instanceof EagerField); } ) - ->each(fn(Field $field) => $field->resolveForIndex($this)) - ->map(fn(Field $field) => $field->serializeToValue($request)) - ->mapWithKeys(fn($value) => $value) + ->each(fn (Field $field) => $field->resolveForIndex($this)) + ->map(fn (Field $field) => $field->serializeToValue($request)) + ->mapWithKeys(fn ($value) => $value) ->all(); if ($this instanceof Mergeable) { @@ -502,7 +502,7 @@ function ($items) { return false; } - if (!$field->authorize($request)) { + if (! $field->authorize($request)) { return false; } @@ -530,10 +530,10 @@ public function resolveShowPivots(RestifyRequest $request): array } return $pivots - ->filter(fn(Field $field) => $field->authorize($request)) - ->each(fn(Field $field) => $field->resolve($this)) - ->map(fn(Field $field) => $field->serializeToValue($request)) - ->mapWithKeys(fn($value) => $value) + ->filter(fn (Field $field) => $field->authorize($request)) + ->each(fn (Field $field) => $field->resolve($this)) + ->map(fn (Field $field) => $field->serializeToValue($request)) + ->mapWithKeys(fn ($value) => $value) ->all(); } @@ -575,16 +575,16 @@ public function resolveRelationships($request): array : $this->resource->{$relation}(); collect([ - Builder::class => fn() => $withs->put($relation, (static::$relatedCast)::fromBuilder($request, $paginator, $this)), + Builder::class => fn () => $withs->put($relation, (static::$relatedCast)::fromBuilder($request, $paginator, $this)), - Relation::class => fn() => $withs->put($relation, (static::$relatedCast)::fromRelation($request, $paginator, $this)), + Relation::class => fn () => $withs->put($relation, (static::$relatedCast)::fromRelation($request, $paginator, $this)), - Collection::class => fn() => $withs->put($relation, $paginator), + Collection::class => fn () => $withs->put($relation, $paginator), - Model::class => fn() => fn() => $withs->put($relation, $paginator), + Model::class => fn () => fn () => $withs->put($relation, $paginator), - ])->first(fn($fn, $class) => $paginator instanceof $class, - fn() => fn() => $withs->put($relation, $paginator) + ])->first(fn ($fn, $class) => $paginator instanceof $class, + fn () => fn () => $withs->put($relation, $paginator) )(); }); @@ -638,14 +638,14 @@ public function index(RestifyRequest $request) [ 'meta' => $this->when( $meta = $this->resolveIndexMainMeta( - $request, $models = $items->map(fn(self $repository) => $repository->resource), RepositoryCollection::meta($paginator->toArray()) + $request, $models = $items->map(fn (self $repository) => $repository->resource), RepositoryCollection::meta($paginator->toArray()) ), $meta ), 'links' => $this->when( $links = $this->resolveIndexLinks($request, $models, RepositoryCollection::paginationLinks($paginator->toArray())), $links ), - 'data' => $items->map(fn(self $repository) => $repository->serializeForIndex($request)), + 'data' => $items->map(fn (self $repository) => $repository->serializeForIndex($request)), ] ) ); @@ -695,7 +695,7 @@ public function store(RestifyRequest $request) } } - $fields->each(fn(Field $field) => $field->invokeAfter($request, $this->resource)); + $fields->each(fn (Field $field) => $field->invokeAfter($request, $this->resource)); }); static::stored($this->resource, $request); @@ -726,7 +726,7 @@ public function storeBulk(RepositoryStoreBulkRequest $request) $this->resource->save(); - $fields->each(fn(Field $field) => $field->invokeAfter($request, $this->resource)); + $fields->each(fn (Field $field) => $field->invokeAfter($request, $this->resource)); return $this->resource; }); @@ -753,7 +753,7 @@ public function update(RestifyRequest $request, $repositoryId) return $fields; })->each( - fn(Field $field) => $field->invokeAfter($request, $this->resource) + fn (Field $field) => $field->invokeAfter($request, $this->resource) ); return $this->response() @@ -782,7 +782,7 @@ public function attach(RestifyRequest $request, $repositoryId, Collection $pivot $eagerField = $this->authorizeBelongsToMany($request)->belongsToManyField($request); DB::transaction(function () use ($request, $pivots, $eagerField) { - $fields = $eagerField->collectPivotFields()->filter(fn($pivotField) => $request->has($pivotField->attribute))->values(); + $fields = $eagerField->collectPivotFields()->filter(fn ($pivotField) => $request->has($pivotField->attribute))->values(); $pivots->map(function ($pivot) use ($request, $fields, $eagerField) { static::validatorForAttach($request)->validate(); @@ -815,7 +815,7 @@ public function detach(RestifyRequest $request, $repositoryId, Collection $pivot $deleted = DB::transaction(function () use ($pivots, $eagerField, $request) { return $pivots - ->map(fn($pivot) => $eagerField->authorizeToDetach($request, $pivot) && $pivot->delete()); + ->map(fn ($pivot) => $eagerField->authorizeToDetach($request, $pivot) && $pivot->delete()); }); return $this->response() @@ -847,18 +847,18 @@ public function allowToUpdate(RestifyRequest $request, $payload = null): self public function allowToAttach(RestifyRequest $request, Collection $attachers): self { - $methodGuesser = 'attach' . Str::studly($request->relatedRepository); + $methodGuesser = 'attach'.Str::studly($request->relatedRepository); - $attachers->each(fn($model) => $this->authorizeToAttach($request, $methodGuesser, $model)); + $attachers->each(fn ($model) => $this->authorizeToAttach($request, $methodGuesser, $model)); return $this; } public function allowToDetach(RestifyRequest $request, Collection $attachers): self { - $methodGuesser = 'detach' . Str::studly($request->relatedRepository); + $methodGuesser = 'detach'.Str::studly($request->relatedRepository); - $attachers->each(fn($model) => $this->authorizeToDetach($request, $methodGuesser, $model)); + $attachers->each(fn ($model) => $this->authorizeToDetach($request, $methodGuesser, $model)); return $this; } @@ -948,7 +948,7 @@ public function response($content = '', $status = 200, array $headers = []): Res public function serializeForShow(RestifyRequest $request): array { return $this->filter([ - 'id' => $this->when(optional($this->resource)->id, fn() => $this->getId($request)), + 'id' => $this->when(optional($this->resource)->id, fn () => $this->getId($request)), 'type' => $this->when($type = $this->getType($request), $type), 'attributes' => $request->isShowRequest() ? $this->resolveShowAttributes($request) : $this->resolveIndexAttributes($request), 'relationships' => $this->when(value($related = $this->resolveRelationships($request)), $related), @@ -962,7 +962,7 @@ public function serializeForIndex(RestifyRequest $request): array return $this->filter([ 'id' => $this->when($id = $this->getId($request), $id), 'type' => $this->when($type = $this->getType($request), $type), - 'attributes' => $this->when((bool)$attrs = $this->resolveIndexAttributes($request), $attrs), + 'attributes' => $this->when((bool) $attrs = $this->resolveIndexAttributes($request), $attrs), 'relationships' => $this->when(value($related = $this->resolveIndexRelationships($request)), $related), 'meta' => $this->when(value($meta = $this->resolveIndexMeta($request)), $meta), 'pivots' => $this->when(value($pivots = $this->resolveIndexPivots($request)), $pivots), @@ -976,7 +976,7 @@ protected function getType(RestifyRequest $request): ?string protected function getId(RestifyRequest $request): ?string { - if (!static::$id) { + if (! static::$id) { return null; } @@ -1005,7 +1005,7 @@ private function modelAttributes(Request $request = null): Collection */ protected static function fillFields(RestifyRequest $request, Model $model, Collection $fields) { - return $fields->map(fn(Field $field) => $field->fillAttribute($request, $model)); + return $fields->map(fn (Field $field) => $field->fillAttribute($request, $model)); } protected static function fillBulkFields(RestifyRequest $request, Model $model, Collection $fields, int $bulkRow = null) @@ -1017,12 +1017,12 @@ protected static function fillBulkFields(RestifyRequest $request, Model $model, public static function uriTo(Model $model) { - return Str::replaceFirst('//', '/', Restify::path() . '/' . static::uriKey() . '/' . $model->getKey()); + return Str::replaceFirst('//', '/', Restify::path().'/'.static::uriKey().'/'.$model->getKey()); } public function availableFilters(RestifyRequest $request) { - return collect($this->filter($this->filters($request)))->each(fn(Filter $filter) => $filter->authorizedToSee($request)) + return collect($this->filter($this->filters($request)))->each(fn (Filter $filter) => $filter->authorizedToSee($request)) ->values(); } diff --git a/tests/Controllers/RepositoryAttachControllerTest.php b/tests/Controllers/RepositoryAttachControllerTest.php index c99ad83a4..967f53a4f 100644 --- a/tests/Controllers/RepositoryAttachControllerTest.php +++ b/tests/Controllers/RepositoryAttachControllerTest.php @@ -15,7 +15,7 @@ public function test_attach_a_user_to_a_company() $user = $this->mockUsers(2)->first(); $company = factory(Company::class)->create(); - $response = $this->postJson('companies/' . $company->id . '/attach/users', [ + $response = $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, 'is_admin' => true, ])->assertStatus(201); @@ -32,7 +32,7 @@ public function test_pivot_field_validation() $user = $this->mockUsers(2)->first(); $company = factory(Company::class)->create(); - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, ]) ->assertStatus(400); @@ -47,7 +47,7 @@ public function test_pivot_field_present_when_show() $company->users()->attach($this->mockUsers()->first()->id); }); - $response = $this->getJson('companies/' . $company->id . '?related=users') + $response = $this->getJson('companies/'.$company->id.'?related=users') ->assertOk(); $this->assertSame( @@ -67,7 +67,7 @@ public function test_attach_multiple_users_to_a_company() $usersFromCompany = $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users'); $this->assertCount(0, $usersFromCompany->json('data')); - $response = $this->postJson('companies/' . $company->id . '/attach/users', [ + $response = $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => [1, 2], 'is_admin' => true, ]) @@ -91,7 +91,7 @@ public function test_after_attach_a_user_to_company_number_of_users_increased() $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users') ->assertJsonCount(0, 'data'); - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, 'is_admin' => true, ]); @@ -112,7 +112,7 @@ public function test_policy_to_attach_a_user_to_a_company() $_SERVER['allow_attach_users'] = false; - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, 'is_admin' => true, ]) @@ -120,7 +120,7 @@ public function test_policy_to_attach_a_user_to_a_company() $_SERVER['allow_attach_users'] = true; - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, 'is_admin' => true, ]) diff --git a/tests/Controllers/RepositoryIndexControllerTest.php b/tests/Controllers/RepositoryIndexControllerTest.php index 56cc7e0aa..67672daf3 100644 --- a/tests/Controllers/RepositoryIndexControllerTest.php +++ b/tests/Controllers/RepositoryIndexControllerTest.php @@ -125,7 +125,7 @@ public function test_repository_with_deep_relations() CompanyRepository::partialMock() ->expects('related') ->andReturn([ - 'users.posts' + 'users.posts', ]); tap(factory(Company::class)->create(), function (Company $company) { diff --git a/tests/Fixtures/Company/CompanyRepository.php b/tests/Fixtures/Company/CompanyRepository.php index a172d6596..3188f9900 100644 --- a/tests/Fixtures/Company/CompanyRepository.php +++ b/tests/Fixtures/Company/CompanyRepository.php @@ -28,7 +28,7 @@ public function fields(RestifyRequest $request) BelongsToMany::make('users', 'users', UserRepository::class)->withPivot( Field::make('is_admin')->rules('required') - )->canDetach(fn($request, $pivot) => $_SERVER['roles.canDetach.users']), + )->canDetach(fn ($request, $pivot) => $_SERVER['roles.canDetach.users']), ]; } } From 8c482882aa6324cb631e39ebf167b5e48a1bedcc Mon Sep 17 00:00:00 2001 From: Eduard Lupacescu Date: Wed, 23 Dec 2020 18:24:32 +0200 Subject: [PATCH 3/6] Use related instead of fields for many to many attach detach fields. --- src/Eager/RelatedCollection.php | 46 ++++- src/Fields/Concerns/Attachable.php | 5 +- src/Fields/EagerField.php | 8 - src/Fields/Field.php | 13 +- .../RepositoryAttachController.php | 4 +- .../Concerns/InteractsWithAttachers.php | 11 +- src/Repositories/Repository.php | 21 +- src/Repositories/ValidatingTrait.php | 30 ++- .../RepositoryAttachControllerTest.php | 183 ++++++++++++++---- .../RepositoryAttachInterceptorTest.php | 81 -------- .../RepositoryDetachControllerTest.php | 162 ++++++++++------ .../RepositoryDetachInterceptorTest.php | 118 ----------- tests/Fields/BelongsToManyFieldTest.php | 107 +++++----- tests/Fixtures/Company/CompanyRepository.php | 10 +- tests/Fixtures/User/User.php | 1 + tests/IntegrationTest.php | 1 + 16 files changed, 395 insertions(+), 406 deletions(-) delete mode 100644 tests/Controllers/RepositoryAttachInterceptorTest.php delete mode 100644 tests/Controllers/RepositoryDetachInterceptorTest.php diff --git a/src/Eager/RelatedCollection.php b/src/Eager/RelatedCollection.php index 2baf9b827..aa7f9219d 100644 --- a/src/Eager/RelatedCollection.php +++ b/src/Eager/RelatedCollection.php @@ -3,10 +3,13 @@ namespace Binaryk\LaravelRestify\Eager; use Binaryk\LaravelRestify\Fields\BelongsTo; +use Binaryk\LaravelRestify\Fields\BelongsToMany; use Binaryk\LaravelRestify\Fields\EagerField; use Binaryk\LaravelRestify\Fields\Field; +use Binaryk\LaravelRestify\Fields\MorphToMany; use Binaryk\LaravelRestify\Filters\SortableFilter; use Binaryk\LaravelRestify\Http\Requests\RestifyRequest; +use Binaryk\LaravelRestify\Repositories\Repository; use Illuminate\Support\Collection; class RelatedCollection extends Collection @@ -22,23 +25,52 @@ public function intoAssoc(): self public function forEager(RestifyRequest $request): self { - return $this->filter(fn ($value, $key) => $value instanceof EagerField) - ->filter(fn (Field $field) => $field->authorize($request)) + return $this->filter(fn($value, $key) => $value instanceof EagerField) + ->filter(fn(Field $field) => $field->authorize($request)) ->unique('attribute'); } + public function forManyToManyRelations(RestifyRequest $request): self + { + return $this->filter(function ($field) { + return $field instanceof BelongsToMany || $field instanceof MorphToMany; + })->filter(fn (EagerField $field) => $field->authorize($request)); + } + public function mapIntoSortable(RestifyRequest $request): self { - return $this->filter(fn (EagerField $field) => $field->isSortable()) + return $this->filter(fn(EagerField $field) => $field->isSortable()) //Now we support only belongs to sort from related. - ->filter(fn (EagerField $field) => $field instanceof BelongsTo) - ->map(fn (BelongsTo $field) => SortableFilter::make()->usingBelongsTo($field)); + ->filter(fn(EagerField $field) => $field instanceof BelongsTo) + ->map(fn(BelongsTo $field) => SortableFilter::make()->usingBelongsTo($field)); + } + + public function forShow(RestifyRequest $request, Repository $repository): self + { + return $this->filter(function ($related) use ($request, $repository) { + if ($related instanceof Field) { + return $related->isShownOnShow($request, $repository); + } + + return $related; + }); + } + + public function forIndex(RestifyRequest $request, Repository $repository): self + { + return $this->filter(function ($related) use ($request, $repository) { + if ($related instanceof Field) { + return $related->isShownOnIndex($request, $repository); + } + + return $related; + }); } public function inRequest(RestifyRequest $request): self { return $this - ->filter(fn ($field, $key) => in_array($key, str_getcsv($request->input('related')))) + ->filter(fn($field, $key) => in_array($key, str_getcsv($request->input('related')))) ->unique(); } @@ -52,6 +84,6 @@ public function mapIntoRelated(RestifyRequest $request) public function authorized(RestifyRequest $request) { return $this->intoAssoc() - ->filter(fn ($key, $value) => $key instanceof EagerField ? $key->authorize($request) : true); + ->filter(fn($key, $value) => $key instanceof EagerField ? $key->authorize($request) : true); } } diff --git a/src/Fields/Concerns/Attachable.php b/src/Fields/Concerns/Attachable.php index 511a35727..a4a9694f8 100644 --- a/src/Fields/Concerns/Attachable.php +++ b/src/Fields/Concerns/Attachable.php @@ -3,6 +3,7 @@ namespace Binaryk\LaravelRestify\Fields\Concerns; use Binaryk\LaravelRestify\Http\Requests\RestifyRequest; +use Binaryk\LaravelRestify\Repositories\PivotsCollection; use Closure; use DateTime; use Illuminate\Auth\Access\AuthorizationException; @@ -136,8 +137,8 @@ public function withPivot($fields) return $this; } - public function collectPivotFields(): Collection + public function collectPivotFields(): PivotsCollection { - return collect($this->pivotFields); + return PivotsCollection::make($this->pivotFields); } } diff --git a/src/Fields/EagerField.php b/src/Fields/EagerField.php index f95efe2ef..f529ce6bc 100644 --- a/src/Fields/EagerField.php +++ b/src/Fields/EagerField.php @@ -25,14 +25,6 @@ class EagerField extends Field */ public string $repositoryClass; - public function __construct($attribute, callable $resolveCallback = null) - { - parent::__construct($attribute, $resolveCallback); - - $this->showOnShow() - ->hideFromIndex(); - } - /** * Determine if the field should be displayed for the given request. * diff --git a/src/Fields/Field.php b/src/Fields/Field.php index ed50c8ad2..f2be0bb43 100644 --- a/src/Fields/Field.php +++ b/src/Fields/Field.php @@ -309,7 +309,7 @@ protected function fillAttributeFromValue(RestifyRequest $request, $model, $attr */ public function getAttribute() { - return $this->attribute; + return $this->label ?? $this->attribute; } /** @@ -381,6 +381,17 @@ public function messages(array $messages) return $this; } + public function serializeMessages(): array + { + $messages = []; + + foreach ($this->messages as $ruleFor => $message) { + $messages[$this->getAttribute() . '.' . $ruleFor] = $message; + } + + return $messages; + } + public function getStoringRules(): array { return array_merge($this->rules, $this->storingRules); diff --git a/src/Http/Controllers/RepositoryAttachController.php b/src/Http/Controllers/RepositoryAttachController.php index a6fd612e3..35c29a6b5 100644 --- a/src/Http/Controllers/RepositoryAttachController.php +++ b/src/Http/Controllers/RepositoryAttachController.php @@ -24,8 +24,8 @@ public function __invoke(RepositoryAttachRequest $request) return $repository->attach( $request, $request->repositoryId, collect(Arr::wrap($request->input($request->relatedRepository))) - ->filter(fn ($relatedRepositoryId) => $request->repository()->allowToAttach($request, $request->attachRelatedModels())) - ->map(fn ($relatedRepositoryId) => $this->belongsToManyField($request) + ->filter(fn($relatedRepositoryId) => $request->repository()->allowToAttach($request, $request->attachRelatedModels())) + ->map(fn($relatedRepositoryId) => $this->belongsToManyField($request) ->initializePivot( $request, $model->{$request->viaRelationship ?? $request->relatedRepository}(), $relatedRepositoryId )) diff --git a/src/Repositories/Concerns/InteractsWithAttachers.php b/src/Repositories/Concerns/InteractsWithAttachers.php index 623dd6ee8..1af9951b4 100644 --- a/src/Repositories/Concerns/InteractsWithAttachers.php +++ b/src/Repositories/Concerns/InteractsWithAttachers.php @@ -10,9 +10,8 @@ trait InteractsWithAttachers { public function belongsToManyField(RestifyRequest $request): ?BelongsToMany { - return $request->newRepository() - ->collectFields($request) - ->filterForManyToManyRelations($request) + return $request->newRepository()::collectRelated() + ->forManyToManyRelations($request) ->firstWhere('attribute', $request->relatedRepository); } @@ -20,7 +19,7 @@ public function authorizeBelongsToMany(RestifyRequest $request): self { if (is_null($field = $this->belongsToManyField($request))) { $class = class_basename($request->repository()); - abort(400, "Missing BelongsToMany or MorphToMany field for [{$request->relatedRepository}]. This field should be in the [{$class}] class. Or you are not authorized to use that repository (see `allowRestify` policy method)."); + abort(400, "Missing BelongsToMany or MorphToMany field for [{$request->relatedRepository}]. This field should be in the related of the [{$class}] class. Or you are not authorized to use that repository (see `allowRestify` policy method)."); } $field->authorizeToAttach( @@ -44,7 +43,7 @@ public function guessAttachMethod(RestifyRequest $request): ?callable return $cb; } - $methodGuesser = 'attach'.Str::studly($request->relatedRepository); + $methodGuesser = 'attach' . Str::studly($request->relatedRepository); if (method_exists($repository, $methodGuesser)) { return [$repository, $methodGuesser]; @@ -67,7 +66,7 @@ public function guessDetachMethod(RestifyRequest $request): ?callable return $cb; } - $methodGuesser = 'detach'.Str::studly($request->relatedRepository); + $methodGuesser = 'detach' . Str::studly($request->relatedRepository); if (method_exists($repository, $methodGuesser)) { return [$repository, $methodGuesser]; diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index 328904acf..5ecf698be 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -5,6 +5,7 @@ use Binaryk\LaravelRestify\Contracts\RestifySearchable; use Binaryk\LaravelRestify\Controllers\RestResponse; use Binaryk\LaravelRestify\Eager\Related; +use Binaryk\LaravelRestify\Eager\RelatedCollection; use Binaryk\LaravelRestify\Exceptions\InstanceOfException; use Binaryk\LaravelRestify\Fields\BelongsToMany; use Binaryk\LaravelRestify\Fields\EagerField; @@ -545,7 +546,7 @@ public function resolveIndexPivots(RestifyRequest $request): array /** * Return a list with relationship for the current model. * - * @param $request + * @param RestifyRequest $request * @return array */ public function resolveRelationships($request): array @@ -555,6 +556,12 @@ public function resolveRelationships($request): array static::collectRelated() ->authorized($request) ->inRequest($request) + ->when($request->isShowRequest(), function (RelatedCollection $collection) use ($request) { + return $collection->forShow($request, $this); + }) + ->when($request->isForRepositoryRequest(), function (RelatedCollection $collection) use ($request) { + return $collection->forIndex($request, $this); + }) ->mapIntoRelated($request) ->each(function (Related $related) use ($request, $withs) { $relation = $related->getRelation(); @@ -789,7 +796,7 @@ public function attach(RestifyRequest $request, $repositoryId, Collection $pivot static::fillFields($request, $pivot, $fields); - $eagerField->authorizeToAttach($request, $pivot); + $eagerField->authorizeToAttach($request); return $pivot; })->each->save(); @@ -803,16 +810,10 @@ public function attach(RestifyRequest $request, $repositoryId, Collection $pivot public function detach(RestifyRequest $request, $repositoryId, Collection $pivots) { /** * @var BelongsToMany $eagerField */ - $eagerField = $request->newRepository() - ->collectFields($request) - ->filterForManyToManyRelations($request) + $eagerField = $request->newRepository()::collectRelated() + ->forManyToManyRelations($request) ->firstWhere('attribute', $request->relatedRepository); - if (is_null($eagerField)) { - $class = class_basename($request->repository()); - abort(400, "Missing BelongsToMany or MorphToMany field for [{$request->relatedRepository}]. This field should be in the [{$class}] class."); - } - $deleted = DB::transaction(function () use ($pivots, $eagerField, $request) { return $pivots ->map(fn($pivot) => $eagerField->authorizeToDetach($request, $pivot) && $pivot->delete()); diff --git a/src/Repositories/ValidatingTrait.php b/src/Repositories/ValidatingTrait.php index 47d1352f8..2725273cf 100644 --- a/src/Repositories/ValidatingTrait.php +++ b/src/Repositories/ValidatingTrait.php @@ -34,7 +34,7 @@ public static function validatorForStoring(RestifyRequest $request, array $plain $messages = $on->collectFields($request)->flatMap(function ($k) { $messages = []; foreach ($k->messages as $ruleFor => $message) { - $messages[$k->attribute.'.'.$ruleFor] = $message; + $messages[$k->attribute . '.' . $ruleFor] = $message; } return $messages; @@ -54,7 +54,7 @@ public static function validatorForStoringBulk(RestifyRequest $request, array $p $messages = $on->collectFields($request)->flatMap(function ($k) { $messages = []; foreach ($k->messages as $ruleFor => $message) { - $messages['*'.$k->attribute.'.'.$ruleFor] = $message; + $messages['*' . $k->attribute . '.' . $ruleFor] = $message; } return $messages; @@ -84,7 +84,7 @@ public static function validatorForUpdate(RestifyRequest $request, $resource = n $messages = $on->collectFields($request)->flatMap(function ($k) { $messages = []; foreach ($k->messages as $ruleFor => $message) { - $messages[$k->attribute.'.'.$ruleFor] = $message; + $messages[$k->attribute . '.' . $ruleFor] = $message; } return $messages; @@ -101,23 +101,15 @@ public static function validatorForAttach(RestifyRequest $request, $resource = n /** * @var Repository $on */ $on = $resource ?? static::resolveWith(static::newModel()); - /** - * @var BelongsToMany $field - */ - $pivotFields = $on - ->collectFields($request) - ->filterForManyToManyRelations($request) - ->firstWhere('attribute', $request->relatedRepository) - ->collectPivotFields(); - $messages = $pivotFields->flatMap(function ($field) { - $messages = []; - foreach ($field->messages as $ruleFor => $message) { - $messages[$field->attribute.'.'.$ruleFor] = $message; - } + /** * @var BelongsToMany $field */ + $field = $on::collectRelated() + ->forManyToManyRelations($request) + ->firstWhere('attribute', $request->relatedRepository); - return $messages; - })->all(); + $pivotFields = $field->collectPivotFields(); + + $messages = $pivotFields->flatMap(fn(Field $field) => $field->serializeMessages())->all(); $rules = $pivotFields->mapWithKeys(function (Field $k) { return [ @@ -139,7 +131,7 @@ public static function validatorForUpdateBulk(RestifyRequest $request, $resource $messages = $on->collectFields($request)->flatMap(function ($k) { $messages = []; foreach ($k->messages as $ruleFor => $message) { - $messages['*'.$k->attribute.'.'.$ruleFor] = $message; + $messages['*' . $k->attribute . '.' . $ruleFor] = $message; } return $messages; diff --git a/tests/Controllers/RepositoryAttachControllerTest.php b/tests/Controllers/RepositoryAttachControllerTest.php index c99ad83a4..89f9c727f 100644 --- a/tests/Controllers/RepositoryAttachControllerTest.php +++ b/tests/Controllers/RepositoryAttachControllerTest.php @@ -2,40 +2,86 @@ namespace Binaryk\LaravelRestify\Tests\Controllers; +use Binaryk\LaravelRestify\Fields\BelongsToMany; +use Binaryk\LaravelRestify\Fields\Field; use Binaryk\LaravelRestify\Tests\Fixtures\Company\Company; use Binaryk\LaravelRestify\Tests\Fixtures\Company\CompanyPolicy; +use Binaryk\LaravelRestify\Tests\Fixtures\Company\CompanyRepository; use Binaryk\LaravelRestify\Tests\Fixtures\User\User; +use Binaryk\LaravelRestify\Tests\Fixtures\User\UserRepository; use Binaryk\LaravelRestify\Tests\IntegrationTest; +use Illuminate\Database\Eloquent\Relations\Pivot; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Gate; class RepositoryAttachControllerTest extends IntegrationTest { - public function test_attach_a_user_to_a_company() + public function test_can_attach_repositories() { - $user = $this->mockUsers(2)->first(); + $user = $this->mockUsers()->first(); $company = factory(Company::class)->create(); - $response = $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => $user->id, 'is_admin' => true, - ])->assertStatus(201); - - $response->assertJsonFragment([ + ])->assertCreated()->assertJsonFragment([ 'company_id' => '1', 'user_id' => $user->id, 'is_admin' => true, ]); + + $this->assertCount(1, Company::first()->users); } - public function test_pivot_field_validation() + public function test_cant_attach_repositories_not_authorized_to_attach() { - $user = $this->mockUsers(2)->first(); + Gate::policy(Company::class, CompanyPolicy::class); + + $user = $this->mockUsers()->first(); + $company = factory(Company::class)->create(); + + $this->authenticate( + factory(User::class)->create() + ); + + $_SERVER['allow_attach_users'] = false; + + $this->postJson('companies/' . $company->id . '/attach/users', [ + 'users' => $user->id, + 'is_admin' => true, + ])->assertForbidden(); + + $_SERVER['allow_attach_users'] = true; + + $this->postJson('companies/' . $company->id . '/attach/users', [ + 'users' => $user->id, + 'is_admin' => true, + ])->assertCreated(); + + unset($_SERVER['allow_attach_users']); + } + + public function test_attach_pivot_field_validation() + { + $user = $this->mockUsers()->first(); $company = factory(Company::class)->create(); + CompanyRepository::partialMock() + ->shouldReceive('related') + ->andReturn([ + 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->withPivot( + Field::make('is_admin')->rules('required')->messages([ + 'required' => $message = 'You should fill the is_admin information.', + ]) + ) + ]); + $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => $user->id, - ]) - ->assertStatus(400); + ])->assertStatus(400)->assertJsonFragment([ + 'is_admin' => [ + $message + ]]); } public function test_pivot_field_present_when_show() @@ -54,76 +100,133 @@ public function test_pivot_field_present_when_show() true, $response->json('data.relationships.users.0.pivots.is_admin') ); + $this->assertSame( false, $response->json('data.relationships.users.1.pivots.is_admin') ); } + public function test_pivot_field_present_when_index() + { + tap(factory(Company::class)->create(), function (Company $company) { + $company->users()->attach($this->mockUsers()->first()->id, [ + 'is_admin' => true, + ]); + $company->users()->attach($this->mockUsers()->first()->id); + }); + + $response = $this->getJson('companies?related=users') + ->assertOk(); + + $this->assertSame( + true, + $response->json('data.0.relationships.users.0.pivots.is_admin') + ); + $this->assertSame( + false, + $response->json('data.0.relationships.users.1.pivots.is_admin') + ); + } + public function test_attach_multiple_users_to_a_company() { $user = $this->mockUsers(2)->first(); $company = factory(Company::class)->create(); - $usersFromCompany = $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users'); - $this->assertCount(0, $usersFromCompany->json('data')); - $response = $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->assertCount(0, $company->users); + + $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => [1, 2], 'is_admin' => true, - ]) - ->assertStatus(201); - - $response->assertJsonFragment([ + ])->assertCreated()->assertJsonFragment([ 'company_id' => '1', 'user_id' => $user->id, 'is_admin' => true, ]); - $usersFromCompany = $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users'); - $this->assertCount(2, $usersFromCompany->json('data')); + $this->assertCount(2, $company->fresh()->users); } - public function test_after_attach_a_user_to_company_number_of_users_increased() + public function test_many_to_many_field_can_intercept_attach_authorization() { $user = $this->mockUsers()->first(); $company = factory(Company::class)->create(); - $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users') - ->assertJsonCount(0, 'data'); + CompanyRepository::partialMock() + ->shouldReceive('related') + ->andReturn([ + 'users' => BelongsToMany::make('users', 'users', UserRepository::class) + ->canAttach(function ($request, $pivot) { + $this->assertInstanceOf(Request::class, $request); + $this->assertInstanceOf(Pivot::class, $pivot); + + return false; + }) + ]); $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => $user->id, 'is_admin' => true, - ]); - - $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users') - ->assertJsonCount(1, 'data'); + ])->assertForbidden(); } - public function test_policy_to_attach_a_user_to_a_company() + public function test_many_to_many_field_can_intercept_attach_method() { - Gate::policy(Company::class, CompanyPolicy::class); - - $user = $this->mockUsers(2)->first(); + $user = $this->mockUsers()->first(); $company = factory(Company::class)->create(); - $this->authenticate( - factory(User::class)->create() - ); - $_SERVER['allow_attach_users'] = false; + CompanyRepository::partialMock() + ->shouldReceive('related') + ->andReturn([ + 'users' => BelongsToMany::make('users', 'users', UserRepository::class) + ->canAttach(function ($request, $pivot) { + $this->assertInstanceOf(Request::class, $request); + $this->assertInstanceOf(Pivot::class, $pivot); + + return true; + }) + ->attachCallback(function ($request, $repository, $model) { + $this->assertInstanceOf(Request::class, $request); + $this->assertInstanceOf(CompanyRepository::class, $repository); + $this->assertInstanceOf(Company::class, $model); + + $model->users()->attach($request->input('users')); + }) + ]); $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => $user->id, 'is_admin' => true, - ]) - ->assertForbidden(); + ])->assertOk(); - $_SERVER['allow_attach_users'] = true; + $this->assertCount(1, Company::first()->users); + } + + public function test_repository_can_intercept_attach() + { + $user = $this->mockUsers()->first(); + $company = factory(Company::class)->create(); + + CompanyRepository::partialMock()->shouldReceive('related') + ->andReturn([ + 'users' => BelongsToMany::make('users', 'users', UserRepository::class), + ]); + + CompanyRepository::$attachers = [ + 'users' => function ($request, $repository, $model) { + $this->assertInstanceOf(Request::class, $request); + $this->assertInstanceOf(CompanyRepository::class, $repository); + $this->assertInstanceOf(Company::class, $model); + + $model->users()->attach($request->input('users')); + }, + ]; $this->postJson('companies/' . $company->id . '/attach/users', [ 'users' => $user->id, - 'is_admin' => true, - ]) - ->assertCreated(); + ])->assertOk(); + + $this->assertCount(1, $company->fresh()->users); } } diff --git a/tests/Controllers/RepositoryAttachInterceptorTest.php b/tests/Controllers/RepositoryAttachInterceptorTest.php deleted file mode 100644 index 92f89552b..000000000 --- a/tests/Controllers/RepositoryAttachInterceptorTest.php +++ /dev/null @@ -1,81 +0,0 @@ -create(); - $user = $this->mockUsers()->first(); - - $_SERVER['roles.canAttach.users'] = true; - - $this->postJson('roles/'.$role->id.'/attach/users', [ - 'users' => $user->id, - ])->assertCreated(); - - $this->assertDatabaseCount('model_has_roles', 1); - - $_SERVER['roles.canAttach.users'] = false; - - $this->postJson('roles/'.$role->id.'/attach/users', [ - 'users' => $user->id, - ])->assertForbidden(); - } - - public function test_attach_uses_field_resolver() - { - $this->mock(BelongsToMany::class); - - RoleRepository::partialMock() - ->expects('fields') - ->twice() - ->andReturn([ - field('name'), - BelongsToMany::new('users', 'users', UserRepository::class) - ->canAttach(function ($request, $pivot) { - $this->assertInstanceOf(RestifyRequest::class, $request); - $this->assertInstanceOf(Pivot::class, $pivot); - - return true; - }) - ->attachCallback(function ($request, $repository, Role $model) { - $this->assertInstanceOf(RestifyRequest::class, $request); - $this->assertInstanceOf(Repository::class, $repository); - $this->assertInstanceOf(Model::class, $model); - - $model->users()->attach($request->input('users')); - }), - ]); - - $role = factory(Role::class)->create(); - - $this->assertCount(0, $role->users()->get()); - - $user = $this->mockUsers()->first(); - - $this->postJson('roles/'.$role->id.'/attach/users', [ - 'users' => $user->id, - ])->assertSuccessful(); - - $this->assertCount(1, $role->users()->get()); - } -} diff --git a/tests/Controllers/RepositoryDetachControllerTest.php b/tests/Controllers/RepositoryDetachControllerTest.php index 3b3910661..ead589956 100644 --- a/tests/Controllers/RepositoryDetachControllerTest.php +++ b/tests/Controllers/RepositoryDetachControllerTest.php @@ -2,96 +2,138 @@ namespace Binaryk\LaravelRestify\Tests\Controllers; +use Binaryk\LaravelRestify\Fields\BelongsToMany; use Binaryk\LaravelRestify\Tests\Fixtures\Company\Company; use Binaryk\LaravelRestify\Tests\Fixtures\Company\CompanyPolicy; +use Binaryk\LaravelRestify\Tests\Fixtures\Company\CompanyRepository; use Binaryk\LaravelRestify\Tests\Fixtures\User\User; +use Binaryk\LaravelRestify\Tests\Fixtures\User\UserRepository; use Binaryk\LaravelRestify\Tests\IntegrationTest; +use Illuminate\Database\Eloquent\Relations\Pivot; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Gate; class RepositoryDetachControllerTest extends IntegrationTest { - protected function setUp(): void + public function test_can_detach_repositories() { - parent::setUp(); - $_SERVER['roles.canDetach.users'] = true; - } - public function test_detach_a_user_from_a_company() - { - $user = $this->mockUsers(2)->first(); - $company = factory(Company::class)->create(); - $company->users()->attach($user->id); - $usersFromCompany = $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users'); - $this->assertCount(1, $usersFromCompany->json('data')); - $this->postJson('companies/'.$company->id.'/detach/users', [ - 'users' => $user->id, - ])->assertStatus(204); - - $usersFromCompany = $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users'); - $this->assertCount(0, $usersFromCompany->json('data')); + $company = tap(factory(Company::class)->create(), function (Company $company) { + $company->users()->attach($this->mockUsers()->first()->id, [ + 'is_admin' => true, + ]); + $company->users()->attach($this->mockUsers()->first()->id); + }); + + $this->assertCount(2, $company->users); + + $this->postJson('companies/' . $company->id . '/detach/users', [ + 'users' => [1, 2] + ])->assertNoContent(); + + $this->assertCount(0, $company->fresh()->users); } - public function test_detach_multiple_users_from_a_company() + public function test_cant_detach_repositories_not_authorized_to_detach() { - $users = $this->mockUsers(3); - $company = factory(Company::class)->create(); - $company->users()->attach($users->pluck('id')); + Gate::policy(Company::class, CompanyPolicy::class); - $usersFromCompany = $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users'); - $this->assertCount(3, $usersFromCompany->json('data')); + $this->authenticate( + factory(User::class)->create() + ); + + $company = tap(factory(Company::class)->create(), function (Company $company) { + $company->users()->attach($this->mockUsers()->first()->id, [ + 'is_admin' => true, + ]); + $company->users()->attach($this->mockUsers()->first()->id); + }); + + $_SERVER['allow_detach_users'] = false; - $this->postJson('companies/'.$company->id.'/detach/users', [ - 'users' => [1, 2], - ])->assertStatus(204); + $this->postJson('companies/' . $company->id . '/detach/users', [ + 'users' => [1, 2] + ])->assertForbidden(); + } - $usersFromCompany = $this->getJson('users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users'); - $this->assertCount(1, $usersFromCompany->json('data')); + public function test_many_to_many_field_can_intercept_detach_authorization() + { + CompanyRepository::partialMock() + ->shouldReceive('related') + ->andReturn([ + 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->canDetach(function ($request, $pivot) { + $this->assertInstanceOf(Request::class, $request); + $this->assertInstanceOf(Pivot::class, $pivot); + + return false; + }), + ]); + + $company = tap(factory(Company::class)->create(), function (Company $company) { + $company->users()->attach($this->mockUsers()->first()->id); + }); + + $this->postJson('companies/' . $company->id . '/detach/users', [ + 'users' => [1] + ])->assertForbidden(); } - public function test_forbidden_detach_users_from_company() + public function test_many_to_many_field_can_intercept_detach_method() { - $_SERVER['roles.canDetach.users'] = false; + CompanyRepository::partialMock() + ->shouldReceive('related') + ->andReturn([ + 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->detachCallback(function ($request, $repository, $model) { + $this->assertInstanceOf(Request::class, $request); + $this->assertInstanceOf(CompanyRepository::class, $repository); + $this->assertInstanceOf(Company::class, $model); - $users = $this->mockUsers(3); - $company = factory(Company::class)->create(); - $company->users()->attach($users->pluck('id')); + $model->users()->detach($request->input('users')); - $this->postJson('companies/'.$company->id.'/detach/users', [ - 'users' => [1, 2], - ])->assertForbidden(); + return response()->noContent(); + }), + ]); + + $company = tap(factory(Company::class)->create(), function (Company $company) { + $company->users()->attach($this->mockUsers()->first()->id); + }); + + $this->postJson('companies/' . $company->id . '/detach/users', [ + 'users' => [1] + ])->assertNoContent(); + + $this->assertCount(0, $company->fresh()->users); } - public function test_policy_to_detach_a_user_to_a_company() + public function test_repository_can_intercept_detach() { - Gate::policy(Company::class, CompanyPolicy::class); + $mock = CompanyRepository::partialMock(); + $mock->shouldReceive('related') + ->andReturn([ + 'users' => BelongsToMany::make('users', 'users', UserRepository::class), + ]); - $user = $this->mockUsers(2)->first(); - $company = factory(Company::class)->create(); - $this->authenticate( - factory(User::class)->create() - ); + CompanyRepository::$detachers = [ + 'users' => function ($request, $repository, $model) { + $this->assertInstanceOf(Request::class, $request); + $this->assertInstanceOf(CompanyRepository::class, $repository); + $this->assertInstanceOf(Company::class, $model); - $this->postJson('companies/'.$company->id.'/attach/users', [ - 'users' => $user->id, - 'is_admin' => true, - ]) - ->assertCreated(); + $model->users()->detach($request->input('users')); - $_SERVER['allow_detach_users'] = false; + return response()->noContent(); + }, + ]; - $this->postJson('companies/'.$company->id.'/detach/users', [ - 'users' => $user->id, - 'is_admin' => true, - ]) - ->assertForbidden(); + $company = tap(factory(Company::class)->create(), function (Company $company) { + $company->users()->attach($this->mockUsers()->first()->id); + }); - $_SERVER['allow_detach_users'] = true; + $this->postJson('companies/' . $company->id . '/detach/users', [ + 'users' => [1] + ])->assertNoContent(); - $this->postJson('companies/'.$company->id.'/detach/users', [ - 'users' => $user->id, - 'is_admin' => true, - ]) - ->assertNoContent(); + $this->assertCount(0, $company->fresh()->users); } } diff --git a/tests/Controllers/RepositoryDetachInterceptorTest.php b/tests/Controllers/RepositoryDetachInterceptorTest.php deleted file mode 100644 index c0106de37..000000000 --- a/tests/Controllers/RepositoryDetachInterceptorTest.php +++ /dev/null @@ -1,118 +0,0 @@ -create(); - $user = $this->mockUsers()->first(); - $role->users()->attach($user->id); - - $_SERVER['roles.canDetach.users'] = true; - - $this->assertCount(1, $role->users()->get()); - - $this->postJson('roles/'.$role->id.'/detach/users', [ - 'users' => $user->id, - ])->assertSuccessful(); - - $this->assertCount(0, $role->users()->get()); - - $_SERVER['roles.canDetach.users'] = false; - - $this->postJson('roles/'.$role->id.'/detach/users', [ - 'users' => $user->id, - ])->assertForbidden(); - } - - public function test_detach_uses_field_resolver() - { - RoleRepository::partialMock() - ->expects('fields') - ->twice() - ->andReturn([ - field('name'), - BelongsToMany::new('users', 'users', UserRepository::class) - ->canDetach(function ($request, $pivot) { - $this->assertInstanceOf(RestifyRequest::class, $request); - $this->assertInstanceOf(Pivot::class, $pivot); - - return true; - }) - ->detachCallback(function ($request, $repository, Role $model) { - $this->assertInstanceOf(RestifyRequest::class, $request); - $this->assertInstanceOf(Repository::class, $repository); - $this->assertInstanceOf(Model::class, $model); - - $model->users()->detach($request->input('users')); - }), - ]); - - $role = factory(Role::class)->create(); - $user = $this->mockUsers()->first(); - $role->users()->attach($user->id); - - $this->assertCount(1, $role->users()->get()); - - $this->postJson('roles/'.$role->id.'/detach/users', [ - 'users' => $user->id, - ])->assertSuccessful(); - - $this->assertCount(0, $role->users()->get()); - } - - public function test_detach_uses_repository_resolver() - { - RoleRepository::partialMock() - ->expects('getDetachers') - ->twice() - ->andReturn([ - 'users' => function (RestifyRequest $request, RoleRepository $repository, Role $model) { - $this->assertInstanceOf(RestifyRequest::class, $request); - $this->assertInstanceOf(RoleRepository::class, $repository); - $this->assertInstanceOf(Role::class, $model); - - $model->users()->detach($request->input('users')); - }, - ]); - - $role = factory(Role::class)->create(); - $user = $this->mockUsers()->first(); - $role->users()->attach($user->id); - - $this->assertCount(1, $role->users()->get()); - - $this->postJson('roles/'.$role->id.'/detach/users', [ - 'users' => $user->id, - ])->assertSuccessful(); - - $this->assertCount(0, $role->users()->get()); - } -} diff --git a/tests/Fields/BelongsToManyFieldTest.php b/tests/Fields/BelongsToManyFieldTest.php index d516b0b98..8637db251 100644 --- a/tests/Fields/BelongsToManyFieldTest.php +++ b/tests/Fields/BelongsToManyFieldTest.php @@ -7,21 +7,13 @@ use Binaryk\LaravelRestify\Repositories\Repository; use Binaryk\LaravelRestify\Restify; use Binaryk\LaravelRestify\Tests\Fixtures\Company\Company; +use Binaryk\LaravelRestify\Tests\Fixtures\Company\CompanyRepository; use Binaryk\LaravelRestify\Tests\Fixtures\User\User; use Binaryk\LaravelRestify\Tests\Fixtures\User\UserRepository; use Binaryk\LaravelRestify\Tests\IntegrationTest; class BelongsToManyFieldTest extends IntegrationTest { - protected function setUp(): void - { - parent::setUp(); - - Restify::repositories([ - CompanyWithUsersRepository::class, - ]); - } - public function test_belongs_to_many_displays_on_relationships_show() { $company = tap(factory(Company::class)->create(), function (Company $company) { @@ -30,7 +22,7 @@ public function test_belongs_to_many_displays_on_relationships_show() ); }); - $this->get(CompanyWithUsersRepository::uriKey()."/{$company->id}?related=users") + $this->get(CompanyRepository::uriKey() . "/{$company->id}?related=users") ->assertJsonStructure([ 'data' => [ 'relationships' => [ @@ -40,7 +32,7 @@ public function test_belongs_to_many_displays_on_relationships_show() ])->assertJsonCount(5, 'data.relationships.users'); } - public function test_can_hide_relationships() + public function test_belongs_to_many_can_hide_relationships_from_show() { $company = tap(factory(Company::class)->create(), function (Company $company) { $company->users()->attach( @@ -48,20 +40,68 @@ public function test_can_hide_relationships() ); }); - $_SERVER['hide_users_from_show'] = true; + CompanyRepository::partialMock() + ->expects('related') + ->andReturn([ + 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->hideFromShow(), + ]); - $this->get(CompanyWithUsersRepository::uriKey()."/{$company->id}") + $this->get(CompanyRepository::uriKey() . "/{$company->id}?related=users") ->assertJsonStructure([ 'data' => [], ])->assertJsonMissing([ - [ - 'relationships' => [ - 'users' => [], - ], ], + 'users' + ]); + } + + public function test_belongs_to_many_can_hide_relationships_from_index() + { + tap(factory(Company::class)->create(), function (Company $company) { + $company->users()->attach( + factory(User::class)->create() + ); + }); + + CompanyRepository::partialMock() + ->expects('related') + ->andReturn([ + 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->hideFromIndex() ]); + + $this->get(CompanyRepository::uriKey() . "?related=users")->assertJsonMissing([ + 'users' + ]); + + CompanyRepository::partialMock() + ->expects('related') + ->andReturn([ + 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->hideFromShow() + ]); + + $this->get(CompanyRepository::uriKey() . "?related=users")->assertJsonFragment([ + 'users' + ]); } - public function test_ignored_when_storing() + public function test_belongs_to_many_generates_nested_uri() + { + $company = tap(factory(Company::class)->create(), function (Company $company) { + $company->users()->attach( + factory(User::class)->create() + ); + }); + + $response = $this->get(CompanyRepository::uriKey() . "/{$company->id}/users") + ->dump() + ->assertOk(); + + $this->assertSame( + 'users', + $response->json('data.0.type') + ); + } + + public function test_belongs_to_many_ignored_when_storing() { /** * @var User $user */ $user = factory(User::class)->create(); @@ -70,41 +110,14 @@ public function test_ignored_when_storing() $user->companies()->attach($companies); - $this->postJson(CompanyWithUsersRepository::uriKey(), [ + $this->postJson(CompanyRepository::uriKey(), [ 'name' => 'Binar Code', 'users' => [1, 2], ])->assertJsonMissing([ [ 'relationships' => [ 'users' => [], - ], ], + ],], ]); } } - -class CompanyWithUsersRepository extends Repository -{ - public static $model = Company::class; - - public static function getRelated() - { - return [ - 'users' => BelongsToMany::make('users', 'users', UserRepository::class) - ->hideFromShow(function () { - return $_SERVER['hide_users_from_show'] ?? false; - }), - ]; - } - - public function fields(RestifyRequest $request) - { - return [ - field('name'), - ]; - } - - public static function uriKey() - { - return 'companies-with-users-repository'; - } -} diff --git a/tests/Fixtures/Company/CompanyRepository.php b/tests/Fixtures/Company/CompanyRepository.php index a172d6596..988351147 100644 --- a/tests/Fixtures/Company/CompanyRepository.php +++ b/tests/Fixtures/Company/CompanyRepository.php @@ -17,7 +17,7 @@ public static function related(): array return [ 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->withPivot( Field::make('is_admin')->rules('required') - ), + )->canDetach(fn($request, $pivot) => isset($_SERVER['roles.canDetach.users']) && $_SERVER['roles.canDetach.users']), ]; } @@ -25,10 +25,10 @@ public function fields(RestifyRequest $request) { return [ field('name'), - - BelongsToMany::make('users', 'users', UserRepository::class)->withPivot( - Field::make('is_admin')->rules('required') - )->canDetach(fn($request, $pivot) => $_SERVER['roles.canDetach.users']), +// +// BelongsToMany::make('users', 'users', UserRepository::class)->withPivot( +// Field::make('is_admin')->rules('required') +// )->canDetach(fn($request, $pivot) => $_SERVER['roles.canDetach.users']), ]; } } diff --git a/tests/Fixtures/User/User.php b/tests/Fixtures/User/User.php index 6e5a97c6c..a4b793c7b 100644 --- a/tests/Fixtures/User/User.php +++ b/tests/Fixtures/User/User.php @@ -9,6 +9,7 @@ use Binaryk\LaravelRestify\Tests\Fixtures\Role\Role; use Binaryk\LaravelRestify\Traits\InteractWithSearch; use Illuminate\Contracts\Auth\MustVerifyEmail; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Query\Builder; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index dce19f7c1..8705baa5c 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -23,6 +23,7 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Route; +use Illuminate\Testing\Assert as PHPUnit; use Mockery; use Orchestra\Testbench\TestCase; From 81c1cac29c16ebfa917b73eaaa491a7ac555801e Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Wed, 23 Dec 2020 18:25:13 +0200 Subject: [PATCH 4/6] Apply fixes from StyleCI (#330) --- src/Eager/RelatedCollection.php | 14 +++++----- src/Fields/Concerns/Attachable.php | 1 - src/Fields/Field.php | 2 +- .../RepositoryAttachController.php | 4 +-- .../Concerns/InteractsWithAttachers.php | 4 +-- src/Repositories/ValidatingTrait.php | 11 ++++---- .../RepositoryAttachControllerTest.php | 28 +++++++++---------- .../RepositoryDetachControllerTest.php | 20 ++++++------- tests/Fields/BelongsToManyFieldTest.php | 25 ++++++++--------- tests/Fixtures/Company/CompanyRepository.php | 10 +++---- tests/Fixtures/User/User.php | 1 - tests/IntegrationTest.php | 1 - 12 files changed, 57 insertions(+), 64 deletions(-) diff --git a/src/Eager/RelatedCollection.php b/src/Eager/RelatedCollection.php index aa7f9219d..e5727186c 100644 --- a/src/Eager/RelatedCollection.php +++ b/src/Eager/RelatedCollection.php @@ -25,8 +25,8 @@ public function intoAssoc(): self public function forEager(RestifyRequest $request): self { - return $this->filter(fn($value, $key) => $value instanceof EagerField) - ->filter(fn(Field $field) => $field->authorize($request)) + return $this->filter(fn ($value, $key) => $value instanceof EagerField) + ->filter(fn (Field $field) => $field->authorize($request)) ->unique('attribute'); } @@ -39,10 +39,10 @@ public function forManyToManyRelations(RestifyRequest $request): self public function mapIntoSortable(RestifyRequest $request): self { - return $this->filter(fn(EagerField $field) => $field->isSortable()) + return $this->filter(fn (EagerField $field) => $field->isSortable()) //Now we support only belongs to sort from related. - ->filter(fn(EagerField $field) => $field instanceof BelongsTo) - ->map(fn(BelongsTo $field) => SortableFilter::make()->usingBelongsTo($field)); + ->filter(fn (EagerField $field) => $field instanceof BelongsTo) + ->map(fn (BelongsTo $field) => SortableFilter::make()->usingBelongsTo($field)); } public function forShow(RestifyRequest $request, Repository $repository): self @@ -70,7 +70,7 @@ public function forIndex(RestifyRequest $request, Repository $repository): self public function inRequest(RestifyRequest $request): self { return $this - ->filter(fn($field, $key) => in_array($key, str_getcsv($request->input('related')))) + ->filter(fn ($field, $key) => in_array($key, str_getcsv($request->input('related')))) ->unique(); } @@ -84,6 +84,6 @@ public function mapIntoRelated(RestifyRequest $request) public function authorized(RestifyRequest $request) { return $this->intoAssoc() - ->filter(fn($key, $value) => $key instanceof EagerField ? $key->authorize($request) : true); + ->filter(fn ($key, $value) => $key instanceof EagerField ? $key->authorize($request) : true); } } diff --git a/src/Fields/Concerns/Attachable.php b/src/Fields/Concerns/Attachable.php index a4a9694f8..52c6d7398 100644 --- a/src/Fields/Concerns/Attachable.php +++ b/src/Fields/Concerns/Attachable.php @@ -9,7 +9,6 @@ use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Database\Eloquent\Relations\Pivot; use Illuminate\Support\Arr; -use Illuminate\Support\Collection; trait Attachable { diff --git a/src/Fields/Field.php b/src/Fields/Field.php index f2be0bb43..0db7ac771 100644 --- a/src/Fields/Field.php +++ b/src/Fields/Field.php @@ -386,7 +386,7 @@ public function serializeMessages(): array $messages = []; foreach ($this->messages as $ruleFor => $message) { - $messages[$this->getAttribute() . '.' . $ruleFor] = $message; + $messages[$this->getAttribute().'.'.$ruleFor] = $message; } return $messages; diff --git a/src/Http/Controllers/RepositoryAttachController.php b/src/Http/Controllers/RepositoryAttachController.php index 35c29a6b5..a6fd612e3 100644 --- a/src/Http/Controllers/RepositoryAttachController.php +++ b/src/Http/Controllers/RepositoryAttachController.php @@ -24,8 +24,8 @@ public function __invoke(RepositoryAttachRequest $request) return $repository->attach( $request, $request->repositoryId, collect(Arr::wrap($request->input($request->relatedRepository))) - ->filter(fn($relatedRepositoryId) => $request->repository()->allowToAttach($request, $request->attachRelatedModels())) - ->map(fn($relatedRepositoryId) => $this->belongsToManyField($request) + ->filter(fn ($relatedRepositoryId) => $request->repository()->allowToAttach($request, $request->attachRelatedModels())) + ->map(fn ($relatedRepositoryId) => $this->belongsToManyField($request) ->initializePivot( $request, $model->{$request->viaRelationship ?? $request->relatedRepository}(), $relatedRepositoryId )) diff --git a/src/Repositories/Concerns/InteractsWithAttachers.php b/src/Repositories/Concerns/InteractsWithAttachers.php index 1af9951b4..1a8863059 100644 --- a/src/Repositories/Concerns/InteractsWithAttachers.php +++ b/src/Repositories/Concerns/InteractsWithAttachers.php @@ -43,7 +43,7 @@ public function guessAttachMethod(RestifyRequest $request): ?callable return $cb; } - $methodGuesser = 'attach' . Str::studly($request->relatedRepository); + $methodGuesser = 'attach'.Str::studly($request->relatedRepository); if (method_exists($repository, $methodGuesser)) { return [$repository, $methodGuesser]; @@ -66,7 +66,7 @@ public function guessDetachMethod(RestifyRequest $request): ?callable return $cb; } - $methodGuesser = 'detach' . Str::studly($request->relatedRepository); + $methodGuesser = 'detach'.Str::studly($request->relatedRepository); if (method_exists($repository, $methodGuesser)) { return [$repository, $methodGuesser]; diff --git a/src/Repositories/ValidatingTrait.php b/src/Repositories/ValidatingTrait.php index 2725273cf..45e26bb50 100644 --- a/src/Repositories/ValidatingTrait.php +++ b/src/Repositories/ValidatingTrait.php @@ -34,7 +34,7 @@ public static function validatorForStoring(RestifyRequest $request, array $plain $messages = $on->collectFields($request)->flatMap(function ($k) { $messages = []; foreach ($k->messages as $ruleFor => $message) { - $messages[$k->attribute . '.' . $ruleFor] = $message; + $messages[$k->attribute.'.'.$ruleFor] = $message; } return $messages; @@ -54,7 +54,7 @@ public static function validatorForStoringBulk(RestifyRequest $request, array $p $messages = $on->collectFields($request)->flatMap(function ($k) { $messages = []; foreach ($k->messages as $ruleFor => $message) { - $messages['*' . $k->attribute . '.' . $ruleFor] = $message; + $messages['*'.$k->attribute.'.'.$ruleFor] = $message; } return $messages; @@ -84,7 +84,7 @@ public static function validatorForUpdate(RestifyRequest $request, $resource = n $messages = $on->collectFields($request)->flatMap(function ($k) { $messages = []; foreach ($k->messages as $ruleFor => $message) { - $messages[$k->attribute . '.' . $ruleFor] = $message; + $messages[$k->attribute.'.'.$ruleFor] = $message; } return $messages; @@ -101,7 +101,6 @@ public static function validatorForAttach(RestifyRequest $request, $resource = n /** * @var Repository $on */ $on = $resource ?? static::resolveWith(static::newModel()); - /** * @var BelongsToMany $field */ $field = $on::collectRelated() ->forManyToManyRelations($request) @@ -109,7 +108,7 @@ public static function validatorForAttach(RestifyRequest $request, $resource = n $pivotFields = $field->collectPivotFields(); - $messages = $pivotFields->flatMap(fn(Field $field) => $field->serializeMessages())->all(); + $messages = $pivotFields->flatMap(fn (Field $field) => $field->serializeMessages())->all(); $rules = $pivotFields->mapWithKeys(function (Field $k) { return [ @@ -131,7 +130,7 @@ public static function validatorForUpdateBulk(RestifyRequest $request, $resource $messages = $on->collectFields($request)->flatMap(function ($k) { $messages = []; foreach ($k->messages as $ruleFor => $message) { - $messages['*' . $k->attribute . '.' . $ruleFor] = $message; + $messages['*'.$k->attribute.'.'.$ruleFor] = $message; } return $messages; diff --git a/tests/Controllers/RepositoryAttachControllerTest.php b/tests/Controllers/RepositoryAttachControllerTest.php index 89f9c727f..c496b2f53 100644 --- a/tests/Controllers/RepositoryAttachControllerTest.php +++ b/tests/Controllers/RepositoryAttachControllerTest.php @@ -21,7 +21,7 @@ public function test_can_attach_repositories() $user = $this->mockUsers()->first(); $company = factory(Company::class)->create(); - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, 'is_admin' => true, ])->assertCreated()->assertJsonFragment([ @@ -46,14 +46,14 @@ public function test_cant_attach_repositories_not_authorized_to_attach() $_SERVER['allow_attach_users'] = false; - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, 'is_admin' => true, ])->assertForbidden(); $_SERVER['allow_attach_users'] = true; - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, 'is_admin' => true, ])->assertCreated(); @@ -73,15 +73,15 @@ public function test_attach_pivot_field_validation() Field::make('is_admin')->rules('required')->messages([ 'required' => $message = 'You should fill the is_admin information.', ]) - ) + ), ]); - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, ])->assertStatus(400)->assertJsonFragment([ 'is_admin' => [ - $message - ]]); + $message, + ], ]); } public function test_pivot_field_present_when_show() @@ -93,7 +93,7 @@ public function test_pivot_field_present_when_show() $company->users()->attach($this->mockUsers()->first()->id); }); - $response = $this->getJson('companies/' . $company->id . '?related=users') + $response = $this->getJson('companies/'.$company->id.'?related=users') ->assertOk(); $this->assertSame( @@ -136,7 +136,7 @@ public function test_attach_multiple_users_to_a_company() $this->assertCount(0, $company->users); - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => [1, 2], 'is_admin' => true, ])->assertCreated()->assertJsonFragment([ @@ -162,10 +162,10 @@ public function test_many_to_many_field_can_intercept_attach_authorization() $this->assertInstanceOf(Pivot::class, $pivot); return false; - }) + }), ]); - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, 'is_admin' => true, ])->assertForbidden(); @@ -192,10 +192,10 @@ public function test_many_to_many_field_can_intercept_attach_method() $this->assertInstanceOf(Company::class, $model); $model->users()->attach($request->input('users')); - }) + }), ]); - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, 'is_admin' => true, ])->assertOk(); @@ -223,7 +223,7 @@ public function test_repository_can_intercept_attach() }, ]; - $this->postJson('companies/' . $company->id . '/attach/users', [ + $this->postJson('companies/'.$company->id.'/attach/users', [ 'users' => $user->id, ])->assertOk(); diff --git a/tests/Controllers/RepositoryDetachControllerTest.php b/tests/Controllers/RepositoryDetachControllerTest.php index ead589956..5cfed3241 100644 --- a/tests/Controllers/RepositoryDetachControllerTest.php +++ b/tests/Controllers/RepositoryDetachControllerTest.php @@ -28,8 +28,8 @@ public function test_can_detach_repositories() $this->assertCount(2, $company->users); - $this->postJson('companies/' . $company->id . '/detach/users', [ - 'users' => [1, 2] + $this->postJson('companies/'.$company->id.'/detach/users', [ + 'users' => [1, 2], ])->assertNoContent(); $this->assertCount(0, $company->fresh()->users); @@ -52,8 +52,8 @@ public function test_cant_detach_repositories_not_authorized_to_detach() $_SERVER['allow_detach_users'] = false; - $this->postJson('companies/' . $company->id . '/detach/users', [ - 'users' => [1, 2] + $this->postJson('companies/'.$company->id.'/detach/users', [ + 'users' => [1, 2], ])->assertForbidden(); } @@ -74,8 +74,8 @@ public function test_many_to_many_field_can_intercept_detach_authorization() $company->users()->attach($this->mockUsers()->first()->id); }); - $this->postJson('companies/' . $company->id . '/detach/users', [ - 'users' => [1] + $this->postJson('companies/'.$company->id.'/detach/users', [ + 'users' => [1], ])->assertForbidden(); } @@ -99,8 +99,8 @@ public function test_many_to_many_field_can_intercept_detach_method() $company->users()->attach($this->mockUsers()->first()->id); }); - $this->postJson('companies/' . $company->id . '/detach/users', [ - 'users' => [1] + $this->postJson('companies/'.$company->id.'/detach/users', [ + 'users' => [1], ])->assertNoContent(); $this->assertCount(0, $company->fresh()->users); @@ -130,8 +130,8 @@ public function test_repository_can_intercept_detach() $company->users()->attach($this->mockUsers()->first()->id); }); - $this->postJson('companies/' . $company->id . '/detach/users', [ - 'users' => [1] + $this->postJson('companies/'.$company->id.'/detach/users', [ + 'users' => [1], ])->assertNoContent(); $this->assertCount(0, $company->fresh()->users); diff --git a/tests/Fields/BelongsToManyFieldTest.php b/tests/Fields/BelongsToManyFieldTest.php index 8637db251..6468d1a67 100644 --- a/tests/Fields/BelongsToManyFieldTest.php +++ b/tests/Fields/BelongsToManyFieldTest.php @@ -3,9 +3,6 @@ namespace Binaryk\LaravelRestify\Tests\Fields; use Binaryk\LaravelRestify\Fields\BelongsToMany; -use Binaryk\LaravelRestify\Http\Requests\RestifyRequest; -use Binaryk\LaravelRestify\Repositories\Repository; -use Binaryk\LaravelRestify\Restify; use Binaryk\LaravelRestify\Tests\Fixtures\Company\Company; use Binaryk\LaravelRestify\Tests\Fixtures\Company\CompanyRepository; use Binaryk\LaravelRestify\Tests\Fixtures\User\User; @@ -22,7 +19,7 @@ public function test_belongs_to_many_displays_on_relationships_show() ); }); - $this->get(CompanyRepository::uriKey() . "/{$company->id}?related=users") + $this->get(CompanyRepository::uriKey()."/{$company->id}?related=users") ->assertJsonStructure([ 'data' => [ 'relationships' => [ @@ -46,11 +43,11 @@ public function test_belongs_to_many_can_hide_relationships_from_show() 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->hideFromShow(), ]); - $this->get(CompanyRepository::uriKey() . "/{$company->id}?related=users") + $this->get(CompanyRepository::uriKey()."/{$company->id}?related=users") ->assertJsonStructure([ 'data' => [], ])->assertJsonMissing([ - 'users' + 'users', ]); } @@ -65,21 +62,21 @@ public function test_belongs_to_many_can_hide_relationships_from_index() CompanyRepository::partialMock() ->expects('related') ->andReturn([ - 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->hideFromIndex() + 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->hideFromIndex(), ]); - $this->get(CompanyRepository::uriKey() . "?related=users")->assertJsonMissing([ - 'users' + $this->get(CompanyRepository::uriKey().'?related=users')->assertJsonMissing([ + 'users', ]); CompanyRepository::partialMock() ->expects('related') ->andReturn([ - 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->hideFromShow() + 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->hideFromShow(), ]); - $this->get(CompanyRepository::uriKey() . "?related=users")->assertJsonFragment([ - 'users' + $this->get(CompanyRepository::uriKey().'?related=users')->assertJsonFragment([ + 'users', ]); } @@ -91,7 +88,7 @@ public function test_belongs_to_many_generates_nested_uri() ); }); - $response = $this->get(CompanyRepository::uriKey() . "/{$company->id}/users") + $response = $this->get(CompanyRepository::uriKey()."/{$company->id}/users") ->dump() ->assertOk(); @@ -117,7 +114,7 @@ public function test_belongs_to_many_ignored_when_storing() [ 'relationships' => [ 'users' => [], - ],], + ], ], ]); } } diff --git a/tests/Fixtures/Company/CompanyRepository.php b/tests/Fixtures/Company/CompanyRepository.php index 988351147..4d1802d0e 100644 --- a/tests/Fixtures/Company/CompanyRepository.php +++ b/tests/Fixtures/Company/CompanyRepository.php @@ -17,7 +17,7 @@ public static function related(): array return [ 'users' => BelongsToMany::make('users', 'users', UserRepository::class)->withPivot( Field::make('is_admin')->rules('required') - )->canDetach(fn($request, $pivot) => isset($_SERVER['roles.canDetach.users']) && $_SERVER['roles.canDetach.users']), + )->canDetach(fn ($request, $pivot) => isset($_SERVER['roles.canDetach.users']) && $_SERVER['roles.canDetach.users']), ]; } @@ -25,10 +25,10 @@ public function fields(RestifyRequest $request) { return [ field('name'), -// -// BelongsToMany::make('users', 'users', UserRepository::class)->withPivot( -// Field::make('is_admin')->rules('required') -// )->canDetach(fn($request, $pivot) => $_SERVER['roles.canDetach.users']), + // + // BelongsToMany::make('users', 'users', UserRepository::class)->withPivot( + // Field::make('is_admin')->rules('required') + // )->canDetach(fn($request, $pivot) => $_SERVER['roles.canDetach.users']), ]; } } diff --git a/tests/Fixtures/User/User.php b/tests/Fixtures/User/User.php index a4b793c7b..6e5a97c6c 100644 --- a/tests/Fixtures/User/User.php +++ b/tests/Fixtures/User/User.php @@ -9,7 +9,6 @@ use Binaryk\LaravelRestify\Tests\Fixtures\Role\Role; use Binaryk\LaravelRestify\Traits\InteractWithSearch; use Illuminate\Contracts\Auth\MustVerifyEmail; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Query\Builder; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 8705baa5c..dce19f7c1 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -23,7 +23,6 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Route; -use Illuminate\Testing\Assert as PHPUnit; use Mockery; use Orchestra\Testbench\TestCase; From de4c1419212050eaa63a66afd0c0f51cc9bfe5f0 Mon Sep 17 00:00:00 2001 From: Eduard Lupacescu Date: Wed, 23 Dec 2020 18:28:43 +0200 Subject: [PATCH 5/6] wip --- src/Fields/Field.php | 4 ---- tests/Fixtures/Company/CompanyRepository.php | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/Fields/Field.php b/src/Fields/Field.php index f2be0bb43..2df1b1a71 100644 --- a/src/Fields/Field.php +++ b/src/Fields/Field.php @@ -457,10 +457,6 @@ public function isSortable() */ public function resolveForShow($repository, $attribute = null) { - if ($this->attribute === 'is_admin') { - dd('foo'); - } - $attribute = $attribute ?? $this->attribute; if ($attribute === 'Computed') { diff --git a/tests/Fixtures/Company/CompanyRepository.php b/tests/Fixtures/Company/CompanyRepository.php index 988351147..01364d380 100644 --- a/tests/Fixtures/Company/CompanyRepository.php +++ b/tests/Fixtures/Company/CompanyRepository.php @@ -25,10 +25,6 @@ public function fields(RestifyRequest $request) { return [ field('name'), -// -// BelongsToMany::make('users', 'users', UserRepository::class)->withPivot( -// Field::make('is_admin')->rules('required') -// )->canDetach(fn($request, $pivot) => $_SERVER['roles.canDetach.users']), ]; } } From 4e554374da715691ebed14cf8ec228be3361d32c Mon Sep 17 00:00:00 2001 From: Eduard Lupacescu Date: Wed, 23 Dec 2020 18:29:59 +0200 Subject: [PATCH 6/6] wip --- tests/Fields/BelongsToManyFieldTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Fields/BelongsToManyFieldTest.php b/tests/Fields/BelongsToManyFieldTest.php index 6468d1a67..1b84bb433 100644 --- a/tests/Fields/BelongsToManyFieldTest.php +++ b/tests/Fields/BelongsToManyFieldTest.php @@ -89,7 +89,6 @@ public function test_belongs_to_many_generates_nested_uri() }); $response = $this->get(CompanyRepository::uriKey()."/{$company->id}/users") - ->dump() ->assertOk(); $this->assertSame(