-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: Add enctype to Form Close: #674 * remove pattern from constructor arguments * fix checkstyle * add validation test * validate message * Handle null in EnctypePostRequiredValidator --------- Co-authored-by: Tim Yates <tim.yates@gmail.com>
- Loading branch information
Showing
11 changed files
with
316 additions
and
8 deletions.
There are no files selected for viewing
2 changes: 1 addition & 1 deletion
2
test-suite-thymeleaf-fieldset/src/test/resources/views/fieldset/form.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
<form th:fragment="form(form)" xmlns:th="http://www.thymeleaf.org" th:action="${form.action()}" th:method="${form.method()}"><fieldset th:replace="~{fieldset/fieldset :: fieldset(${form.fieldset()})}"></fieldset></form> | ||
<th:block th:fragment="form(form)" xmlns:th="http://www.thymeleaf.org"><form th:action="${form.action()}" th:method="${form.method()}" th:enctype="${form.enctype()}"><fieldset th:replace="~{fieldset/fieldset :: fieldset(${form.fieldset()})}"></fieldset></form></th:block> |
45 changes: 45 additions & 0 deletions
45
views-fieldset-tck/src/main/java/io/micronaut/views/fields/tck/FormEncTypeRenderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright 2017-2023 original authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.views.fields.tck; | ||
|
||
import io.micronaut.test.extensions.junit5.annotation.MicronautTest; | ||
import io.micronaut.views.ViewsRenderer; | ||
import io.micronaut.views.fields.Fieldset; | ||
import io.micronaut.views.fields.Form; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.io.IOException; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
|
||
|
||
@SuppressWarnings({"java:S5960"}) // Assertions are fine, these are tests | ||
@MicronautTest(startApplication = false) | ||
class FormEncTypeRenderTest { | ||
|
||
@Test | ||
void render(ViewsRenderer<Map<String, Object>, ?> viewsRenderer) throws IOException { | ||
assertNotNull(viewsRenderer); | ||
Form form = new Form("/foo/bar", "post", new Fieldset(Collections.emptyList(), Collections.emptyList()), "application/x-www-form-urlencoded"); | ||
assertEquals(""" | ||
<form action="/foo/bar" method="post" enctype="application/x-www-form-urlencoded">\ | ||
</form>""", | ||
TestUtils.render("fieldset/form.html", viewsRenderer, Map.of("form", form))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
views-fieldset/src/main/java/io/micronaut/views/fields/constraints/EnctypePostRequired.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright 2017-2023 original authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.views.fields.constraints; | ||
|
||
import jakarta.validation.Constraint; | ||
import jakarta.validation.Payload; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* The annotated {@link io.micronaut.views.fields.Form} must not have an encytpe declared if the method is not post. | ||
* @author Sergio del Amo | ||
* @since 5.1.0 | ||
* | ||
*/ | ||
@Constraint(validatedBy = EnctypePostRequiredValidator.class) | ||
@Target({ElementType.TYPE, ElementType.FIELD}) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface EnctypePostRequired { | ||
String MESSAGE = "io.micronaut.views.fields.constraints.EnctypePostRequired.message"; | ||
|
||
String message() default "{" + MESSAGE + "}"; | ||
|
||
Class<?>[] groups() default {}; | ||
|
||
Class<? extends Payload>[] payload() default {}; | ||
} |
45 changes: 45 additions & 0 deletions
45
...set/src/main/java/io/micronaut/views/fields/constraints/EnctypePostRequiredValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright 2017-2023 original authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.views.fields.constraints; | ||
|
||
import io.micronaut.core.annotation.AnnotationValue; | ||
import io.micronaut.core.annotation.Introspected; | ||
import io.micronaut.core.annotation.NonNull; | ||
import io.micronaut.core.annotation.Nullable; | ||
import io.micronaut.validation.validator.constraints.ConstraintValidator; | ||
import io.micronaut.validation.validator.constraints.ConstraintValidatorContext; | ||
import io.micronaut.views.fields.Form; | ||
|
||
/** | ||
* Validator for the constraint {@link EnctypePostRequired} being applied to a {@link Form}. | ||
* @author Sergio del Amo | ||
* @since 5.1.0 | ||
*/ | ||
@Introspected | ||
public class EnctypePostRequiredValidator implements ConstraintValidator<EnctypePostRequired, Form> { | ||
|
||
private static final String METHOD_POST = "post"; | ||
|
||
@Override | ||
public boolean isValid(@Nullable Form form, | ||
@NonNull AnnotationValue<EnctypePostRequired> annotationMetadata, | ||
@NonNull ConstraintValidatorContext context) { | ||
if (form == null) { | ||
return true; | ||
} | ||
return form.enctype() == null || form.method().equals(METHOD_POST); | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
views-fieldset/src/main/java/io/micronaut/views/fields/constraints/FormMessages.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Copyright 2017-2023 original authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.micronaut.views.fields.constraints; | ||
|
||
import io.micronaut.context.StaticMessageSource; | ||
import io.micronaut.core.annotation.Internal; | ||
import jakarta.inject.Singleton; | ||
|
||
/** | ||
* Messages contributed by Form validation annotations. | ||
* @author Sergio del Amo | ||
* @since 5.1.0 | ||
*/ | ||
@Singleton | ||
@Internal | ||
class FormMessages extends StaticMessageSource { | ||
private static final String ENCTYPE_POST_REQUIRED_MESSAGE = "enctype attribute can be used only if method equals post"; | ||
|
||
private static final String MESSAGE_SUFFIX = ".message"; | ||
|
||
FormMessages() { | ||
addMessage(EnctypePostRequired.class.getName() + MESSAGE_SUFFIX, ENCTYPE_POST_REQUIRED_MESSAGE); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
views-fieldset/src/main/java/io/micronaut/views/fields/constraints/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright 2017-2023 original authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
/** | ||
* Custom Constraints for validating HTML Forms. | ||
* @author Sergio del Amo | ||
* @since 5.1.0 | ||
*/ | ||
package io.micronaut.views.fields.constraints; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
views-fieldset/src/test/java/io/micronaut/views/fields/FormTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,60 @@ | ||
package io.micronaut.views.fields; | ||
|
||
import io.micronaut.core.beans.BeanIntrospection; | ||
import io.micronaut.test.extensions.junit5.annotation.MicronautTest; | ||
import io.micronaut.validation.validator.Validator; | ||
import io.micronaut.views.fields.elements.InputSubmitFormElement; | ||
import jakarta.validation.ConstraintViolation; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.Collections; | ||
import java.util.Set; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
@MicronautTest(startApplication = false) | ||
class FormTest { | ||
@Test | ||
void isAnnotatedWithIntrospected() { | ||
assertDoesNotThrow(() -> BeanIntrospection.getIntrospection(Form.class)); | ||
} | ||
|
||
@Test | ||
void formValidation(Validator validator) { | ||
Fieldset fieldset = new Fieldset(Collections.singletonList(new InputSubmitFormElement(FormGenerator.SUBMIT)), Collections.emptyList()); | ||
// action cannot be an empty string | ||
assertFalse(validator.validate(new Form("", "post", fieldset, "application/x-www-form-urlencoded")).isEmpty()); | ||
// action cannot be null | ||
assertFalse(validator.validate(new Form(null, "post", fieldset, "application/x-www-form-urlencoded")).isEmpty()); | ||
|
||
// method cannot be an empty string | ||
assertFalse(validator.validate(new Form("/foo/bar", "", fieldset, null)).isEmpty()); | ||
// method cannot be null | ||
assertFalse(validator.validate(new Form("/foo/bar", null, fieldset, null)).isEmpty()); | ||
// method can only be get or post | ||
assertFalse(validator.validate(new Form("/foo/bar", "put", fieldset, null)).isEmpty()); | ||
|
||
//method cannot be get if enctype | ||
Set<ConstraintViolation<Form>> violations = validator.validate(new Form("/foo/bar", "get", fieldset, "application/x-www-form-urlencoded")); | ||
assertFalse(violations.isEmpty()); | ||
assertEquals(Collections.singletonList("enctype attribute can be used only if method equals post"), violations.stream().map(ConstraintViolation::getMessage).toList()); | ||
|
||
// fieldset cannot be null | ||
Fieldset invalidFieldset = new Fieldset(Collections.emptyList(), Collections.emptyList()); | ||
assertFalse(validator.validate(new Form("/foo/bar", "post", invalidFieldset, "application/x-www-form-urlencoded")).isEmpty()); | ||
|
||
// fieldset must be valid | ||
assertFalse(validator.validate(new Form("/foo/bar", "post", null, "application/x-www-form-urlencoded")).isEmpty()); | ||
|
||
// enctype has to be form-url-enconded form-data or txt | ||
assertFalse(validator.validate(new Form("/foo/bar", "post", fieldset, "text/html")).isEmpty()); | ||
|
||
// enctype can be null | ||
assertTrue(validator.validate(new Form("/foo/bar", "post", fieldset, null)).isEmpty()); | ||
assertTrue(validator.validate(new Form("/foo/bar", "post", fieldset, "application/x-www-form-urlencoded")).isEmpty()); | ||
assertTrue(validator.validate(new Form("/foo/bar", "post", fieldset, "multipart/form-data")).isEmpty()); | ||
assertTrue(validator.validate(new Form("/foo/bar", "post", fieldset, "text/plain")).isEmpty()); | ||
assertTrue(validator.validate(new Form("/foo/bar", "get", fieldset, null)).isEmpty()); | ||
|
||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
views-fieldset/src/test/java/io/micronaut/views/fields/messages/MessageTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package io.micronaut.views.fields.messages; | ||
|
||
import io.micronaut.test.extensions.junit5.annotation.MicronautTest; | ||
import io.micronaut.validation.validator.Validator; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
@MicronautTest(startApplication = false) | ||
class MessageTest { | ||
|
||
@Test | ||
void messageValidation(Validator validator) { | ||
assertTrue(validator.validate(Message.of("Foo")).isEmpty()); | ||
assertTrue(validator.validate(Message.of("Foo", "foo.code")).isEmpty()); | ||
assertFalse(validator.validate(Message.of("")).isEmpty()); | ||
String msg = null; | ||
assertFalse(validator.validate(Message.of(msg)).isEmpty()); | ||
} | ||
} |