diff --git a/extensions/mentions/src/Formatter/UnparsePostMentions.php b/extensions/mentions/src/Formatter/UnparsePostMentions.php index f223dd638f..3cfbfa0558 100644 --- a/extensions/mentions/src/Formatter/UnparsePostMentions.php +++ b/extensions/mentions/src/Formatter/UnparsePostMentions.php @@ -28,12 +28,16 @@ public function __construct(TranslatorInterface $translator) /** * Configure rendering for user mentions. * - * @param string $xml + * @param string|null $xml * @param mixed $context - * @return string $xml to be unparsed + * @return mixed $xml to be unparsed */ - public function __invoke($context, string $xml) + public function __invoke($context, $xml) { + if ($xml === null) { + return $xml; + } + $xml = $this->updatePostMentionTags($context, $xml); $xml = $this->unparsePostMentionTags($xml); diff --git a/extensions/mentions/src/Formatter/UnparseTagMentions.php b/extensions/mentions/src/Formatter/UnparseTagMentions.php index b2cae82f2f..ff3ccf8342 100644 --- a/extensions/mentions/src/Formatter/UnparseTagMentions.php +++ b/extensions/mentions/src/Formatter/UnparseTagMentions.php @@ -18,12 +18,16 @@ class UnparseTagMentions /** * Configure rendering for user mentions. * - * @param string $xml + * @param string|null $xml * @param mixed $context - * @return string $xml to be unparsed + * @return mixed $xml to be unparsed */ - public function __invoke($context, string $xml) + public function __invoke($context, $xml) { + if ($xml === null) { + return $xml; + } + $xml = $this->updateTagMentionTags($context, $xml); $xml = $this->unparseTagMentionTags($xml); diff --git a/extensions/mentions/src/Formatter/UnparseUserMentions.php b/extensions/mentions/src/Formatter/UnparseUserMentions.php index b150d2f7ba..f42c7bac39 100644 --- a/extensions/mentions/src/Formatter/UnparseUserMentions.php +++ b/extensions/mentions/src/Formatter/UnparseUserMentions.php @@ -29,12 +29,16 @@ public function __construct(TranslatorInterface $translator) /** * Configure rendering for user mentions. * - * @param string $xml + * @param string|null $xml * @param mixed $context - * @return string $xml to be unparsed + * @return mixed $xml to be unparsed */ - public function __invoke($context, string $xml) + public function __invoke($context, $xml) { + if ($xml === null) { + return $xml; + } + $xml = $this->updateUserMentionTags($context, $xml); $xml = $this->unparseUserMentionTags($xml); diff --git a/extensions/mentions/tests/integration/api/CreateDiscussionTest.php b/extensions/mentions/tests/integration/api/CreateDiscussionTest.php new file mode 100644 index 0000000000..6c93a34e49 --- /dev/null +++ b/extensions/mentions/tests/integration/api/CreateDiscussionTest.php @@ -0,0 +1,137 @@ +extension('flarum-mentions'); + + $this->extend( + (new Extend\Event()) + ->listen(\Flarum\Post\Event\Saving::class, function ($event) { + $event->post->content; + }) + ); + } + + /** + * @test + */ + public function cannot_create_discussion_with_empty_string() + { + $response = $this->send( + $this->request('POST', '/api/discussions', [ + 'authenticatedAs' => 1, + 'json' => [ + 'data' => [ + 'attributes' => [ + 'title' => 'Test post', + 'content' => '', + ], + ], + ], + ]) + ); + + $this->assertEquals(422, $response->getStatusCode()); + + $body = (string) $response->getBody(); + $this->assertJson($body); + $this->assertEquals([ + 'errors' => [ + [ + 'status' => '422', + 'code' => 'validation_error', + 'detail' => 'The content field is required.', + 'source' => ['pointer' => '/data/attributes/content'], + ], + ], + ], json_decode($body, true)); + } + + /** + * @test + */ + public function cannot_create_discussion_without_content_property() + { + $response = $this->send( + $this->request('POST', '/api/discussions', [ + 'authenticatedAs' => 1, + 'json' => [ + 'data' => [ + 'attributes' => [ + 'title' => 'Test post', + ], + ], + ], + ]) + ); + + $this->assertEquals(422, $response->getStatusCode()); + + $body = (string) $response->getBody(); + $this->assertJson($body); + $this->assertEquals([ + 'errors' => [ + [ + 'status' => '422', + 'code' => 'validation_error', + 'detail' => 'The content field is required.', + 'source' => ['pointer' => '/data/attributes/content'], + ], + ], + ], json_decode($body, true)); + } + + /** + * @test + */ + public function cannot_create_discussion_with_content_set_to_null() + { + $response = $this->send( + $this->request('POST', '/api/discussions', [ + 'authenticatedAs' => 1, + 'json' => [ + 'data' => [ + 'attributes' => [ + 'title' => 'Test post', + 'content' => null, + ], + ], + ], + ]) + ); + + $this->assertEquals(422, $response->getStatusCode()); + + $body = (string) $response->getBody(); + $this->assertJson($body); + $this->assertEquals([ + 'errors' => [ + [ + 'status' => '422', + 'code' => 'validation_error', + 'detail' => 'The content field is required.', + 'source' => ['pointer' => '/data/attributes/content'], + ], + ], + ], json_decode($body, true)); + } +} diff --git a/extensions/mentions/tests/integration/api/EditPostTest.php b/extensions/mentions/tests/integration/api/EditPostTest.php new file mode 100644 index 0000000000..52b48a1f74 --- /dev/null +++ b/extensions/mentions/tests/integration/api/EditPostTest.php @@ -0,0 +1,110 @@ +extension('flarum-mentions'); + + $this->prepareDatabase([ + 'discussions' => [ + ['id' => 1, 'title' => 'Discussion with post', 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1], + ], + 'posts' => [ + ['id' => 1, 'discussion_id' => 1, 'user_id' => 1, 'type' => 'comment', 'content' => '

Text

'], + ] + ]); + + $this->extend( + (new Extend\Event()) + ->listen(\Flarum\Post\Event\Saving::class, function ($event) { + $event->post->content; + }) + ); + } + + /** + * @test + */ + public function cannot_update_post_with_empty_string() + { + $response = $this->send( + $this->request('PATCH', '/api/posts/1', [ + 'authenticatedAs' => 1, + 'json' => [ + 'data' => [ + 'attributes' => [ + 'content' => '', + ], + ], + ], + ]) + ); + + $this->assertEquals(422, $response->getStatusCode()); + + $body = (string) $response->getBody(); + $this->assertJson($body); + $this->assertEquals([ + 'errors' => [ + [ + 'status' => '422', + 'code' => 'validation_error', + 'detail' => 'The content field is required.', + 'source' => ['pointer' => '/data/attributes/content'], + ], + ], + ], json_decode($body, true)); + } + + /** + * @test + */ + public function cannot_update_post_with_invalid_content_type() + { + $response = $this->send( + $this->request('PATCH', '/api/posts/1', [ + 'authenticatedAs' => 1, + 'json' => [ + 'data' => [ + 'attributes' => [ + 'content' => [], + ], + ], + ], + ]) + ); + + $this->assertEquals(422, $response->getStatusCode()); + + $body = (string) $response->getBody(); + $this->assertJson($body); + $this->assertEquals([ + 'errors' => [ + [ + 'status' => '422', + 'code' => 'validation_error', + 'detail' => 'The content field is required.', + 'source' => ['pointer' => '/data/attributes/content'], + ], + ], + ], json_decode($body, true)); + } +} diff --git a/framework/core/src/Formatter/Formatter.php b/framework/core/src/Formatter/Formatter.php index f47daae694..b93072eddf 100644 --- a/framework/core/src/Formatter/Formatter.php +++ b/framework/core/src/Formatter/Formatter.php @@ -139,7 +139,7 @@ public function unparse($xml, $context = null) $xml = $callback($context, $xml); } - return Unparser::unparse($xml); + return $xml !== null ? Unparser::unparse($xml) : null; } /**