Skip to content

Commit

Permalink
Mbc 41 task fix bug swagger and verify bill services by test cases (#24)
Browse files Browse the repository at this point in the history
* fix: bug login, swagger https

* test: 50% bill + projection showtime

* test: 100% bill service unit testing

* refactor: add projection for rooms

* fix: application not loaded integration testing

* test: add test crash controller
refactor: separate error info ( use for swagger later)

* add chore file

* test: add integration test for creating bill success

* test: 100% coverage bills

* hotfix: fix reference and error information of swagger

* hotfix: fix security tickets

---------

Co-authored-by: Tiền Minh Vy <[email protected]>
  • Loading branch information
1119-DuyNguyen and tienminhvy authored Jul 19, 2024
1 parent ccd59c8 commit 91be72f
Show file tree
Hide file tree
Showing 56 changed files with 3,742 additions and 407 deletions.
Binary file added document/bill-100-coverage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 40 additions & 52 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@
<version>1.19.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mysql</artifactId>
<version>1.19.8</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
Expand Down Expand Up @@ -298,41 +304,7 @@
</dependency>
</dependencies>
</plugin>
<!-- <plugin>-->
<!-- <groupId>io.github.berkleytechnologyservices</groupId>-->
<!-- <artifactId>restdocs-spec-maven-plugin</artifactId>-->
<!-- <version>${restdocs-spec.version}</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <goals>-->
<!-- <goal>generate</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <specification>OPENAPI_V3</specification>-->
<!-- <outputDirectory>${project.build.directory}/classes/static</outputDirectory>-->
<!-- <host>${server.variable.url}</host>-->
<!-- <oauth2>-->

<!-- <tokenUrl>http://${server.variable.url}/oauth2/token</tokenUrl>-->
<!-- <authorizationUrl>http://${server.variable.url}/oauth2/authorize</authorizationUrl>-->
<!-- <flows>-->
<!-- <flow>authorizationCode</flow>-->
<!-- </flows>-->
<!-- &lt;!&ndash; <scopes>&ndash;&gt;-->
<!-- &lt;!&ndash; <scope>&ndash;&gt;-->
<!-- &lt;!&ndash; <name>read</name>&ndash;&gt;-->
<!-- &lt;!&ndash; <description>Access to read operations.</description>&ndash;&gt;-->
<!-- &lt;!&ndash; </scope>&ndash;&gt;-->
<!-- &lt;!&ndash; <scope>&ndash;&gt;-->
<!-- &lt;!&ndash; <name>write</name>&ndash;&gt;-->
<!-- &lt;!&ndash; <description>Access to write operations.</description>&ndash;&gt;-->
<!-- &lt;!&ndash; </scope>&ndash;&gt;-->
<!-- &lt;!&ndash; </scopes>&ndash;&gt;-->
<!-- </oauth2>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
Expand All @@ -353,24 +325,6 @@
</execution>
</executions>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.springdoc</groupId>-->
<!-- <artifactId>springdoc-openapi-maven-plugin</artifactId>-->
<!-- <version>1.4</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <phase>integration-test</phase>-->
<!-- <goals>-->
<!-- <goal>generate</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- <plugin>-->
<!-- <groupId>de.qaware.maven</groupId>-->
<!-- <artifactId>go-offline-maven-plugin</artifactId>-->
<!-- <version>${go-offline-maven-plugin.version}</version>-->
<!-- </plugin>-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
Expand All @@ -391,5 +345,39 @@
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>unit-test</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/Test*.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>integration-test</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</profile>

</profiles>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
import java.util.UUID;

@SpringBootApplication
@EnableJpaRepositories(includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = JpaRepository.class))
@EnableElasticsearchRepositories(includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ElasticsearchRepository.class))
//@EnableJpaRepositories(includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = JpaRepository.class))
//@EnableElasticsearchRepositories(includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ElasticsearchRepository.class))
public class MovieBookingApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

package com.tech_symfony.movie_booking.api;

import com.tech_symfony.movie_booking.system.exception.ErrorInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* Controller used to showcase what happens when an exception is thrown
*/
@RestController
class CrashController {

@Operation(
summary = "Kiểm thử khả năng xử lý lỗi của ứng dụng"
)

@GetMapping("/oups")
public ResponseEntity<String> triggerException() {
throw new RuntimeException(
"Expected: controller used to showcase what " + "happens when an exception is thrown");
}

}
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
package com.tech_symfony.movie_booking.api;

import com.tech_symfony.movie_booking.api.bill.Bill;
import com.tech_symfony.movie_booking.api.cinema.Cinema;
import com.tech_symfony.movie_booking.api.movie.Movie;
import com.tech_symfony.movie_booking.api.movie.MovieRepository;
import com.tech_symfony.movie_booking.api.showtime.Showtime;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkRelation;
import org.springframework.hateoas.RepresentationModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

