├── .gitignore ├── composer.json ├── examples ├── NovaCreateTest.php ├── NovaDetailTest.php ├── NovaEditTest.php ├── NovaIndexTest.php ├── NovaLensTest.php └── NovaPolicyTest.php ├── license.md ├── readme.md └── src ├── Assert ├── AssertActions.php ├── AssertCards.php ├── AssertFields.php ├── AssertFilters.php ├── AssertLenses.php ├── AssertPolicies.php ├── AssertRelations.php └── AssertResources.php ├── NovaAssertions.php └── NovaResponse.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dillingham/nova-assertions", 3 | "description": "Nova api testing requests & assertions", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Brian Dillingham", 9 | "email": "bdillingham88@gmail.com" 10 | } 11 | ], 12 | "autoload": { 13 | "psr-4": { 14 | "NovaTesting\\": "src/" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/NovaCreateTest.php: -------------------------------------------------------------------------------- 1 | be(factory(User::class)->create()); 19 | 20 | $response = $this->novaCreate('users'); 21 | $response->assertFieldsInclude('email'); 22 | $response->assertFieldsInclude(['email', 'name', 'password']); 23 | 24 | 25 | $response->assertFieldsExclude('id'); 26 | $response->assertFieldsExclude(['created_at', 'updated_at']); 27 | 28 | $response->assertFields(function ($fields) { 29 | return $fields->count() == 4; 30 | }); 31 | 32 | $response->assertFields(function ($fields) { 33 | return $fields->firstWhere('attribute', 'group'); 34 | }); 35 | } 36 | 37 | public function testRelations() 38 | { 39 | $this->be(factory(User::class)->create()); 40 | 41 | $group = factory(Group::class)->create(); 42 | 43 | $users = factory(User::class, 3)->create([ 44 | 'group_id' => $group->id 45 | ]); 46 | 47 | $this->novaDetail('groups', $group->id) 48 | ->assertRelation('users', function ($users) { 49 | return $users->count() == 3; 50 | }); 51 | 52 | $this->novaCreate('users') 53 | ->assertRelation('group', function ($groups) { 54 | return $groups->count() == 1; 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /examples/NovaDetailTest.php: -------------------------------------------------------------------------------- 1 | create(); 20 | $authed = $users->first(); 21 | $this->be($authed); 22 | 23 | $response = $this->novaDetail('users', $authed->id); 24 | 25 | $response->assertActionCount(1); 26 | $response->assertActionsInclude(ApproveUser::class); 27 | $response->assertActionsExclude(ProcessOrder::class); 28 | $response->assertActions(function ($actions) { 29 | return $actions->count() == 1; 30 | }); 31 | } 32 | 33 | public function testFields() 34 | { 35 | $users = factory(User::class, 10)->create(); 36 | $authed = $users->first(); 37 | 38 | $this->be($authed); 39 | 40 | $response = $this->novaDetail('users', $authed->id); 41 | 42 | $response->assertFieldsInclude('id'); 43 | $response->assertFieldsInclude(['id', 'email', 'name']); 44 | $response->assertFieldsInclude(['id' => $authed->id, 'email' => $authed->email]); 45 | 46 | $response->assertFieldsExclude('created_at'); 47 | $response->assertFieldsExclude(['created_at', 'updated_at']); 48 | $response->assertFieldsExclude(['created_at' => $authed->created_at, 'updated_at' => $authed->updated_at]); 49 | 50 | $response->assertFields(function ($fields) { 51 | return $fields->count() == 6; 52 | }); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /examples/NovaEditTest.php: -------------------------------------------------------------------------------- 1 | create(); 18 | 19 | $this->be($user); 20 | 21 | $response = $this->novaEdit('users', $user->id); 22 | $response->assertFieldsInclude('email'); 23 | $response->assertFieldsInclude(['email', 'name', 'password']); 24 | $response->assertFieldsInclude(['email' => $user->email, 'name' => $user->name]); 25 | 26 | $response->assertFieldsExclude('id'); 27 | $response->assertFieldsExclude(['created_at', 'updated_at']); 28 | 29 | $response->assertFields(function ($fields) { 30 | return $fields->count() == 4; 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/NovaIndexTest.php: -------------------------------------------------------------------------------- 1 | create(); 29 | $authed = $users->first(); 30 | $this->be($authed); 31 | 32 | $response = $this->novaIndex('users'); 33 | 34 | $response->assertCardCount(1); 35 | $response->assertCardsInclude(UsersPerDay::class); 36 | $response->assertCardsExclude(OrdersPerDay::class); 37 | $response->assertCards(function ($cards) { 38 | return $cards->count() == 1; 39 | }); 40 | } 41 | 42 | public function testActions() 43 | { 44 | $users = factory(User::class, 10)->create(); 45 | $authed = $users->first(); 46 | $this->be($authed); 47 | 48 | $response = $this->novaIndex('users'); 49 | 50 | $response->assertActionCount(1); 51 | $response->assertActionsInclude(ApproveUser::class); 52 | $response->assertActionsExclude(ProcessOrder::class); 53 | $response->assertActions(function ($actions) { 54 | return $actions->count() == 1; 55 | }); 56 | } 57 | 58 | public function testFilters() 59 | { 60 | $users = factory(User::class, 10)->create(); 61 | $authed = $users->first(); 62 | $this->be($authed); 63 | 64 | $response = $this->novaIndex('users'); 65 | 66 | $response->assertFilterCount(2); 67 | $response->assertFiltersInclude(UserStatus::class); 68 | $response->assertFiltersExclude(OrderStatus::class); 69 | $response->assertFilters(function ($filters) { 70 | return $filters->count() == 2; 71 | }); 72 | } 73 | 74 | public function testFilteredIndex() 75 | { 76 | $users = factory(User::class, 10)->create(); 77 | $authed = $users->first(); 78 | 79 | $this->be($authed); 80 | 81 | $response = $this->novaIndex('users', [ 82 | UserFilter::class => $authed->id 83 | ]); 84 | 85 | $response->assertResourceCount(1); 86 | $response->assertFieldsInclude(['id' => $authed->id]); 87 | } 88 | 89 | public function testLenses() 90 | { 91 | $users = factory(User::class, 10)->create(); 92 | $authed = $users->first(); 93 | $this->be($authed); 94 | 95 | $response = $this->novaIndex('users'); 96 | 97 | $response->assertLensCount(1); 98 | $response->assertLensesInclude(UserLens::class); 99 | $response->assertLensesExclude(OrderLens::class); 100 | $response->assertLenses(function ($lenses) { 101 | return $lenses->count() == 1; 102 | }); 103 | } 104 | 105 | public function testResources() 106 | { 107 | $users = factory(User::class, 10)->create(); 108 | $authed = $users->first(); 109 | $this->be($authed); 110 | 111 | $response = $this->novaIndex('users'); 112 | 113 | $response->assertResourceCount(10); 114 | $response->assertResources(function ($resources) { 115 | return $resources->count() == 10; 116 | }); 117 | } 118 | 119 | public function testFields() 120 | { 121 | $users = factory(User::class, 10)->create(); 122 | $authed = $users->first(); 123 | 124 | $this->be($authed); 125 | 126 | $response = $this->novaIndex('users'); 127 | 128 | $response->assertFieldsInclude('id'); 129 | $response->assertFieldsInclude(['id', 'email', 'name']); 130 | $response->assertFieldsInclude(['id' => $authed->id, 'email' => $authed->email]); 131 | $response->assertFieldsInclude('id', $users->pluck('id')); 132 | 133 | $response->assertFieldsExclude('created_at'); 134 | $response->assertFieldsExclude(['created_at', 'updated_at']); 135 | $response->assertFieldsExclude(['created_at' => $authed->created_at, 'updated_at' => $authed->updated_at]); 136 | $response->assertFieldsExclude('created_at', $users->pluck('created_at')); 137 | 138 | $response->assertFields(function ($fields) { 139 | // collection of field arrays 140 | return $fields->count() == 10 && count($fields->first()) == 6; 141 | }); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /examples/NovaLensTest.php: -------------------------------------------------------------------------------- 1 | be(factory(User::class)->create()); 25 | 26 | $response = $this->novaLens('users', UserLens::class); 27 | 28 | $response->assertCardCount(1); 29 | $response->assertCardsInclude(UsersPerDay::class); 30 | $response->assertCardsExclude(OrdersPerDay::class); 31 | $response->assertCards(function ($cards) { 32 | return $cards->count() == 1; 33 | }); 34 | } 35 | 36 | public function testActions() 37 | { 38 | $this->be(factory(User::class)->create()); 39 | 40 | $response = $this->novaLens('users', UserLens::class); 41 | 42 | $response->assertActionCount(1); 43 | $response->assertActionsInclude(ApproveUser::class); 44 | $response->assertActionsExclude(ProcessOrder::class); 45 | $response->assertActions(function ($actions) { 46 | return $actions->count() == 1; 47 | }); 48 | } 49 | 50 | public function testFilteredLens() 51 | { 52 | $users = factory(User::class, 10)->create(); 53 | $authed = $users->first(); 54 | 55 | $this->be($authed); 56 | 57 | $response = $this->novaLens('users', UserLens::class, [ 58 | UserFilter::class => $authed->id 59 | ]); 60 | 61 | $response->assertResourceCount(1); 62 | $response->assertFieldsInclude(['id' => $authed->id]); 63 | } 64 | 65 | public function testFields() 66 | { 67 | $users = factory(User::class, 10)->create(); 68 | $authed = $users->first(); 69 | 70 | $this->be($authed); 71 | 72 | $response = $this->novaLens('users', UserLens::class); 73 | 74 | $response->assertFieldsInclude('id'); 75 | $response->assertFieldsInclude(['id', 'email', 'name']); 76 | $response->assertFieldsInclude(['id' => $authed->id, 'email' => $authed->email]); 77 | $response->assertFieldsExclude('created_at'); 78 | $response->assertFieldsExclude(['created_at', 'updated_at']); 79 | $response->assertFieldsExclude(['created_at' => $authed->created_at, 'updated_at' => $authed->updated_at]); 80 | $response->assertFields(function ($fields) { 81 | // collection of field arrays 82 | return $fields->count() == 10 && count($fields->first()) == 3; 83 | }); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /examples/NovaPolicyTest.php: -------------------------------------------------------------------------------- 1 | be(factory(User::class)->create()); 20 | 21 | $response = $this->novaIndex('users'); 22 | 23 | $response->assertOk(); 24 | $response->assertCanView(); 25 | $response->assertCanCreate(); 26 | $response->assertCanUpdate(); 27 | $response->assertCanDelete(); 28 | $response->assertCanForceDelete(); 29 | $response->assertCanRestore(); 30 | } 31 | 32 | public function testPolicyCannotViewAny() 33 | { 34 | Config::set('testing.viewAny', false); 35 | $this->be(factory(User::class)->create()); 36 | $response = $this->novaIndex('users'); 37 | $response->assertStatus(403); 38 | } 39 | 40 | public function testPolicyCannot() 41 | { 42 | $this->be(factory(User::class)->create()); 43 | 44 | Config::set('testing.create', false); 45 | Config::set('testing.update', false); 46 | Config::set('testing.delete', false); 47 | Config::set('testing.forceDelete', false); 48 | Config::set('testing.restore', false); 49 | 50 | $response = $this->novaIndex('users'); 51 | 52 | $response->assertCannotCreate(); 53 | $response->assertCannotUpdate(); 54 | $response->assertCannotDelete(); 55 | $response->assertCannotForceDelete(); 56 | $response->assertCannotRestore(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Brian Dillingham 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Nova Assertions 2 | 3 | [![Latest Version on Github](https://img.shields.io/github/release/dillingham/nova-assertions.svg?style=flat-square)](https://packagist.org/packages/dillingham/nova-assertions) 4 | [![Total Downloads](https://img.shields.io/packagist/dt/dillingham/nova-assertions.svg?style=flat-square)](https://packagist.org/packages/dillingham/nova-assertions) [![Twitter Follow](https://img.shields.io/twitter/follow/im_brian_d?color=%231da1f1&label=Twitter&logo=%231da1f1&logoColor=%231da1f1&style=flat-square)](https://twitter.com/im_brian_d) 5 | 6 | Nova requests & assertions for Laravel tests - [View examples](https://github.com/dillingham/nova-assertions/tree/master/examples) 7 | 8 | ![testing tdd laravel nova](https://user-images.githubusercontent.com/29180903/63385407-e3f7d680-c36e-11e9-96f8-6ebbe48bd62b.png) 9 | 10 | Assert: 11 | [Policies](https://github.com/dillingham/nova-assertions#assert-policies) | 12 | [Cards](https://github.com/dillingham/nova-assertions#assert-cards) | 13 | [Actions](https://github.com/dillingham/nova-assertions#assert-actions) | 14 | [Filters](https://github.com/dillingham/nova-assertions#assert-filters) | 15 | [Lenses](https://github.com/dillingham/nova-assertions#assert-lenses) | 16 | [Resources](https://github.com/dillingham/nova-assertions#assert-resources) | 17 | [Fields](https://github.com/dillingham/nova-assertions#assert-fields) | 18 | [Relations](https://github.com/dillingham/nova-assertions#assert-relations) 19 | 20 | --- 21 | 22 | ### Installation 23 | 24 | ``` 25 | composer require dillingham/nova-assertions --dev 26 | ``` 27 | Enable by adding the `NovaAssertions` to a test 28 | ```php 29 | use NovaTesting\NovaAssertions; 30 | 31 | class UserTest extends TestCase 32 | { 33 | use NovaAssertions; 34 | } 35 | ``` 36 | 37 | --- 38 | 39 | ### Authentication 40 | Log in a user that **[has access to Nova](https://nova.laravel.com/docs/2.0/installation.html#authorizing-nova)** 41 | ```php 42 | $this->be(factory(User::class)->create()); 43 | ``` 44 | 45 | ### Nova Requests 46 | 47 | Request using a resource's uriKey to perform assertions: 48 | 49 | ```php 50 | $response = $this->novaIndex('users'); 51 | 52 | $response = $this->novaDetail('users', $user->id); 53 | 54 | $response = $this->novaCreate('users'); 55 | 56 | $response = $this->novaEdit('users', $user->id); 57 | 58 | $response = $this->novaLens('users', Lens::class); 59 | ``` 60 | 61 | ### Request Filters 62 | You may also pass filters & their values to indexes & lenses 63 | ```php 64 | $response = $this->novaIndex('users', [ 65 | StatusFilter::class => 'active' 66 | ]); 67 | ``` 68 | ```php 69 | $response = $this->novaLens('users', Lens::class, [ 70 | StatusFilter::class => 'active' 71 | ]); 72 | ``` 73 | ### Assert Http 74 | You can call **[http response methods](https://laravel.com/docs/5.8/http-tests#available-assertions)** as usual: 75 | 76 | ```php 77 | $response->assertOk(); 78 | ``` 79 | ### Assert Resources 80 | ```php 81 | $response->assertResourceCount(3); 82 | ``` 83 | ```php 84 | $response->assertResources(function($resources) { 85 | return $resources->count() > 0; 86 | }); 87 | ``` 88 | 89 | ### Assert Cards 90 | ```php 91 | $response->assertCardCount(5); 92 | ``` 93 | ```php 94 | $response->assertCardsInclude(Card::class); 95 | ``` 96 | ```php 97 | $response->assertCardsExclude(Card::class); 98 | ``` 99 | ```php 100 | $response->assertCards(function($cards) { 101 | return $cards->count() > 0; 102 | }); 103 | ``` 104 | 105 | ### Assert Actions 106 | ```php 107 | $response->assertActionCount(5); 108 | ``` 109 | ```php 110 | $response->assertActionsInclude(Action::class); 111 | ``` 112 | ```php 113 | $response->assertActionsExclude(Action::class); 114 | ``` 115 | ```php 116 | $response->assertActions(function($actions) { 117 | return $actions->count() > 0; 118 | }); 119 | ``` 120 | ### Assert Filters 121 | ```php 122 | $response->assertFilterCount(5); 123 | ``` 124 | ```php 125 | $response->assertFiltersInclude(Filter::class); 126 | ``` 127 | ```php 128 | $response->assertFiltersExclude(Filter::class); 129 | ``` 130 | ```php 131 | $response->assertFilters(function($filters) { 132 | return $filters->count() > 0; 133 | }); 134 | ``` 135 | ### Assert Lenses 136 | ```php 137 | $response->assertLensCount(5); 138 | ``` 139 | ```php 140 | $response->assertLensesInclude(Lens::class); 141 | ``` 142 | ```php 143 | $response->assertLensesExclude(Lens::class); 144 | ``` 145 | ```php 146 | $response->assertLenses(function($lenses) { 147 | return $lenses->count() > 0; 148 | }); 149 | ``` 150 | ### Assert Fields 151 | ```php 152 | $response->assertFieldCount(5); 153 | ``` 154 | Assert a specific field exists 155 | ```php 156 | $response->assertFieldsInclude('id'); 157 | ``` 158 | Assert a specific field contains a value 159 | ```php 160 | $response->assertFieldsInclude('id', $user->id); 161 | ``` 162 | Assert multiple fields exist 163 | ```php 164 | $response->assertFieldsInclude(['id', 'email']); 165 | ``` 166 | Assert multiple fields with specific values exist 167 | ```php 168 | $response->assertFieldsInclude(['id' => 1, 'email' => 'example']); 169 | ``` 170 | Assert multiple values for one field exist 171 | ```php 172 | $response->assertFieldsInclude('id', $users->pluck('id')); 173 | ``` 174 | Make assertions against a collection of fields 175 | ```php 176 | $response->assertFields(function($fields) { 177 | return $fields->count() > 0; 178 | }); 179 | ``` 180 | Also `exclude` works in all of these scenarios 181 | ```php 182 | $response->assertFieldsExclude(['id' => 1, 'email' => 'example']); 183 | ``` 184 | ### Assert Relations 185 | ```php 186 | // App\Nova\Post 187 | // BelongsTo::make('Category'), 188 | ``` 189 | ```php 190 | $response = $this->novaCreate('posts'); 191 | 192 | $response->assertRelation('categories', function($categories) { 193 | // 194 | }); 195 | ``` 196 | ```php 197 | // App\Nova\Category 198 | // HasMany::make('Posts'), 199 | ``` 200 | ```php 201 | $response = $this->novaDetail('categories'); 202 | 203 | $response->assertRelation('posts', function($posts) { 204 | // 205 | }); 206 | ``` 207 | 208 | ### Assert Policies 209 | 210 | Assert **[Nova's use of policies](https://nova.laravel.com/docs/2.0/resources/authorization.html#authorization)** & the authed user: 211 | 212 | ```php 213 | $response->assertCanView(); 214 | 215 | $response->assertCanCreate(); 216 | 217 | $response->assertCanUpdate(); 218 | 219 | $response->assertCanDelete(); 220 | 221 | $response->assertCanForceDelete(); 222 | 223 | $response->assertCanRestore(); 224 | ``` 225 | Also can assert `cannot` for each: 226 | ```php 227 | $response->assertCannotView(); 228 | ``` 229 | 230 | 231 | --- 232 | 233 | # Author 234 | 235 | Hi 👋, Im Brian Dillingham, creator of this Nova package [and others](https://novapackages.com/collaborators/dillingham) 236 | 237 | Hope you find it useful. Feel free to reach out with feedback. 238 | 239 | Follow me on twitter: [@im_brian_d](https://twitter.com/im_brian_d) 240 | -------------------------------------------------------------------------------- /src/Assert/AssertActions.php: -------------------------------------------------------------------------------- 1 | setNovaActionResponse(); 17 | 18 | $this->novaActionResponse->assertJsonCount($amount, 'actions'); 19 | 20 | return $this; 21 | } 22 | 23 | public function assertActions(closure $callable) 24 | { 25 | $original = $this->novaActionResponse->original; 26 | 27 | $actions = collect(json_decode(json_encode(Arr::get($original, 'actions', []), true))); 28 | 29 | PHPUnit::assertTrue($callable($actions)); 30 | 31 | return $this; 32 | } 33 | 34 | public function assertActionsInclude($class) 35 | { 36 | $this->setNovaActionResponse(); 37 | 38 | $this->novaActionResponse->assertJsonFragment([ 39 | 'uriKey' => app($class)->uriKey() 40 | ]); 41 | 42 | return $this; 43 | } 44 | 45 | public function assertActionsExclude($class) 46 | { 47 | $this->setNovaActionResponse(); 48 | 49 | $this->novaActionResponse->assertJsonMissing([ 50 | 'uriKey' => app($class)->uriKey() 51 | ]); 52 | 53 | return $this; 54 | } 55 | 56 | public function setNovaActionResponse() 57 | { 58 | if ($this->novaActionResponse) { 59 | return; 60 | } 61 | 62 | extract($this->novaParameters); 63 | 64 | $endpoint = "$endpoint/actions"; 65 | 66 | if (isset($resourceId)) { 67 | $endpoint = "$endpoint?resourceId=$resourceId"; 68 | $endpoint = str_replace("/$resourceId", '', $endpoint); 69 | } 70 | 71 | abort_if(strpos($endpoint, 'creation-fields'), 500, 'No actions on forms'); 72 | abort_if(strpos($endpoint, 'update-fields'), 500, 'No actions on forms'); 73 | 74 | $this->novaActionResponse = new NovaResponse( 75 | $this->parent->getJson($endpoint), 76 | $this->novaParameters, 77 | $this->parent 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Assert/AssertCards.php: -------------------------------------------------------------------------------- 1 | setNovaCardResponse(); 16 | 17 | $this->novaCardResponse->assertJsonCount($amount); 18 | 19 | return $this; 20 | } 21 | 22 | public function assertCards(closure $callable) 23 | { 24 | $original = $this->novaCardResponse->original; 25 | 26 | $cards = collect(json_decode(json_encode($original, true))); 27 | 28 | PHPUnit::assertTrue($callable($cards)); 29 | 30 | return $this; 31 | } 32 | 33 | public function assertCardsInclude($class) 34 | { 35 | $this->setNovaCardResponse(); 36 | 37 | $this->novaCardResponse->assertJsonFragment([ 38 | 'component' => $this->extractComponentName($class) 39 | ]); 40 | 41 | return $this; 42 | } 43 | 44 | public function assertCardsExclude($class) 45 | { 46 | $this->setNovaCardResponse(); 47 | 48 | $this->novaCardResponse->assertJsonMissing([ 49 | 'component' => $this->extractComponentName($class) 50 | ]); 51 | 52 | return $this; 53 | } 54 | 55 | /** 56 | * @param string|\Laravel\Nova\Card $class 57 | * @return string 58 | */ 59 | protected function extractComponentName($class) 60 | { 61 | if (is_object($class)) { 62 | return $class->component(); 63 | } 64 | 65 | return class_exists($class) ? app($class)->component() : $class; 66 | } 67 | 68 | public function setNovaCardResponse() 69 | { 70 | if ($this->novaCardResponse) { 71 | return; 72 | } 73 | 74 | extract($this->novaParameters); 75 | 76 | $endpoint = "$endpoint/cards"; 77 | 78 | if (isset($resourceId)) { 79 | $endpoint = "$endpoint?resourceId=$resourceId"; 80 | } 81 | 82 | abort_if(strpos($endpoint, 'creation-fields'), 500, 'No cards on forms'); 83 | abort_if(strpos($endpoint, 'update-fields'), 500, 'No cards on forms'); 84 | 85 | $this->novaCardResponse = new NovaResponse( 86 | $this->parent->getJson($endpoint), 87 | $this->novaParameters, 88 | $this->parent 89 | ); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Assert/AssertFields.php: -------------------------------------------------------------------------------- 1 | original['resources']) ? 'resources.0.fields' : 'resource.fields'; 14 | 15 | $this->assertJsonCount($amount, $path); 16 | 17 | return $this; 18 | } 19 | 20 | public function assertFields(closure $callable) 21 | { 22 | if (isset($this->original['resources'][0]['fields'])) { 23 | $path = 'resources.*.fields'; 24 | } elseif (isset($this->original['resource']['fields'])) { 25 | $path = 'resource.fields'; 26 | } elseif (isset($this->original['fields'])) { 27 | $path = 'fields'; 28 | } 29 | 30 | $fields = collect(json_decode(json_encode(data_get($this->original, $path, []), true))); 31 | 32 | PHPUnit::assertTrue($callable($fields)); 33 | 34 | return $this; 35 | } 36 | 37 | public function assertFieldsInclude($attribute, $value=null) 38 | { 39 | return $this->fieldCheck($attribute, $value, 'assertJsonFragment'); 40 | } 41 | 42 | public function assertFieldsExclude($attribute, $value=null) 43 | { 44 | return $this->fieldCheck($attribute, $value, 'assertJsonMissing'); 45 | } 46 | 47 | protected function fieldCheck($attribute, $value, $method = null) 48 | { 49 | if ($attribute instanceof Collection) { 50 | $attribute = $attribute->toArray(); 51 | } 52 | 53 | if ($value instanceof Collection) { 54 | $value = $value->toArray(); 55 | } 56 | 57 | // ->assertFieldsInclude('id') 58 | if (!is_array($attribute) && is_null($value)) { 59 | return $this->assertFieldAttribute($attribute, $method); 60 | } 61 | 62 | // ->assertFieldsInclude('id', [1,2,3]) 63 | if (!is_array($attribute) && is_array($value)) { 64 | return $this->assertFieldManyValues($attribute, $value, $method); 65 | } 66 | 67 | // ->assertFieldsInclude('id', 1) 68 | if (!is_array($attribute) && !is_null($value)) { 69 | return $this->assertFieldValue($attribute, $value, $method); 70 | } 71 | 72 | // ->assertFieldsInclude(['id', 'email']) 73 | if (is_array($attribute) && is_numeric(array_keys($attribute)[0])) { 74 | return $this->assertFieldKeys($attribute, $method); 75 | } 76 | 77 | // ->assertFieldsInclude(['id' => 1]) 78 | if (is_array($attribute)) { 79 | return $this->assertFieldKeyValue($attribute, $method); 80 | } 81 | 82 | return $this; 83 | } 84 | 85 | public function assertFieldAttribute($attribute, $method) 86 | { 87 | return $this->$method([ 88 | 'attribute' => $attribute 89 | ]); 90 | } 91 | 92 | public function assertFieldValue($attribute, $value, $method) 93 | { 94 | return $this->$method([ 95 | 'attribute' => $attribute, 96 | 'value' => $value, 97 | ]); 98 | } 99 | 100 | public function assertFieldManyValues($attribute, array $value, $method) 101 | { 102 | foreach ($value as $v) { 103 | $this->assertFieldValue($attribute, $v, $method); 104 | } 105 | 106 | return $this; 107 | } 108 | 109 | public function assertFieldKeys(array $keys, $method) 110 | { 111 | foreach ($keys as $key) { 112 | $this->assertFieldAttribute($key, $method); 113 | } 114 | 115 | return $this; 116 | } 117 | 118 | public function assertFieldKeyValue($attribute, $method) 119 | { 120 | foreach ($attribute as $attr => $value) { 121 | $this->assertFieldValue($attr, $value, $method); 122 | } 123 | 124 | return $this; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/Assert/AssertFilters.php: -------------------------------------------------------------------------------- 1 | setNovaFilterResponse(); 16 | 17 | $this->novaFilterResponse->assertJsonCount($amount); 18 | 19 | return $this; 20 | } 21 | 22 | public function assertFilters(closure $callable) 23 | { 24 | $original = $this->novaFilterResponse->original; 25 | 26 | $filters = collect(json_decode(json_encode($original, true))); 27 | 28 | PHPUnit::assertTrue($callable($filters)); 29 | 30 | return $this; 31 | } 32 | 33 | public function assertFiltersInclude($class) 34 | { 35 | $this->setNovaFilterResponse(); 36 | 37 | $this->novaFilterResponse->assertJsonFragment([ 38 | 'class' => $class 39 | ]); 40 | 41 | return $this; 42 | } 43 | 44 | public function assertFiltersExclude($class) 45 | { 46 | $this->setNovaFilterResponse(); 47 | 48 | $this->novaFilterResponse->assertJsonMissing([ 49 | 'class' => $class 50 | ]); 51 | 52 | return $this; 53 | } 54 | 55 | public function setNovaFilterResponse() 56 | { 57 | if ($this->novaFilterResponse) { 58 | return; 59 | } 60 | 61 | extract($this->novaParameters); 62 | 63 | abort_if(strpos($endpoint, 'creation-fields'), 500, 'No filters on forms'); 64 | abort_if(strpos($endpoint, 'update-fields'), 500, 'No filters on forms'); 65 | 66 | $this->novaFilterResponse = new NovaResponse( 67 | $this->parent->getJson("$endpoint/filters"), 68 | $this->novaParameters, 69 | $this->parent 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Assert/AssertLenses.php: -------------------------------------------------------------------------------- 1 | setNovaLensResponse(); 16 | 17 | $this->novaLensResponse->assertJsonCount($amount); 18 | 19 | return $this; 20 | } 21 | 22 | public function assertLenses(closure $callable) 23 | { 24 | $this->setNovaLensResponse(); 25 | 26 | $original = $this->novaLensResponse->original; 27 | 28 | $lenses = collect(json_decode(json_encode($original, true))); 29 | 30 | PHPUnit::assertTrue($callable($lenses)); 31 | 32 | return $this; 33 | } 34 | 35 | public function assertLensesInclude($class) 36 | { 37 | $this->setNovaLensResponse(); 38 | 39 | $this->novaLensResponse->assertJsonFragment([ 40 | 'uriKey' => app($class)->uriKey() 41 | ]); 42 | 43 | return $this; 44 | } 45 | 46 | public function assertLensesExclude($class) 47 | { 48 | $this->setNovaLensResponse(); 49 | 50 | $this->novaLensResponse->assertJsonMissing([ 51 | 'uriKey' => app($class)->uriKey() 52 | ]); 53 | 54 | return $this; 55 | } 56 | 57 | public function setNovaLensResponse() 58 | { 59 | if ($this->novaLensResponse) { 60 | return; 61 | } 62 | 63 | extract($this->novaParameters); 64 | 65 | abort_if(strpos($endpoint, 'creation-fields'), 500, 'No lenses on forms'); 66 | abort_if(strpos($endpoint, 'update-fields'), 500, 'No lenses on forms'); 67 | 68 | $this->novaLensResponse = new NovaResponse( 69 | $this->parent->getJson("$endpoint/lenses"), 70 | $this->novaParameters, 71 | $this->parent 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Assert/AssertPolicies.php: -------------------------------------------------------------------------------- 1 | where('uriKey', $this->novaParameters['resource']) 16 | ->first()['authorizedToCreate'] 17 | ); 18 | } 19 | 20 | public function assertCannotCreate() 21 | { 22 | PHPUnit::assertFalse( 23 | collect(Nova::jsonVariables(request())['resources']) 24 | ->where('uriKey', $this->novaParameters['resource']) 25 | ->first()['authorizedToCreate'] 26 | ); 27 | } 28 | 29 | public function assertCanDelete() 30 | { 31 | return $this->assertJsonFragment([ 32 | 'authorizedToDelete' => true 33 | ]); 34 | } 35 | 36 | public function assertCannotDelete() 37 | { 38 | return $this->assertJsonFragment([ 39 | 'authorizedToDelete' => false 40 | ]); 41 | } 42 | 43 | public function assertCanForceDelete() 44 | { 45 | return $this->assertJsonFragment([ 46 | 'authorizedToForceDelete' => true 47 | ]); 48 | } 49 | 50 | public function assertCannotForceDelete() 51 | { 52 | return $this->assertJsonFragment([ 53 | 'authorizedToForceDelete' => false 54 | ]); 55 | } 56 | 57 | public function assertCanRestore() 58 | { 59 | return $this->assertJsonFragment([ 60 | 'authorizedToRestore' => true 61 | ]); 62 | } 63 | 64 | public function assertCannotRestore() 65 | { 66 | return $this->assertJsonFragment([ 67 | 'authorizedToRestore' => false 68 | ]); 69 | } 70 | 71 | public function assertCanUpdate() 72 | { 73 | return $this->assertJsonFragment([ 74 | 'authorizedToUpdate' => true 75 | ]); 76 | } 77 | 78 | public function assertCannotUpdate() 79 | { 80 | return $this->assertJsonFragment([ 81 | 'authorizedToUpdate' => false 82 | ]); 83 | } 84 | 85 | public function assertCanView() 86 | { 87 | return $this->assertJsonFragment([ 88 | 'authorizedToView' => true 89 | ]); 90 | } 91 | 92 | public function assertCannotView() 93 | { 94 | return $this->assertJsonFragment([ 95 | 'authorizedToView' => false 96 | ]); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/Assert/AssertRelations.php: -------------------------------------------------------------------------------- 1 | setNovaRelationshipResponse($key); 20 | 21 | $original = $this->novaRelationshipResponse[$key]->original; 22 | 23 | $results = collect(json_decode(json_encode($original['resources'], true))); 24 | 25 | PHPUnit::assertTrue($callable($results)); 26 | 27 | return $this; 28 | } 29 | 30 | public function setNovaRelationshipResponse($key) 31 | { 32 | if (isset($this->novaRelationshipResponse[$key])) { 33 | return; 34 | } 35 | 36 | extract($this->novaParameters); 37 | 38 | $original = $this->originalResponse()->original; 39 | 40 | if (isset($original['resource']['fields'])) { 41 | $path = 'resource.fields'; 42 | } 43 | 44 | if (isset($original['fields'])) { 45 | $path = 'fields'; 46 | } 47 | 48 | $field = collect(data_get($original, $path))->firstWhere('attribute', $key); 49 | 50 | abort_if(is_null($field), 500, 'Field not found'); 51 | 52 | $type = $this->relationshipCollectionType($field); 53 | 54 | if ($type) { 55 | $endpoint = "nova-api/$key?viaResource=$resource&viaResourceId=$resourceId&viaRelationship=$key&relationshipType=$type"; 56 | } 57 | 58 | if ($field instanceof BelongsTo) { 59 | $endpoint = "nova-api/$resource/associatable/$key"; 60 | 61 | if (isset($resourceId)) { 62 | $endpoint = "$endpoint?viaResourceId=$resourceId"; 63 | } 64 | } 65 | 66 | $this->novaRelationshipResponse[$key] = new NovaResponse( 67 | $this->parent->getJson($endpoint), 68 | $this->novaParameters, 69 | $this->parent 70 | ); 71 | } 72 | 73 | public function relationshipCollectionType($field) 74 | { 75 | if ($field instanceof HasMany) { 76 | return "hasMany"; 77 | } 78 | 79 | if ($field instanceof BelongsToMany) { 80 | return "belongsToMany"; 81 | } 82 | 83 | if ($field instanceof HasOne) { 84 | return "hasOne"; 85 | } 86 | 87 | return null; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Assert/AssertResources.php: -------------------------------------------------------------------------------- 1 | assertJsonCount($amount, 'resources'); 15 | 16 | return $this; 17 | } 18 | 19 | public function assertResources(closure $callable) 20 | { 21 | $resources = collect(json_decode(json_encode(Arr::get($this->original, 'resources', []), true))); 22 | 23 | PHPUnit::assertTrue($callable($resources)); 24 | 25 | return $this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/NovaAssertions.php: -------------------------------------------------------------------------------- 1 | resolveUriKey($resource); 14 | $filters = $this->makeNovaFilters($resource, $filters); 15 | $endpoint = "nova-api/$resource"; 16 | $json = $this->getJson("$endpoint?$filters"); 17 | 18 | return new NovaResponse($json, compact('endpoint', 'resource'), $this); 19 | } 20 | 21 | public function novaDetail($resource, $resourceId) 22 | { 23 | $resource = $this->resolveUriKey($resource); 24 | $endpoint = "nova-api/$resource/$resourceId"; 25 | $json = $this->getJson($endpoint); 26 | 27 | return new NovaResponse($json, compact('endpoint', 'resource', 'resourceId'), $this); 28 | } 29 | 30 | public function novaCreate($resource) 31 | { 32 | $resource = $this->resolveUriKey($resource); 33 | $endpoint = "nova-api/$resource/creation-fields"; 34 | $json = $this->getJson($endpoint); 35 | 36 | return new NovaResponse($json, compact('endpoint', 'resource'), $this); 37 | } 38 | 39 | public function novaEdit($resource, $resourceId) 40 | { 41 | $resource = $this->resolveUriKey($resource); 42 | $endpoint = "nova-api/$resource/$resourceId/update-fields"; 43 | $json = $this->getJson($endpoint); 44 | 45 | return new NovaResponse($json, compact('endpoint', 'resource', 'resourceId'), $this); 46 | } 47 | 48 | public function novaLens($resource, $lens, $filters = []) 49 | { 50 | $resource = $this->resolveUriKey($resource); 51 | $lens = $this->resolveUriKey($lens); 52 | $filters = $this->makeNovaFilters($resource, $filters); 53 | $endpoint = "nova-api/$resource/lens/$lens"; 54 | $json = $this->getJson("$endpoint?$filters"); 55 | 56 | return new NovaResponse($json, compact('endpoint', 'resource', 'lens'), $this); 57 | } 58 | 59 | public function makeNovaFilters($resource, $filters) 60 | { 61 | if (empty($filters)) { 62 | return ''; 63 | } 64 | 65 | $encoded = base64_encode(json_encode( 66 | collect($filters)->map(function ($value, $key) { 67 | return ['class' => $key, 'value' => $value]; 68 | })->values() 69 | )); 70 | 71 | return "filters=$encoded"; 72 | } 73 | 74 | public function resolveUriKey($class) 75 | { 76 | if (strpos($class, '\\')) { 77 | return app($class)->uriKey(); 78 | } 79 | 80 | return $class; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/NovaResponse.php: -------------------------------------------------------------------------------- 1 | originalJsonResponse = $originalJsonResponse; 37 | 38 | $this->novaParameters = $parameters; 39 | 40 | $this->parent = $parent; 41 | } 42 | 43 | public function __get($property) 44 | { 45 | return $this->originalJsonResponse->$property; 46 | } 47 | 48 | public function __call($method, $arguments) 49 | { 50 | $this->originalJsonResponse->$method(...$arguments); 51 | 52 | return $this; 53 | } 54 | 55 | /** 56 | * @return \Illuminate\Foundation\Testing\TestResponse 57 | */ 58 | public function originalResponse() 59 | { 60 | return $this->originalJsonResponse; 61 | } 62 | } 63 | --------------------------------------------------------------------------------