Skip to content

Commit

Permalink
Merge pull request #118 from Ajou-Hertz/feature/#111-update-acoustic-…
Browse files Browse the repository at this point in the history
…guitar

어쿠스틱 & 클래식 기타 매물 수정 api 구현
  • Loading branch information
Wo-ogie authored May 16, 2024
2 parents 9ce110e + 04f6054 commit 1e71a01
Show file tree
Hide file tree
Showing 7 changed files with 268 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.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.acoustic_and_classic_guitar.constant.AcousticAndClassicGuitarBrand;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.constant.AcousticAndClassicGuitarModel;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.constant.AcousticAndClassicGuitarPickUp;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.constant.AcousticAndClassicGuitarWood;
import com.ajou.hertz.domain.instrument.constant.InstrumentProgressStatus;
import com.ajou.hertz.domain.instrument.dto.request.InstrumentUpdateRequest;

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 AcousticAndClassicGuitarUpdateRequest extends InstrumentUpdateRequest {

@Nullable
private AcousticAndClassicGuitarBrand brand;

@Nullable
private AcousticAndClassicGuitarModel model;

@NotNull
private AcousticAndClassicGuitarWood wood;

@NotNull
private AcousticAndClassicGuitarPickUp pickUp;

private AcousticAndClassicGuitarUpdateRequest(
@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 AcousticAndClassicGuitarBrand brand,
@Nullable AcousticAndClassicGuitarModel model,
@Nullable AcousticAndClassicGuitarWood wood,
@Nullable AcousticAndClassicGuitarPickUp pickUp
) {
super(title, progressStatus, tradeAddress, qualityStatus, price, hasAnomaly, description,
deletedImageIds, newImages, deletedHashtagIds, newHashtags);
this.brand = brand;
this.model = model;
this.wood = wood;
this.pickUp = pickUp;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.constant.AcousticAndClassicGuitarModel;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.constant.AcousticAndClassicGuitarPickUp;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.constant.AcousticAndClassicGuitarWood;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.AcousticAndClassicGuitarUpdateRequest;
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 @@ -81,4 +83,13 @@ public static AcousticAndClassicGuitar create(
price, hasAnomaly, description, brand, model, wood, pickUp
);
}

public void update(InstrumentUpdateRequest updateRequest) {
AcousticAndClassicGuitarUpdateRequest acousticAndClassicGuitarUpdateRequest = (AcousticAndClassicGuitarUpdateRequest)updateRequest;
super.update(updateRequest);
this.brand = acousticAndClassicGuitarUpdateRequest.getBrand();
this.model = acousticAndClassicGuitarUpdateRequest.getModel();
this.wood = acousticAndClassicGuitarUpdateRequest.getWood();
this.pickUp = acousticAndClassicGuitarUpdateRequest.getPickUp();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.ajou.hertz.common.auth.UserPrincipal;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.AcousticAndClassicGuitarDto;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.AcousticAndClassicGuitarFilterConditions;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.AcousticAndClassicGuitarUpdateRequest;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.CreateNewAcousticAndClassicGuitarRequest;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.response.AcousticAndClassicGuitarResponse;
import com.ajou.hertz.domain.instrument.amplifier.dto.AmplifierDto;
Expand Down Expand Up @@ -469,6 +470,29 @@ public ElectricGuitarResponse updateElectricGuitarV1(
return InstrumentMapper.toElectricGuitarResponse(electricGuitarDto);
}

@Operation(
summary = "어쿠스틱 기타 매물 수정",
description = """
<p>어쿠스틱 기타 매물 정보를 수정합니다.
<p>요청 시 <strong>multipart/form-data</strong> content-type으로 요쳥해야 합니다.
<p>변경하고자 하는 매물 정보만 request body에 담아 요청하면 됩니다. 요청 시 보내지 않은 필드는 수정하지 않습니다.
""",
security = @SecurityRequirement(name = "access-token")
)
@PatchMapping("/acoustic-and-classic-guitars/{AcousticAndClassicGuitarId}")
public AcousticAndClassicGuitarResponse updateAcousticAndClassicGuitarV1(
@AuthenticationPrincipal UserPrincipal userPrincipal,
@Parameter(description = "수정하고자 하는 악기 매물의 id", example = "2") @PathVariable Long AcousticAndClassicGuitarId,
@ParameterObject @ModelAttribute @Valid AcousticAndClassicGuitarUpdateRequest updateRequest
) {
AcousticAndClassicGuitarDto acousticAndClassicGuitarDto = instrumentCommandService.updateAcousticAndClassicGuitar(
userPrincipal.getUserId(),
AcousticAndClassicGuitarId,
updateRequest
);
return InstrumentMapper.toAcousticAndClassicGuitarResponse(acousticAndClassicGuitarDto);
}

@Operation(
summary = "악기 매물 삭제",
description = "악기 매물을 삭제합니다. 매물 삭제는 판매자만 할 수 있습니다.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.transaction.annotation.Transactional;

import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.AcousticAndClassicGuitarDto;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.AcousticAndClassicGuitarUpdateRequest;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.CreateNewAcousticAndClassicGuitarRequest;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.entity.AcousticAndClassicGuitar;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.strategy.AcousticAndClassicGuitarCreationStrategy;
Expand Down Expand Up @@ -232,6 +233,22 @@ public ElectricGuitarDto updateElectricGuitar(
return (ElectricGuitarDto)updateInstrument(userId, electricGuitarId, updateRequest);
}

/**
* 어쿠스틱 & 클래식 기타 매물 정보를 수정한다.
*
* @param userId 수정하고자 하는 유저의 id. 악기 판매자와 동일해야 한다.
* @param acousticAndClassicGuitarId 수정할 일렉 기타의 id
* @param updateRequest 수정하고자 하는 정보
* @return 수정된 일렉 기타 매물 정보
*/
public AcousticAndClassicGuitarDto updateAcousticAndClassicGuitar(
Long userId,
Long acousticAndClassicGuitarId,
AcousticAndClassicGuitarUpdateRequest updateRequest
) {
return (AcousticAndClassicGuitarDto)updateInstrument(userId, acousticAndClassicGuitarId, updateRequest);
}

/**
* 악기 매물을 삭제한다.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.constant.AcousticAndClassicGuitarWood;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.AcousticAndClassicGuitarDto;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.AcousticAndClassicGuitarFilterConditions;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.AcousticAndClassicGuitarUpdateRequest;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.CreateNewAcousticAndClassicGuitarRequest;
import com.ajou.hertz.domain.instrument.amplifier.constant.AmplifierBrand;
import com.ajou.hertz.domain.instrument.amplifier.constant.AmplifierType;
Expand Down Expand Up @@ -705,6 +706,50 @@ public InstrumentControllerTest(MockMvc mvc) {
verifyEveryMocksShouldHaveNoMoreInteractions();
}

@Test
void 수정할_어쿠스틱기타와_클래식기타_정보가_주어지고_주어진_정보로_매물_정보를_수정한다() throws Exception {
// given
long userId = 1L;
long acousticAndClassicGuitarId = 2L;
AcousticAndClassicGuitarUpdateRequest updateRequest = createAcousticAndClassicGuitarUpdateRequest();
AcousticAndClassicGuitarDto expectedResult = createAcousticAndClassicGuitarDto(acousticAndClassicGuitarId,
userId);
given(instrumentCommandService.updateAcousticAndClassicGuitar(
eq(userId),
eq(acousticAndClassicGuitarId),
any(AcousticAndClassicGuitarUpdateRequest.class)
)).willReturn(expectedResult);

// when & then
mvc.perform(
multipart("/api/instruments/acoustic-and-classic-guitars/{acousticAndClassicGuitarId}",
acousticAndClassicGuitarId)
.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("brand", String.valueOf(updateRequest.getBrand()))
.param("model", String.valueOf(updateRequest.getModel()))
.param("wood", String.valueOf(updateRequest.getWood()))
.param("pickUp", String.valueOf(updateRequest.getPickUp()))
.with(user(createTestUser(userId)))
.with(request -> {
request.setMethod("PATCH");
return request;
})
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(expectedResult.getId()));
then(instrumentCommandService)
.should()
.updateAcousticAndClassicGuitar(eq(userId), eq(acousticAndClassicGuitarId),
any(AcousticAndClassicGuitarUpdateRequest.class));
verifyEveryMocksShouldHaveNoMoreInteractions();
}

@Test
void 악기_id가_주어지고_해당하는_악기_매물을_삭제한다() throws Exception {
// given
Expand Down Expand Up @@ -1046,4 +1091,25 @@ private ElectricGuitarUpdateRequest createElectricGuitarUpdateRequest() throws E
GuitarColor.RED
);
}

private AcousticAndClassicGuitarUpdateRequest createAcousticAndClassicGuitarUpdateRequest() throws Exception {
return ReflectionUtils.createAcousticAndClassicGuitarUpdateRequest(
"Test AcousticAndClassicGuitar",
InstrumentProgressStatus.SOLD_OUT,
createAddressRequest(),
(short)3,
550000,
true,
"description",
null,
null,
null,
null,
AcousticAndClassicGuitarBrand.CRAFTER,
AcousticAndClassicGuitarModel.CUTAWAY,
AcousticAndClassicGuitarWood.SOLID_WOOD,
AcousticAndClassicGuitarPickUp.MAGNETIC
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.constant.AcousticAndClassicGuitarPickUp;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.constant.AcousticAndClassicGuitarWood;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.AcousticAndClassicGuitarDto;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.AcousticAndClassicGuitarUpdateRequest;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.CreateNewAcousticAndClassicGuitarRequest;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.entity.AcousticAndClassicGuitar;
import com.ajou.hertz.domain.instrument.amplifier.constant.AmplifierBrand;
Expand Down Expand Up @@ -334,6 +335,35 @@ class InstrumentCommandServiceTest {
assertThat(result.getImages()).hasSize(initialImages.size() - deleteImageIds.size());
}

@Test
void 삭제할_이미지들의_id_리스트가_주어지고_어쿠스틱_매물_정보를_수정하면_악기_이미지들이_삭제된다() throws Exception {
// given
long userId = 1L;
long instrumentId = 2L;
List<Long> deleteImageIds = List.of(3L, 4L);
AcousticAndClassicGuitar AcousticAndClassicGuitar = createAcousticAndClassicGuitar(instrumentId,
createUser(userId));
List<InstrumentImage> initialImages = List.of(
createInstrumentImage(deleteImageIds.get(0), AcousticAndClassicGuitar),
createInstrumentImage(deleteImageIds.get(1), AcousticAndClassicGuitar)
);
AcousticAndClassicGuitar.getImages().addAll(initialImages);
AcousticAndClassicGuitarUpdateRequest updateRequest = createAcousticAndClassicGuitarUpdateRequest(
deleteImageIds, null, null, null);
given(instrumentQueryService.getInstrumentById(instrumentId))
.willReturn(AcousticAndClassicGuitar);
willDoNothing().given(instrumentImageCommandService).deleteAllByIds(deleteImageIds);

// when
AcousticAndClassicGuitarDto result = sut.updateAcousticAndClassicGuitar(userId, instrumentId, updateRequest);

// then
then(instrumentQueryService).should().getInstrumentById(instrumentId);
then(instrumentImageCommandService).should().deleteAllByIds(deleteImageIds);
verifyEveryMocksShouldHaveNoMoreInteractions();
assertThat(result.getImages()).hasSize(initialImages.size() - deleteImageIds.size());
}

@Test
void 추가할_이미지들이_주어지고_매물_정보를_수정하면_새로운_악기_이미지들이_추가된다() throws Exception {
// given
Expand Down Expand Up @@ -749,4 +779,17 @@ private ElectricGuitarUpdateRequest createElectricGuitarUpdateRequest(
null, null, null, null
);
}

private AcousticAndClassicGuitarUpdateRequest createAcousticAndClassicGuitarUpdateRequest(
@Nullable List<Long> deletedImageIds,
@Nullable List<MultipartFile> newImages,
@Nullable List<Long> deletedHashtagIds,
@Nullable List<String> newHashtags
) throws Exception {
return ReflectionUtils.createAcousticAndClassicGuitarUpdateRequest(
null, null, null, null, null, null, null,
deletedImageIds, newImages, deletedHashtagIds, newHashtags,
null, null, null, null
);
}
}
44 changes: 44 additions & 0 deletions src/test/java/com/ajou/hertz/util/ReflectionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.constant.AcousticAndClassicGuitarWood;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.AcousticAndClassicGuitarDto;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.AcousticAndClassicGuitarFilterConditions;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.AcousticAndClassicGuitarUpdateRequest;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.dto.request.CreateNewAcousticAndClassicGuitarRequest;
import com.ajou.hertz.domain.instrument.acoustic_and_classic_guitar.entity.AcousticAndClassicGuitar;
import com.ajou.hertz.domain.instrument.amplifier.constant.AmplifierBrand;
Expand Down Expand Up @@ -1015,6 +1016,49 @@ public static ElectricGuitarUpdateRequest createElectricGuitarUpdateRequest(
);
}

public static AcousticAndClassicGuitarUpdateRequest createAcousticAndClassicGuitarUpdateRequest(
@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 AcousticAndClassicGuitarBrand brand,
@Nullable AcousticAndClassicGuitarModel model,
@Nullable AcousticAndClassicGuitarWood wood,
@Nullable AcousticAndClassicGuitarPickUp pickUp
) throws Exception {
Constructor<AcousticAndClassicGuitarUpdateRequest> constructor = AcousticAndClassicGuitarUpdateRequest.class.getDeclaredConstructor(
String.class, InstrumentProgressStatus.class, AddressRequest.class, Short.class,
Integer.class, Boolean.class, String.class, List.class, List.class, List.class, List.class,
AcousticAndClassicGuitarBrand.class, AcousticAndClassicGuitarModel.class,
AcousticAndClassicGuitarWood.class, AcousticAndClassicGuitarPickUp.class
);
constructor.setAccessible(true);
return constructor.newInstance(
title,
progressStatus,
tradeAddress,
qualityStatus,
price,
hasAnomaly,
description,
deletedImageIds,
newImages,
deletedHashtagIds,
newHashtags,
brand,
model,
wood,
pickUp
);
}

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

0 comments on commit 1e71a01

Please sign in to comment.