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
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package in.koreatech.koin.domain.land.controller;

import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import in.koreatech.koin.domain.land.dto.LandListItemResponse;
import in.koreatech.koin.domain.land.service.LandService;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
public class LandController {

private final LandService landService;

@GetMapping("/lands")
public ResponseEntity<List<LandListItemResponse>> getLands() {
List<LandListItemResponse> responses = landService.getLands();
return ResponseEntity.ok(responses);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package in.koreatech.koin.domain.land.dto;

import static com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;

import com.fasterxml.jackson.databind.annotation.JsonNaming;

import in.koreatech.koin.domain.land.model.Land;

@JsonNaming(value = SnakeCaseStrategy.class)
public record LandListItemResponse(
String internalName,
String monthlyFee,
String latitude,
String charterFee,
String name,
Long id,
String longitude,
String roomType) {

public static LandListItemResponse from(Land land) {
return new LandListItemResponse(
land.getInternalName(),
land.getMonthlyFee(),
land.getLatitude(),
land.getCharterFee(),
land.getName(),
land.getId(),
land.getLongitude(),
land.getRoomType()
);
}
}
177 changes: 177 additions & 0 deletions src/main/java/in/koreatech/koin/domain/land/model/Land.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package in.koreatech.koin.domain.land.model;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Entity
@Table(name = "lands")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Land {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@Size(max = 255)
@NotNull
@Column(name = "name", nullable = false)
private String name;

@Size(max = 50)
@NotNull
@Column(name = "internal_name", nullable = false, length = 50)
private String internalName;

@Size(max = 20)
@Column(name = "size", length = 20)
private String size;

@Size(max = 20)
@Column(name = "room_type", length = 20)
private String roomType;

@Size(max = 20)
@Column(name = "latitude", length = 20)
private String latitude;

@Size(max = 20)
@Column(name = "longitude", length = 20)
private String longitude;

@Size(max = 20)
@Column(name = "phone", length = 20)
private String phone;

@Lob
@Column(name = "image_urls")
private String imageUrls;

@Lob
@Column(name = "address")
private String address;

@Lob
@Column(name = "description")
private String description;

@Column(name = "floor")
private Long floor;

@Size(max = 255)
@Column(name = "deposit")
private String deposit;

@Size(max = 255)
@Column(name = "monthly_fee")
private String monthlyFee;

@Size(max = 20)
@Column(name = "charter_fee", length = 20)
private String charterFee;

@Size(max = 255)
@Column(name = "management_fee")
private String managementFee;

@NotNull
@Column(name = "opt_refrigerator", nullable = false)
private Boolean optRefrigerator = false;

@NotNull
@Column(name = "opt_closet", nullable = false)
private Boolean optCloset = false;

@NotNull
@Column(name = "opt_tv", nullable = false)
private Boolean optTv = false;

@NotNull
@Column(name = "opt_microwave", nullable = false)
private Boolean optMicrowave = false;

@NotNull
@Column(name = "opt_gas_range", nullable = false)
private Boolean optGasRange = false;

@NotNull
@Column(name = "opt_induction", nullable = false)
private Boolean optInduction = false;

@NotNull
@Column(name = "opt_water_purifier", nullable = false)
private Boolean optWaterPurifier = false;

@NotNull
@Column(name = "opt_air_conditioner", nullable = false)
private Boolean optAirConditioner = false;

@NotNull
@Column(name = "opt_washer", nullable = false)
private Boolean optWasher = false;

@NotNull
@Column(name = "opt_bed", nullable = false)
private Boolean optBed = false;

@NotNull
@Column(name = "opt_desk", nullable = false)
private Boolean optDesk = false;

@NotNull
@Column(name = "opt_shoe_closet", nullable = false)
private Boolean optShoeCloset = false;

@NotNull
@Column(name = "opt_electronic_door_locks", nullable = false)
private Boolean optElectronicDoorLocks = false;

@NotNull
@Column(name = "opt_bidet", nullable = false)
private Boolean optBidet = false;

@NotNull
@Column(name = "opt_veranda", nullable = false)
private Boolean optVeranda = false;

@NotNull
@Column(name = "opt_elevator", nullable = false)
private Boolean optElevator = false;

@NotNull
@Column(name = "is_deleted", nullable = false)
private Boolean isDeleted = false;

@Builder
private Land(String internalName, String name, String size, String roomType, String latitude, String longitude,
String phone, String imageUrls, String address, String description, Long floor, String deposit,
String monthlyFee, String charterFee, String managementFee) {
this.internalName = internalName;
this.name = name;
this.size = size;
this.roomType = roomType;
this.latitude = latitude;
this.longitude = longitude;
this.phone = phone;
this.imageUrls = imageUrls;
this.address = address;
this.description = description;
this.floor = floor;
this.deposit = deposit;
this.monthlyFee = monthlyFee;
this.charterFee = charterFee;
this.managementFee = managementFee;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package in.koreatech.koin.domain.land.repository;

import java.util.List;

import org.springframework.data.repository.Repository;

import in.koreatech.koin.domain.land.model.Land;

public interface LandRepository extends Repository<Land, Long> {

List<Land> findAll();

Land save(Land request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package in.koreatech.koin.domain.land.service;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import in.koreatech.koin.domain.land.dto.LandListItemResponse;
import in.koreatech.koin.domain.land.repository.LandRepository;
import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class LandService {

private final LandRepository landRepository;

public List<LandListItemResponse> getLands() {
return landRepository.findAll()
.stream()
.map(LandListItemResponse::from)
.toList();
}
}
67 changes: 67 additions & 0 deletions src/test/java/in/koreatech/koin/acceptance/LandApiTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package in.koreatech.koin.acceptance;

import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;

import in.koreatech.koin.AcceptanceTest;
import in.koreatech.koin.domain.land.model.Land;
import in.koreatech.koin.domain.land.repository.LandRepository;
import io.restassured.RestAssured;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;

class LandApiTest extends AcceptanceTest {

@Autowired
private LandRepository landRepository;

@Test
@DisplayName("복덕방 리스트를 조회한다.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼼꼼한 테스트 👍

void getLands() {
Land request = Land.builder()
.internalName("복덕방")
.name("복덕방")
.roomType("원룸")
.latitude("37.555")
.longitude("126.555")
.monthlyFee("100")
.charterFee("1000")
.build();

Land land = landRepository.save(request);

ExtractableResponse<Response> response = RestAssured
.given()
.log().all()
.when()
.log().all()
.get("/lands")
.then()
.log().all()
.statusCode(HttpStatus.OK.value())
.extract();

SoftAssertions.assertSoftly(
softly -> {
softly.assertThat(response.body().jsonPath().getList(".").size()).isEqualTo(1);
softly.assertThat(response.body().jsonPath().getLong("[0].id")).isEqualTo(land.getId());
softly.assertThat(response.body().jsonPath().getString("[0].internal_name"))
.isEqualTo(land.getInternalName());
softly.assertThat(response.body().jsonPath().getString("[0].name")).isEqualTo(land.getName());
softly.assertThat(response.body().jsonPath().getString("[0].room_type"))
.isEqualTo(land.getRoomType());
softly.assertThat(response.body().jsonPath().getString("[0].latitude"))
.isEqualTo(land.getLatitude());
softly.assertThat(response.body().jsonPath().getString("[0].longitude"))
.isEqualTo(land.getLongitude());
softly.assertThat(response.body().jsonPath().getString("[0].monthly_fee"))
.isEqualTo(land.getMonthlyFee());
softly.assertThat(response.body().jsonPath().getString("[0].charter_fee"))
.isEqualTo(land.getCharterFee());
}
);
}
}