Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Submit Assessment #23

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
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
Prev Previous commit
Next Next commit
finish all requirement and starting test
caunhach committed Feb 22, 2024
commit b1e60d39702a3c9c85ecac92f9bdcc01c6895861
Original file line number Diff line number Diff line change
@@ -24,13 +24,20 @@ public AdminController(LotteryService lotteryService) {
this.lotteryService = lotteryService;
}

@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/lotteries")
public ResponseEntity<Map<String, String>> createLottery(@Valid @RequestBody LotteryRequestDto lottery) {
public ResponseEntity<Map<String, String>> createLottery(@Valid @RequestBody LotteryRequestDto lottery, BindingResult result) {
lottery.validate();
String createdLottery = lotteryService.createLottery(lottery);
Map<String, String> response = Collections.singletonMap("ticket", createdLottery);

return ResponseEntity.status(HttpStatus.CREATED).body(response);
}

@DeleteMapping("/lotteries/{ticketId}")
public ResponseEntity<Map<String, String>> deleteLottery(@PathVariable String ticketId) {
String DeletedLottery = lotteryService.deleteLottery(ticketId);
Map<String, String> response = Collections.singletonMap("ticket", DeletedLottery);

return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.kbtg.bootcamp.posttest.Controller;

import com.kbtg.bootcamp.posttest.Exception.NotFoundException;
import com.kbtg.bootcamp.posttest.Lottery.LotteryRequestDto;
import com.kbtg.bootcamp.posttest.Lottery.LotteryService;
import jakarta.validation.Valid;
@@ -14,7 +15,7 @@
import java.util.Map;

@RestController
@RequestMapping("")
@RequestMapping("/lotteries")
public class LotteryController {

@Autowired
@@ -24,24 +25,13 @@ public LotteryController(LotteryService lotteryService) {
this.lotteryService = lotteryService;
}

@GetMapping("/test")
public String hello() {
return "Hello, ";
}

@PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
@GetMapping("/lotteries")
@GetMapping("")
public ResponseEntity<Map<String, List<String>>> getLottery() {
Map<String, List<String>> response = Collections.singletonMap("ticket", lotteryService.getLottery());

return ResponseEntity.ok(response);
}

@PreAuthorize("hasRole('ADMIN')")
@DeleteMapping("admin/lotteries/{ticketId}")
public ResponseEntity<Map<String, String>> deleteLottery(@PathVariable String ticketId) {
String DeletedLottery = lotteryService.deleteLottery(ticketId);
Map<String, String> response = Collections.singletonMap("ticket", DeletedLottery);
List<String> AllLotteries = lotteryService.getLottery();
if (AllLotteries.isEmpty()) {
throw new NotFoundException("Lotteries not found");
}
Map<String, List<String>> response = Collections.singletonMap("ticket", AllLotteries);

return ResponseEntity.ok(response);
}
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
import java.util.Map;

@RestController
@RequestMapping("")
@RequestMapping("/users")
public class UserController {
@Autowired
private final UserTicketService user_ticketService;
@@ -20,22 +20,22 @@ public UserController(UserTicketService user_ticketService) {
this.user_ticketService = user_ticketService;
}

@PostMapping("/users/{userId}/lotteries/{ticketId}")
@PostMapping("/{userId}/lotteries/{ticketId}")
public ResponseEntity<Map<String, String>> BuyTicket(@PathVariable String userId, @PathVariable String ticketId) {
String transactionId = user_ticketService.BuyTicket(userId, ticketId);
Map<String, String> response = Collections.singletonMap("id", transactionId);

return ResponseEntity.status(HttpStatus.CREATED).body(response);
}

@GetMapping("/users/{userId}/lotteries")
@GetMapping("/{userId}/lotteries")
public ResponseEntity<UserTicketResponseDto> getUserTicket(@PathVariable String userId) {
UserTicketResponseDto userTicket = user_ticketService.getUserTicket(userId);

return ResponseEntity.ok(userTicket);
}

@DeleteMapping("/users/{userId}/lotteries/{ticketId}")
@DeleteMapping("/{userId}/lotteries/{ticketId}")
public ResponseEntity<Map<String, String>> deleteLottery(@PathVariable String userId, @PathVariable String ticketId) {
String SoldTicket = user_ticketService.deleteLottery(userId, ticketId);
Map<String, String> response = Collections.singletonMap("ticket", SoldTicket);
Original file line number Diff line number Diff line change
@@ -23,15 +23,15 @@ public class UserTicket {
private String transaction_type;

@NotNull
private Integer transaction_amount;
private Long transaction_amount;

@ManyToOne(cascade = {CascadeType.DETACH})
@ToString.Exclude
private Lottery lottery;

public UserTicket() {}

public UserTicket(String userId, String transaction_type, Integer transaction_amount, Lottery lottery) {
public UserTicket(String userId, String transaction_type, Long transaction_amount, Lottery lottery) {
this.userid = userId;
this.transaction_type = transaction_type;
this.transaction_amount = transaction_amount;
@@ -50,7 +50,7 @@ public String getTransaction_type() {
return transaction_type;
}

public Integer getTransaction_amount() {
public Long getTransaction_amount() {
return transaction_amount;
}

@@ -70,7 +70,7 @@ public void setTransaction_type(String transaction_type) {
this.transaction_type = transaction_type;
}

public void setTransaction_amount(Integer transaction_amount) {
public void setTransaction_amount(Long transaction_amount) {
this.transaction_amount = transaction_amount;
}

Original file line number Diff line number Diff line change
@@ -22,17 +22,6 @@ public ResponseEntity<Object> handleNotFoundException(NotFoundException e) {
return new ResponseEntity<>(apiExceptionResponse, HttpStatus.NOT_FOUND);
}

@ExceptionHandler(value = {InternalServiceException.class})
public ResponseEntity<Object> handleInternalServiceException(InternalServiceException e) {

ApiExceptionResponse apiExceptionResponse = new ApiExceptionResponse(
e.getMessage(),
HttpStatus.INTERNAL_SERVER_ERROR,
ZonedDateTime.now()
);
return new ResponseEntity<>(apiExceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}

@ExceptionHandler(value = {ConflictException.class})
public ResponseEntity<Object> handleConflictException(ConflictException e) {

This file was deleted.

Original file line number Diff line number Diff line change
@@ -13,6 +13,8 @@
public interface LotteryRepository extends JpaRepository<Lottery, Integer> {
Optional<Lottery> findByTicket(String ticketId);

Optional<Lottery> findFirstByTicket(String ticketId);

@Query("SELECT u from Lottery u JOIN FETCH u.user_tickets a WHERE a.userid = :userId")
@Transactional
List<Lottery> findByUserTicketUserId(String userId);
Original file line number Diff line number Diff line change
@@ -4,29 +4,41 @@
import com.kbtg.bootcamp.posttest.Exception.NotFoundException;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import org.antlr.v4.runtime.misc.NotNull;

public record LotteryRequestDto(String ticket, Long amount, Double price) {
@Override
public class LotteryRequestDto {
private String ticket;
private Long amount;
private Double price;

public LotteryRequestDto(String ticket, Long amount, Double price) {
this.ticket = ticket;
this.amount = amount;
this.price = price;
}

@NotNull
@Size(min = 6, max = 6)
@Pattern(regexp = "^[0-9]{6}$")
public String ticket() {
return ticket;
}

@Override
public Long amount() {
return amount;
}

@Override
public Double price() {
return price;
}

public void validate() {
if (ticket == null || ticket.length() != 6) {
if (ticket == null || ticket.length() != 6 || !ticket.matches("\\d+")) {
throw new BadRequestException("Invalid ticket: " + ticket);
}
if (amount == null || amount < 0 || amount != Math.floor(amount)) {
if (amount == null || amount < 0 ) {
throw new BadRequestException("Invalid amount: " + amount);
}
if (price == null || price < 0) {
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.kbtg.bootcamp.posttest.Lottery;

import com.kbtg.bootcamp.posttest.Entity.Lottery;
import com.kbtg.bootcamp.posttest.Exception.ConflictException;
import com.kbtg.bootcamp.posttest.Exception.InternalServiceException;
import com.kbtg.bootcamp.posttest.Exception.NotFoundException;
import jakarta.validation.Valid;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.util.List;
@@ -18,14 +21,12 @@ public LotteryService(LotteryRepository lotteryRepository) {
}

public List<String> getLottery() {
try {
return lotteryRepository.findAll().stream().map(lottery -> lottery.getTicket()).toList();
} catch (Exception e) {
throw new InternalServiceException(e.getMessage());
}
return lotteryRepository.findAll().stream().map(lottery -> lottery.getTicket()).toList();
}

public String createLottery(LotteryRequestDto lottery) {
if (lotteryRepository.findFirstByTicket(lottery.ticket()).isPresent())
throw new ConflictException("Lottery with ticket " + lottery.ticket() + " already exists");
Lottery newlottery = new Lottery(lottery.ticket(), lottery.amount(), lottery.price());
lotteryRepository.save(newlottery);

@@ -35,14 +36,13 @@ public String createLottery(LotteryRequestDto lottery) {
public String deleteLottery(String ticketId) {
Optional<Lottery> optionalLottery = lotteryRepository.findById(Integer.parseInt(ticketId));

if (optionalLottery.isPresent()) {
Lottery lottery = optionalLottery.get();
String ticket = lottery.getTicket();
lotteryRepository.delete(lottery);
return ticket;
} else {
// Handle case where the lottery with the given ticketId is not found
throw new NoSuchElementException("Lottery with ticketId " + ticketId + " not found");
}
if (!optionalLottery.isPresent())
throw new NotFoundException("Lottery with ticketId " + ticketId + " not found");

Lottery lottery = optionalLottery.get();
String ticket = lottery.getTicket();
lotteryRepository.delete(lottery);

return ticket;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.kbtg.bootcamp.posttest.securityConfig;
package com.kbtg.bootcamp.posttest.SecurityConfig;

import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
@@ -29,6 +29,9 @@ SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Excepti

return http.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests((requests) -> requests
.requestMatchers("/lotteries/**").permitAll()
.requestMatchers("/users/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated())
.httpBasic(withDefaults())
.build();
Original file line number Diff line number Diff line change
@@ -28,10 +28,10 @@ public String BuyTicket(String userId, String ticketId) {
if (!lottery.isPresent())
throw new NotFoundException("Lottery with ticketId " + ticketId + " not found");

if (!user_ticketRepository.findByUserid(userId).isEmpty())
throw new ConflictException("User already has a ticket");
if (user_ticketRepository.findByUserIdAndTicket(userId, ticketId).isPresent())
throw new ConflictException("User already has a ticket " + ticketId);

UserTicket user_ticket = new UserTicket(userId,"buy", 1, lottery.get());
UserTicket user_ticket = new UserTicket(userId,"buy", 1L, lottery.get());
user_ticketRepository.save(user_ticket);
return user_ticket.getId().toString();
}
@@ -40,25 +40,21 @@ public UserTicketResponseDto getUserTicket(String userId) {
List<Lottery> lotteries = lotteryRepository.findByUserTicketUserId(userId);
List<String> tickets = lotteries.stream().map(lottery -> lottery.getTicket()).toList();

if (!tickets.isEmpty()) {
Long count = tickets.stream().mapToLong(ticket -> 1).sum();
Double total = lotteries.stream().mapToDouble(lottery -> lottery.getPrice()).sum();
return new UserTicketResponseDto(tickets, count, total);
} else {
// Handle case where the user with the given userId is not found
throw new NotFoundException("User not found with userId: " + userId);
}
if (tickets.isEmpty())
throw new NotFoundException("No tickets found for user with userId: " + userId);

Long count = tickets.stream().mapToLong(ticket -> 1).sum();
Double total = lotteries.stream().mapToDouble(lottery -> lottery.getPrice()).sum();
return new UserTicketResponseDto(tickets, count, total);
}

public String deleteLottery(String userId, String ticketId) {
Optional<UserTicket> user_tickets = user_ticketRepository.findByUserIdAndTicket(userId, ticketId);

if (user_tickets.isPresent()) {
user_ticketRepository.delete(user_tickets.get());
return ticketId;
} else {
// Handle case where the user with the given userId is not found
if (!user_tickets.isPresent())
throw new NotFoundException("User with userId " + userId + " not found");
}

user_ticketRepository.delete(user_tickets.get());
return ticketId;
}
}