diff --git a/src/main/java/com/ajou/hertz/domain/instrument/amplifier/entity/Amplifier.java b/src/main/java/com/ajou/hertz/domain/instrument/amplifier/entity/Amplifier.java
index 6fb8fe5..d674949 100644
--- a/src/main/java/com/ajou/hertz/domain/instrument/amplifier/entity/Amplifier.java
+++ b/src/main/java/com/ajou/hertz/domain/instrument/amplifier/entity/Amplifier.java
@@ -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;
@@ -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();
+ }
}
diff --git a/src/main/java/com/ajou/hertz/domain/instrument/controller/InstrumentController.java b/src/main/java/com/ajou/hertz/domain/instrument/controller/InstrumentController.java
index 8d69d43..851271d 100644
--- a/src/main/java/com/ajou/hertz/domain/instrument/controller/InstrumentController.java
+++ b/src/main/java/com/ajou/hertz/domain/instrument/controller/InstrumentController.java
@@ -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;
@@ -517,6 +518,29 @@ public AmplifierResponse updateAmplifiersV1(
return InstrumentMapper.toAmplifierResponse(amplifierDto);
}
+ @Operation(
+ summary = "이펙터 기타 매물 수정",
+ description = """
+
이펙터 매물 정보를 수정합니다.
+
요청 시 multipart/form-data content-type으로 요쳥해야 합니다.
+
변경하고자 하는 매물 정보만 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 = "악기 매물을 삭제합니다. 매물 삭제는 판매자만 할 수 있습니다.",
diff --git a/src/main/java/com/ajou/hertz/domain/instrument/effector/dto/request/EffectorUpdateRequest.java b/src/main/java/com/ajou/hertz/domain/instrument/effector/dto/request/EffectorUpdateRequest.java
new file mode 100644
index 0000000..ed7624e
--- /dev/null
+++ b/src/main/java/com/ajou/hertz/domain/instrument/effector/dto/request/EffectorUpdateRequest.java
@@ -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 deletedImageIds,
+ @Nullable List newImages,
+ @Nullable List deletedHashtagIds,
+ @Nullable List 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;
+ }
+}
diff --git a/src/main/java/com/ajou/hertz/domain/instrument/effector/entity/Effector.java b/src/main/java/com/ajou/hertz/domain/instrument/effector/entity/Effector.java
index 9f87d7b..5dbdba7 100644
--- a/src/main/java/com/ajou/hertz/domain/instrument/effector/entity/Effector.java
+++ b/src/main/java/com/ajou/hertz/domain/instrument/effector/entity/Effector.java
@@ -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;
@@ -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();
+ }
}
diff --git a/src/main/java/com/ajou/hertz/domain/instrument/service/InstrumentCommandService.java b/src/main/java/com/ajou/hertz/domain/instrument/service/InstrumentCommandService.java
index f9ee636..69677c4 100644
--- a/src/main/java/com/ajou/hertz/domain/instrument/service/InstrumentCommandService.java
+++ b/src/main/java/com/ajou/hertz/domain/instrument/service/InstrumentCommandService.java
@@ -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;
@@ -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);
+ }
+
/**
* 악기 매물을 삭제한다.
*
diff --git a/src/test/java/com/ajou/hertz/unit/domain/instrument/controller/InstrumentControllerTest.java b/src/test/java/com/ajou/hertz/unit/domain/instrument/controller/InstrumentControllerTest.java
index 933ae46..fd71268 100644
--- a/src/test/java/com/ajou/hertz/unit/domain/instrument/controller/InstrumentControllerTest.java
+++ b/src/test/java/com/ajou/hertz/unit/domain/instrument/controller/InstrumentControllerTest.java
@@ -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;
@@ -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()))
@@ -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
@@ -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
+ );
+ }
+
}
diff --git a/src/test/java/com/ajou/hertz/unit/domain/instrument/service/InstrumentCommandServiceTest.java b/src/test/java/com/ajou/hertz/unit/domain/instrument/service/InstrumentCommandServiceTest.java
index e3aee2b..c4be6da 100644
--- a/src/test/java/com/ajou/hertz/unit/domain/instrument/service/InstrumentCommandServiceTest.java
+++ b/src/test/java/com/ajou/hertz/unit/domain/instrument/service/InstrumentCommandServiceTest.java
@@ -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;
@@ -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 newImages = List.of(
+ createMultipartFile(),
+ createMultipartFile()
+ );
+ List 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;
@@ -836,4 +867,17 @@ private AmplifierUpdateRequest createAmplifierUpdateRequest(
null, null, null
);
}
+
+ private EffectorUpdateRequest createEffectorUpdateRequest(
+ @Nullable List deletedImageIds,
+ @Nullable List newImages,
+ @Nullable List deletedHashtagIds,
+ @Nullable List newHashtags
+ ) throws Exception {
+ return ReflectionUtils.createEffectorUpdateRequest(
+ null, null, null, null, null, null, null,
+ deletedImageIds, newImages, deletedHashtagIds, newHashtags,
+ null, null
+ );
+ }
}
diff --git a/src/test/java/com/ajou/hertz/util/ReflectionUtils.java b/src/test/java/com/ajou/hertz/util/ReflectionUtils.java
index dac8c14..1b7cecc 100644
--- a/src/test/java/com/ajou/hertz/util/ReflectionUtils.java
+++ b/src/test/java/com/ajou/hertz/util/ReflectionUtils.java
@@ -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;
@@ -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 deletedImageIds,
+ @Nullable List newImages,
+ @Nullable List deletedHashtagIds,
+ @Nullable List newHashtags,
+ @Nullable EffectorType type,
+ @Nullable EffectorFeature feature
+ ) throws Exception {
+ Constructor 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 constructor =
SendUserAuthCodeRequest.class.getDeclaredConstructor(String.class);