renderer = Mockery::mock(TemplateRenderer::class); $this->formFactory = Mockery::mock(AdminFormFactory::class); $this->service = new CrudService($this->renderer, $this->formFactory); $this->config = CrudConfig::forResource( resource: 'campaigns', resourceName: 'Campaign', title: 'Campaigns' )->withColumns([ ['field' => 'name', 'label' => 'Name'], ['field' => 'status', 'label' => 'Status'], ]); }); afterEach(function () { Mockery::close(); }); describe('CrudService', function () { describe('renderIndex', function () { it('renders index view with items and pagination', function () { $items = [ ['id' => '1', 'name' => 'Campaign 1', 'status' => 'active'], ['id' => '2', 'name' => 'Campaign 2', 'status' => 'draft'], ]; $pagination = [ 'current_page' => 1, 'total_pages' => 5, 'per_page' => 10, ]; $request = Mockery::mock(HttpRequest::class); $request->shouldReceive('uri')->andReturn('/admin/campaigns'); $result = $this->service->renderIndex( $this->config, $items, $request, $pagination ); expect($result)->toBeInstanceOf(ViewResult::class); expect($result->template)->toBe('crud-index'); expect($result->data['items'])->toBe($items); expect($result->data['pagination'])->toBe($pagination); expect($result->data['resource'])->toBe('campaigns'); expect($result->data['createUrl'])->toBe('/admin/campaigns/create'); }); }); describe('renderCreate', function () { it('renders create form with default configuration', function () { $formFields = [ ['type' => 'text', 'name' => 'name', 'label' => 'Name'], ]; $mockForm = Mockery::mock(); $mockForm->shouldReceive('build')->andReturn('
'); $mockForm->shouldReceive('getId')->andReturn('campaign-form'); $this->formFactory->shouldReceive('create') ->once() ->andReturn($mockForm); $result = $this->service->renderCreate( $this->config, $formFields ); expect($result)->toBeInstanceOf(ViewResult::class); expect($result->template)->toBe('crud-create'); expect($result->data['title'])->toBe('Create Campaign'); expect($result->data['formId'])->toBe('campaign-form'); expect($result->data['backUrl'])->toBe('/admin/campaigns'); }); it('renders create form with help text', function () { $formFields = []; $helpText = 'Fill in the campaign details carefully.'; $mockForm = Mockery::mock(); $mockForm->shouldReceive('build')->andReturn(''); $mockForm->shouldReceive('getId')->andReturn('form-id'); $this->formFactory->shouldReceive('create')->andReturn($mockForm); $result = $this->service->renderCreate( $this->config, $formFields, null, $helpText ); expect($result->data['helpText'])->toBe($helpText); }); }); describe('renderEdit', function () { it('renders edit form with item data and metadata', function () { $formFields = [ ['type' => 'text', 'name' => 'name', 'label' => 'Name'], ]; $itemData = [ 'id' => '123', 'name' => 'Test Campaign', 'status' => 'active', ]; $metadata = [ 'id' => '123', 'createdAt' => '2024-01-01 10:00:00', 'updatedAt' => '2024-01-02 15:30:00', ]; $mockForm = Mockery::mock(); $mockForm->shouldReceive('build')->andReturn(''); $mockForm->shouldReceive('getId')->andReturn('edit-form'); $this->formFactory->shouldReceive('create') ->once() ->andReturn($mockForm); $result = $this->service->renderEdit( $this->config, '123', $formFields, $itemData, $metadata ); expect($result)->toBeInstanceOf(ViewResult::class); expect($result->template)->toBe('crud-edit'); expect($result->data['title'])->toBe('Edit Campaign'); expect($result->data['metadata'])->toBe($metadata); expect($result->data['deleteUrl'])->toBe('/admin/campaigns/delete/123'); }); }); describe('renderShow', function () { it('renders show view with fields and metadata', function () { $fields = [ ['label' => 'Name', 'value' => 'Test Campaign', 'type' => 'text'], ['label' => 'Status', 'value' => 'Active', 'type' => 'badge', 'color' => 'success'], ]; $metadata = [ 'id' => '123', 'createdAt' => '2024-01-01', ]; $result = $this->service->renderShow( $this->config, '123', $fields, $metadata ); expect($result)->toBeInstanceOf(ViewResult::class); expect($result->template)->toBe('crud-show'); expect($result->data['fields'])->toBe($fields); expect($result->data['metadata'])->toBe($metadata); expect($result->data['editUrl'])->toBe('/admin/campaigns/edit/123'); }); }); describe('redirectAfterCreate', function () { it('redirects to index after successful create', function () { $request = Mockery::mock(HttpRequest::class); $request->parsedBody = Mockery::mock(); $request->parsedBody->shouldReceive('get') ->with('action') ->andReturn(null); $result = $this->service->redirectAfterCreate( $this->config, $request, '123' ); expect($result)->toBeInstanceOf(Redirect::class); expect($result->url)->toBe('/admin/campaigns'); }); it('redirects to create form when save-and-continue is requested', function () { $request = Mockery::mock(HttpRequest::class); $request->parsedBody = Mockery::mock(); $request->parsedBody->shouldReceive('get') ->with('action') ->andReturn('save-and-continue'); $result = $this->service->redirectAfterCreate( $this->config, $request, '123' ); expect($result->url)->toBe('/admin/campaigns/create'); }); }); describe('redirectAfterUpdate', function () { it('redirects to index after successful update', function () { $request = Mockery::mock(HttpRequest::class); $request->parsedBody = Mockery::mock(); $request->parsedBody->shouldReceive('get') ->with('action') ->andReturn(null); $result = $this->service->redirectAfterUpdate( $this->config, $request, '123' ); expect($result->url)->toBe('/admin/campaigns'); }); it('redirects to show view when save-and-view is requested', function () { $request = Mockery::mock(HttpRequest::class); $request->parsedBody = Mockery::mock(); $request->parsedBody->shouldReceive('get') ->with('action') ->andReturn('save-and-view'); $result = $this->service->redirectAfterUpdate( $this->config, $request, '123' ); expect($result->url)->toBe('/admin/campaigns/view/123'); }); }); describe('redirectAfterDelete', function () { it('redirects to index after successful delete', function () { $result = $this->service->redirectAfterDelete($this->config); expect($result)->toBeInstanceOf(Redirect::class); expect($result->url)->toBe('/admin/campaigns'); }); }); describe('redirectWithError', function () { it('redirects back with error message', function () { $result = $this->service->redirectWithError('Something went wrong'); expect($result)->toBeInstanceOf(Redirect::class); }); it('redirects with error message and input data', function () { $inputData = ['name' => 'Test', 'email' => 'test@example.com']; $result = $this->service->redirectWithError( 'Validation failed', $inputData ); expect($result)->toBeInstanceOf(Redirect::class); }); }); });