diff --git a/api/src/Entity/Category.php b/api/src/Entity/Category.php index 23937d2e17..c5ac7b2a4e 100644 --- a/api/src/Entity/Category.php +++ b/api/src/Entity/Category.php @@ -143,6 +143,8 @@ class Category extends BaseEntity implements BelongsToCampInterface, CopyFromPro /** * The color of the activities in this category, as a hex color string. */ + #[InputFilter\Trim] + #[Assert\NotBlank] #[Assert\Regex(pattern: '/^#[0-9a-zA-Z]{6}$/')] #[ApiProperty(example: '#4DBB52')] #[Groups(['read', 'write'])] diff --git a/api/tests/Api/Categories/CreateCategoryTest.php b/api/tests/Api/Categories/CreateCategoryTest.php index 52fb1ebe81..5433282fb1 100644 --- a/api/tests/Api/Categories/CreateCategoryTest.php +++ b/api/tests/Api/Categories/CreateCategoryTest.php @@ -341,6 +341,49 @@ public function testCreateCategoryCleansForbiddenCharactersFromName() { )); } + public function testCreateCategoryValidatesNullColor() { + static::createClientWithCredentials()->request( + 'POST', + '/categories', + [ + 'json' => $this->getExampleWritePayload( + [ + 'color' => null, + ] + ), + ] + ); + + $this->assertResponseStatusCodeSame(400); + $this->assertJsonContains([ + 'detail' => 'The type of the "color" attribute must be "string", "NULL" given.', + ]); + } + + public function testCreateCategoryValidatesEmptyColor() { + static::createClientWithCredentials()->request( + 'POST', + '/categories', + [ + 'json' => $this->getExampleWritePayload( + [ + 'color' => '', + ] + ), + ] + ); + + $this->assertResponseStatusCodeSame(422); + $this->assertJsonContains([ + 'violations' => [ + [ + 'propertyPath' => 'color', + 'message' => 'This value should not be blank.', + ], + ], + ]); + } + public function testCreateCategoryValidatesMissingColor() { static::createClientWithCredentials()->request('POST', '/categories', ['json' => $this->getExampleWritePayload([], ['color'])]); @@ -349,7 +392,7 @@ public function testCreateCategoryValidatesMissingColor() { 'violations' => [ [ 'propertyPath' => 'color', - 'message' => 'This value should not be null.', + 'message' => 'This value should not be blank.', ], ], ]); @@ -371,6 +414,25 @@ public function testCreateCategoryValidatesInvalidColor() { ]); } + public function testCreateCategoryTrimsColor() { + static::createClientWithCredentials()->request( + 'POST', + '/categories', + [ + 'json' => $this->getExampleWritePayload( + [ + 'color' => " \t #4DBB52 \t ", + ] + ), + ] + ); + + $this->assertResponseStatusCodeSame(201); + $this->assertJsonContains($this->getExampleReadPayload([ + 'color' => '#4DBB52', + ])); + } + public function testCreateCategoryUsesDefaultForMissingNumberingStyle() { static::createClientWithCredentials()->request('POST', '/categories', ['json' => $this->getExampleWritePayload([], ['numberingStyle'])]); diff --git a/api/tests/Api/Categories/UpdateCategoryTest.php b/api/tests/Api/Categories/UpdateCategoryTest.php index 3b5a858f0c..b9b51146a6 100644 --- a/api/tests/Api/Categories/UpdateCategoryTest.php +++ b/api/tests/Api/Categories/UpdateCategoryTest.php @@ -416,6 +416,49 @@ public function testPatchCategoryCleansForbiddenCharactersFromName() { ); } + public function testPatchCategoryValidatesNullColor() { + $category = static::$fixtures['category1']; + static::createClientWithCredentials()->request( + 'PATCH', + '/categories/'.$category->getId(), + [ + 'json' => [ + 'color' => null, + ], + 'headers' => ['Content-Type' => 'application/merge-patch+json'], + ] + ); + + $this->assertResponseStatusCodeSame(400); + $this->assertJsonContains([ + 'detail' => 'The type of the "color" attribute must be "string", "NULL" given.', + ]); + } + + public function testPatchCategoryValidatesEmptyColor() { + $category = static::$fixtures['category1']; + static::createClientWithCredentials()->request( + 'PATCH', + '/categories/'.$category->getId(), + [ + 'json' => [ + 'color' => '', + ], + 'headers' => ['Content-Type' => 'application/merge-patch+json'], + ] + ); + + $this->assertResponseStatusCodeSame(422); + $this->assertJsonContains([ + 'violations' => [ + [ + 'propertyPath' => 'color', + 'message' => 'This value should not be blank.', + ], + ], + ]); + } + public function testPatchCategoryValidatesInvalidColor() { $category = static::$fixtures['category1']; static::createClientWithCredentials()->request('PATCH', '/categories/'.$category->getId(), ['json' => [ @@ -433,6 +476,25 @@ public function testPatchCategoryValidatesInvalidColor() { ]); } + public function testPatchCategoryTrimsColor() { + $category = static::$fixtures['category1']; + static::createClientWithCredentials()->request( + 'PATCH', + '/categories/'.$category->getId(), + [ + 'json' => [ + 'color' => " \t #4DBB52 \t ", + ], + 'headers' => ['Content-Type' => 'application/merge-patch+json'], + ] + ); + + $this->assertResponseStatusCodeSame(200); + $this->assertJsonContains([ + 'color' => '#4DBB52', + ]); + } + public function testPatchCategoryValidatesInvalidNumberingStyle() { $category = static::$fixtures['category1']; static::createClientWithCredentials()->request('PATCH', '/categories/'.$category->getId(), ['json' => [