@RestController
@RequiredArgsConstructor
public class RootController {
private final RepositoryEntityLinks entityLinks;

@Operation(
summary = "Đường dẫn gốc",
description = "Từ đường dẫn này sẽ đi đến những đường dẫn khác dựa theo hành vi người dùng"
)
@GetMapping
RepresentationModel<?> index() {

Expand Down
16 changes: 8 additions & 8 deletions src/main/java/com/tech_symfony/movie_booking/api/bill/Bill.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.tech_symfony.movie_booking.api.bill;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.tech_symfony.movie_booking.api.ticket.Ticket;
import com.tech_symfony.movie_booking.api.user.User;
import com.tech_symfony.movie_booking.model.BaseUUIDEntity;
Expand Down Expand Up @@ -38,34 +39,34 @@ public class Bill extends BaseUUIDEntity {
private Double total;

@Column(name = "transaction_id")
// @NotEmpty(message = "Transaction id must not be empty")
private String transactionId;

@Column(name = "cancel_reason")
@NotNull(message = "Cancel reason must not be null")
private String cancelReason = "";

@Column(name = "cancel_date")
@Temporal(TemporalType.TIMESTAMP)
private LocalDateTime cancelDate;


//WARN: a collection doesn't contain tickets so avoiding N+1 problem
@OneToMany(
mappedBy = "bill",
fetch = FetchType.LAZY,
cascade = CascadeType.ALL
cascade = CascadeType.PERSIST
)
@JoinColumn(name = "bill_id")
private Set<Ticket> tickets;

@ManyToOne
@JoinColumn(
name = "user_id",
nullable = false
nullable = false,
updatable = false
)
@NotNull(message = "User must not be null")
private User user;


@NotNull(message = "Gender must not be null")
@NotNull(message = "Status must not be null")
@Enumerated(EnumType.ORDINAL)
private BillStatus status = BillStatus.IN_PROGRESS;

Expand All @@ -74,7 +75,6 @@ public void addTicket(
) {
if (this.tickets == null) this.tickets = new HashSet<>();
this.tickets.add(ticket);
ticket.setBill(this);
}

@Transient
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.tech_symfony.movie_booking.api.bill;

import com.tech_symfony.movie_booking.api.bill.dto.BillRequestDTO;
import com.tech_symfony.movie_booking.api.user.UserAuthUtilService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.rest.webmvc.RepositoryRestController;
Expand All @@ -11,21 +12,22 @@
import org.springframework.hateoas.Link;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.UUID;


@RequiredArgsConstructor
@RepositoryRestController
@ResponseBody
@SecurityRequirement(name = "security_auth")
@Tag(name = "bill-entity-controller")
public class BillController {

private final BillService billService;
private final RepositoryEntityLinks entityLinks;
private final BillModelAssembler billModelAssembler;
private final UserAuthUtilService userAuthUtilService;

@Operation(
summary = "Thêm hóa đơn kèm vé trước khi thanh toán",
Expand All @@ -35,11 +37,11 @@ public class BillController {
)
@PostMapping(value = "/bills")
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<EntityModel<Bill>> create(
@Valid @RequestBody BillRequestDTO dataRaw,
Principal principal
public ResponseEntity<EntityModel<BillInfoProjection>> create(
@Valid @RequestBody BillRequestDTO dataRaw
) {
Bill newBill = billService.create(dataRaw, principal.getName());

Bill newBill = billService.create(dataRaw, userAuthUtilService.getCurrentUsername());
Link link = entityLinks.linkToItemResource(Bill.class, newBill.getId());
return ResponseEntity
.created(link.toUri())
Expand All @@ -54,22 +56,21 @@ public ResponseEntity<EntityModel<Bill>> create(
"sẽ được nêu rõ. "
)
@PutMapping(value = "/bills/{id}/payment")
public EntityModel<Bill> pay(
public EntityModel<BillInfoProjection> pay(
@PathVariable UUID id
) {

return billModelAssembler.toModel(billService.pay(id));
return billModelAssembler.toModel(billService.pay(id, userAuthUtilService.getCurrentUsername()));
}

@Operation(
summary = "Cập nhập thanh toán",
description = "Api được gọi khi khách hàng vào rạp, nhân viên sẽ quét QR và cập nhập trạng thái đơn hàng đã sử dụng thành công"
description = "Api được gọi khi khách hàng vào rạp, nhân viên sẽ quét và cập nhập trạng thái đã sử dụng thành công"
)
@PutMapping(value = "/bills/{id}")
public EntityModel<Bill> updateStatus(
public EntityModel<BillInfoProjection> updateStatus(
@PathVariable UUID id
) {
// TODO: chưa ràng buộc thời hạn nếu như vé bị outdated
return billModelAssembler.toModel(billService.updateStatus(id));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,43 @@
package com.tech_symfony.movie_booking.api.bill;


import jakarta.servlet.ServletException;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.RepresentationModelAssembler;
import org.springframework.stereotype.Component;

import java.io.IOException;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

@Component
@AllArgsConstructor
class BillModelAssembler implements RepresentationModelAssembler<Bill, EntityModel<Bill>> {
@RequiredArgsConstructor
class BillModelAssembler implements RepresentationModelAssembler<Bill, EntityModel<BillInfoProjection>> {

private final RepositoryEntityLinks entityLinks;
private final ProjectionFactory projectionFactory;

@Override
public EntityModel<Bill> toModel(Bill bill) {
public EntityModel<BillInfoProjection> toModel(Bill bill) {
Link linkNewResource = entityLinks.linkToItemResource(Bill.class, bill.getId());
Link linkCollectionResource = entityLinks.linkToCollectionResource(Bill.class);

// Unconditional links to single-item resource and aggregate root
BillInfoProjection projection = projectionFactory.createProjection(BillInfoProjection.class, bill);

EntityModel<Bill> billModel = EntityModel.of(
bill,
EntityModel<BillInfoProjection> billModel = EntityModel.of(
projection,
linkNewResource,
linkCollectionResource);

// Conditional links based on state of the order

if (bill.getStatus() == BillStatus.IN_PROGRESS) {
// orderModel.add(linkTo(methodOn(BillController.class).cancel(bill.getId())).withRel("cancel"));
billModel.add(linkTo(methodOn(BillController.class).pay(bill.getId())).withRel("pay"));
}

return billModel;
}

Expand Down
Loading

0 comments on commit 91be72f

Please sign in to comment.