Skip to content

Commit

Permalink
fix:[news] '#' glitches the filter - EXO-65188
Browse files Browse the repository at this point in the history
Prior to this change, when create a tag in article and go to news app make a search for that tag(# followed by tag name), there is no filter applied, the display remain the same. After this change, return results with the searched tag.
  • Loading branch information
akhanfir committed Aug 9, 2023
1 parent 5ddd3e9 commit d98e19e
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 25 deletions.
2 changes: 1 addition & 1 deletion services/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<rest.api.doc.version>1.0</rest.api.doc.version>
<rest.api.doc.description>News addon used Rest endpoints</rest.api.doc.description>

<exo.test.coverage.ratio>0.41</exo.test.coverage.ratio>
<exo.test.coverage.ratio>0.44</exo.test.coverage.ratio>
</properties>

<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,17 @@ public StringBuilder buildQuery(NewsFilter filter) throws Exception {
String escapedQuoteFuzzyText = fuzzyText.replace("'", "''").replace("\"", "\"\"");
String escapedQuoteSearchText = filter.getSearchText().replace("'", "''").replace("\"", "\"\"");
sqlQuery.append("(CONTAINS(.,'").append(escapedQuoteFuzzyText).append("') OR (exo:body LIKE '%").append(escapedQuoteSearchText).append("%'))");
if (filter.getTagNames() != null && !filter.getTagNames().isEmpty()){
sqlQuery.append(" OR (");
sqlQuery.append("AND ");
} else {
if (filter.getTagNames() != null && !filter.getTagNames().isEmpty()) {
for (String tagName : filter.getTagNames()) {
sqlQuery.append(" exo:body LIKE '%#").append(tagName).append("%'");
if (filter.getTagNames().indexOf(tagName) != filter.getTagNames().size() -1) {
if (filter.getTagNames().indexOf(tagName) != filter.getTagNames().size() - 1) {
sqlQuery.append(" OR");
}
}
sqlQuery.append(" ) AND ");
} else sqlQuery.append("AND ");
sqlQuery.append(" AND ");
}
}
if (filter.isPublishedNews()) {
sqlQuery.append("exo:pinned = 'true' AND ");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,8 +483,12 @@ public Response getNews(@Context HttpServletRequest request,
String lang = request.getLocale().getLanguage();
TagService tagService = CommonsUtils.getService(TagService.class);
long userIdentityId = RestUtils.getCurrentUserIdentityId();
List<TagName> tagNames = tagService.findTags(new TagFilter(text, 0), userIdentityId);
if (tagNames != null && !tagNames.isEmpty()) newsFilter.setTagNames(tagNames.stream().map(e -> e.getName()).toList());
if (text.indexOf("#") == 0) {
String tagName = text.replace("#","");
List<TagName> tagNames = tagService.findTags(new TagFilter(tagName, 0), userIdentityId);
if (tagNames != null && !tagNames.isEmpty()) newsFilter.setTagNames(tagNames.stream().map(e -> e.getName()).toList());
}

news = newsService.searchNews(newsFilter, lang);
} else {
org.exoplatform.services.security.Identity currentIdentity = ConversationState.getCurrent().getIdentity();
Expand Down Expand Up @@ -1008,7 +1012,7 @@ private NewsFilter buildFilter(List<String> spaces, String filter, String text,
}
}
// Set text to search news with
if (StringUtils.isNotEmpty(text)) {
if (StringUtils.isNotEmpty(text) && text.indexOf("#") != 0) {
newsFilter.setSearchText(text);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.exoplatform.commons.utils.CommonsUtils;
import org.exoplatform.social.core.identity.model.Identity;
import org.exoplatform.social.core.identity.provider.OrganizationIdentityProvider;
import org.exoplatform.social.core.manager.IdentityManager;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.MockitoJUnitRunner;

Expand All @@ -20,19 +23,17 @@
import org.exoplatform.services.security.ConversationState;
import org.exoplatform.services.security.MembershipEntry;
import org.exoplatform.social.core.space.model.Space;
import org.exoplatform.social.core.space.spi.SpaceService;

@RunWith(MockitoJUnitRunner.class)
public class NewsQueryBuilderTest {

private static final MockedStatic<NewsUtils> NEWS_UTILS = mockStatic(NewsUtils.class);

@Mock
SpaceService spaceService;
private static final MockedStatic<CommonsUtils> COMMONS_UTILS = mockStatic(CommonsUtils.class);

@AfterClass
public static void afterRunBare() throws Exception { // NOSONAR
NEWS_UTILS.close();
COMMONS_UTILS.close();
}

@Test
Expand All @@ -48,20 +49,31 @@ public void shouldCreateQueryWithPinnedStateAndSearchTextAndAuthorAndOneSpaceAnd
List<String> spaces = new ArrayList<>();
spaces.add("1");
filter.setSpaces(spaces);
filter.setDraftNews(true);
Space space1 = new Space();
space1.setId("1");
List<Space> allowedDraftNewsSpaces = new ArrayList<>();
allowedDraftNewsSpaces.add(space1);
NEWS_UTILS.when(() -> NewsUtils.getAllowedDraftNewsSpaces(any())).thenReturn(allowedDraftNewsSpaces);
Identity identity = new Identity(OrganizationIdentityProvider.NAME, "jean");
identity.setRemoteId("jean");
org.exoplatform.services.security.Identity currentIdentity = new org.exoplatform.services.security.Identity("john");
MembershipEntry membershipentry = new MembershipEntry("/platform/web-contributors", "redactor");
List<MembershipEntry> memberships = new ArrayList<MembershipEntry>();
memberships.add(membershipentry);
currentIdentity.setMemberships(memberships);
ConversationState state = new ConversationState(currentIdentity);
ConversationState.setCurrent(state);
IdentityManager identityMock = mock(IdentityManager.class);
COMMONS_UTILS.when(() -> CommonsUtils.getService(IdentityManager.class)).thenReturn(identityMock);
when(identityMock.getOrCreateIdentity(anyString(), anyString())).thenReturn(identity);

// when
StringBuilder query = queryBuilder.buildQuery(filter);

// then
assertNotNull(query);
assertEquals("SELECT * FROM exo:news WHERE ( exo:archived IS NULL OR exo:archived = 'false' OR ( exo:archived = 'true' AND exo:author = 'john')) AND (CONTAINS(.,'text~0.6') OR (exo:body LIKE '%text%')) OR ( exo:body LIKE '%#text%' OR exo:body LIKE '%#tex%' ) AND exo:pinned = 'true' AND ( exo:spaceId = '1') AND exo:author = 'john' AND (publication:currentState = 'published' OR (publication:currentState = 'draft' AND exo:activities <> '' )) AND jcr:path LIKE '/Groups/spaces/%' ORDER BY jcr:score DESC",
assertEquals("SELECT * FROM exo:news WHERE ( exo:archived IS NULL OR exo:archived = 'false' OR ( exo:archived = 'true' AND exo:author = 'john')) AND (CONTAINS(.,'text~0.6') OR (exo:body LIKE '%text%'))AND exo:pinned = 'true' AND ( exo:spaceId = '1') AND publication:currentState = 'draft' AND (('null' IN exo:newsModifiersIds AND exo:activities <> '') OR ( exo:author = 'john' AND exo:activities = '')OR (exo:spaceId = '1') AND exo:draftVisible = 'true') AND jcr:path LIKE '/Groups/spaces/%' ORDER BY jcr:score DESC",
query.toString());
}

Expand Down Expand Up @@ -221,6 +233,27 @@ public void shouldCreateQueryWithNoFilter() throws Exception {
assertNotNull(query);
assertEquals("SELECT * FROM exo:news WHERE ", query.toString());
}

@Test
public void testBuildQueryWithTagNames() throws Exception {
// Given
NewsQueryBuilder queryBuilder = new NewsQueryBuilder();
org.exoplatform.services.security.Identity currentIdentity = new org.exoplatform.services.security.Identity("john");
ConversationState state = new ConversationState(currentIdentity);
ConversationState.setCurrent(state);
NewsFilter filter = new NewsFilter();
filter.setAuthor("john");
filter.setTagNames(Arrays.asList(new String[]{"text"}));

// when
StringBuilder query = queryBuilder.buildQuery(filter);

// then
assertNotNull(query);
assertEquals("SELECT * FROM exo:news WHERE ( exo:archived IS NULL OR exo:archived = 'false' OR ( exo:archived = 'true' AND exo:author = 'john')) AND exo:body LIKE '%#text%' AND exo:author = 'john' AND (publication:currentState = 'published' OR (publication:currentState = 'draft' AND exo:activities <> '' )) AND jcr:path LIKE '/Groups/spaces/%' ORDER BY null DESC",
query.toString());
}

@Test
public void shouldAddFuzzySyntaxWhitQuotedWord() throws Exception {
// Given
Expand All @@ -232,7 +265,7 @@ public void shouldAddFuzzySyntaxWhitQuotedWord() throws Exception {

// Then
assertNotNull(result);
assertEquals(result, "\"quoted\"~0.6");
assertEquals("\"quoted\"~0.6", result);
}

@Test
Expand All @@ -246,7 +279,7 @@ public void shouldAddFuzzySyntaxWhenTextContainsMultiWords() throws Exception {

// Then
assertNotNull(result);
assertEquals(result, "search~0.6 OR text~0.6");
assertEquals("search~0.6 OR text~0.6", result);
}

@Test
Expand All @@ -260,7 +293,7 @@ public void shouldAddFuzzySyntaxWhenTextContainsQuotedMultiWords() throws Except

// Then
assertNotNull(result);
assertEquals(result, "\"search text\"~0.6");
assertEquals("\"search text\"~0.6", result);
}
@Test
public void shouldAddFuzzySyntaxWhenTextContainsMultiWordsAndQuotedOne() throws Exception {
Expand All @@ -273,6 +306,19 @@ public void shouldAddFuzzySyntaxWhenTextContainsMultiWordsAndQuotedOne() throws

// Then
assertNotNull(result);
assertEquals(result, "this~0.6 OR is~0.6 OR a~0.6 OR \"search text\"~0.6");
assertEquals("this~0.6 OR is~0.6 OR a~0.6 OR \"search text\"~0.6", result);
}

@Test
public void testAddFuzzySyntaxAndORQuoteInsideQuote() {
// Given
NewsQueryBuilder queryBuilder = new NewsQueryBuilder();
String text = "This \"quoted\" text.";

// when
String result = queryBuilder.addFuzzySyntaxAndOR(text);

// then
assertEquals("This~0.6 OR \"quoted\"~0.6 OR text.~0.6", result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,6 @@ public void shouldGetAllNewsWhenSearchingWithTextInTheGivenSpaces() throws Excep
allNews.add(news3);
COMMONS_UTILS.when(()-> CommonsUtils.getService(TagService.class)).thenReturn(tagService);
REST_UTILS.when(()-> RestUtils.getCurrentUserIdentityId()).thenReturn(1L);
when(tagService.findTags(new TagFilter(text, 0), 1L)).thenReturn(new ArrayList<>());
lenient().when(newsService.searchNews(any(), any())).thenReturn(allNews);
lenient().when(spaceService.isMember(any(Space.class), any())).thenReturn(true);
lenient().when(spaceService.getSpaceById(anyString())).thenReturn(new Space());
Expand Down Expand Up @@ -1632,7 +1631,6 @@ public void shouldGetAllNewsWhenSearchingWithTextInTheGivenSpace() throws Except
allNews.add(news3);
COMMONS_UTILS.when(()-> CommonsUtils.getService(TagService.class)).thenReturn(tagService);
REST_UTILS.when(()-> RestUtils.getCurrentUserIdentityId()).thenReturn(1L);
when(tagService.findTags(new TagFilter(text, 0), 1L)).thenReturn(new ArrayList<>());
lenient().when(newsService.searchNews(any(), any())).thenReturn(allNews);
lenient().when(spaceService.isMember(any(Space.class), any())).thenReturn(true);
lenient().when(spaceService.getSpaceById(anyString())).thenReturn(new Space());
Expand Down Expand Up @@ -1681,7 +1679,6 @@ public void shouldGetAllNewsWhenSearchingWithTagTextInTheGivenSpace() throws Exc
allNews.add(news2);
COMMONS_UTILS.when(()-> CommonsUtils.getService(TagService.class)).thenReturn(tagService);
REST_UTILS.when(()-> RestUtils.getCurrentUserIdentityId()).thenReturn(1L);
when(tagService.findTags(new TagFilter(tagText, 0), 1L)).thenReturn(Arrays.asList(new TagName("tagText")));
lenient().when(newsService.searchNews(any(), any())).thenReturn(allNews);
lenient().when(spaceService.isMember(any(Space.class), any())).thenReturn(true);
lenient().when(spaceService.getSpaceById(anyString())).thenReturn(new Space());
Expand Down Expand Up @@ -1733,7 +1730,6 @@ public void shouldGetPinnedNewsWhenSearchingWithTextInTheGivenSpaces() throws Ex
allNews.add(news3);
COMMONS_UTILS.when(()-> CommonsUtils.getService(TagService.class)).thenReturn(tagService);
REST_UTILS.when(()-> RestUtils.getCurrentUserIdentityId()).thenReturn(1L);
when(tagService.findTags(new TagFilter(text, 0), 1L)).thenReturn(new ArrayList<>());
lenient().when(newsService.searchNews(any(), any())).thenReturn(allNews);
lenient().when(spaceService.isMember(any(Space.class), any())).thenReturn(true);
lenient().when(spaceService.getSpaceById(anyString())).thenReturn(new Space());
Expand Down Expand Up @@ -1918,7 +1914,6 @@ public void shouldGetMyPostedNewsWhenSearchingWithTheGivenSpaces() throws Except
allNews.add(news3);
COMMONS_UTILS.when(()-> CommonsUtils.getService(TagService.class)).thenReturn(tagService);
REST_UTILS.when(()-> RestUtils.getCurrentUserIdentityId()).thenReturn(1L);
when(tagService.findTags(new TagFilter(text, 0), 1L)).thenReturn(new ArrayList<>());
lenient().when(newsService.searchNews(any(), any())).thenReturn(allNews);
lenient().when(spaceService.isMember(any(Space.class), any())).thenReturn(true);
lenient().when(spaceService.getSpaceById(anyString())).thenReturn(new Space());
Expand Down
3 changes: 3 additions & 0 deletions webapp/src/main/webapp/services/newsServices.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ export function markNewsAsRead(newsId){
export function getNews(filter, spaces, searchText, offset, limit, returnSize) {
let url = `${newsConstants.NEWS_API}?author=${newsConstants.userName}&publicationState=published&filter=${filter}`;
if (searchText) {
if (searchText.indexOf('#') === 0) {
searchText = searchText.replace('#', '%23');
}
url += `&text=${searchText}`;
}
if (spaces) {
Expand Down

0 comments on commit d98e19e

Please sign in to comment.