Skip to content

Commit

Permalink
#30438 Adding back builder to properly handle content type base types.
Browse files Browse the repository at this point in the history
  • Loading branch information
jgambarios committed Oct 31, 2024
1 parent 98b2439 commit c12d848
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,43 @@ public String idFromValue(Object value) {

}

/**
* Custom Builder to handle the typeInf attribute.
*/
public static class Builder extends SaveContentTypeRequest.Builder {

private Class<? extends ContentType> typeInf = SimpleContentType.class;

/**
* Sets the typeInf attribute based on the provided ContentType instance.
*
* @param in the ContentType instance
* @return the updated SaveContentTypeRequest.Builder
*/
public SaveContentTypeRequest.Builder of(ContentType in) {
this.typeInf = in.getClass();
return from(in);
}

/**
* Builds the SaveContentTypeRequest and sets the typeInf attribute.
*
* @return the built SaveContentTypeRequest
*/
@Override
public SaveContentTypeRequest build() {
this.typeInf(typeInf);
return super.build();
}
}

/**
* Helper method to create the custom Builder.
*
* @return a new instance of the custom Builder
*/
public static Builder builder() {
return new Builder();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
import com.dotcms.contenttype.model.field.Relationships;
import com.dotcms.contenttype.model.type.BaseContentType;
import com.dotcms.contenttype.model.type.ContentType;
import com.dotcms.contenttype.model.type.ImmutablePageContentType;
import com.dotcms.contenttype.model.type.ImmutableSimpleContentType;
import com.dotcms.contenttype.model.type.SimpleContentType;
import com.dotcms.contenttype.model.workflow.SystemAction;
import com.dotcms.model.ResponseEntityView;
import com.dotcms.model.config.ServiceBean;
import com.dotcms.model.contenttype.AbstractSaveContentTypeRequest;
import com.dotcms.model.contenttype.FilterContentTypesRequest;
import com.dotcms.model.contenttype.SaveContentTypeRequest;
import com.dotcms.model.site.GetSiteByNameRequest;
Expand Down Expand Up @@ -114,7 +116,6 @@ void Test_Content_Type_Model_Serialization() throws JsonProcessingException {
.build()).build();

final String ctAsString = objectMapper.writeValueAsString(contentType);
System.out.println(ctAsString);

final ContentType ct = objectMapper.readValue(ctAsString, ContentType.class);
Assert.assertNotNull(ct);
Expand Down Expand Up @@ -144,6 +145,50 @@ abstract class AbstractContentTypesResponse extends AbstractResponseEntityView <
*/
}

/**
* Generate a CT using our classes model then test we can go back and forth using serialization
* and test our fields actually get translated properly using polymorphism to finally test we
* can create a SaveContentTypeRequest from a ContentType and the values are properly set.
*
* @throws JsonProcessingException If an error occurs while processing JSON.
*/
@Test
void Test_Content_Type_Model_SaveContentTypeRequest() throws JsonProcessingException {

final ObjectMapper objectMapper = new ClientObjectMapper().getContext(null);

final ImmutablePageContentType contentType = ImmutablePageContentType.builder()
.baseType(BaseContentType.HTMLPAGE)
.description("desc")
.id("1")
.variable("var")
.addFields(ImmutableBinaryField.builder()
.name("name")
.id("1")
.variable("fieldVar")
.build()).build();

final String ctAsString = objectMapper.writeValueAsString(contentType);

final ContentType ct = objectMapper.readValue(ctAsString, ContentType.class);
Assert.assertNotNull(ct);
Assert.assertTrue(
ct.fields().stream().anyMatch(field -> field instanceof BinaryField));

Assertions.assertEquals(BaseContentType.HTMLPAGE, ct.baseType());
Assertions.assertEquals(ContentType.SYSTEM_HOST, ct.host());
Assertions.assertEquals(ContentType.SYSTEM_FOLDER, ct.folder());

// Now we validate that when we create a SaveContentTypeRequest from a ContentType we have
// the proper values
final SaveContentTypeRequest contentTypeRequest = AbstractSaveContentTypeRequest.builder()
.of(ct).build();
Assertions.assertEquals(BaseContentType.HTMLPAGE, contentTypeRequest.baseType());
Assertions.assertEquals(ct.getClass(), contentTypeRequest.typeInf());
Assertions.assertEquals(ContentType.SYSTEM_HOST, contentTypeRequest.host());
Assertions.assertEquals(ContentType.SYSTEM_FOLDER, contentTypeRequest.folder());
}

