diff --git a/src/Cms/Services/Post/Updater.php b/src/Cms/Services/Post/Updater.php index 8e3a045..e7d1796 100644 --- a/src/Cms/Services/Post/Updater.php +++ b/src/Cms/Services/Post/Updater.php @@ -64,6 +64,12 @@ public function update( $post->setFeaturedImage( $featuredImage ); $post->setStatus( $status ); + // Business rule: auto-set published date when changing to published status + if( $status === Post::STATUS_PUBLISHED && !$post->getPublishedAt() ) + { + $post->setPublishedAt( new \DateTimeImmutable() ); + } + // Update relationships $categories = $this->_categoryRepository->findByIds( $categoryIds ); $post->setCategories( $categories ); diff --git a/tests/Cms/Services/Post/UpdaterTest.php b/tests/Cms/Services/Post/UpdaterTest.php index 7d8e0bc..a5881b2 100644 --- a/tests/Cms/Services/Post/UpdaterTest.php +++ b/tests/Cms/Services/Post/UpdaterTest.php @@ -285,4 +285,76 @@ public function testReturnsUpdatedPost(): void $this->assertSame( $post, $result ); $this->assertEquals( 'Updated', $result->getTitle() ); } + + public function testSetsPublishedAtWhenChangingToPublished(): void + { + $post = new Post(); + $post->setId( 1 ); + $post->setTitle( 'Draft Post' ); + $post->setStatus( Post::STATUS_DRAFT ); + // Ensure publishedAt is not set + $this->assertNull( $post->getPublishedAt() ); + + $this->_mockCategoryRepository + ->method( 'findByIds' ) + ->willReturn( [] ); + + $this->_mockTagResolver + ->method( 'resolveFromString' ) + ->willReturn( [] ); + + $this->_mockPostRepository + ->expects( $this->once() ) + ->method( 'update' ) + ->with( $this->callback( function( Post $p ) { + return $p->getStatus() === Post::STATUS_PUBLISHED + && $p->getPublishedAt() instanceof \DateTimeImmutable; + } ) ); + + $result = $this->_updater->update( + $post, + 'Published Post', + 'Body', + Post::STATUS_PUBLISHED + ); + + $this->assertEquals( Post::STATUS_PUBLISHED, $result->getStatus() ); + $this->assertInstanceOf( \DateTimeImmutable::class, $result->getPublishedAt() ); + } + + public function testDoesNotOverwriteExistingPublishedAt(): void + { + $post = new Post(); + $post->setId( 1 ); + $post->setTitle( 'Published Post' ); + $post->setStatus( Post::STATUS_PUBLISHED ); + $existingPublishedAt = new \DateTimeImmutable( '2024-01-01 12:00:00' ); + $post->setPublishedAt( $existingPublishedAt ); + + $this->_mockCategoryRepository + ->method( 'findByIds' ) + ->willReturn( [] ); + + $this->_mockTagResolver + ->method( 'resolveFromString' ) + ->willReturn( [] ); + + $this->_mockPostRepository + ->expects( $this->once() ) + ->method( 'update' ) + ->with( $this->callback( function( Post $p ) use ( $existingPublishedAt ) { + return $p->getStatus() === Post::STATUS_PUBLISHED + && $p->getPublishedAt() === $existingPublishedAt; + } ) ); + + $result = $this->_updater->update( + $post, + 'Updated Published Post', + 'Body', + Post::STATUS_PUBLISHED + ); + + $this->assertEquals( Post::STATUS_PUBLISHED, $result->getStatus() ); + $this->assertSame( $existingPublishedAt, $result->getPublishedAt() ); + } }