Skip to content

Commit

Permalink
Merge pull request #708 from bounswe/develop
Browse files Browse the repository at this point in the history
Deploy
  • Loading branch information
mmtftr authored Dec 16, 2024
2 parents c628604 + 4bae66e commit 5bb654b
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,45 +1,47 @@
package com.group1.programminglanguagesforum.Repositories;

import com.group1.programminglanguagesforum.Entities.DifficultyLevel;
import com.group1.programminglanguagesforum.Entities.Question;
import com.group1.programminglanguagesforum.Entities.User;
import java.util.List;
import java.util.Optional;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;
import com.group1.programminglanguagesforum.Entities.DifficultyLevel;
import com.group1.programminglanguagesforum.Entities.Question;
import com.group1.programminglanguagesforum.Entities.User;

@Repository
public interface QuestionRepository extends JpaRepository<Question, Long> {

@Query("SELECT q FROM Question q JOIN q.tags t WHERE t.id = :tagId order by q.likeCount desc ")
List<Question> findQuestionsByTagId(@Param("tagId") Long tagId);

@Query("SELECT DISTINCT q FROM Question q " +
"LEFT JOIN q.tags t " +
"WHERE (:query IS NULL OR " +
" LOWER(q.title) LIKE LOWER(CONCAT('%', :query, '%')) OR " +
" LOWER(q.questionBody) LIKE LOWER(CONCAT('%', :query, '%'))) " +
"AND (:tagIds IS NULL OR t.id IN :tagIds) " +
"AND (:difficulty IS NULL OR q.difficulty = :difficulty)")
@Query("SELECT DISTINCT q FROM Question q "
+ "LEFT JOIN q.tags t "
+ "WHERE (:query IS NULL OR "
+ " LOWER(q.title) LIKE LOWER(CONCAT('%', :query, '%')) OR "
+ " LOWER(q.questionBody) LIKE LOWER(CONCAT('%', :query, '%'))) "
+ "AND (:tagIds IS NULL OR t.id IN :tagIds) "
+ "AND (:difficulty IS NULL OR q.difficulty = :difficulty)")
Page<Question> searchQuestions(
@Param("query") String query,
@Param("tagIds") List<Long> tagIds,
@Param("difficulty") DifficultyLevel difficulty,
Pageable pageable);

@Query("SELECT DISTINCT q FROM Question q " +
"LEFT JOIN q.tags t " +
"WHERE (:query IS NULL OR " +
" LOWER(q.title) LIKE LOWER(CONCAT('%', :query, '%')) OR " +
" LOWER(q.questionBody) LIKE LOWER(CONCAT('%', :query, '%'))) " +
"AND (:tagIds IS NULL OR t.id IN :tagIds) " +
"AND (:difficulty IS NULL OR q.difficulty = :difficulty) " +
"ORDER BY " +
" CASE WHEN :authorIds IS NOT NULL AND q.askedBy.id IN :authorIds THEN 1 ELSE 0 END DESC")
@Query("SELECT DISTINCT q FROM Question q "
+ "LEFT JOIN q.tags t "
+ "WHERE (:query IS NULL OR "
+ " LOWER(q.title) LIKE LOWER(CONCAT('%', :query, '%')) OR "
+ " LOWER(q.questionBody) LIKE LOWER(CONCAT('%', :query, '%'))) "
+ "AND (:tagIds IS NULL OR t.id IN :tagIds) "
+ "AND (:difficulty IS NULL OR q.difficulty = :difficulty) "
+ "ORDER BY "
+ " CASE WHEN :authorIds IS NOT NULL AND q.askedBy.id IN :authorIds THEN 1 ELSE 0 END DESC")
Page<Question> searchQuestionsByRecommended(
@Param("query") String query,
@Param("authorIds") List<Long> authorIds,
Expand All @@ -52,5 +54,7 @@ Page<Question> searchQuestionsByRecommended(

@Query("SELECT q.askedBy FROM Question q WHERE q.id = :id")
Optional<User> findQuestionOwner(@Param("id") Long questionId);
}

@Query("SELECT q FROM Question q JOIN q.tags t WHERE t.id = :tagId AND q.difficulty = :difficulty order by q.likeCount desc limit 3")
List<Question> findQuestionsByDifficultyAndTagId(@Param("difficulty") DifficultyLevel difficulty, @Param("tagId") Long tagId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.group1.programminglanguagesforum.DTOs.Responses.SelfProfileResponseDto;
import com.group1.programminglanguagesforum.DTOs.Responses.TagDto;
import com.group1.programminglanguagesforum.Entities.ComputerScienceTermTag;
import com.group1.programminglanguagesforum.Entities.DifficultyLevel;
import com.group1.programminglanguagesforum.Entities.ProgrammingLanguagesTag;
import com.group1.programminglanguagesforum.Entities.ProgrammingParadigmTag;
import com.group1.programminglanguagesforum.Entities.Question;
Expand All @@ -35,6 +36,7 @@
@Service
@RequiredArgsConstructor
public class TagService {

private final TagRepository tagRepository;
private final ModelMapper modelMapper;
private final QuestionRepository questionRepository;
Expand Down Expand Up @@ -85,7 +87,7 @@ public GetTagDetailsResponseDto getTagDetails(Long tagId) {
}
Tag tagEntity = tag.get();
TagType tagType = getTagType(tagEntity);
List<Question> questions = questionRepository.findQuestionsByTagId(tagId);
List<Question> questions = questionRepository.findQuestionsByDifficultyAndTagId(DifficultyLevel.EASY, tagId);
List<QuestionSummaryDto> relatedQuestions = questions.stream()
.map(QuestionService::mapToQuestionSummary)
.toList();
Expand Down Expand Up @@ -141,11 +143,11 @@ public GetTagDetailsResponseDto getTagDetails(Long tagId) {
public List<SelfProfileResponseDto.FollowedTags> getFollowedTags(Long userId) {
return tagRepository.findTagByFollowers(userId).stream()
.map(tag -> SelfProfileResponseDto.FollowedTags.builder()
.id(tag.getId())
.name(tag.getTagName())
.tagType(getTagType(tag))
.description(tag.getTagDescription())
.build())
.id(tag.getId())
.name(tag.getTagName())
.tagType(getTagType(tag))
.description(tag.getTagDescription())
.build())
.toList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ void testGetTagDetails_Success() {

when(tagRepository.findById(tagId)).thenReturn(Optional.of(mockTag));
when(questionRepository.findQuestionsByTagId(tagId)).thenReturn(mockQuestions);
when(questionRepository.findQuestionsByDifficultyAndTagId(DifficultyLevel.EASY, tagId)).thenReturn(mockQuestions);

// Mocking modelMapper behavior
when(modelMapper.map(any(Question.class), eq(GetQuestionWithTagDto.class)))
Expand All @@ -161,7 +162,7 @@ void testGetTagDetails_Success() {
assertEquals("Description1", response.getDescription());
assertEquals(2, response.getRelatedQuestions().size());
verify(tagRepository, times(1)).findById(tagId);
verify(questionRepository, times(1)).findQuestionsByTagId(tagId);
verify(questionRepository, times(1)).findQuestionsByDifficultyAndTagId(DifficultyLevel.EASY, tagId);
}

@Test
Expand Down
11 changes: 6 additions & 5 deletions frontend/src/routes/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export default function Profile() {
)
)}
</div>
{profile.followedTags && (
{profile.followedTags && profile.followedTags.length > 0 ? (
<div className="flex flex-col">
<div className="flex flex-wrap gap-2">
<span className="flex items-center gap-2">
Expand All @@ -189,13 +189,14 @@ export default function Profile() {
</Link>
))
.slice(0, 3)}
{profile.followedTags?.length &&
profile.followedTags?.length > 3 && (
<span>+ {profile.followedTags?.length - 3} more</span>
)}
{profile.followedTags?.length > 3 && (
<span>+ {profile.followedTags?.length - 3} more</span>
)}
</span>
</div>
</div>
) : (
<div>No followed tags to show.</div>
)}
</div>
<div className="mt-4 flex flex-col gap-4 px-4 py-2">
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/tag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export default function TagPage() {
src={tag?.logoImage || "https://placehold.co/400x300"}
alt={`${tag.name} logo`}
title={`alt:The logo image of ${tag.name}`}
className="h-48 w-full rounded-3xl object-contain lg:h-96"
className="h-20 w-full rounded-3xl object-contain lg:h-40"
/>
)}
<div className="mb-4 flex items-center justify-between px-1">
Expand Down

0 comments on commit 5bb654b

Please sign in to comment.