diff --git a/src/Traits/NovaTestTrait.php b/src/Traits/NovaTestTrait.php index 19d72ae..53c6a68 100644 --- a/src/Traits/NovaTestTrait.php +++ b/src/Traits/NovaTestTrait.php @@ -2,9 +2,14 @@ namespace RonasIT\Support\Traits; +use Illuminate\Contracts\Auth\Authenticatable; +use Illuminate\Foundation\Testing\TestCase; +use Illuminate\Support\Str; +use Illuminate\Testing\TestResponse; + trait NovaTestTrait { - public function novaSearchParams(array $filters, string $search = '', int $perPage = 25): array + protected function novaSearchParams(array $filters, string $search = '', int $perPage = 25): array { return [ 'search' => $search, @@ -12,4 +17,93 @@ public function novaSearchParams(array $filters, string $search = '', int $perPa 'perPage' => $perPage, ]; } + + protected function novaCreateResourceAPICall(string $resourceClass, ?array $data = []): TestResponse + { + $uri = $this->generateNovaUri($resourceClass); + + return $this->json('post', $uri, $data); + } + + protected function novaUpdateResourceAPICall(string $resourceClass, int $resourceId, ?array $data = []): TestResponse + { + $uri = $this->generateNovaUri($resourceClass); + + return $this->json('put', "{$uri}/{$resourceId}", $data); + } + + protected function novaGetResourceAPICall(string $resourceClass, int $resourceId, ?array $data = []): TestResponse + { + $uri = $this->generateNovaUri($resourceClass); + + return $this->json('get', "{$uri}/{$resourceId}", $data); + } + + protected function novaSearchResourceAPICall(string $resourceClass, ?array $request = []): TestResponse + { + $uri = $this->generateNovaUri($resourceClass); + + return $this->json('get', $uri, $request); + } + + protected function novaGetCreationFieldsAPICall(string $resourceClass): TestResponse + { + $uri = $this->generateNovaUri($resourceClass, '/creation-fields'); + + return $this->json('get', $uri); + } + + protected function novaRunActionAPICall(string $resourceClass, string $actionClass, ?array $request = []): TestResponse + { + $actionUri = app($actionClass)->uriKey(); + + $uri = $this->generateNovaUri($resourceClass, "/action?action={$actionUri}"); + + return $this->json('post', $uri, $request); + } + + protected function novaGetActionsAPICall(string $resourceClass, array $resourceIds): TestResponse + { + $uri = $this->generateNovaUri($resourceClass, '/actions'); + + $request = [ + 'resources' => implode(',', $resourceIds), + ]; + + return $this->json('get', $uri, $request); + } + + protected function novaDeleteResourceAPICall(string $resourceClass, array $resourceIds): TestResponse + { + $uri = $this->generateNovaUri($resourceClass); + + $request = [ + 'resources' => $resourceIds, + ]; + + return $this->json('delete', $uri, $request); + } + + protected function novaGetUpdatableFieldsAPICall(string $resourceClass, int $resourceId): TestResponse + { + $uri = $this->generateNovaUri($resourceClass, "/{$resourceId}/update-fields"); + + return $this->json('get', $uri); + } + + protected function novaActingAs(?Authenticatable $user = null): TestCase|self + { + return (empty($user)) + ? $this + : $this->actingAs($user, 'web'); + } + + protected function generateNovaUri(string $modelClass, string $path = ''): string + { + $modelName = Str::afterLast($modelClass, '\\'); + + $modelName = Str::kebab($modelName); + + return "/nova-api/{$modelName}-resources{$path}"; + } } diff --git a/tests/NovaTestTraitTest.php b/tests/NovaTestTraitTest.php index 851e85e..1f95219 100644 --- a/tests/NovaTestTraitTest.php +++ b/tests/NovaTestTraitTest.php @@ -2,8 +2,15 @@ namespace RonasIT\Support\Tests; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Route; +use RonasIT\Support\Tests\Support\Mock\MockAuthUser; +use RonasIT\Support\Tests\Support\Mock\TestModel; +use RonasIT\Support\Tests\Support\Mock\TestNovaAction; use RonasIT\Support\Traits\MockTrait; use RonasIT\Support\Traits\NovaTestTrait; +use Symfony\Component\HttpFoundation\Response; class NovaTestTraitTest extends HelpersTestCase { @@ -22,4 +29,152 @@ public function testMockSingleCall() 'perPage' => 25, ]); } + + public function testGetNovaResourceUri() + { + $result = $this->generateNovaUri(TestModel::class); + + $this->assertEquals($result, '/nova-api/test-model-resources'); + } + + public function testNovaCreateResource() + { + Route::post('/nova-api/test-model-resources', function (Request $request) { + $request->validate([ + 'key' => 'required|string', + ]); + + return response('', Response::HTTP_CREATED); + }); + + $result = $this->novaCreateResourceAPICall(TestModel::class, ['key' => 'value']); + + $result->assertCreated(); + } + + public function testNovaUpdateResource() + { + Route::put('/nova-api/test-model-resources/1', function (Request $request) { + $request->validate([ + 'key' => 'required|string', + ]); + + return response($request->all(), Response::HTTP_OK); + }); + + $result = $this->novaUpdateResourceAPICall(TestModel::class, 1, ['key' => 'value']); + + $result->assertOk(); + } + + public function testNovaGetResource() + { + Route::get('/nova-api/test-model-resources/1', function () { + return response('', Response::HTTP_OK); + }); + + $result = $this->novaGetResourceAPICall(TestModel::class, 1); + + $result->assertOk(); + } + + public function testNovaSearchResource() + { + Route::get('/nova-api/test-model-resources', function (Request $request) { + $request->validate([ + 'key' => 'required|string', + ]); + + return response($request->all(), Response::HTTP_OK); + }); + + $result = $this->novaSearchResourceAPICall(TestModel::class, ['key' => 'value']); + + $result->assertOk(); + } + + public function testNovaGetCreationFields() + { + Route::get('/nova-api/test-model-resources/creation-fields', function (Request $request) { + return response('', Response::HTTP_OK); + }); + + $result = $this->novaGetCreationFieldsAPICall(TestModel::class); + + $result->assertOk(); + } + + public function testNovaGetActions() + { + Route::get('/nova-api/test-model-resources/actions', function (Request $request) { + $request->validate([ + 'resources' => 'required|string', + ]); + + return response($request->all(), Response::HTTP_OK); + }); + + $result = $this->novaGetActionsAPICall(TestModel::class, [1, 2]); + + $result->assertOk(); + + $result->assertContent('{"resources":"1,2"}'); + } + + public function testNovaDeleteResource() + { + Route::delete('/nova-api/test-model-resources', function (Request $request) { + $request->validate([ + 'resources' => 'required|array', + ]); + + return response($request->all(), Response::HTTP_OK); + }); + + $result = $this->novaDeleteResourceAPICall(TestModel::class, [1, 2]); + + $result->assertOk(); + + $result->assertContent('{"resources":[1,2]}'); + } + + public function testNovaGetUpdatableFields() + { + Route::get('/nova-api/test-model-resources/1/update-fields', function (Request $request) { + return response('', Response::HTTP_OK); + }); + + $result = $this->novaGetUpdatableFieldsAPICall(TestModel::class, 1); + + $result->assertOk(); + } + + public function testNovaRunAction() + { + Route::post('/nova-api/test-model-resources/action', function (Request $request) { + return response($request->all(), Response::HTTP_OK); + }); + + $result = $this->novaRunActionAPICall(TestModel::class, TestNovaAction::class, ['key' => 'value']); + + $result->assertOk(); + + $result->assertContent('{"key":"value","action":"test-nova-action"}'); + } + + public function testNovaActingAs() + { + $mockedUser = new MockAuthUser(); + + $this->novaActingAs($mockedUser); + + $this->assertEquals($mockedUser, Auth::user()); + } + + public function testNovaActingAsUserNotSet() + { + $result = $this->novaActingAs(); + + $this->assertEquals(true, ($result instanceof self)); + } } diff --git a/tests/support/Mock/TestNovaAction.php b/tests/support/Mock/TestNovaAction.php new file mode 100644 index 0000000..c3d4fe6 --- /dev/null +++ b/tests/support/Mock/TestNovaAction.php @@ -0,0 +1,11 @@ +