Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Communication: Add answer posts content to course wide search #9638

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ public static Specification<Post> getConversationSpecification(Long conversation
}

/**
* Specification which filters Messages according to a search string in a match-all-manner
* message is only kept if the search string (which is not a #id pattern) is included in the message content (all strings lowercased)
* Specification which filters Messages and answer posts according to a search string in a match-all-manner
* message and answer post are only kept if the search string (which is not a #id pattern) is included in the message content (all strings lowercased)
*
* @param searchText Text to be searched within messages
* @return specification used to chain DB operations
Expand All @@ -60,8 +60,10 @@ else if (searchText.startsWith("#") && StringUtils.isNumeric(searchText.substrin
Expression<String> searchTextLiteral = criteriaBuilder.literal("%" + searchText.toLowerCase() + "%");

Predicate searchInMessageContent = criteriaBuilder.like(criteriaBuilder.lower(root.get(Post_.CONTENT)), searchTextLiteral);
Join<Post, AnswerPost> answersJoin = root.join(Post_.ANSWERS, JoinType.LEFT);
Predicate searchInAnswerContent = criteriaBuilder.like(criteriaBuilder.lower(answersJoin.get(AnswerPost_.CONTENT)), searchTextLiteral);

return criteriaBuilder.and(searchInMessageContent);
return criteriaBuilder.or(searchInMessageContent, searchInAnswerContent);
cremertim marked this conversation as resolved.
Show resolved Hide resolved
}
});
}
Expand Down Expand Up @@ -102,7 +104,7 @@ public static Specification<Post> getCourseWideChannelsSpecification(Long course
}

/**
* Specification to fetch Posts of the calling user
* Specification to fetch Posts and answer posts of the calling user
*
* @param filterToOwn whether only calling users own Posts should be fetched or not
* @param userId id of the calling user
Expand All @@ -114,7 +116,10 @@ public static Specification<Post> getOwnSpecification(boolean filterToOwn, Long
return null;
}
else {
return criteriaBuilder.equal(root.get(Post_.AUTHOR).get(User_.ID), userId);
Join<Post, AnswerPost> answersJoin = root.join(Post_.ANSWERS, JoinType.LEFT);
Predicate searchInAnswerContent = criteriaBuilder.equal(answersJoin.get(AnswerPost_.AUTHOR).get(User_.ID), userId);
Predicate isPostOwner = criteriaBuilder.equal(root.get(Post_.AUTHOR).get(User_.ID), userId);
return criteriaBuilder.or(isPostOwner, searchInAnswerContent);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;

import de.tum.cit.aet.artemis.communication.domain.AnswerPost;
import de.tum.cit.aet.artemis.communication.domain.ConversationParticipant;
import de.tum.cit.aet.artemis.communication.domain.DisplayPriority;
import de.tum.cit.aet.artemis.communication.domain.Post;
Expand Down Expand Up @@ -520,6 +521,51 @@ void testGetCourseWideMessagesFromOneChannel() throws Exception {
assertThat(returnedPosts.size()).isLessThan(courseWidePosts.size());
}

@Test
@WithMockUser(username = TEST_PREFIX + "student1", roles = "USER")
void testGetCourseWideMessages_WithOwnWithCourseWideContentAndSearchText() throws Exception {
// conversation set will fetch all posts of conversation if the user is involved
var params = new LinkedMultiValueMap<String, String>();
var courseWidePosts = existingConversationMessages.stream().filter(post -> post.getConversation() instanceof Channel channel && channel.getIsCourseWide()).toList();
var courseWideChannelId = courseWidePosts.getFirst().getConversation().getId();
params.add("courseWideChannelIds", courseWideChannelId.toString());
params.add("filterToOwn", "true");
params.add("size", "50");
params.add("searchText", "Content");

List<Post> returnedPosts = request.getList("/api/courses/" + courseId + "/messages", HttpStatus.OK, Post.class, params);
// get amount of posts with that certain
assertThat(returnedPosts).hasSize(existingCourseWideMessages.stream().filter(post -> post.getConversation().getId().equals(courseWideChannelId)
&& post.getAuthor().getLogin().equals(TEST_PREFIX + "student1") && (post.getContent().contains("Content") || answerHasContext(post.getAnswers(), "Content")))
.toList().size());
assertThat(returnedPosts.size()).isLessThan(courseWidePosts.size());
}

private boolean answerHasContext(Set<AnswerPost> answers, String searchText) {
return answers.stream().anyMatch(answerPost -> answerPost.getContent().contains(searchText));
}

@Test
@WithMockUser(username = TEST_PREFIX + "student1", roles = "USER")
void testGetCourseWideMessages_WithOwnWithCourseWideContentAndSearchTextInAnswer() throws Exception {
// conversation set will fetch all posts of conversation if the user is involved
var params = new LinkedMultiValueMap<String, String>();
var courseWidePosts = existingConversationMessages.stream().filter(post -> post.getConversation() instanceof Channel channel && channel.getIsCourseWide()).toList();
var courseWideChannelId = courseWidePosts.getFirst().getConversation().getId();
courseWidePosts.getFirst().getAnswers().forEach(answer -> answer.setContent("AnswerPost"));
params.add("courseWideChannelIds", courseWideChannelId.toString());
params.add("filterToOwn", "true");
params.add("size", "50");
params.add("searchText", "Answer");

List<Post> returnedPosts = request.getList("/api/courses/" + courseId + "/messages", HttpStatus.OK, Post.class, params);
// get amount of posts with that certain
assertThat(returnedPosts).hasSize(existingCourseWideMessages.stream().filter(post -> post.getConversation().getId().equals(courseWideChannelId)
&& post.getAuthor().getLogin().equals(TEST_PREFIX + "student1") && (post.getContent().contains("answer") || answerHasContext(post.getAnswers(), "Content")))
.toList().size());
assertThat(returnedPosts.size()).isLessThan(courseWidePosts.size());
}
cremertim marked this conversation as resolved.
Show resolved Hide resolved

@Test
@WithMockUser(username = TEST_PREFIX + "tutor1")
void testEditConversationPost() throws Exception {
Expand Down
Loading