Skip to content

Commit

Permalink
Feat: #120 이펙터 매물 수정 api 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
tinon1004 authored and Wo-ogie committed May 18, 2024
1 parent d09580e commit 138ba49
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import com.ajou.hertz.domain.instrument.amplifier.constant.AmplifierBrand;
import com.ajou.hertz.domain.instrument.amplifier.constant.AmplifierType;
import com.ajou.hertz.domain.instrument.amplifier.constant.AmplifierUsage;
import com.ajou.hertz.domain.instrument.amplifier.dto.request.AmplifierUpdateRequest;
import com.ajou.hertz.domain.instrument.constant.InstrumentProgressStatus;
import com.ajou.hertz.domain.instrument.dto.request.InstrumentUpdateRequest;
import com.ajou.hertz.domain.instrument.entity.Instrument;
import com.ajou.hertz.domain.user.entity.User;

Expand Down Expand Up @@ -73,4 +75,12 @@ public static Amplifier create(
price, hasAnomaly, description, type, brand, usage
);
}

public void update(InstrumentUpdateRequest updateRequest) {
AmplifierUpdateRequest amplifierUpdateRequest = (AmplifierUpdateRequest)updateRequest;
super.update(updateRequest);
this.type = amplifierUpdateRequest.getType();
this.brand = amplifierUpdateRequest.getBrand();
this.usage = amplifierUpdateRequest.getUsage();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import com.ajou.hertz.domain.instrument.effector.dto.EffectorDto;
import com.ajou.hertz.domain.instrument.effector.dto.request.CreateNewEffectorRequest;
import com.ajou.hertz.domain.instrument.effector.dto.request.EffectorFilterConditions;
import com.ajou.hertz.domain.instrument.effector.dto.request.EffectorUpdateRequest;
import com.ajou.hertz.domain.instrument.effector.dto.response.EffectorResponse;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.ElectricGuitarDto;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.request.CreateNewElectricGuitarRequest;
Expand Down Expand Up @@ -517,6 +518,29 @@ public AmplifierResponse updateAmplifiersV1(
return InstrumentMapper.toAmplifierResponse(amplifierDto);
}

@Operation(
summary = "이펙터 기타 매물 수정",
description = """
<p>이펙터 매물 정보를 수정합니다.
<p>요청 시 <strong>multipart/form-data</strong> content-type으로 요쳥해야 합니다.
<p>변경하고자 하는 매물 정보만 request body에 담아 요청하면 됩니다. 요청 시 보내지 않은 필드는 수정하지 않습니다.
""",
security = @SecurityRequirement(name = "access-token")
)
@PatchMapping("/effectors/{effectorId}")
public EffectorResponse updateEffectorV1(
@AuthenticationPrincipal UserPrincipal userPrincipal,
@Parameter(description = "수정하고자 하는 악기 매물의 id", example = "2") @PathVariable Long effectorId,
@ParameterObject @ModelAttribute @Valid EffectorUpdateRequest updateRequest
) {
EffectorDto effectorDto = instrumentCommandService.updateEffector(
userPrincipal.getUserId(),
effectorId,
updateRequest
);
return InstrumentMapper.toEffectorResponse(effectorDto);
}

@Operation(
summary = "악기 매물 삭제",
description = "악기 매물을 삭제합니다. 매물 삭제는 판매자만 할 수 있습니다.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.ajou.hertz.domain.instrument.effector.dto.request;

import java.util.List;

import org.springframework.lang.Nullable;
import org.springframework.web.multipart.MultipartFile;

import com.ajou.hertz.common.dto.request.AddressRequest;
import com.ajou.hertz.domain.instrument.constant.InstrumentProgressStatus;
import com.ajou.hertz.domain.instrument.dto.request.InstrumentUpdateRequest;
import com.ajou.hertz.domain.instrument.effector.constant.EffectorFeature;
import com.ajou.hertz.domain.instrument.effector.constant.EffectorType;

import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Setter
@Getter
public class EffectorUpdateRequest extends InstrumentUpdateRequest {

@NotNull
private EffectorType type;

@NotNull
private EffectorFeature feature;

private EffectorUpdateRequest(
@Nullable String title,
@Nullable InstrumentProgressStatus progressStatus,
@Nullable AddressRequest tradeAddress,
@Nullable Short qualityStatus,
@Nullable Integer price,
@Nullable Boolean hasAnomaly,
@Nullable String description,
@Nullable List<Long> deletedImageIds,
@Nullable List<MultipartFile> newImages,
@Nullable List<Long> deletedHashtagIds,
@Nullable List<String> newHashtags,
@Nullable EffectorType type,
@Nullable EffectorFeature feature
) {
super(title, progressStatus, tradeAddress, qualityStatus, price, hasAnomaly, description,
deletedImageIds, newImages, deletedHashtagIds, newHashtags);
this.type = type;
this.feature = feature;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.ajou.hertz.domain.instrument.effector.entity;

import com.ajou.hertz.common.entity.Address;
import com.ajou.hertz.domain.instrument.constant.InstrumentProgressStatus;
import com.ajou.hertz.domain.instrument.dto.request.InstrumentUpdateRequest;
import com.ajou.hertz.domain.instrument.effector.constant.EffectorFeature;
import com.ajou.hertz.domain.instrument.effector.constant.EffectorType;
import com.ajou.hertz.domain.instrument.constant.InstrumentProgressStatus;
import com.ajou.hertz.domain.instrument.effector.dto.request.EffectorUpdateRequest;
import com.ajou.hertz.domain.instrument.entity.Instrument;
import com.ajou.hertz.domain.user.entity.User;

Expand Down Expand Up @@ -65,4 +67,11 @@ public static Effector create(
price, hasAnomaly, description, type, feature
);
}

public void update(InstrumentUpdateRequest updateRequest) {
EffectorUpdateRequest effectorUpdateRequest = (EffectorUpdateRequest)updateRequest;
super.update(updateRequest);
this.type = effectorUpdateRequest.getType();
this.feature = effectorUpdateRequest.getFeature();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.ajou.hertz.domain.instrument.dto.request.InstrumentUpdateRequest;
import com.ajou.hertz.domain.instrument.effector.dto.EffectorDto;
import com.ajou.hertz.domain.instrument.effector.dto.request.CreateNewEffectorRequest;
import com.ajou.hertz.domain.instrument.effector.dto.request.EffectorUpdateRequest;
import com.ajou.hertz.domain.instrument.effector.entity.Effector;
import com.ajou.hertz.domain.instrument.effector.strategy.EffectorCreationStrategy;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.ElectricGuitarDto;
Expand Down Expand Up @@ -266,6 +267,22 @@ public AmplifierDto updateAmplifier(
return (AmplifierDto)updateInstrument(userId, amplifierId, updateRequest);
}

/**
* 이펙터 매물 정보를 수정한다.
*
* @param userId 수정하고자 하는 유저의 id. 악기 판매자와 동일해야 한다.
* @param effectorId 수정할 일렉 기타의 id
* @param updateRequest 수정하고자 하는 정보
* @return 수정된 일렉 기타 매물 정보
*/
public EffectorDto updateEffector(
Long userId,
Long effectorId,
EffectorUpdateRequest updateRequest
) {
return (EffectorDto)updateInstrument(userId, effectorId, updateRequest);
}

/**
* 악기 매물을 삭제한다.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import com.ajou.hertz.domain.instrument.effector.dto.EffectorDto;
import com.ajou.hertz.domain.instrument.effector.dto.request.CreateNewEffectorRequest;
import com.ajou.hertz.domain.instrument.effector.dto.request.EffectorFilterConditions;
import com.ajou.hertz.domain.instrument.effector.dto.request.EffectorUpdateRequest;
import com.ajou.hertz.domain.instrument.electric_guitar.constant.ElectricGuitarBrand;
import com.ajou.hertz.domain.instrument.electric_guitar.constant.ElectricGuitarModel;
import com.ajou.hertz.domain.instrument.electric_guitar.dto.ElectricGuitarDto;
Expand Down Expand Up @@ -774,7 +775,6 @@ public InstrumentControllerTest(MockMvc mvc) {
.param("price", String.valueOf(updateRequest.getPrice()))
.param("hasAnomaly", String.valueOf(updateRequest.getHasAnomaly()))
.param("description", updateRequest.getDescription())
.param("brand", String.valueOf(updateRequest.getBrand()))
.param("type", String.valueOf(updateRequest.getType()))
.param("brand", String.valueOf(updateRequest.getBrand()))
.param("usage", String.valueOf(updateRequest.getUsage()))
Expand All @@ -793,6 +793,46 @@ public InstrumentControllerTest(MockMvc mvc) {
verifyEveryMocksShouldHaveNoMoreInteractions();
}

@Test
void 수정할_이펙터_정보가_주어지고_주어진_정보로_매물_정보를_수정한다() throws Exception {
// given
long userId = 1L;
long effectorId = 2L;
EffectorUpdateRequest updateRequest = createEffectorUpdateRequest();
EffectorDto expectedResult = createEffectorDto(effectorId, userId);
given(instrumentCommandService.updateEffector(
eq(userId),
eq(effectorId),
any(EffectorUpdateRequest.class)
)).willReturn(expectedResult);

// when & then
mvc.perform(
multipart("/api/instruments/effectors/{effectorId}", effectorId)
.header(API_VERSION_HEADER_NAME, 1)
.param("title", updateRequest.getTitle())
.param("progressStatus", String.valueOf(updateRequest.getProgressStatus()))
.param("qualityStatus", String.valueOf(updateRequest.getQualityStatus()))
.param("price", String.valueOf(updateRequest.getPrice()))
.param("hasAnomaly", String.valueOf(updateRequest.getHasAnomaly()))
.param("description", updateRequest.getDescription())
.param("type", String.valueOf(updateRequest.getType()))
.param("feature", String.valueOf(updateRequest.getFeature()))
.with(user(createTestUser(userId)))
.with(request -> {
request.setMethod("PATCH");
return request;
})
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(expectedResult.getId()));
then(instrumentCommandService)
.should()
.updateEffector(eq(userId), eq(effectorId),
any(EffectorUpdateRequest.class));
verifyEveryMocksShouldHaveNoMoreInteractions();
}

@Test
void 악기_id가_주어지고_해당하는_악기_매물을_삭제한다() throws Exception {
// given
Expand Down Expand Up @@ -1174,4 +1214,22 @@ private AmplifierUpdateRequest createAmplifierUpdateRequest() throws Exception {
);
}

private EffectorUpdateRequest createEffectorUpdateRequest() throws Exception {
return ReflectionUtils.createEffectorUpdateRequest(
"Test Effector",
InstrumentProgressStatus.SOLD_OUT,
createAddressRequest(),
(short)3,
550000,
true,
"description",
null,
null,
null,
null,
EffectorType.GUITAR,
EffectorFeature.GUITAR_WAH
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import com.ajou.hertz.domain.instrument.effector.constant.EffectorType;
import com.ajou.hertz.domain.instrument.effector.dto.EffectorDto;
import com.ajou.hertz.domain.instrument.effector.dto.request.CreateNewEffectorRequest;
import com.ajou.hertz.domain.instrument.effector.dto.request.EffectorUpdateRequest;
import com.ajou.hertz.domain.instrument.effector.entity.Effector;
import com.ajou.hertz.domain.instrument.electric_guitar.constant.ElectricGuitarBrand;
import com.ajou.hertz.domain.instrument.electric_guitar.constant.ElectricGuitarModel;
Expand Down Expand Up @@ -425,6 +426,36 @@ class InstrumentCommandServiceTest {
assertThat(result.getImages()).hasSize(newImages.size());
}

@Test
void 추가할_이미지들이_주어지고_이펙터_정보를_수정하면_새로운_악기_이미지들이_추가된다() throws Exception {
// given
long userId = 1L;
long instrumentId = 2L;
Effector effector = createEffector(instrumentId, createUser(userId));
List<MultipartFile> newImages = List.of(
createMultipartFile(),
createMultipartFile()
);
List<InstrumentImage> newInstrumentImages = List.of(
createInstrumentImage(3L, effector),
createInstrumentImage(4L, effector)
);
EffectorUpdateRequest updateRequest = createEffectorUpdateRequest(List.of(), newImages, null, null);
given(instrumentQueryService.getInstrumentById(instrumentId))
.willReturn(effector);
given(instrumentImageCommandService.saveImages(effector, updateRequest.getNewImages()))
.willReturn(newInstrumentImages);

// when
EffectorDto result = sut.updateEffector(userId, instrumentId, updateRequest);

// then
then(instrumentQueryService).should().getInstrumentById(instrumentId);
then(instrumentImageCommandService).should().saveImages(effector, updateRequest.getNewImages());
verifyEveryMocksShouldHaveNoMoreInteractions();
assertThat(result.getImages()).hasSize(newImages.size());
}

@Test
void 삭제할_해시태그들의_id_리스트가_주어지고_매물_정보를_수정하면_해시태그가_삭제된다() throws Exception {
long userId = 1L;
Expand Down Expand Up @@ -836,4 +867,17 @@ private AmplifierUpdateRequest createAmplifierUpdateRequest(
null, null, null
);
}

private EffectorUpdateRequest createEffectorUpdateRequest(
@Nullable List<Long> deletedImageIds,
@Nullable List<MultipartFile> newImages,
@Nullable List<Long> deletedHashtagIds,
@Nullable List<String> newHashtags
) throws Exception {
return ReflectionUtils.createEffectorUpdateRequest(
null, null, null, null, null, null, null,
deletedImageIds, newImages, deletedHashtagIds, newHashtags,
null, null
);
}
}
39 changes: 39 additions & 0 deletions src/test/java/com/ajou/hertz/util/ReflectionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import com.ajou.hertz.domain.instrument.effector.dto.EffectorDto;
import com.ajou.hertz.domain.instrument.effector.dto.request.CreateNewEffectorRequest;
import com.ajou.hertz.domain.instrument.effector.dto.request.EffectorFilterConditions;
import com.ajou.hertz.domain.instrument.effector.dto.request.EffectorUpdateRequest;
import com.ajou.hertz.domain.instrument.effector.entity.Effector;
import com.ajou.hertz.domain.instrument.electric_guitar.constant.ElectricGuitarBrand;
import com.ajou.hertz.domain.instrument.electric_guitar.constant.ElectricGuitarModel;
Expand Down Expand Up @@ -1100,6 +1101,44 @@ public static AmplifierUpdateRequest createAmplifierUpdateRequest(
);
}

public static EffectorUpdateRequest createEffectorUpdateRequest(
@Nullable String title,
@Nullable InstrumentProgressStatus progressStatus,
@Nullable AddressRequest tradeAddress,
@Nullable Short qualityStatus,
@Nullable Integer price,
@Nullable Boolean hasAnomaly,
@Nullable String description,
@Nullable List<Long> deletedImageIds,
@Nullable List<MultipartFile> newImages,
@Nullable List<Long> deletedHashtagIds,
@Nullable List<String> newHashtags,
@Nullable EffectorType type,
@Nullable EffectorFeature feature
) throws Exception {
Constructor<EffectorUpdateRequest> constructor = EffectorUpdateRequest.class.getDeclaredConstructor(
String.class, InstrumentProgressStatus.class, AddressRequest.class, Short.class,
Integer.class, Boolean.class, String.class, List.class, List.class, List.class, List.class,
EffectorType.class, EffectorFeature.class
);
constructor.setAccessible(true);
return constructor.newInstance(
title,
progressStatus,
tradeAddress,
qualityStatus,
price,
hasAnomaly,
description,
deletedImageIds,
newImages,
deletedHashtagIds,
newHashtags,
type,
feature
);
}

public static SendUserAuthCodeRequest createSendUserAuthCodeRequest(String phoneNumber) throws Exception {
Constructor<SendUserAuthCodeRequest> constructor =
SendUserAuthCodeRequest.class.getDeclaredConstructor(String.class);
Expand Down

0 comments on commit 138ba49

Please sign in to comment.