/**
* Test that we can hit
*/
Expand Down Expand Up @@ -234,8 +279,8 @@ void Test_Create_Then_Update_Then_Delete_Content_Type() {
).build();

final ContentTypeAPI client = apiClientFactory.getClient(ContentTypeAPI.class);
final SaveContentTypeRequest saveRequest = SaveContentTypeRequest.builder().
from(contentType).build();
final SaveContentTypeRequest saveRequest = AbstractSaveContentTypeRequest.builder().
of(contentType).build();

final ResponseEntityView<List<ContentType>> response = client.createContentTypes(List.of(saveRequest));
Assertions.assertNotNull(response);
Expand All @@ -250,8 +295,8 @@ void Test_Create_Then_Update_Then_Delete_Content_Type() {

// Now lets test update
final ImmutableSimpleContentType updatedContentType = ImmutableSimpleContentType.builder().from(newContentType).description("Updated").build();
final SaveContentTypeRequest request = SaveContentTypeRequest.builder().
from(updatedContentType).build();
final SaveContentTypeRequest request = AbstractSaveContentTypeRequest.builder().
of(updatedContentType).build();
final ResponseEntityView<ContentType> responseEntityView = getUpdateContentTypeResponse(
client, request);
Assertions.assertEquals("Updated", responseEntityView.entity().description());
Expand Down Expand Up @@ -358,8 +403,8 @@ void Test_Create_Then_Update_Action_Mappings() throws JsonProcessingException {
// ---
// Create the content type with the action mappings
final var contentType = contentTypeWithoutMapping.withSystemActionMappings(jsonNodeV1);
final SaveContentTypeRequest request = SaveContentTypeRequest.builder()
.from(contentType).build();
final SaveContentTypeRequest request = AbstractSaveContentTypeRequest.builder()
.of(contentType).build();
final ResponseEntityView<List<ContentType>> createContentTypeResponse =
client.createContentTypes(List.of(request));

Expand All @@ -378,8 +423,8 @@ void Test_Create_Then_Update_Action_Mappings() throws JsonProcessingException {
// Modifying the content type without system mappings, nothing should change in mappings
var modifiedContentType = contentTypeWithoutMapping.withDescription("Modified!");

final SaveContentTypeRequest contentTypeRequest = SaveContentTypeRequest.builder()
.from(modifiedContentType).build();
final SaveContentTypeRequest contentTypeRequest = AbstractSaveContentTypeRequest.builder()
.of(modifiedContentType).build();

// Use of Awaitility to wait for the modified response
await().atMost(10, TimeUnit.SECONDS).until(() -> {
Expand All @@ -402,7 +447,8 @@ void Test_Create_Then_Update_Action_Mappings() throws JsonProcessingException {
.withDescription("Modified 2!")
.withSystemActionMappings(jsonNodeV2);

final SaveContentTypeRequest contentTypeRequest1 = SaveContentTypeRequest.builder().from(modifiedContentType).build();
final SaveContentTypeRequest contentTypeRequest1 = AbstractSaveContentTypeRequest.builder()
.of(modifiedContentType).build();

await().atMost(10, TimeUnit.SECONDS).until(() -> {
ResponseEntityView<ContentType> updateContentTypeResponse = getUpdateContentTypeResponse(
Expand All @@ -424,7 +470,8 @@ void Test_Create_Then_Update_Action_Mappings() throws JsonProcessingException {
.withDescription("Modified 3!")
.withSystemActionMappings(jsonNodeV3);

final SaveContentTypeRequest contentTypeRequest2 = SaveContentTypeRequest.builder().from(modifiedContentType).build();
final SaveContentTypeRequest contentTypeRequest2 = AbstractSaveContentTypeRequest.builder()
.of(modifiedContentType).build();

await().atMost(10, TimeUnit.SECONDS).until(() -> {
ResponseEntityView<ContentType> updateContentTypeResponse = getUpdateContentTypeResponse(
Expand All @@ -443,7 +490,8 @@ void Test_Create_Then_Update_Action_Mappings() throws JsonProcessingException {
.withDescription("Modified 4!")
.withSystemActionMappings(jsonNodeV4);

final SaveContentTypeRequest contentTypeRequest3 = SaveContentTypeRequest.builder().from(modifiedContentType).build();
final SaveContentTypeRequest contentTypeRequest3 = AbstractSaveContentTypeRequest.builder()
.of(modifiedContentType).build();

await().atMost(10, TimeUnit.SECONDS).until(() -> {
ResponseEntityView<ContentType> updateContentTypeResponse = getUpdateContentTypeResponse(
Expand Down Expand Up @@ -623,8 +671,8 @@ void Test_Send_Invalid_Host_And_Folder_Verify_Defaults() {
.build()
).build();

final SaveContentTypeRequest saveRequest = SaveContentTypeRequest.builder().
from(contentType1).build();
final SaveContentTypeRequest saveRequest = AbstractSaveContentTypeRequest.builder().
of(contentType1).build();

final ResponseEntityView<List<ContentType>> contentTypeResponse1 = client.createContentTypes(List.of(saveRequest));
Assertions.assertNotNull(contentTypeResponse1);
Expand Down Expand Up @@ -670,8 +718,8 @@ void Test_Send_Folder_Path_Only_Valid_Folder_Expect_Matching_Folder_Id() {
.build()
).build();

final SaveContentTypeRequest saveRequest = SaveContentTypeRequest.builder().
from(contentType1).build();
final SaveContentTypeRequest saveRequest = AbstractSaveContentTypeRequest.builder()
.of(contentType1).build();

final ResponseEntityView<List<ContentType>> contentTypeResponse2 = client.createContentTypes(List.of(saveRequest));
Assertions.assertNotNull(contentTypeResponse2);
Expand Down Expand Up @@ -718,8 +766,8 @@ void Test_Create_Content_Type_Out_Of_Folder_Path() {
.build()
).build();

final SaveContentTypeRequest saveRequest = SaveContentTypeRequest.builder().
from(contentType2).build();
final SaveContentTypeRequest saveRequest = AbstractSaveContentTypeRequest.builder().
of(contentType2).build();

final ResponseEntityView<List<ContentType>> contentTypeResponse2 = client.createContentTypes(List.of(saveRequest));
Assertions.assertNotNull(contentTypeResponse2);
Expand Down Expand Up @@ -770,8 +818,8 @@ void Test_ContentType_Without_Layout_Attribute() {

final ContentTypeAPI client = apiClientFactory.getClient(ContentTypeAPI.class);

final SaveContentTypeRequest saveRequest = SaveContentTypeRequest.builder().
from(contentType).build();
final SaveContentTypeRequest saveRequest = AbstractSaveContentTypeRequest.builder().
of(contentType).build();

final ResponseEntityView<List<ContentType>> contentTypeResponse = client.createContentTypes(List.of(saveRequest));
Assertions.assertNotNull(contentTypeResponse);
Expand Down Expand Up @@ -865,8 +913,8 @@ void Test_ContentType_Layout_Attribute_Is_Ignored() {

final ContentTypeAPI client = apiClientFactory.getClient(ContentTypeAPI.class);

final SaveContentTypeRequest saveRequest = SaveContentTypeRequest.builder().
from(contentType).build();
final SaveContentTypeRequest saveRequest = AbstractSaveContentTypeRequest.builder().
of(contentType).build();

final ResponseEntityView<List<ContentType>> contentTypeResponse = client.createContentTypes(List.of(saveRequest));
Assertions.assertNotNull(contentTypeResponse);
Expand Down Expand Up @@ -949,8 +997,8 @@ void Simple_Relationship_Support_Test() throws IOException {

final ContentTypeAPI client = apiClientFactory.getClient(ContentTypeAPI.class);

final SaveContentTypeRequest saveBlogRequest = SaveContentTypeRequest.builder().
from(blog).build();
final SaveContentTypeRequest saveBlogRequest = AbstractSaveContentTypeRequest.builder().
of(blog).build();
final ResponseEntityView<List<ContentType>> contentTypeResponse1 = client.createContentTypes(List.of(saveBlogRequest));
ContentType savedContentType1 = null;
ContentType savedContentType2 = null;
Expand All @@ -973,8 +1021,8 @@ void Simple_Relationship_Support_Test() throws IOException {
//Assertions.assertTrue(relationships1.isParentField());
Assertions.assertEquals("MyBlogComment" + timeMark, relationships1.velocityVar());

final SaveContentTypeRequest saveBlogCommentRequest = SaveContentTypeRequest.builder().
from(blogComment).build();
final SaveContentTypeRequest saveBlogCommentRequest = AbstractSaveContentTypeRequest.builder().
of(blogComment).build();
final ResponseEntityView<List<ContentType>> contentTypeResponse2 = client.createContentTypes(
List.of(saveBlogCommentRequest));
final List<ContentType> contentTypes2 = contentTypeResponse2.entity();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.dotcms.api.client.push.PushHandler;
import com.dotcms.api.client.util.NamingUtils;
import com.dotcms.contenttype.model.type.ContentType;
import com.dotcms.model.contenttype.AbstractSaveContentTypeRequest;
import com.dotcms.model.contenttype.SaveContentTypeRequest;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.context.control.ActivateRequestContext;
Expand Down Expand Up @@ -61,8 +62,8 @@ public ContentType add(File localFile, ContentType localContentType,

final ContentTypeAPI contentTypeAPI = clientFactory.getClient(ContentTypeAPI.class);

final SaveContentTypeRequest saveRequest = SaveContentTypeRequest.builder().
from(localContentType).build();
final SaveContentTypeRequest saveRequest = AbstractSaveContentTypeRequest.builder()
.of(localContentType).build();
final var response = contentTypeAPI.createContentTypes(List.of(saveRequest));

return response.entity().stream()
Expand All @@ -78,8 +79,8 @@ public ContentType edit(File localFile, ContentType localContentType,

final ContentTypeAPI contentTypeAPI = clientFactory.getClient(ContentTypeAPI.class);

final SaveContentTypeRequest saveRequest = SaveContentTypeRequest.builder().
from(localContentType).build();
final SaveContentTypeRequest saveRequest = AbstractSaveContentTypeRequest.builder()
.of(localContentType).build();
final var response = contentTypeAPI.updateContentType(localContentType.variable(),
saveRequest);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2345,6 +2345,66 @@ void Test_Command_Content_Find_Authenticated_With_Token() {
}
}

/**
* Given scenario: Testing the Content Type push command and checking the base type.
* Expected Result: The base type on the server should the same as the one on the descriptor before
* and after the push operation.
*
* @throws IOException if an I/O error occurs during the execution of the test
*/
@Test
void Test_Push_Content_Type_Update_Checking_Base_Type() throws IOException {

// Create a temporal folder for the workspace
var tempFolder = createTempFolder();
final Workspace workspace = workspaceManager.getOrCreate(tempFolder);

final CommandLine commandLine = createCommand();
final StringWriter writer = new StringWriter();
try (PrintWriter out = new PrintWriter(writer)) {

commandLine.setOut(out);
commandLine.setErr(out);

// ╔══════════════════════╗
// ║ Preparing the data ║
// ╚══════════════════════╝
// Creating a HTML page content type file descriptor
final var newContentTypeResult = contentTypesTestHelper.createPageContentTypeDescriptor(
workspace
);

// ╔════════════════════════════════════════════════════════════╗
// ║ Pushing the descriptor for the just created Content Type ║
// ╚════════════════════════════════════════════════════════════╝
var status = commandLine.execute(ContentTypeCommand.NAME, ContentTypePush.NAME,
workspace.contentTypes().toAbsolutePath().toString(),
"--fail-fast", "-e");
Assertions.assertEquals(CommandLine.ExitCode.OK, status);

// ╔════════════════════════════════════════════╗
// ║ Validating the information on the server ║
// ╚════════════════════════════════════════════╝
var byVarName = contentTypesTestHelper.findContentType(newContentTypeResult.variable());
Assertions.assertTrue(byVarName.isPresent());
Assertions.assertEquals(BaseContentType.HTMLPAGE, byVarName.get().baseType());

// ---
// Now validating the auto update updated the content type descriptor
var updatedContentTypeDescriptor = this.mapperService.map(
newContentTypeResult.path().toFile(),
ContentType.class
);
Assertions.assertNotNull(updatedContentTypeDescriptor.fields());
Assertions.assertEquals(
BaseContentType.HTMLPAGE, updatedContentTypeDescriptor.baseType()
);

} finally {
deleteTempDirectory(tempFolder);
}
}

/**
* Function to verify if a list of strings is sorted in ascending order (case-insensitive)
*
Expand Down
Loading

0 comments on commit c12d848

Please sign in to comment.