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

[FIX] 통과하지 않는 테스트를 통과시킨다. #145

Merged
merged 12 commits into from
Aug 26, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/backend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- name: Create application.properties
run: |
cd ./src/main/resources
echo "${{ secrets.PROPERTIES }}" > ./application.properties
echo "${{ secrets.PROPERTIES }}" > ./env.properties

- name: Start DB
run: |
Expand Down
12 changes: 0 additions & 12 deletions eeos/resources/test-develop-environment/mysql-init.d/00_init.sql

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ public String getActiveStatus() {
return activeStatus.getStatus();
}

@Override
public Long getMemberId() {
return id;
}

private void canEdit(ActiveStatus requestStatus) {
if (requestStatus.isAll()) {
throw new DeniedUpdateActiveException(requestStatus.getStatus());
}
}

@Override
public Long getMemberId() {
return id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,59 +19,56 @@

@Service
@RequiredArgsConstructor
public class CommandMemberService implements ChangeActiveStatusUsecase {
public class AdminMemberService implements ChangeActiveStatusUsecase {
private final MemberRepository memberRepository;
private final OAuthMemberRepository oAuthMemberRepository;
private final MemberEntityConverter memberConverter;
private final CommandMemberResponseConverter responseConverter;
private final ApplicationEventPublisher applicationEventPublisher;
private final QueryMemberService memberService;

@Transactional
@Override
public CommandMemberResponse adminChangeStatus(
public CommandMemberResponse changeActiveStatus(
final Long adminMemberId, Long memberId, final ChangeActiveStatusRequest request) {
validateUser(adminMemberId);
MemberModel model =
memberRepository
.findById(memberId)
.map(memberConverter::from)
.orElseThrow(NotFoundMemberException::new);
validateAdminPermission(adminMemberId);

MemberModel model = findMember(memberId);
MemberEntity updateMember = updateActiveStatus(model, request.getActiveStatus());

return responseConverter.from(
updateMember.getName(), updateMember.getActiveStatus().getStatus());
}

private MemberEntity updateActiveStatus(final MemberModel model, final String status) {
MemberModel memberModel = model.updateActiveStatus(status);
return memberRepository.save(memberConverter.toEntity(memberModel));
}
@Override
@Transactional
public void delete(final Long adminMemberId, final Long memberId) {
validateAdminPermission(adminMemberId);

private MemberModel findMember(final Long memberId) {
return memberRepository
.findById(memberId)
.map(memberConverter::from)
.orElseThrow(NotFoundMemberException::new);
MemberModel member = findMember(memberId);
memberRepository.deleteById(member.getId());
oAuthMemberRepository.deleteById(member.getId());

applicationEventPublisher.publishEvent(DeletedMemberEvent.of(memberId));
}

private void validateUser(Long memberId) {
if (memberService.findMember(memberId).isAdmin()) {
private void validateAdminPermission(Long memberId) {
MemberModel member = findMember(memberId);

if (member.isAdmin()) {
return;
}
throw new DeniedMemberEditException(memberId);
}

@Override
@Transactional
public void delete(final Long adminMemberId, final Long memberId) {
MemberModel member = findMember(memberId);
validateUser(adminMemberId);

memberRepository.deleteById(member.getId());
oAuthMemberRepository.deleteById(member.getId());
private MemberModel findMember(final Long memberId) {
return memberRepository
.findById(memberId)
.map(memberConverter::from)
.orElseThrow(NotFoundMemberException::new);
}

applicationEventPublisher.publishEvent(DeletedMemberEvent.of(memberId));
private MemberEntity updateActiveStatus(final MemberModel model, final String status) {
MemberModel memberModel = model.updateActiveStatus(status);
return memberRepository.save(memberConverter.toEntity(memberModel));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

/** 멤버의 활동 상태를 변경한다. */
public interface ChangeActiveStatusUsecase {
CommandMemberResponse adminChangeStatus(
CommandMemberResponse changeActiveStatus(
Long adminMemberId, Long memberId, ChangeActiveStatusRequest request);

void delete(Long adminMemberId, Long memberId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@
import com.blackcompany.eeos.member.presentation.docs.MemberApi;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/members")
@Slf4j
public class MemberController implements MemberApi {
private final ChangeActiveStatusUsecase changeActiveStatusUsecase;
private final GetMembersByActiveStatus getMembersByActiveStatus;
Expand All @@ -30,7 +28,7 @@ public ApiResponse<SuccessBody<CommandMemberResponse>> adminChangeActiveStatus(
@PathVariable("memberId") Long memberId,
@RequestBody @Valid ChangeActiveStatusRequest request) {
CommandMemberResponse response =
changeActiveStatusUsecase.adminChangeStatus(adminMemberId, memberId, request);
changeActiveStatusUsecase.changeActiveStatus(adminMemberId, memberId, request);
return ApiResponseGenerator.success(response, HttpStatus.OK, MessageCode.UPDATE);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@
@Builder(toBuilder = true)
public class ChangeAllAttendStatusRequest implements AbstractRequestDto {
private Long memberId;
private String beforeAttendStatus;
private String afterAttendStatus;
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ public void validateCreate() {
if (!isGithubUrl()) {
throw new IsNotGithubUrlException();
}

return;
}

public void validateEditAttend(Long memberId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,6 @@ public AttendModel changeStatus(String afterStatus) {
return this;
}

public AttendModel changeStatusByManager(String beforeStatus, String afterStatus) {
validateChangeByManager(beforeStatus);
this.status = AttendStatus.find(afterStatus);

return this;
}

public String getStatus() {
return status.getStatus();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ private <T extends MemberIdModel> List<Long> findDifferent(
private void updateAttendStatus(
AttendModel model, List<ChangeAllAttendStatusRequest> requests, AttendManager attendManager) {
ChangeAllAttendStatusRequest request = findUpdateRequest(model.getMemberId(), requests);
model.changeStatusByManager(request.getBeforeAttendStatus(), request.getAfterAttendStatus());
model.changeStatus(request.getAfterAttendStatus());

if (Objects.equals(request.getAfterAttendStatus(), AttendStatus.NONRELATED.getStatus())) {
attendManager.addNonRelated(model);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.blackcompany.eeos.common;

import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.springframework.stereotype.Component;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@Component
public class DataClearExtension implements BeforeEachCallback {

@Override
public void beforeEach(ExtensionContext context) {
DatabaseCleaner dataCleaner = getDataCleaner(context);
dataCleaner.clear();
}

private DatabaseCleaner getDataCleaner(final ExtensionContext extensionContext) {
return SpringExtension.getApplicationContext(extensionContext).getBean(DatabaseCleaner.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.blackcompany.eeos.common;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
public class DatabaseCleaner {
private static final String FOREIGN_KEY_CHECK_FORMAT = "SET FOREIGN_KEY_CHECKS = %d";
private static final String TRUNCATE_FORMAT = "TRUNCATE TABLE %s";
private static final String AUTO_INCREMENT_FORMAT = "ALTER TABLE %s AUTO_INCREMENT = 1";

@PersistenceContext private EntityManager entityManager;

@Transactional
public void clear() {
disableForeignKeyChecks();
List<String> tableNames = getTableNames();
truncate(tableNames);
enableForeignKeyChecks();
}

private void disableForeignKeyChecks() {
entityManager.createNativeQuery(String.format(FOREIGN_KEY_CHECK_FORMAT, 0)).executeUpdate();
}

private List<String> getTableNames() {
String query =
"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE()";
return entityManager.createNativeQuery(query).getResultList();
}

private void enableForeignKeyChecks() {
entityManager.createNativeQuery(String.format(FOREIGN_KEY_CHECK_FORMAT, 1)).executeUpdate();
}

private void truncate(List<String> tableNames) {
for (String tableName : tableNames) {
entityManager.createNativeQuery(String.format(TRUNCATE_FORMAT, tableName)).executeUpdate();
entityManager
.createNativeQuery(String.format(AUTO_INCREMENT_FORMAT, tableName))
.executeUpdate();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package com.blackcompany.eeos.member.application.service;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.blackcompany.eeos.auth.persistence.OAuthMemberRepository;
import com.blackcompany.eeos.common.DataClearExtension;
import com.blackcompany.eeos.member.application.dto.ChangeActiveStatusRequest;
import com.blackcompany.eeos.member.application.dto.CommandMemberResponse;
import com.blackcompany.eeos.member.application.exception.DeniedMemberEditException;
import com.blackcompany.eeos.member.application.model.ActiveStatus;
import com.blackcompany.eeos.member.fixture.MemberFixture;
import com.blackcompany.eeos.member.persistence.MemberEntity;
import com.blackcompany.eeos.member.persistence.MemberRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;

@SpringBootTest
@ExtendWith(DataClearExtension.class)
class AdminMemberServiceTest {

@Autowired private AdminMemberService adminMemberService;

@SpyBean private MemberRepository memberRepository;

@MockBean private OAuthMemberRepository oAuthMemberRepository;

Long adminId = 1L;
Long memberId1 = 2L;
Long memberId2 = 3L;

@Test
@DisplayName("관리자는 회원의 상태를 변경할 수 있다.")
void admin_change_status() {
// given
MemberEntity adminEntity = MemberFixture.어드민_엔티티(adminId);
MemberEntity memberEntity = MemberFixture.멤버_엔티티(memberId1, ActiveStatus.AM);

memberRepository.save(adminEntity);
memberRepository.save(memberEntity);

ChangeActiveStatusRequest request =
ChangeActiveStatusRequest.builder().activeStatus("rm").build();

// when
CommandMemberResponse result =
adminMemberService.changeActiveStatus(adminEntity.getId(), memberEntity.getId(), request);

// then
assertEquals(ActiveStatus.RM.getStatus(), result.getActiveStatus());
assertEquals(memberEntity.getName(), result.getName());
}

@Test
@DisplayName("관리자가 아닌 사용자가 회원 상태를 변경하려고 하면 예외가 발생한다.")
void non_admin_change_status() {
// given
MemberEntity nonAdminEntity = MemberFixture.멤버_엔티티(memberId1, ActiveStatus.AM);
MemberEntity memberEntity = MemberFixture.멤버_엔티티(memberId2, ActiveStatus.AM);

memberRepository.save(nonAdminEntity);
memberRepository.save(memberEntity);

ChangeActiveStatusRequest request =
ChangeActiveStatusRequest.builder().activeStatus("rm").build();

// when & then
assertThrows(
DeniedMemberEditException.class,
() ->
adminMemberService.changeActiveStatus(
nonAdminEntity.getId(), memberEntity.getId(), request));
}

@Test
@DisplayName("관리자는 회원을 삭제할 수 있다.")
void admin_delete_member() {
// given
MemberEntity adminEntity = MemberFixture.어드민_엔티티(adminId);
MemberEntity memberEntity = MemberFixture.멤버_엔티티(memberId1, ActiveStatus.AM);

memberRepository.save(adminEntity);
memberRepository.save(memberEntity);

// when
adminMemberService.delete(adminEntity.getId(), memberEntity.getId());

// then
assertFalse(memberRepository.existsById(memberEntity.getId()));
assertFalse(oAuthMemberRepository.existsById(memberEntity.getId()));
}

@Test
@DisplayName("관리자가 아닌 사용자가 회원을 삭제하려고하면 예외가 발생한다.")
void non_admin_delete_member() {
// given
MemberEntity nonAdminEntity = MemberFixture.멤버_엔티티(memberId1, ActiveStatus.AM);
MemberEntity memberEntity = MemberFixture.멤버_엔티티(memberId2, ActiveStatus.AM);

memberRepository.save(nonAdminEntity);
memberRepository.save(memberEntity);

// when & then
assertThrows(
DeniedMemberEditException.class,
() -> adminMemberService.delete(nonAdminEntity.getId(), memberEntity.getId()));
}
}
Loading
Loading