Skip to content
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
1 change: 0 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ JWT_REFRESH_TOKEN_COOKIE_SECURE=false
JWT_REFRESH_TOKEN_COOKIE_SAME_SITE=Lax

CORS_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:8080,https://quespot.site,https://www.quespot.site
DEFAULT_PROFILE_IMAGE_URL=https://example.com/images/default-profile.png

GOOGLE_OAUTH_ENABLED=false
GOOGLE_CLIENT_ID=
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ CREATE DATABASE IF NOT EXISTS quespot
```

- 환경변수는 `.env.example`을 참고해 로컬 환경이나 IDE 실행 설정에 등록합니다. Spring Boot는 `.env` 파일을 자동으로 읽지 않으므로 터미널에서 실행할 때는 직접 export가 필요합니다.
- `DEFAULT_PROFILE_IMAGE_URL`은 프로필에 S3 Object Key가 없을 때 사용할 기본 이미지의 HTTPS URL입니다.
- Google 로그인을 사용하려면 `.env.example`의 `GOOGLE_*` 환경변수를 등록하고 `GOOGLE_OAUTH_ENABLED=true`로 설정합니다.
- Kakao 로그인을 사용하려면 `.env.example`의 `KAKAO_*` 환경변수를 등록하고 `KAKAO_OAUTH_ENABLED=true`로 설정합니다.
- Naver 로그인을 사용하려면 `.env.example`의 `NAVER_*` 환경변수를 등록하고 `NAVER_OAUTH_ENABLED=true`로 설정합니다.
Expand Down
15 changes: 4 additions & 11 deletions src/main/java/com/quespot/domain/user/service/ProfileService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import com.quespot.global.file.enums.UploadPurpose;
import com.quespot.global.file.service.FileService;
import com.quespot.global.security.principal.AuthenticatedUser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -27,18 +26,15 @@ public class ProfileService {
private final UserRepository userRepository;
private final UserProfileRepository userProfileRepository;
private final FileService fileService;
private final String defaultProfileImageUrl;

public ProfileService(
UserRepository userRepository,
UserProfileRepository userProfileRepository,
FileService fileService,
@Value("${app.profile.default-image-url}") String defaultProfileImageUrl
FileService fileService
) {
this.userRepository = userRepository;
this.userProfileRepository = userProfileRepository;
this.fileService = fileService;
this.defaultProfileImageUrl = defaultProfileImageUrl;
}

// 프로필 생성 로직
Expand Down Expand Up @@ -142,12 +138,9 @@ private String resolveProfileImageObjectKey(Long userId, String objectKey) {

private ProfileResponseDTO toProfileResponseDTO(UserProfile profile) {
String objectKey = profile.getProfileImageObjectKey();
String profileImageUrl;
if (objectKey == null || objectKey.isBlank()) {
profileImageUrl = defaultProfileImageUrl;
} else {
profileImageUrl = fileService.createPresignedDownloadUrl(objectKey);
}
String profileImageUrl = objectKey == null || objectKey.isBlank()
? null
: fileService.createPresignedDownloadUrl(objectKey);
return ProfileConverter.toProfileResponseDTO(profile, profileImageUrl);
}
}
2 changes: 0 additions & 2 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ app:
region: ${AWS_REGION:ap-northeast-2}
presigned-url-expiration-seconds: ${S3_PRESIGNED_URL_EXPIRATION_SECONDS:300}
max-file-size-bytes: ${S3_MAX_FILE_SIZE_BYTES:10485760}
profile:
default-image-url: ${DEFAULT_PROFILE_IMAGE_URL:https://example.com/images/default-profile.png}
oauth2:
frontend-redirect-uri: ${OAUTH2_FRONTEND_REDIRECT_URI:http://localhost:5173/oauth/callback}
allowed-frontend-redirect-uris: ${OAUTH2_ALLOWED_FRONTEND_REDIRECT_URIS:${OAUTH2_FRONTEND_REDIRECT_URI:http://localhost:5173/oauth/callback}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.quespot.domain.user.service;

import com.quespot.domain.user.entity.User;
import com.quespot.domain.user.entity.UserProfile;
import com.quespot.domain.user.enums.Gender;
import com.quespot.domain.user.enums.ResidenceRegion;
import com.quespot.domain.user.enums.UserRole;
import com.quespot.domain.user.repository.UserProfileRepository;
import com.quespot.domain.user.repository.UserRepository;
import com.quespot.global.file.service.FileService;
import com.quespot.global.security.principal.AuthenticatedUser;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;

import java.time.LocalDate;
import java.util.Optional;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class ProfileServiceTest {

private static final Long USER_ID = 1L;
private static final AuthenticatedUser AUTHENTICATED_USER =
new AuthenticatedUser(USER_ID, UserRole.USER, "session-id");

@Mock
private UserRepository userRepository;

@Mock
private UserProfileRepository userProfileRepository;

@Mock
private FileService fileService;

@InjectMocks
private ProfileService profileService;

@Test
void returnsNullImageUrlWhenProfileImageIsNotSet() {
UserProfile profile = createProfile(null);
when(userRepository.findById(USER_ID)).thenReturn(Optional.of(profile.getUser()));
when(userProfileRepository.findByUserId(USER_ID)).thenReturn(Optional.of(profile));

var response = profileService.getProfile(AUTHENTICATED_USER);

assertThat(response.profileImageUrl()).isNull();
verifyNoInteractions(fileService);
}

@Test
void returnsPresignedImageUrlWhenProfileImageIsSet() {
String objectKey = "profiles/1/profile.png";
String presignedUrl = "https://example.com/presigned-profile.png";
UserProfile profile = createProfile(objectKey);
when(userRepository.findById(USER_ID)).thenReturn(Optional.of(profile.getUser()));
when(userProfileRepository.findByUserId(USER_ID)).thenReturn(Optional.of(profile));
when(fileService.createPresignedDownloadUrl(objectKey)).thenReturn(presignedUrl);

var response = profileService.getProfile(AUTHENTICATED_USER);

assertThat(response.profileImageUrl()).isEqualTo(presignedUrl);
verify(fileService).createPresignedDownloadUrl(objectKey);
}

private UserProfile createProfile(String objectKey) {
User user = User.createEmailUser("member@example.com", "encoded-password");
ReflectionTestUtils.setField(user, "id", USER_ID);
return UserProfile.create(
user,
"회원",
objectKey,
Gender.MALE,
LocalDate.of(2000, 1, 1),
ResidenceRegion.SEOUL,
null,
Set.of()
);
}
}
Loading