diff --git a/api-docs/aggregated.swagger.yaml b/api-docs/aggregated.swagger.yaml index 378e77449a..65e004cc9c 100644 --- a/api-docs/aggregated.swagger.yaml +++ b/api-docs/aggregated.swagger.yaml @@ -517,6 +517,7 @@ definitions: - FixedList - MoneyGBP - TextArea + - RichTextArea - ComplexType - Collection - MultiSelectList diff --git a/build.gradle b/build.gradle index 7244fea4a0..199a3e87f4 100644 --- a/build.gradle +++ b/build.gradle @@ -219,6 +219,14 @@ task integration(type: Test) { failFast = true } +task aatTest(type: Test) { + description = "Runs JUnit AAT tests" + group = "Verification" + testClassesDirs = sourceSets.aat.output.classesDirs + classpath = sourceSets.aat.runtimeClasspath + failFast = true +} + ext.libraries = [ junit5: [ "org.junit.jupiter:junit-jupiter-api:${junit}", diff --git a/docs/api/case-data.md b/docs/api/case-data.md index 8da3dc68ab..fdead28066 100644 --- a/docs/api/case-data.md +++ b/docs/api/case-data.md @@ -122,6 +122,16 @@ A `TextArea` value is a `string`. It contain `\n` to represent line breaks. } ``` +### RichTextArea + +A `RichTextArea` value is a `string`. CCD stores the rich text content as an opaque string and does not interpret the markup. + +```json +{ + "FieldId": "

Order

" +} +``` + ### FixedList A `FixedList` value is a `string` exactly matching the code of one the pre-defined options for that list. @@ -349,4 +359,3 @@ Also shows the optional required OrganisationPolicyField field. } } ``` - diff --git a/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/v2/external/RichTextAreaCaseTest.java b/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/v2/external/RichTextAreaCaseTest.java new file mode 100644 index 0000000000..f346affafb --- /dev/null +++ b/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/v2/external/RichTextAreaCaseTest.java @@ -0,0 +1,168 @@ +package uk.gov.hmcts.ccd.datastore.tests.v2.external; + +import io.restassured.response.Response; +import io.restassured.specification.RequestSpecification; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import uk.gov.hmcts.ccd.datastore.tests.AATHelper; +import uk.gov.hmcts.ccd.datastore.tests.BaseTest; +import uk.gov.hmcts.ccd.v2.V2; + +import java.util.function.Supplier; + +import static java.lang.Boolean.FALSE; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; + +@DisplayName("RichTextArea case data") +class RichTextAreaCaseTest extends BaseTest { + + private static final String CASE_TYPE = "AllDataTypes2"; + private static final String CREATE_EVENT = "createCase"; + private static final String UPDATE_EVENT = "updateRichTextArea"; + private static final String RICH_TEXT_AREA_FIELD = "RichTextAreaField"; + private static final String RICH_TEXT_AREA_COMPLEX_FIELD = "RichTextAreaComplexField"; + private static final String RICH_TEXT_AREA_COMPLEX_ELEMENT = "RichTextAreaElement"; + private static final String CREATED_RICH_TEXT = "

Order created for CCD-7988

"; + private static final String CREATED_COMPLEX_RICH_TEXT = + "

Complex order text created for CCD-7988

"; + private static final String UPDATED_RICH_TEXT = "

Order updated for CCD-7988

"; + private static final String UPDATED_COMPLEX_RICH_TEXT = + "

Complex order text updated for CCD-7988

"; + + protected RichTextAreaCaseTest(AATHelper aat) { + super(aat); + } + + @Test + @DisplayName("should create, update and retrieve RichTextArea fields") + void shouldCreateUpdateAndRetrieveRichTextAreaFields() { + String createToken = getStartCaseToken(CREATE_EVENT); + + String caseReference = createCase(createToken) + .then() + .statusCode(201) + .body("id", notNullValue()) + .body("data." + RICH_TEXT_AREA_FIELD, equalTo(CREATED_RICH_TEXT)) + .body("data." + RICH_TEXT_AREA_COMPLEX_FIELD + "." + RICH_TEXT_AREA_COMPLEX_ELEMENT, + equalTo(CREATED_COMPLEX_RICH_TEXT)) + .extract() + .path("id"); + + String updateToken = getStartEventToken(caseReference, UPDATE_EVENT); + + updateCase(caseReference, updateToken) + .then() + .statusCode(201) + .body("id", equalTo(caseReference)) + .body("data." + RICH_TEXT_AREA_FIELD, equalTo(UPDATED_RICH_TEXT)) + .body("data." + RICH_TEXT_AREA_COMPLEX_FIELD + "." + RICH_TEXT_AREA_COMPLEX_ELEMENT, + equalTo(UPDATED_COMPLEX_RICH_TEXT)); + + getCase(caseReference) + .then() + .statusCode(200) + .body("id", equalTo(caseReference)) + .body("data." + RICH_TEXT_AREA_FIELD, equalTo(UPDATED_RICH_TEXT)) + .body("data." + RICH_TEXT_AREA_COMPLEX_FIELD + "." + RICH_TEXT_AREA_COMPLEX_ELEMENT, + equalTo(UPDATED_COMPLEX_RICH_TEXT)); + } + + private String getStartCaseToken(String eventId) { + return asV2AutoTestCaseworker() + .get() + .given() + .pathParam("caseTypeId", CASE_TYPE) + .pathParam("triggerId", eventId) + .accept(V2.MediaType.START_CASE_EVENT) + .when() + .get("/case-types/{caseTypeId}/event-triggers/{triggerId}?ignore-warning=true") + .then() + .statusCode(200) + .extract() + .path("token"); + } + + private String getStartEventToken(String caseReference, String eventId) { + return asV2AutoTestCaseworker() + .get() + .given() + .pathParam("caseId", caseReference) + .pathParam("triggerId", eventId) + .accept(V2.MediaType.START_EVENT) + .when() + .get("/cases/{caseId}/event-triggers/{triggerId}?ignore-warning=true") + .then() + .statusCode(200) + .extract() + .path("token"); + } + + private Response createCase(String token) { + return asV2AutoTestCaseworker() + .get() + .given() + .pathParam("caseTypeId", CASE_TYPE) + .contentType(V2.MediaType.CREATE_CASE) + .accept(V2.MediaType.CREATE_CASE) + .body(caseDataContent(CREATE_EVENT, token, CREATED_RICH_TEXT, CREATED_COMPLEX_RICH_TEXT)) + .when() + .post("/case-types/{caseTypeId}/cases?ignore-warning=true"); + } + + private Response updateCase(String caseReference, String token) { + return asV2AutoTestCaseworker() + .get() + .given() + .pathParam("caseId", caseReference) + .contentType(V2.MediaType.CREATE_EVENT) + .accept(V2.MediaType.CREATE_EVENT) + .body(caseDataContent(UPDATE_EVENT, token, UPDATED_RICH_TEXT, UPDATED_COMPLEX_RICH_TEXT)) + .when() + .post("/cases/{caseId}/events"); + } + + private Response getCase(String caseReference) { + return asV2AutoTestCaseworker() + .get() + .given() + .pathParam("caseId", caseReference) + .accept(V2.MediaType.CASE) + .when() + .get("/cases/{caseId}"); + } + + private Supplier asV2AutoTestCaseworker() { + return () -> asAutoTestCaseworker(FALSE) + .get() + .given() + .header("experimental", "true"); + } + + private String caseDataContent(String eventId, String token, String richText, String complexRichText) { + return """ + { + "event_token": "%s", + "event": { + "id": "%s", + "summary": "CCD-7988 RichTextArea", + "description": "RichTextArea AAT" + }, + "data": { + "%s": "%s", + "%s": { + "%s": "%s" + } + } + } + """.formatted( + token, + eventId, + RICH_TEXT_AREA_FIELD, + richText, + RICH_TEXT_AREA_COMPLEX_FIELD, + RICH_TEXT_AREA_COMPLEX_ELEMENT, + complexRichText + ); + } +} diff --git a/src/aat/resources/features/common/fieldtypes/base/BaseRichTextAreaFieldType.td.json b/src/aat/resources/features/common/fieldtypes/base/BaseRichTextAreaFieldType.td.json new file mode 100644 index 0000000000..d6ca1fe971 --- /dev/null +++ b/src/aat/resources/features/common/fieldtypes/base/BaseRichTextAreaFieldType.td.json @@ -0,0 +1,7 @@ +{ + "_guid_": "BaseRichTextAreaFieldType", + "_extends_": "CommonFieldType", + + "id": "RichTextArea", + "type": "RichTextArea" +} diff --git a/src/contractTest/resources/application.properties b/src/contractTest/resources/application.properties index 064ab7e8e2..66567cdb85 100644 --- a/src/contractTest/resources/application.properties +++ b/src/contractTest/resources/application.properties @@ -201,7 +201,7 @@ management.health.elasticsearch.enabled=false management.health.status.order=DOWN, OUT_OF_SERVICE, UNKNOWN, UP, OUT_OF_SYNC, PROBLEM, COULD_NOT_CONNECT # Elasticsearch mappings -elasticsearch.type-mappings.defaultText=Text, TextArea, FixedList, FixedListEdit, MultiSelectList, FixedRadioList, DynamicList, DynamicRadioList, DynamicMultiSelectList, Region, BaseLocation, PhoneUK +elasticsearch.type-mappings.defaultText=Text, TextArea, RichTextArea, FixedList, FixedListEdit, MultiSelectList, FixedRadioList, DynamicList, DynamicRadioList, DynamicMultiSelectList, Region, BaseLocation, PhoneUK elasticsearch.case-predefined-mappings.defaultText=reference, jurisdiction, state, case_type_id # Remote Case Audit @@ -271,6 +271,7 @@ ccd.messaging.type-mappings.Text=SimpleText ccd.messaging.type-mappings.PhoneUK=SimpleText ccd.messaging.type-mappings.Email=SimpleText ccd.messaging.type-mappings.TextArea=SimpleText +ccd.messaging.type-mappings.RichTextArea=SimpleText ccd.messaging.type-mappings.BaseLocation=SimpleText ccd.messaging.type-mappings.Region=SimpleText ccd.messaging.type-mappings.Date=SimpleDate diff --git a/src/main/java/uk/gov/hmcts/ccd/domain/model/definition/FieldTypeDefinition.java b/src/main/java/uk/gov/hmcts/ccd/domain/model/definition/FieldTypeDefinition.java index 371e1c1fab..7a049c8cff 100644 --- a/src/main/java/uk/gov/hmcts/ccd/domain/model/definition/FieldTypeDefinition.java +++ b/src/main/java/uk/gov/hmcts/ccd/domain/model/definition/FieldTypeDefinition.java @@ -34,6 +34,7 @@ public class FieldTypeDefinition implements Serializable, Copyable validate(final String dataFieldId, + final JsonNode dataValue, + final CaseFieldDefinition caseFieldDefinition) { + if (isNullOrEmpty(dataValue)) { + return Collections.emptyList(); + } + + if (!dataValue.isTextual()) { + final String nodeType = dataValue.getNodeType().toString().toLowerCase(Locale.ROOT); + return Collections.singletonList(new ValidationResult(nodeType + " is not a string", dataFieldId)); + } + + final String value = dataValue.textValue(); + + final BigDecimal minLength = caseFieldDefinition.getFieldTypeDefinition().getMin(); + + if (!TextValidator.checkMin(minLength, value)) { + return Collections.singletonList( + new ValidationResult("requires a minimum length of " + minLength, dataFieldId) + ); + } + + return Collections.emptyList(); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 67c9733f40..dd114d8089 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -234,7 +234,7 @@ management.health.elasticsearch.enabled=false management.health.status.order=DOWN, OUT_OF_SERVICE, UNKNOWN, UP, OUT_OF_SYNC, PROBLEM, COULD_NOT_CONNECT # Elasticsearch mappings -elasticsearch.type-mappings.defaultText=Text, TextArea, FixedList, FixedListEdit, MultiSelectList, FixedRadioList, DynamicList, DynamicRadioList, DynamicMultiSelectList, Region, BaseLocation, PhoneUK +elasticsearch.type-mappings.defaultText=Text, TextArea, RichTextArea, FixedList, FixedListEdit, MultiSelectList, FixedRadioList, DynamicList, DynamicRadioList, DynamicMultiSelectList, Region, BaseLocation, PhoneUK elasticsearch.case-predefined-mappings.defaultText=reference, jurisdiction, state, case_type_id # Remote Case Audit @@ -295,6 +295,7 @@ ccd.messaging.type-mappings.Text=SimpleText ccd.messaging.type-mappings.PhoneUK=SimpleText ccd.messaging.type-mappings.Email=SimpleText ccd.messaging.type-mappings.TextArea=SimpleText +ccd.messaging.type-mappings.RichTextArea=SimpleText ccd.messaging.type-mappings.BaseLocation=SimpleText ccd.messaging.type-mappings.Region=SimpleText ccd.messaging.type-mappings.Date=SimpleDate diff --git a/src/test/java/uk/gov/hmcts/ccd/TestConfiguration.java b/src/test/java/uk/gov/hmcts/ccd/TestConfiguration.java index 608c4c0d71..d6e567bd30 100644 --- a/src/test/java/uk/gov/hmcts/ccd/TestConfiguration.java +++ b/src/test/java/uk/gov/hmcts/ccd/TestConfiguration.java @@ -75,6 +75,9 @@ class TestConfiguration extends ContextCleanupListener { + " \"type\": \"TextArea\"\n" + " },\n" + " {\n" + + " \"type\": \"RichTextArea\"\n" + + " },\n" + + " {\n" + " \"type\": \"Complex\"\n" + " },\n" + " {\n" diff --git a/src/test/java/uk/gov/hmcts/ccd/data/ReferenceDataCacheRefreshIT.java b/src/test/java/uk/gov/hmcts/ccd/data/ReferenceDataCacheRefreshIT.java index f835f5fc54..6a9e5788fc 100644 --- a/src/test/java/uk/gov/hmcts/ccd/data/ReferenceDataCacheRefreshIT.java +++ b/src/test/java/uk/gov/hmcts/ccd/data/ReferenceDataCacheRefreshIT.java @@ -133,10 +133,19 @@ private void referenceDataNotFoundUpstream() { private void verifyWiremockInvocation(final String path, final int count) { final RequestPattern requestPattern = getRequestedFor(urlPathEqualTo(path)).build(); - final VerificationResult verificationResult = wireMockServer.countRequestsMatching(requestPattern); - assertThat(verificationResult) - .isNotNull() - .satisfies(result -> assertThat(result.getCount()).isGreaterThanOrEqualTo(count)); + + await() + .atMost(Durations.FIVE_SECONDS) + .untilAsserted(() -> { + final VerificationResult verificationResult = wireMockServer.countRequestsMatching(requestPattern); + + assertThat(verificationResult) + .isNotNull(); + + assertThat(verificationResult.getCount()) + .as("Expected WireMock path %s to be called at least %s times", path, count) + .isGreaterThanOrEqualTo(count); + }); } private void cacheContainsInitialReferenceData() { diff --git a/src/test/java/uk/gov/hmcts/ccd/data/definition/DefaultCaseDefinitionRepositoryIT.java b/src/test/java/uk/gov/hmcts/ccd/data/definition/DefaultCaseDefinitionRepositoryIT.java index 8d693a4a16..46f1abd0c9 100644 --- a/src/test/java/uk/gov/hmcts/ccd/data/definition/DefaultCaseDefinitionRepositoryIT.java +++ b/src/test/java/uk/gov/hmcts/ccd/data/definition/DefaultCaseDefinitionRepositoryIT.java @@ -56,7 +56,7 @@ public void shouldGetBaseTypes() { assertAll( "Assert All of these", - () -> assertThat(baseTypes, IsCollectionWithSize.hasSize(18)), + () -> assertThat(baseTypes, IsCollectionWithSize.hasSize(19)), () -> assertThat(baseTypes, hasItem(hasProperty("type", is("Text")))), () -> assertThat(baseTypes, hasItem(hasProperty("type", is("Number")))), () -> assertThat(baseTypes, hasItem(hasProperty("type", is("Email")))), @@ -68,6 +68,7 @@ public void shouldGetBaseTypes() { () -> assertThat(baseTypes, hasItem(hasProperty("type", is("MoneyGBP")))), () -> assertThat(baseTypes, hasItem(hasProperty("type", is("PhoneUK")))), () -> assertThat(baseTypes, hasItem(hasProperty("type", is("TextArea")))), + () -> assertThat(baseTypes, hasItem(hasProperty("type", is("RichTextArea")))), () -> assertThat(baseTypes, hasItem(hasProperty("type", is(COLLECTION)))), () -> assertThat(baseTypes, hasItem(hasProperty("type", is("MultiSelectList")))), () -> assertThat(baseTypes, hasItem(hasProperty("type", is("DynamicRadioList")))), diff --git a/src/test/java/uk/gov/hmcts/ccd/domain/service/search/elasticsearch/ElasticsearchMappingsTest.java b/src/test/java/uk/gov/hmcts/ccd/domain/service/search/elasticsearch/ElasticsearchMappingsTest.java index 08f12b9c2e..829f6ec9e3 100644 --- a/src/test/java/uk/gov/hmcts/ccd/domain/service/search/elasticsearch/ElasticsearchMappingsTest.java +++ b/src/test/java/uk/gov/hmcts/ccd/domain/service/search/elasticsearch/ElasticsearchMappingsTest.java @@ -18,8 +18,8 @@ class ElasticsearchMappingsTest { @BeforeEach void setUp() { ElasticsearchMappings.TypeMappings typeMappings = new ElasticsearchMappings.TypeMappings( - Arrays.asList("Text", "TextArea", "FixedList", "FixedListEdit", "MultiSelectList", "FixedRadioList", - "DynamicList", "DynamicRadioList", "DynamicMultiSelectList") + Arrays.asList("Text", "TextArea", "RichTextArea", "FixedList", "FixedListEdit", "MultiSelectList", + "FixedRadioList", "DynamicList", "DynamicRadioList", "DynamicMultiSelectList") ); ElasticsearchMappings.CasePredefinedMappings casePredefinedMappings = diff --git a/src/test/java/uk/gov/hmcts/ccd/domain/types/CaseDataValidatorTest.java b/src/test/java/uk/gov/hmcts/ccd/domain/types/CaseDataValidatorTest.java index 35b725f297..fe0769efd5 100644 --- a/src/test/java/uk/gov/hmcts/ccd/domain/types/CaseDataValidatorTest.java +++ b/src/test/java/uk/gov/hmcts/ccd/domain/types/CaseDataValidatorTest.java @@ -17,6 +17,7 @@ import uk.gov.hmcts.ccd.domain.model.definition.CaseFieldDefinition; import uk.gov.hmcts.ccd.domain.model.definition.CaseTypeDefinition; import uk.gov.hmcts.ccd.domain.service.common.TestBuildersUtil; +import uk.gov.hmcts.ccd.test.CaseFieldDefinitionBuilder; import jakarta.inject.Inject; import java.io.IOException; @@ -31,6 +32,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertThrows; import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -42,6 +44,8 @@ public class CaseDataValidatorTest extends WireMockBaseTest { private static final String CASE_FIELD_JSON = "tests/CaseDataValidator_CaseField.json"; private static final String CASE_FIELD_DYNAMIC_JSON = "tests/CaseDataValidator_DynamicLists.json"; + private static final String RICH_TEXT_AREA_FIELD = "RichTextAreaField"; + private static final String RICH_TEXT_AREA = "RichTextArea"; @Inject private CaseDataValidator caseDataValidator; @@ -413,6 +417,27 @@ public void validDynamicListInCollection() throws Exception { assertEquals(result.toString(), 0, result.size()); } + @Test + public void validRichTextAreaValue() throws Exception { + final String data = """ + { + "RichTextAreaField": "

Order

" + }"""; + final Map values = caseDataFromJsonString(data); + final CaseTypeDefinition caseTypeDefinition = new CaseTypeDefinition(); + caseTypeDefinition.setCaseFieldDefinitions(List.of( + new CaseFieldDefinitionBuilder(RICH_TEXT_AREA_FIELD) + .withType(RICH_TEXT_AREA) + .withMin(10) + .build() + )); + + final ValidationContext validationContext = new ValidationContext(caseTypeDefinition, values); + final List result = caseDataValidator.validate(validationContext); + + assertTrue(result.isEmpty(), result.toString()); + } + @Test public void unknownFieldInCollectionOfComplex() throws Exception { diff --git a/src/test/java/uk/gov/hmcts/ccd/domain/types/RichTextAreaValidatorTest.java b/src/test/java/uk/gov/hmcts/ccd/domain/types/RichTextAreaValidatorTest.java new file mode 100644 index 0000000000..1846bf7b71 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/ccd/domain/types/RichTextAreaValidatorTest.java @@ -0,0 +1,109 @@ +package uk.gov.hmcts.ccd.domain.types; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import uk.gov.hmcts.ccd.data.definition.CaseDefinitionRepository; +import uk.gov.hmcts.ccd.domain.model.definition.CaseFieldDefinition; +import uk.gov.hmcts.ccd.domain.model.definition.FieldTypeDefinition; +import uk.gov.hmcts.ccd.test.CaseFieldDefinitionBuilder; + +import java.util.List; +import java.util.stream.Stream; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@DisplayName("RichTextAreaValidator") +class RichTextAreaValidatorTest { + + private static final JsonNodeFactory NODE_FACTORY = JsonNodeFactory.instance; + private static final String FIELD_ID = "TEST_FIELD_ID"; + + private final RichTextAreaValidator validator = new RichTextAreaValidator(); + + @BeforeEach + void setUp() { + FieldTypeDefinition richTextAreaType = baseTypeDefinition(); + CaseDefinitionRepository definitionRepository = mock(CaseDefinitionRepository.class); + + when(definitionRepository.getBaseTypes()).thenReturn(List.of(richTextAreaType)); + BaseType.setCaseDefinitionRepository(definitionRepository); + BaseType.register(new BaseType(richTextAreaType)); + } + + @Test + void getType() { + assertThat(validator.getType(), is(BaseType.get("RichTextArea"))); + } + + @ParameterizedTest + @MethodSource("validEmptyValues") + void validate_shouldBeValidWhenNullOrEmpty(JsonNode value) { + assertThat(validate(value, caseField().build()), is(empty())); + } + + @ParameterizedTest + @ValueSource(strings = {"Some text", "

Order

", "xxx4"}) + void validate_shouldBeValidWhenMinimumLengthRequirementMet(String value) { + assertThat(validate(NODE_FACTORY.textNode(value), caseField().withMin(4).build()), is(empty())); + } + + @Test + void validate_shouldNotBeValidWhenMinimumLengthRequirementNotMet() { + List results = validate(NODE_FACTORY.textNode("xxx"), caseField().withMin(4).build()); + + assertSingleError(results, "requires a minimum length of 4"); + } + + @Test + void validate_shouldIgnoreMaximumLengthAndRegexRequirements() { + CaseFieldDefinition constrainedField = caseField() + .withMax(4) + .withRegExp("\\d{4}-\\d{2}-\\d{2}") + .build(); + + assertThat(validate(NODE_FACTORY.textNode("not-a-date-and-longer-than-four"), constrainedField), is(empty())); + } + + @Test + void validate_shouldBeInvalidWhenValueProvidedIsNotText() { + List results = validate(NODE_FACTORY.numberNode(2), caseField().build()); + + assertSingleError(results, "number is not a string"); + } + + private static Stream validEmptyValues() { + return Stream.of(null, NODE_FACTORY.nullNode(), NODE_FACTORY.textNode("")); + } + + private List validate(JsonNode value, CaseFieldDefinition fieldDefinition) { + return validator.validate(FIELD_ID, value, fieldDefinition); + } + + private static CaseFieldDefinitionBuilder caseField() { + return new CaseFieldDefinitionBuilder(FIELD_ID).withType(RichTextAreaValidator.TYPE_ID); + } + + private static FieldTypeDefinition baseTypeDefinition() { + FieldTypeDefinition fieldTypeDefinition = new FieldTypeDefinition(); + fieldTypeDefinition.setType(RichTextAreaValidator.TYPE_ID); + return fieldTypeDefinition; + } + + private static void assertSingleError(List results, String errorMessage) { + assertThat(results, hasSize(1)); + assertThat(results.get(0).getFieldId(), equalTo(FIELD_ID)); + assertThat(results.get(0).getErrorMessage(), equalTo(errorMessage)); + } +} diff --git a/src/test/resources/base-types.json b/src/test/resources/base-types.json index e36de1433b..6ed5e6ee2a 100644 --- a/src/test/resources/base-types.json +++ b/src/test/resources/base-types.json @@ -99,6 +99,16 @@ "complex_fields": [], "collection_field_type": null }, + { + "id": "RichTextArea", + "type": "RichTextArea", + "min": null, + "max": null, + "regular_expression": null, + "fixed_list_items": [], + "complex_fields": [], + "collection_field_type": null + }, { "id": "Complex", "type": "Complex", diff --git a/src/test/resources/mappings/base-types.json b/src/test/resources/mappings/base-types.json index b2588aed82..d068ae431f 100644 --- a/src/test/resources/mappings/base-types.json +++ b/src/test/resources/mappings/base-types.json @@ -44,6 +44,9 @@ { "type": "TextArea" }, + { + "type": "RichTextArea" + }, { "type": "Complex" },