clock = new SystemClock(); $this->contentService = Mockery::mock(ContentService::class); $this->jsonSerializer = new JsonSerializer(); $this->controller = new ContentsController( $this->contentService, $this->jsonSerializer ); }); it('lists all contents', function () { $contents = [ CmsTestHelpers::createContent($this->clock), ]; $this->contentService->shouldReceive('findPublished') ->once() ->andReturn($contents); $request = new HttpRequest( method: Method::GET, path: '/api/v1/cms/contents', queryParams: ['status' => 'published'], id: new RequestId('test') ); $response = $this->controller->index($request); expect($response->status)->toBe(Status::OK); expect($response->headers->get('Content-Type'))->toBe('application/json'); }); it('lists contents by content type', function () { $contentTypeId = ContentTypeId::fromString('page'); $contents = [ CmsTestHelpers::createContent($this->clock, contentTypeId: $contentTypeId), ]; $this->contentService->shouldReceive('findByType') ->once() ->andReturn($contents); $request = new HttpRequest( method: Method::GET, path: '/api/v1/cms/contents', queryParams: ['content_type_id' => 'page'], id: new RequestId('test') ); $response = $this->controller->index($request); expect($response->status)->toBe(Status::OK); }); it('shows content by id', function () { $contentId = ContentId::generate($this->clock); $content = CmsTestHelpers::createContent($this->clock, id: $contentId); $this->contentService->shouldReceive('findById') ->once() ->with($contentId) ->andReturn($content); $request = new HttpRequest( method: Method::GET, path: '/api/v1/cms/contents/{id}', queryParams: ['id' => $contentId->toString()], id: new RequestId('test') ); $response = $this->controller->show($request); expect($response->status)->toBe(Status::OK); }); it('returns 404 when content not found', function () { $contentId = ContentId::generate($this->clock); $this->contentService->shouldReceive('findById') ->once() ->andThrow(\App\Domain\Cms\Exceptions\ContentNotFoundException::forId($contentId)); $request = new HttpRequest( method: Method::GET, path: '/api/v1/cms/contents/{id}', queryParams: ['id' => $contentId->toString()], id: new RequestId('test') ); $response = $this->controller->show($request); expect($response->status)->toBe(Status::NOT_FOUND); }); it('creates new content', function () { $content = CmsTestHelpers::createContent($this->clock); $this->contentService->shouldReceive('create') ->once() ->andReturn($content); $request = new HttpRequest( method: Method::POST, path: '/api/v1/cms/contents', body: json_encode([ 'content_type_id' => 'page', 'title' => 'Test Page', 'slug' => 'test-page', 'blocks' => [ [ 'id' => 'hero-1', 'type' => 'hero', 'data' => ['title' => 'Hero Title'], ], ], ]), id: new RequestId('test') ); $createRequest = new \App\Application\Cms\Api\Requests\CreateContentRequest(); $response = $this->controller->create($request, $createRequest); expect($response->status)->toBe(Status::CREATED); }); it('updates content', function () { $contentId = ContentId::generate($this->clock); $content = CmsTestHelpers::createContent($this->clock, id: $contentId); $updatedContent = $content->withTitle('Updated Title'); $this->contentService->shouldReceive('findById') ->once() ->andReturn($content); $this->contentService->shouldReceive('updateTitle') ->once() ->andReturn($updatedContent); $request = new HttpRequest( method: Method::PUT, path: '/api/v1/cms/contents/{id}', queryParams: ['id' => $contentId->toString()], body: json_encode([ 'title' => 'Updated Title', ]), id: new RequestId('test') ); $updateRequest = new \App\Application\Cms\Api\Requests\UpdateContentRequest(); $response = $this->controller->update($request, $updateRequest); expect($response->status)->toBe(Status::OK); }); it('deletes content', function () { $contentId = ContentId::generate($this->clock); $content = CmsTestHelpers::createContent($this->clock, id: $contentId); $this->contentService->shouldReceive('findById') ->once() ->andReturn($content); $this->contentService->shouldReceive('delete') ->once() ->with($contentId) ->andReturnNull(); $request = new HttpRequest( method: Method::DELETE, path: '/api/v1/cms/contents/{id}', queryParams: ['id' => $contentId->toString()], id: new RequestId('test') ); $response = $this->controller->delete($request); expect($response->status)->toBe(Status::NO_CONTENT); }); it('publishes content', function () { $contentId = ContentId::generate($this->clock); $content = CmsTestHelpers::createContent($this->clock, id: $contentId); $publishedContent = $content->withStatus(ContentStatus::PUBLISHED); $this->contentService->shouldReceive('publish') ->once() ->with($contentId) ->andReturn($publishedContent); $request = new HttpRequest( method: Method::POST, path: '/api/v1/cms/contents/{id}/publish', queryParams: ['id' => $contentId->toString()], id: new RequestId('test') ); $response = $this->controller->publish($request); expect($response->status)->toBe(Status::OK); }); it('unpublishes content', function () { $contentId = ContentId::generate($this->clock); $content = CmsTestHelpers::createContent($this->clock, id: $contentId, status: ContentStatus::PUBLISHED); $unpublishedContent = $content->withStatus(ContentStatus::DRAFT); $this->contentService->shouldReceive('unpublish') ->once() ->with($contentId) ->andReturn($unpublishedContent); $request = new HttpRequest( method: Method::POST, path: '/api/v1/cms/contents/{id}/unpublish', queryParams: ['id' => $contentId->toString()], id: new RequestId('test') ); $response = $this->controller->unpublish($request); expect($response->status)->toBe(Status::OK); }); });