From a8768537f31b069d62a698128d216932988523d7 Mon Sep 17 00:00:00 2001 From: Junbye Date: Sat, 11 Jan 2025 14:13:42 +0900 Subject: [PATCH] =?UTF-8?q?DataGenerator=20RequestBody=20=EC=96=91?= =?UTF-8?q?=EC=8B=9D=20=EC=88=98=EC=A0=95=20Price=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20Room=EA=B4=80=EB=A0=A8=20Test=20=EA=B7=B8?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EC=B6=B0=EC=84=9C=20Body=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/toyTeam6Airbnb/DataGenerator.kt | 22 +- .../toyTeam6Airbnb/ReviewIntegrationTest.kt | 136 ++++++++++- .../toyTeam6Airbnb/RoomConcurrencyTest.kt | 62 +++-- .../toyTeam6Airbnb/RoomControllerTest.kt | 212 +++++++++++------- 4 files changed, 316 insertions(+), 116 deletions(-) diff --git a/src/test/kotlin/com/example/toyTeam6Airbnb/DataGenerator.kt b/src/test/kotlin/com/example/toyTeam6Airbnb/DataGenerator.kt index afbe2a6..e3cb204 100644 --- a/src/test/kotlin/com/example/toyTeam6Airbnb/DataGenerator.kt +++ b/src/test/kotlin/com/example/toyTeam6Airbnb/DataGenerator.kt @@ -6,6 +6,7 @@ import com.example.toyTeam6Airbnb.reservation.persistence.ReservationRepository import com.example.toyTeam6Airbnb.review.persistence.ReviewEntity import com.example.toyTeam6Airbnb.review.persistence.ReviewRepository import com.example.toyTeam6Airbnb.room.persistence.Address +import com.example.toyTeam6Airbnb.room.persistence.Price import com.example.toyTeam6Airbnb.room.persistence.RoomDetails import com.example.toyTeam6Airbnb.room.persistence.RoomEntity import com.example.toyTeam6Airbnb.room.persistence.RoomRepository @@ -76,14 +77,16 @@ class DataGenerator( ): ReservationEntity { val userEntity = user ?: generateUserAndToken().first val roomEntity = room ?: generateRoom() + val start = startDate ?: LocalDate.now().plusDays((1..100).random().toLong()) + val end = endDate ?: start.plusDays((1..10).random().toLong()) return reservationRepository.save( ReservationEntity( user = userEntity, room = roomEntity, review = null, - startDate = startDate ?: LocalDate.now().plusDays((1..100).random().toLong()), - endDate = endDate ?: startDate!!.plusDays((1..10).random().toLong()), - totalPrice = roomEntity.price * ChronoUnit.DAYS.between(startDate, endDate), + startDate = start, + endDate = end, + totalPrice = totalPrice ?: (roomEntity.price.total * ChronoUnit.DAYS.between(start, end)), numberOfGuests = numberOfGuests ?: (1..10).random() ) ) @@ -96,7 +99,7 @@ class DataGenerator( type: RoomType? = null, address: Address? = null, roomDetails: RoomDetails? = null, - price: Double? = null, + price: Price? = null, maxOccupancy: Int? = null ): RoomEntity { val hostEntity = host ?: generateUserAndToken().first @@ -117,9 +120,16 @@ class DataGenerator( wifi = (0..1).random() == 1, selfCheckin = (0..1).random() == 1, luggage = (0..1).random() == 1, - TV = (0..1).random() == 1 + TV = (0..1).random() == 1, + bedroom = (1..5).random(), + bathroom = (1..3).random(), + bed = (1..3).random() + ), + price = price ?: Price( + perNight = (10000..50000).random().toDouble(), + cleaningFee = (5000..10000).random().toDouble(), + charge = (1000..5000).random().toDouble() ), - price = price ?: (10000..100000).random().toDouble(), maxOccupancy = maxOccupancy ?: (1..10).random() ) ) diff --git a/src/test/kotlin/com/example/toyTeam6Airbnb/ReviewIntegrationTest.kt b/src/test/kotlin/com/example/toyTeam6Airbnb/ReviewIntegrationTest.kt index e832ec9..7f66014 100644 --- a/src/test/kotlin/com/example/toyTeam6Airbnb/ReviewIntegrationTest.kt +++ b/src/test/kotlin/com/example/toyTeam6Airbnb/ReviewIntegrationTest.kt @@ -1,6 +1,138 @@ package com.example.toyTeam6Airbnb +import com.example.toyTeam6Airbnb.review.persistence.ReviewRepository +import com.example.toyTeam6Airbnb.room.persistence.RoomRepository +import com.example.toyTeam6Airbnb.user.persistence.UserRepository +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.http.MediaType +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders +import org.springframework.test.web.servlet.result.MockMvcResultHandlers +import org.springframework.test.web.servlet.result.MockMvcResultMatchers +import kotlin.test.assertEquals + // Review CRUD 테스트에 대한 테스트코드를 작성해줘 // DataGenerator 사용해 -// ReviewRepository, UserRepository, RoomRepository를 사용해 -class ReviewIntegrationTest +// ReviewRepository, UserRepository, RoomRepository를 사용해서 작성해줘 +@SpringBootTest +@AutoConfigureMockMvc +class ReviewIntegrationTest { + + @Autowired + private lateinit var mockMvc: MockMvc + + @Autowired + private lateinit var reviewRepository: ReviewRepository + + @Autowired + private lateinit var userRepository: UserRepository + + @Autowired + private lateinit var roomRepository: RoomRepository + + @Autowired + private lateinit var dataGenerator: DataGenerator + + @BeforeEach + fun setUp() { + dataGenerator.clearAll() + } + + @Test + fun `should create a review`() { + val (user, token) = dataGenerator.generateUserAndToken() + val room = dataGenerator.generateRoom(maxOccupancy = 100) + val reservation = dataGenerator.generateReservation(user, room) + + val requestBody = """ + { + "roomId": ${room.id}, + "reservationId": ${reservation.id}, + "content": "Great place!", + "rating": 5 + } + """.trimIndent() + + val result = mockMvc.perform( + MockMvcRequestBuilders.post("/api/v1/reviews") + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody) + .header("Authorization", "Bearer $token") + ) + .andDo(MockMvcResultHandlers.print()) + .andExpect(MockMvcResultMatchers.status().isCreated) + .andReturn() + + val reviews = reviewRepository.findAll() + assertEquals(1, reviews.size) + assertEquals("Great place!", reviews[0].content) + } + + @Test + fun `should update a review`() { + val (user, token) = dataGenerator.generateUserAndToken() + val room = dataGenerator.generateRoom() + val reservation = dataGenerator.generateReservation(user, room) + val review = dataGenerator.generateReview(reservation, "Great place!", 5) + + val requestBody = """ + { + "content": "Good place!", + "rating": 4 + } + """.trimIndent() + + val result = mockMvc.perform( + MockMvcRequestBuilders.put("/api/v1/reviews/${review.id}") + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody) + .header("Authorization", "Bearer $token") + ) + .andExpect(MockMvcResultMatchers.status().isOk) + .andReturn() + + val updatedReview = review.id?.let { reviewRepository.findById(it).get() } + assertEquals(4, updatedReview?.rating) + assertEquals("Good place!", updatedReview?.content) + } + + @Test + fun `should delete a review`() { + val (user, token) = dataGenerator.generateUserAndToken() + val room = dataGenerator.generateRoom() + val reservation = dataGenerator.generateReservation(user, room) + val review = dataGenerator.generateReview(reservation) + + val result = mockMvc.perform( + MockMvcRequestBuilders.delete("/api/v1/reviews/${review.id}") + .header("Authorization", "Bearer $token") + ) + .andExpect(MockMvcResultMatchers.status().isNoContent) + .andReturn() + + val reviews = reviewRepository.findAll() + assertEquals(0, reviews.size) + } + + @Test + fun `should get a review`() { + val (user, token) = dataGenerator.generateUserAndToken() + val room = dataGenerator.generateRoom() + val reservation = dataGenerator.generateReservation(user, room) + val review = dataGenerator.generateReview(reservation) + + val result = mockMvc.perform( + MockMvcRequestBuilders.get("/api/v1/reviews/${review.id}") + .header("Authorization", "Bearer $token") + ) + .andExpect(MockMvcResultMatchers.status().isOk) + .andReturn() + + val responseContent = result.response.contentAsString + println(responseContent) + } +} diff --git a/src/test/kotlin/com/example/toyTeam6Airbnb/RoomConcurrencyTest.kt b/src/test/kotlin/com/example/toyTeam6Airbnb/RoomConcurrencyTest.kt index 9b6fd78..e724cec 100644 --- a/src/test/kotlin/com/example/toyTeam6Airbnb/RoomConcurrencyTest.kt +++ b/src/test/kotlin/com/example/toyTeam6Airbnb/RoomConcurrencyTest.kt @@ -55,10 +55,18 @@ class RoomConcurrencyTest { "wifi": true, "selfCheckin": false, "luggage": false, - "TV": true + "TV": true, + "bedroom": 1, + "bathroom": 1, + "bed": 1 }, - "price": 75000.0, - "maxOccupancy": 4 + "price": { + "perNight": 5000, + "cleaningFee": 5000, + "charge": 5000, + "total": 15000 + }, + "maxOccupancy": 1 } """.trimIndent() @@ -102,7 +110,7 @@ class RoomConcurrencyTest { // requestBody를 위와 같은 형태로 하여 서로 다른 유저가 같은 방을 만드는 동시성 상황에 대한 테스트 케이스 형성 @Test - fun `동일한 요청이 서로 다른 유저로부터 들어오면 방이 각각 만들어져야함`() { + fun `동일한 요청이 서로 다른 유저로부터 들어오면 방이 하나만 만들어져야함`() { val (user1, token1) = dataGenerator.generateUserAndToken() val (user2, token2) = dataGenerator.generateUserAndToken() @@ -110,25 +118,33 @@ class RoomConcurrencyTest { val executor = Executors.newFixedThreadPool(2) val requestBody = """ - { - "name": "Cozy Apartment in Seoul", - "description": "A beautiful and cozy apartment located in the heart of Seoul. Perfect for travelers!", - "type": "APARTMENT", - "address": { - "sido": "Seoul", - "sigungu": "Jongno-gu", - "street": "123 Hanok Street", - "detail": "Apartment 5B" - }, - "roomDetails": { - "wifi": true, - "selfCheckin": false, - "luggage": false, - "TV": true - }, - "price": 75000.0, - "maxOccupancy": 4 - } + { + "name": "Cozy Apartment in Seoul", + "description": "A beautiful and cozy apartment located in the heart of Seoul. Perfect for travelers!", + "type": "APARTMENT", + "address": { + "sido": "Seoul", + "sigungu": "Jongno-gu", + "street": "123 Hanok Street", + "detail": "Apartment 5B" + }, + "roomDetails": { + "wifi": true, + "selfCheckin": false, + "luggage": false, + "TV": true, + "bedroom": 1, + "bathroom": 1, + "bed": 1 + }, + "price": { + "perNight": 50000, + "cleaningFee": 20000, + "charge": 5000, + "total": 0 + }, + "maxOccupancy": 4 + } """.trimIndent() executor.submit { diff --git a/src/test/kotlin/com/example/toyTeam6Airbnb/RoomControllerTest.kt b/src/test/kotlin/com/example/toyTeam6Airbnb/RoomControllerTest.kt index 7bc6c0f..1accdb9 100644 --- a/src/test/kotlin/com/example/toyTeam6Airbnb/RoomControllerTest.kt +++ b/src/test/kotlin/com/example/toyTeam6Airbnb/RoomControllerTest.kt @@ -36,22 +36,31 @@ class RoomControllerTest { val requestBody = """ { "name": "Sample Room", - "description": "A nice place to stay", + "description": "A beautiful and cozy apartment located in the heart of Seoul. Perfect for travelers!", "type": "APARTMENT", "address": { "sido": "Seoul", - "sigungu": "Gangnam", - "street": "Gangnam Daero", - "detail": "12345" + "sigungu": "Jongno-gu", + "street": "123 Hanok Street", + "detail": "Apartment 5B" }, "roomDetails": { "wifi": true, - "selfCheckin": true, - "luggage": true, - "TV": true + "selfCheckin": false, + "luggage": false, + "TV": true, + "bedroom": 1, + "bathroom": 1, + "bed": 1, + "tv": true + }, + "price": { + "perNight": 5000, + "cleaningFee": 10000, + "charge": 500, + "total": 0 }, - "price": 10000, - "maxOccupancy": 4 + "maxOccupancy": 1 } """.trimIndent() @@ -75,25 +84,33 @@ class RoomControllerTest { // create a room with mockmvc val requestBody = """ - { - "name": "Sample Room_2", - "description": "A nice place to stay", - "type": "VILLA", - "address": { - "sido": "Seoul", - "sigungu": "Gangnam", - "street": "Gangnam Daero", - "detail": "34567" - }, - "roomDetails": { - "wifi": true, - "selfCheckin": true, - "luggage": true, - "TV": true - }, - "price": 100000, - "maxOccupancy": 4 - } + { + "name": "Sample Room_2", + "description": "A nice place to stay", + "type": "VILLA", + "address": { + "sido": "Seoul", + "sigungu": "Gangnam", + "street": "Gangnam Daero", + "detail": "34567" + }, + "roomDetails": { + "wifi": true, + "selfCheckin": false, + "luggage": false, + "TV": true, + "bedroom": 1, + "bathroom": 1, + "bed": 1 + }, + "price": { + "perNight": 5000, + "cleaningFee": 10000, + "charge": 500, + "total": 0 + }, + "maxOccupancy": 1 + } """.trimIndent() val create_result = mockMvc.perform( @@ -176,27 +193,35 @@ class RoomControllerTest { val (user2, token2) = dataGenerator.generateUserAndToken() val requestBody = """ - { - "name": "Sample Room", - "description": "A nice place to stay", - "type": "APARTMENT", - "address": { - "sido": "Seoul", - "sigungu": "Gangnam", - "street": "Gangnam Daero", - "detail": "12345" - }, - "roomDetails": { - "wifi": true, - "selfCheckin": true, - "luggage": true, - "TV": true - }, - "price": 10000, - "maxOccupancy": 4 - } + { + "name": "Sample Room", + "description": "A beautiful and cozy apartment located in the heart of Seoul. Perfect for travelers!", + "type": "APARTMENT", + "address": { + "sido": "Seoul", + "sigungu": "Jongno-gu", + "street": "123 Hanok Street", + "detail": "Apartment 5B" + }, + "roomDetails": { + "wifi": true, + "selfCheckin": false, + "luggage": false, + "TV": true, + "bedroom": 1, + "bathroom": 1, + "bed": 1, + "tv": true + }, + "price": { + "perNight": 5000, + "cleaningFee": 10000, + "charge": 500, + "total": 0 + }, + "maxOccupancy": 1 + } """.trimIndent() - val result = mockMvc.perform( MockMvcRequestBuilders.post("/api/v1/rooms") .header("Authorization", "Bearer $token") @@ -214,24 +239,32 @@ class RoomControllerTest { val updateRequestBody = """ { - "name": "Sample Room2", - "description": "Samlpe Description", - "type": "VILLA", - "address": { - "sido": "Seoul", - "sigungu": "Gangnam", - "street": "Gangnam Daero", - "detail": "12345" - }, - "roomDetails": { - "wifi": true, - "selfCheckin": true, - "luggage": true, - "TV": true - }, - "price": 10000, - "maxOccupancy": 4 - } + "name": "Sample Room_2", + "description": "A nice place to stay", + "type": "VILLA", + "address": { + "sido": "Seoul", + "sigungu": "Gangnam", + "street": "Gangnam Daero", + "detail": "34567" + }, + "roomDetails": { + "wifi": true, + "selfCheckin": false, + "luggage": false, + "TV": true, + "bedroom": 1, + "bathroom": 1, + "bed": 1 + }, + "price": { + "perNight": 5000, + "cleaningFee": 10000, + "charge": 500, + "total": 0 + }, + "maxOccupancy": 1 + } """.trimIndent() val updateResult = mockMvc.perform( @@ -264,25 +297,34 @@ class RoomControllerTest { val (user2, token2) = dataGenerator.generateUserAndToken() val requestBody = """ - { - "name": "Sample Room", - "description": "A nice place to stay", - "type": "APARTMENT", - "address": { - "sido": "Seoul", - "sigungu": "Gangnam", - "street": "Gangnam Daero", - "detail": "12345" - }, - "roomDetails": { - "wifi": true, - "selfCheckin": true, - "luggage": true, - "TV": true - }, - "price": 10000, - "maxOccupancy": 4 - } + { + "name": "Sample Room", + "description": "A beautiful and cozy apartment located in the heart of Seoul. Perfect for travelers!", + "type": "APARTMENT", + "address": { + "sido": "Seoul", + "sigungu": "Jongno-gu", + "street": "123 Hanok Street", + "detail": "Apartment 5B" + }, + "roomDetails": { + "wifi": true, + "selfCheckin": false, + "luggage": false, + "TV": true, + "bedroom": 1, + "bathroom": 1, + "bed": 1, + "tv": true + }, + "price": { + "perNight": 5000, + "cleaningFee": 10000, + "charge": 500, + "total": 0 + }, + "maxOccupancy": 1 + } """.trimIndent() val result = mockMvc.perform(