Skip to content

Commit

Permalink
feat(Edit Mode) #30799 : Fixing error reported via IQA
Browse files Browse the repository at this point in the history
  • Loading branch information
jcastro-dotcms committed Feb 27, 2025
1 parent ec86c40 commit 5deb5f1
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 23 deletions.
25 changes: 25 additions & 0 deletions dotCMS/src/main/java/com/dotcms/rest/SearchView.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
package com.dotcms.rest;

/**
* This View contains the results of searching for Contentlets in dotCMS. It's used by several
* content search REST Endpoints in order to provide Users the results, and additional information
* related to the execution of the query per se.
*
* @author Jonathan Sanchez
* @since Oct 9th, 2020
*/
public class SearchView {

private final long resultsSize;
private final long queryTook;
private final long contentTook;
private final JsonObjectView jsonObjectView;

/**
* Creates an instance of this View class with the results returned from a content query, and
* additional search metadata.
*
* @param resultsSize The total number of results that are pulled from the query <b>WITHOUT
* taking pagination into account</b>. For instance, if you're pulling 10
* results per result page, but your query matches 35 results total, this
* value will be 35.
* @param queryTook Represents the time in milliseconds that dotCMS needed to retrieve the
* total number of results being returned by the query.
* @param contentTook Represents the time in milliseconds that dotCMS needed to retrieve the
* actual results and transform them into the appropriate JSON
* representation.
* @param jsonObjectView Contains the actual list of returned Contentlets in the appropriate
* JSON format, in the form of a {@link JsonObjectView} object.
*/
public SearchView(final long resultsSize,
final long queryTook,
final long contentTook,
Expand All @@ -33,4 +57,5 @@ public long getContentTook() {
public JsonObjectView getJsonObjectView() {
return jsonObjectView;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public static void registerHandler(final Set<Class<? extends Field>> fieldTypes,
final FieldStrategy strategy = FieldStrategyFactory.getStrategy(fieldHandlerId);
fieldTypes.forEach(fieldType -> handlers.put(fieldType,
context -> strategy.checkRequiredValues(context)
? strategy.generateQuery(context)
? strategy.generateQuery(context).trim()
: BLANK));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public String generateQuery(final FieldContext queryContext) {
.map(Object::toString)
.map(String::trim)
.collect(Collectors.joining(" OR "));
return luceneQuery.append("+").append(fieldName).append(":(").append(value).append(")").toString().trim();
return luceneQuery.append("+").append(fieldName).append(":(").append(value).append(")").toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public String generateQuery(final FieldContext fieldContext) {
value = value.replaceAll("\\*", "");
value = value.replaceAll(SPECIAL_CHARS_TO_ESCAPE, "\\\\$1");
luceneQuery.append("title:").append(value).append("*");
return luceneQuery.toString().trim();
return luceneQuery.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public String generateQuery(final FieldContext fieldContext) {
? this.getRelatedIdentifiers(currentUser, offset, sortBy, fieldValue, childRelationship.get())
: new ArrayList<>();
return UtilMethods.isSet(relatedContent)
? String.join(",", relatedContent).trim()
? String.join(",", relatedContent)
: "+" + fieldName + ":" + fieldValue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.dotcms.rest.api.v1.content.search.handlers.FieldContext;
import com.dotmarketing.util.UtilMethods;

import java.util.Objects;

import static com.dotmarketing.beans.Host.SYSTEM_HOST;
import static com.liferay.util.StringPool.BLANK;

Expand All @@ -20,28 +22,32 @@ public class SiteAttributeStrategy implements FieldStrategy {

@Override
public boolean checkRequiredValues(final FieldContext fieldContext) {
return (null != fieldContext.fieldValue() && !fieldContext.fieldValue().toString().isEmpty())
|| (boolean) fieldContext.extraParams().getOrDefault("systemHostContent", true);
return true;
}

@Override
public String generateQuery(final FieldContext queryContext) {
final String fieldName = queryContext.fieldName();
final Object fieldValue = queryContext.fieldValue();
if (Objects.isNull(fieldValue) || UtilMethods.isNotSet(fieldValue.toString())) {
return BLANK;
}
final boolean includeSystemHostContent = (boolean) queryContext.extraParams().getOrDefault("systemHostContent", true);
final String value = UtilMethods.isSet(fieldValue) && !fieldValue.toString().isEmpty()
final String value = UtilMethods.isSet(fieldValue.toString())
? fieldValue.toString()
: includeSystemHostContent
? SYSTEM_HOST
: BLANK;
final StringBuilder luceneQuery = new StringBuilder();
if (includeSystemHostContent && UtilMethods.isSet(value) && !value.equals(SYSTEM_HOST)) {
luceneQuery.append("+(").append(fieldName).append(":").append(value)
.append(" ").append(fieldName).append(":").append(SYSTEM_HOST).append(")");
luceneQuery.append("+(")
.append(fieldName).append(":").append(value).append(" ")
.append(fieldName).append(":").append(SYSTEM_HOST)
.append(")");
} else if (UtilMethods.isSet(value)) {
luceneQuery.append("+").append(fieldName).append(":").append(value).append(!value.equals(SYSTEM_HOST) ? "*" : BLANK);
}
return luceneQuery.toString().trim();
return luceneQuery.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public String generateQuery(final FieldContext fieldContext) {
luceneQuery.append("+").append(fieldName).append(":")
.append(valueDelimiter).append(valueForQuery).append(valueDelimiter).append(SPACE);
}
return luceneQuery.toString().trim();
return luceneQuery.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public String generateQuery(final FieldContext fieldContext) {
fieldName, finalWildcard, token, finalWildcard))
.collect(Collectors.joining(SPACE));
}
return luceneQuery.trim();
return luceneQuery;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"info": {
"_postman_id": "148b5d29-ef10-41d7-9628-5141da636109",
"_postman_id": "dd2afcb5-bb50-4718-acce-83a05dd215c6",
"name": "Content Resource",
"description": "Content Resource test",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
Expand Down Expand Up @@ -5129,6 +5129,141 @@
"description": "Creates a test Contentlet of the previously generated Content Type."
},
"response": []
},
{
"name": "Test Site",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Test Site created successfully\", function () {",
" var jsonData = pm.response.json();",
" pm.collectionVariables.set(\"testSiteName\", jsonData.entity.siteName);",
" pm.expect(jsonData.entity.siteName).to.eql('www.mytestsiteforcontentsearch.com');",
"});",
""
],
"type": "text/javascript",
"packages": {}
}
}
],
"request": {
"auth": {
"type": "basic",
"basic": [
{
"key": "password",
"value": "admin",
"type": "string"
},
{
"key": "username",
"value": "[email protected]",
"type": "string"
}
]
},
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"siteName\":\"www.mytestsiteforcontentsearch.com\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{serverURL}}/api/v1/site",
"host": [
"{{serverURL}}"
],
"path": [
"api",
"v1",
"site"
]
}
},
"response": []
},
{
"name": "Parent Content 3 in test Site",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Test Third Parent Content created successfully\", function () {",
" const jsonData = pm.response.json();",
" pm.expect(jsonData.errors.length).to.eql(0, \"An error occurred when creating the Test Third Parent Content\");",
" const testContentId = jsonData.entity.identifier;",
" pm.collectionVariables.set(\"testThirdParentContentId\", testContentId);",
"});",
""
],
"type": "text/javascript",
"packages": {}
}
},
{
"listen": "prerequest",
"script": {
"exec": [
"const randomNumber = Math.floor(Math.random() * (999 - 100 + 1) + 100);",
"pm.collectionVariables.set(\"randomNumber\", randomNumber);",
""
],
"type": "text/javascript",
"packages": {}
}
}
],
"request": {
"method": "PUT",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "resources/testpdf.pdf"
},
{
"key": "json",
"value": "{\n \"contentlet\":\n {\n \"contentType\": \"{{testContentTypeVarName}}\",\n \"site\": \"{{testSiteName}}\",\n \"blockEditor\": \"Third Block editor\",\n \"category\": \"{{testCategoryOneInode}}\",\n \"checkbox\": \"1\",\n \"custom\": \"Third custom\",\n \"date\": \"02/27/2025\",\n \"dateAndTime\": \"02/27/2025 16:25:00\",\n \"json\": \"{ \\\"jsonThirdKey\\\": \\\"Third JSON value\\\" }\",\n \"keyValue\": \"{ \\\"thirdKey\\\": \\\"Third value\\\" }\",\n \"multiSelect\": \"1\",\n \"radio\": \"1\",\n \"relationships\": \"+identifier:{{testFirstChildContentId}}\",\n \"select\": \"1\",\n \"tag\": \"{{testTagOne}}\",\n \"title\": \"Test Third Parent Content{{randomNumber}}\",\n \"textArea\": \"Third text area\",\n \"time\": \"7:30:00\",\n \"wysiwyg\": \"Third WYSIWYG\"\n }\n}",
"type": "text"
}
]
},
"url": {
"raw": "{{serverURL}}/api/v1/workflow/actions/default/fire/PUBLISH?indexPolicy=WAIT_FOR",
"host": [
"{{serverURL}}"
],
"path": [
"api",
"v1",
"workflow",
"actions",
"default",
"fire",
"PUBLISH"
],
"query": [
{
"key": "indexPolicy",
"value": "WAIT_FOR"
}
]
},
"description": "Creates a test Contentlet of the previously generated Content Type."
},
"response": []
}
],
"description": "Generating test data for these tests. This part of the verification process includes:\n\n- Creating a test Contentlet that lives under System Host.",
Expand Down Expand Up @@ -5240,19 +5375,28 @@
"name": "Test Content Type",
"item": [
{
"name": "By System Host - Default",
"name": "In ALL Sites",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Test Sytem Content matched successfully\", function () {",
"pm.test(\"Test Parent Contents -- including System Host content -- matched successfully\", function () {",
" const jsonData = pm.response.json();",
" const entity = jsonData.entity;",
" const testSystemContentId = pm.collectionVariables.get(\"testSystemParentContentId\");",
" pm.expect(jsonData.errors.length).to.eql(0, \"An error occurred when retrieving the Test Sytem Content\");",
" pm.expect(entity.resultsSize).to.eql(1, \"One Contentlet should've been returned\");",
" pm.expect(entity.jsonObjectView.contentlets[0].identifier).to.eql(testSystemContentId, \"Test System Content ID should've been returned\");",
" const testFirstParentContentId = pm.collectionVariables.get(\"testFirstParentContentId\");",
" const testSecondParentContentId = pm.collectionVariables.get(\"testSecondParentContentId\");",
" const testSystemParentContentId = pm.collectionVariables.get(\"testSystemParentContentId\");",
" const testThirdParentContentId = pm.collectionVariables.get(\"testThirdParentContentId\");",
" pm.expect(jsonData.errors.length).to.eql(0, \"An error occurred when retrieving the Parent Contents\");",
" pm.expect(entity.resultsSize).to.eql(4, \"Four results should've been returned\");",
" var count = 0;",
" entity.jsonObjectView.contentlets.forEach(function(item) {",
" if (item.identifier == testFirstParentContentId || item.identifier == testSecondParentContentId || item.identifier == testSystemParentContentId || item.identifier == testThirdParentContentId) {",
" count += 1;",
" }",
" });",
" pm.expect(count).to.equal(4, \"The returned Contents are missing one or more of the 4 expected Contentlet IDs\");",
"});",
""
],
Expand All @@ -5266,7 +5410,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"searchableFieldsByContentType\": {\n \"{{testContentTypeVarName}}\": {}\n },\n \"systemSearchableFields\": {},\n \"page\": 0,\n \"perPage\": 40\n}",
"raw": "{\n \"searchableFieldsByContentType\": {\n \"{{testContentTypeVarName}}\": {}\n },\n \"page\": 0,\n \"perPage\": 40\n}",
"options": {
"raw": {
"language": "json"
Expand All @@ -5285,7 +5429,7 @@
"search"
]
},
"description": "When no `siteId` is specified, Contentlets living under System Host are returned by default **UNLESS** the `systemHostContent` attribute is set to `false`."
"description": "When no Site is specified, the Contentlets of the specified type in ALL Sites must be returned."
},
"response": []
},
Expand Down Expand Up @@ -5633,7 +5777,7 @@
"response": []
}
],
"description": "Retrieving Contentlets **of the specified Test Content Type** under a given Site.",
"description": "Retrieving Contentlets **of the specified Test Content Type** with the specified System Searchable attributes.",
"event": [
{
"listen": "prerequest",
Expand Down Expand Up @@ -6138,7 +6282,7 @@
"response": []
}
],
"description": "This new REST Endpoint uses the `ContentSearchForm` class to allow users to retrieve content by abstracting the complexity o creting their own Lucene queries for it. It's based on the same business rules as the `Search` portlet in the back-end.\n\nBy default, the Lucene query will include all Contentlets:\n\n- Living under system Host.\n \n- Live and Working.\n \n- Unarchived.\n \n\nIn case other business rules were missed or new ones must be included, it's very important to keep these test suite up to date with them.",
"description": "This new REST Endpoint uses the `ContentSearchForm` class to allow users to retrieve content by abstracting the complexity o creting their own Lucene queries for it. It's based on the same business rules as the `Search` portlet in the back-end.\n\nBy default, the Lucene query will include all Contentlets:\n\n- Living under system Host.\n \n- Live and Working.\n \n- Unarchived.\n \n- Locked and Unlocked.\n \n\nIn case other business rules were missed or new ones must be included, it's very important to keep these test suite up to date with them.",
"event": [
{
"listen": "prerequest",
Expand Down

0 comments on commit 5deb5f1

Please sign in to comment.