-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add purchase feature and completed purchases listing
- Loading branch information
1 parent
9b4a93a
commit 12d22c3
Showing
8 changed files
with
232 additions
and
0 deletions.
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
src/main/kotlin/org/meliapp/backend/controller/PurchaseController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package org.meliapp.backend.controller | ||
|
||
import org.meliapp.backend.dto.ApiResponse | ||
import org.meliapp.backend.dto.purchase.PurchaseRequest | ||
import org.meliapp.backend.dto.purchase.PurchaseResponse | ||
import org.meliapp.backend.service.PurchaseService | ||
import org.springframework.http.ResponseEntity | ||
import org.springframework.web.bind.annotation.* | ||
|
||
@RestController | ||
@RequestMapping("/api/purchases") | ||
class PurchaseController( | ||
private val purchaseService: PurchaseService | ||
) { | ||
|
||
@PostMapping | ||
fun buy(@RequestBody purchaseRequest: PurchaseRequest): ResponseEntity<ApiResponse<PurchaseResponse>> { | ||
return ResponseEntity.ok(ApiResponse(purchaseService.buy(purchaseRequest))) | ||
} | ||
|
||
@GetMapping | ||
fun purchases(): ResponseEntity<ApiResponse<List<PurchaseResponse>>> { | ||
return ResponseEntity.ok(ApiResponse(purchaseService.purchases())) | ||
} | ||
|
||
} |
12 changes: 12 additions & 0 deletions
12
src/main/kotlin/org/meliapp/backend/dto/product/ProductPurchaseResponse.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.meliapp.backend.dto.product | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty | ||
import java.math.BigDecimal | ||
|
||
data class ProductPurchaseResponse( | ||
@JsonProperty("meli_id") | ||
val meliId: String, | ||
val title: String, | ||
val thumbnail: String, | ||
val price: BigDecimal, | ||
) |
9 changes: 9 additions & 0 deletions
9
src/main/kotlin/org/meliapp/backend/dto/purchase/PurchaseRequest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package org.meliapp.backend.dto.purchase | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty | ||
|
||
data class PurchaseRequest( | ||
@JsonProperty(value = "meli_id") | ||
val meliId: String, | ||
val quantity: Int | ||
) |
15 changes: 15 additions & 0 deletions
15
src/main/kotlin/org/meliapp/backend/dto/purchase/PurchaseResponse.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.meliapp.backend.dto.purchase | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty | ||
import org.meliapp.backend.dto.product.ProductPurchaseResponse | ||
import java.math.BigDecimal | ||
import java.time.LocalDateTime | ||
|
||
data class PurchaseResponse( | ||
val id: Long, | ||
val quantity: Int, | ||
val product: ProductPurchaseResponse, | ||
@JsonProperty("created_at") | ||
val createdAt: LocalDateTime, | ||
val total: BigDecimal, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package org.meliapp.backend.model | ||
|
||
import jakarta.persistence.* | ||
import org.hibernate.annotations.CreationTimestamp | ||
import java.math.BigDecimal | ||
import java.time.LocalDateTime | ||
|
||
@Entity | ||
class Purchase { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
var id: Long = 0 | ||
@ManyToOne | ||
lateinit var user: User | ||
@ManyToOne | ||
lateinit var product: Product | ||
var quantity: Int = 0 | ||
@CreationTimestamp | ||
var purchaseDate: LocalDateTime = LocalDateTime.now() | ||
var totalPrice: BigDecimal = BigDecimal.ZERO | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/kotlin/org/meliapp/backend/repository/PurchaseRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package org.meliapp.backend.repository | ||
|
||
import org.meliapp.backend.model.Purchase | ||
import org.springframework.data.jpa.repository.JpaRepository | ||
import org.springframework.data.jpa.repository.Query | ||
import org.springframework.data.repository.query.Param | ||
|
||
interface PurchaseRepository : JpaRepository<Purchase, Long> { | ||
@Query("SELECT p FROM Purchase p WHERE p.user.id = :id") | ||
fun findByUserId(@Param("id") id: Long): List<Purchase> | ||
} |
59 changes: 59 additions & 0 deletions
59
src/main/kotlin/org/meliapp/backend/service/PurchaseService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package org.meliapp.backend.service | ||
|
||
import org.meliapp.backend.dto.product.ProductPurchaseResponse | ||
import org.meliapp.backend.dto.purchase.PurchaseRequest | ||
import org.meliapp.backend.dto.purchase.PurchaseResponse | ||
import org.meliapp.backend.model.Product | ||
import org.meliapp.backend.model.Purchase | ||
import org.meliapp.backend.repository.PurchaseRepository | ||
import org.springframework.stereotype.Service | ||
import java.math.BigDecimal | ||
|
||
@Service | ||
class PurchaseService( | ||
private val purchaseRepository: PurchaseRepository, | ||
private val authService: AuthService, | ||
private val productService: ProductService | ||
) { | ||
|
||
fun buy(purchaseRequest: PurchaseRequest): PurchaseResponse { | ||
val user = authService.getUserAuthenticated() | ||
val product = productService.findByMeliId(purchaseRequest.meliId) | ||
|
||
val purchase = Purchase() | ||
purchase.user = user | ||
purchase.quantity = purchaseRequest.quantity | ||
purchase.product = product | ||
purchase.totalPrice = product.price * BigDecimal(purchaseRequest.quantity) | ||
|
||
purchaseRepository.save(purchase) | ||
|
||
return toPurchaseResponse(purchase) | ||
|
||
} | ||
|
||
fun purchases(): List<PurchaseResponse> { | ||
val user = authService.getUserAuthenticated() | ||
return purchaseRepository.findByUserId(user.id).map { toPurchaseResponse(it) } | ||
} | ||
|
||
private fun toPurchaseResponse(purchase: Purchase): PurchaseResponse { | ||
return PurchaseResponse( | ||
purchase.id, | ||
purchase.quantity, | ||
toProductPurchaseResponse(purchase.product), | ||
purchase.purchaseDate, | ||
purchase.totalPrice | ||
) | ||
} | ||
|
||
private fun toProductPurchaseResponse(product: Product): ProductPurchaseResponse { | ||
return ProductPurchaseResponse( | ||
product.meliId, | ||
product.title, | ||
product.thumbnail, | ||
product.price) | ||
} | ||
|
||
|
||
} |
78 changes: 78 additions & 0 deletions
78
src/test/kotlin/org/meliapp/backend/service/PurchaseServiceUnitTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package org.meliapp.backend.service | ||
|
||
import org.junit.jupiter.api.AfterEach | ||
import org.junit.jupiter.api.BeforeEach | ||
import org.junit.jupiter.api.Test | ||
import org.junit.jupiter.api.extension.ExtendWith | ||
import org.meliapp.backend.dto.purchase.PurchaseRequest | ||
import org.meliapp.backend.model.Product | ||
import org.meliapp.backend.model.Purchase | ||
import org.meliapp.backend.model.User | ||
import org.meliapp.backend.repository.PurchaseRepository | ||
import org.mockito.InjectMocks | ||
import org.mockito.Mock | ||
import org.mockito.kotlin.* | ||
import org.springframework.test.context.junit.jupiter.SpringExtension | ||
import java.math.BigDecimal | ||
import kotlin.test.assertEquals | ||
|
||
@ExtendWith(SpringExtension::class) | ||
class PurchaseServiceUnitTest { | ||
|
||
@Mock | ||
lateinit var purchaseRepository: PurchaseRepository | ||
|
||
@Mock | ||
lateinit var productService: ProductService | ||
|
||
@Mock | ||
lateinit var authService: AuthService | ||
|
||
@InjectMocks | ||
lateinit var purchaseService: PurchaseService | ||
|
||
@BeforeEach | ||
fun setup() { | ||
val user: User = mock() | ||
whenever(user.id).thenReturn(1) | ||
whenever(authService.getUserAuthenticated()).thenReturn(user) | ||
} | ||
|
||
@AfterEach | ||
fun cleanup() { | ||
reset(purchaseRepository, productService, authService) | ||
} | ||
|
||
@Test | ||
fun `can buy an existing product`() { | ||
val meliId = "MELI_ID" | ||
val productTitle = "TITLE" | ||
val product: Product = mock() | ||
|
||
whenever(product.meliId).thenReturn(meliId) | ||
whenever(product.price).thenReturn(BigDecimal.ZERO) | ||
whenever(product.title).thenReturn(productTitle) | ||
whenever(productService.findByMeliId(meliId)).thenReturn(product) | ||
|
||
val result = purchaseService.buy(PurchaseRequest(meliId, 1)) | ||
|
||
assertEquals(meliId, result.product.meliId) | ||
assertEquals(productTitle, result.product.title) | ||
assertEquals(BigDecimal.ZERO, result.product.price) | ||
assertEquals(1, result.quantity) | ||
assertEquals(BigDecimal.ZERO, result.total) | ||
|
||
verify(purchaseRepository, times(1)).save(any<Purchase>()) | ||
|
||
} | ||
|
||
@Test | ||
fun `can get all the purchases from current user`() { | ||
whenever(purchaseRepository.findByUserId(any())).thenReturn(listOf()) | ||
|
||
val result = purchaseService.purchases() | ||
|
||
assertEquals(0, result.size) | ||
} | ||
|
||
} |