diff --git a/src/main/docker/sonar/docker-compose.yml b/src/main/docker/sonar/docker-compose.yml index ae41491de5384deb0cccef75b5cd5d2068b104e5..f3a5892b992ad46269f609ac5992cce1f557d144 100644 --- a/src/main/docker/sonar/docker-compose.yml +++ b/src/main/docker/sonar/docker-compose.yml @@ -2,9 +2,11 @@ version: "3" services: sonarqube: image: sonarqube:community + platform: linux/amd64 depends_on: - db environment: + SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar SONAR_JDBC_USERNAME: sonar SONAR_JDBC_PASSWORD: sonar @@ -28,4 +30,4 @@ volumes: sonarqube_extensions: sonarqube_logs: postgresql: - postgresql_data: \ No newline at end of file + postgresql_data: diff --git a/src/main/java/de/rwth/swc/sqa/DataService.java b/src/main/java/de/rwth/swc/sqa/DataService.java new file mode 100644 index 0000000000000000000000000000000000000000..7de0f656058d72b4a034f0220b9feb1058a129f4 --- /dev/null +++ b/src/main/java/de/rwth/swc/sqa/DataService.java @@ -0,0 +1,17 @@ +package de.rwth.swc.sqa; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import de.rwth.swc.sqa.model.Customer; +import de.rwth.swc.sqa.model.DiscountCard; +import de.rwth.swc.sqa.model.Ticket; + +public class DataService { + public static List<Customer> customerList = new ArrayList<Customer>(); + public static Map<Long, List<DiscountCard>> discountCardMap = new HashMap<Long, List<DiscountCard>>(); + public static List<Ticket> ticketList = new ArrayList<Ticket>(); + +} diff --git a/src/main/java/de/rwth/swc/sqa/api/CustomerController.java b/src/main/java/de/rwth/swc/sqa/api/CustomerController.java index 22f6ba22b70029239e5c9429dbf7fa794f298f33..2f683ef537062585190c749ae928a94298e93095 100644 --- a/src/main/java/de/rwth/swc/sqa/api/CustomerController.java +++ b/src/main/java/de/rwth/swc/sqa/api/CustomerController.java @@ -1,52 +1,95 @@ + package de.rwth.swc.sqa.api; -import de.rwth.swc.sqa.model.DiscountCard; -import io.swagger.annotations.ApiParam; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; +//import java.net.http.HttpResponse; +import java.util.ArrayList; +import java.util.List; + +import javax.validation.Valid; + import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +import de.rwth.swc.sqa.DataService; +import de.rwth.swc.sqa.model.Customer; +import de.rwth.swc.sqa.model.DiscountCard; +import io.swagger.annotations.ApiParam; -import javax.validation.Valid; -import java.net.http.HttpResponse; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; @Controller @RequestMapping("/customers") public class CustomerController implements CustomersApi{ + + + + @PostMapping("") + public ResponseEntity<Customer> addCustomer(@ApiParam(value = "Customer object that should be added",required = true) @Valid @RequestBody Customer body) { + if(body.getId()!=null || body.getBirthdate().equals("") ) { + return ResponseEntity.status(400).body(null); + }else if(body.getDisabled()==null) { + body.setDisabled(false); + } + body.setId(System.currentTimeMillis()); + DataService.customerList.add(body); + return ResponseEntity.status(201).body(body); + } @PostMapping("/{customerId}/discountcards") public ResponseEntity<DiscountCard> addDiscountCardToCustomer(@ApiParam(value = "ID of customer",required = true) @PathVariable("customerId") Long customerId, @ApiParam(value = "DiscountCard object that needs to be added to the customer",required = true) @RequestBody @Valid DiscountCard body) { - this.getRequest().ifPresent((request) -> { - Iterator var1 = MediaType.parseMediaTypes(request.getHeader("Accept")).iterator(); - - while(var1.hasNext()) { - MediaType mediaType = (MediaType)var1.next(); - if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { - String exampleString = "{ \"validFor\" : \"30d\", \"customerId\" : 6, \"id\" : 0, \"validFrom\" : \"1992-01-01\", \"type\" : 1 }"; - ApiUtil.setExampleResponse(request, "application/json", exampleString); - break; - } - } - - }); - return new ResponseEntity(HttpStatus.NOT_IMPLEMENTED); + if(body.getId()==null) { + return ResponseEntity.status(400).body(null); + } + boolean exists = false; + for(Customer customer: DataService.customerList) { + if(customer.getId().longValue()==customerId.longValue()) { + exists = true; + } + } + if(!exists) { + return ResponseEntity.status(404).body(null); + } + boolean conflict=false; + if( DataService.discountCardMap.containsKey(customerId)) { + List<DiscountCard> discountCardList = DataService.discountCardMap.get(customerId); + for(DiscountCard card:discountCardList) { + + if(card.getValidFrom().equals(body.getValidFrom())) { + conflict = true; + } + } + if(conflict) { + return ResponseEntity.status(409).body(null); + }else { + discountCardList.add(body); + } + }else { + List<DiscountCard> discountCardList = new ArrayList<DiscountCard>(); + discountCardList.add(body); + DataService.discountCardMap.put(customerId, discountCardList); + } + return ResponseEntity.status(201).body(body); } @GetMapping("/{customerId}/discountcards") public ResponseEntity<List<DiscountCard>> getCustomerDiscountCards(@ApiParam(value = "ID of customer to search for discount cards",required = true) @PathVariable("customerId") Long customerId) { - List<DiscountCard> customerDiscountCards = new ArrayList<DiscountCard>(); - - DiscountCard testCard = new DiscountCard(); - testCard.setCustomerId(new Long(55443327)); - testCard.setType(1); - - customerDiscountCards.add(testCard); - - return ResponseEntity.ok().body(customerDiscountCards); + if(customerId.longValue()==0) { + return ResponseEntity.status(400).body(null); + } + boolean exists = false; + for(Customer customer: DataService.customerList) { + if(customer.getId().longValue()==customerId.longValue() && DataService.discountCardMap.containsKey(customerId)) { + exists = true; + } + } + if(!exists) { + return ResponseEntity.status(404).body(null); + } + return ResponseEntity.ok().body( DataService.discountCardMap.get(customerId)); } } diff --git a/src/main/java/de/rwth/swc/sqa/api/TicketController.java b/src/main/java/de/rwth/swc/sqa/api/TicketController.java index e41d626cba9320128973aee6579550b5968f9090..e2e9f39eb1799e6e9873cc0b270693820ba3c802 100644 --- a/src/main/java/de/rwth/swc/sqa/api/TicketController.java +++ b/src/main/java/de/rwth/swc/sqa/api/TicketController.java @@ -1,9 +1,82 @@ package de.rwth.swc.sqa.api; -import de.rwth.swc.sqa.model.Customer; +import java.text.SimpleDateFormat; +import java.util.List; + +import javax.validation.Valid; + +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +import de.rwth.swc.sqa.DataService; +import de.rwth.swc.sqa.model.Ticket; +import de.rwth.swc.sqa.model.TicketRequest; +import de.rwth.swc.sqa.model.TicketValidationRequest; +import io.swagger.annotations.ApiParam; @Controller +@RequestMapping("/tickets") public class TicketController implements TicketsApi{ - Customer customer; + + @PostMapping("") + public ResponseEntity<Ticket> buyTicket(@ApiParam(value = "TicketRequest object" ,required=true ) @Valid @RequestBody TicketRequest body) { + try { + Ticket ticket = new Ticket(); + ticket.setId(System.currentTimeMillis()); + ticket.setBirthdate(body.getBirthdate()); + + ticket.setDisabled(body.getDisabled()==null?false:body.getDisabled()); + ticket.setDiscountCard(body.getDiscountCard()==null?false:body.getDiscountCard()); + ticket.setStudent(body.getStudent()==null?false:body.getStudent()); + ticket.setValidFor(Ticket.ValidForEnum.fromValue(body.getValidFor().getValue())); + ticket.setValidFrom(body.getValidFrom()); + ticket.setZone(Ticket.ZoneEnum.fromValue(body.getZone().getValue())); + DataService.ticketList.add(ticket); + return ResponseEntity.ok().body(ticket); + }catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(400).body(null); + } + + } + + @PostMapping("/validate") + public ResponseEntity<Void> validateTicket(@ApiParam(value = "TicketValidationRequest object that needs to validated" ,required=true ) @Valid @RequestBody TicketValidationRequest body) { + List<Ticket> ticketList = DataService.ticketList; + boolean valid=false; + try { + + for(Ticket ticket:ticketList) { + if(ticket.getId().longValue()==body.getTicketId().longValue() + && ticket.getDisabled().equals(body.getDisabled()) + && ticket.getStudent().equals(body.getStudent()) + && ticket.getZone().getValue().equals(body.getZone().getValue())) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + long startDateTime = dateFormat.parse(ticket.getValidFrom()).getTime(); + long endDateTime = dateFormat.parse(body.getDate()).getTime(); + long diff =endDateTime - startDateTime; + Ticket.ValidForEnum type= ticket.getValidFor(); + long onehour = 1000*60*60; + if( (type.equals(Ticket.ValidForEnum._1H) && diff<onehour) + || (type.equals(Ticket.ValidForEnum._1D) && diff<onehour*24) + || (type.equals(Ticket.ValidForEnum._30D) && diff<onehour*24*30) + || (type.equals(Ticket.ValidForEnum._1Y) && diff<onehour*24*30*365) ) { + valid=true; + + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + } + if(valid) { + return ResponseEntity.ok().body(null); + }else { + return ResponseEntity.status(403).body(null); + } + } } diff --git a/src/test/java/de/rwth/swc/sqa/sqa/CustomerTest.java b/src/test/java/de/rwth/swc/sqa/sqa/CustomerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..88ce728416f334e47ebd72807f231d655f34471c --- /dev/null +++ b/src/test/java/de/rwth/swc/sqa/sqa/CustomerTest.java @@ -0,0 +1,142 @@ +package de.rwth.swc.sqa.sqa; + + +import de.rwth.swc.sqa.model.DiscountCard; +import io.restassured.RestAssured; +import org.junit.jupiter.api.*; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; + +import java.util.HashMap; +import java.util.Map; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest(webEnvironment = RANDOM_PORT) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class CustomerTest { + + @LocalServerPort + int serverPort; + + @BeforeEach + public void setup() { + RestAssured.port = serverPort; + } + + + @Test + @Order(1) + public void addCustomerTest() { + //400 + Map<String, Object> parms1 = new HashMap<String, Object>(); + parms1.put("birthdate", ""); + parms1.put("disabled", true); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms1).when().post("/customers").then().statusCode(400); + + //200 + Map<String, Object> parms = new HashMap<String, Object>(); + parms.put("birthdate", "2000-01-01"); + parms.put("disabled", false); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms).when().post("/customers").then().statusCode(201); + + Map<String, Object> parms3 = new HashMap<String, Object>(); + parms3.put("birthdate", "2001-01-01"); + parms3.put("disabled", false); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms).when().post("/customers").then().statusCode(201); + + + } + + @Test + @Order(2) + public void addDiscountCardToCustomerTest() { + Long customerId =0L; + String path = "/customers/"+customerId+"/discountcards"; + Map<String, Object> parms = new HashMap<String, Object>(); + //404 + customerId = 1L; + path = "/customers/"+customerId+"/discountcards"; + parms.clear(); + parms.put("customerId", customerId); + parms.put("id", 1L); + parms.put("type", 1); + parms.put("validFrom", "2022-01-01"); + parms.put("validFor", DiscountCard.ValidForEnum._30D); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms).when().post(path).then().statusCode(404); + + //400 + customerId = DataService.customerList.get(0).getId(); + path = "/customers/"+customerId+"/discountcards"; + parms.clear(); + parms.put("customerId", customerId); + parms.put("type", 1); + parms.put("validFrom", "2022-01-01"); + parms.put("validFor", DiscountCard.ValidForEnum._30D); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms).when().post(path).then().statusCode(400); + + + //201 + customerId = DataService.customerList.get(0).getId(); + path = "/customers/"+customerId+"/discountcards"; + parms.clear(); + parms.put("customerId", customerId); + parms.put("id", 1L); + parms.put("type", 1); + parms.put("validFrom", "2022-01-01"); + parms.put("validFor", DiscountCard.ValidForEnum._30D); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms).when().post(path).then().statusCode(201); + + //409 repeat conflict + customerId = DataService.customerList.get(0).getId(); + path = "/customers/"+customerId+"/discountcards"; + parms.clear(); + parms.put("customerId", customerId); + parms.put("id", 1L); + parms.put("type", 1); + parms.put("validFrom", "2022-01-01"); + parms.put("validFor", DiscountCard.ValidForEnum._30D); + + RestAssured.given().header("content-Type", "application/json").and() + .body(parms).when().post(path).then().statusCode(409); + + + } + + @Test + @Order(3) + public void getCustomerDiscountCardTest() { + Long customerId =0L; + String path = "/customers/"+customerId+"/discountcards"; + //400 + path = "/customers/"+customerId+"/discountcards"; + RestAssured.given().when().get(path).then().statusCode(400); + + //404 + customerId = 11111L; + path = "/customers/"+customerId+"/discountcards"; + RestAssured.given().when().get(path).then().statusCode(404); + + + + //201 + customerId = DataService.customerList.get(0).getId(); + path = "/customers/"+customerId+"/discountcards"; + RestAssured.given().when().get(path).then().statusCode(200); + + + + } +} + + + + + + diff --git a/src/test/java/de/rwth/swc/sqa/DemoIntegrationTest.java b/src/test/java/de/rwth/swc/sqa/sqa/DemoIntegrationTest.java similarity index 96% rename from src/test/java/de/rwth/swc/sqa/DemoIntegrationTest.java rename to src/test/java/de/rwth/swc/sqa/sqa/DemoIntegrationTest.java index 1dbcf0c5c3fafafd38b8adfba1cdc9df92c6aa73..b715368930dd330f4c7cd22ddd298fe22bd39709 100644 --- a/src/test/java/de/rwth/swc/sqa/DemoIntegrationTest.java +++ b/src/test/java/de/rwth/swc/sqa/sqa/DemoIntegrationTest.java @@ -1,4 +1,4 @@ -package de.rwth.swc.sqa; +package de.rwth.swc.sqa.sqa; import io.restassured.RestAssured; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/de/rwth/swc/sqa/sqa/TicketTest.java b/src/test/java/de/rwth/swc/sqa/sqa/TicketTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a18f8086331a8643a5d4ae619deb9c9f0e81e334 --- /dev/null +++ b/src/test/java/de/rwth/swc/sqa/sqa/TicketTest.java @@ -0,0 +1,126 @@ +package de.rwth.swc.sqa.sqa; + + +import io.restassured.RestAssured; +import org.junit.jupiter.api.*; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; + +import java.util.HashMap; +import java.util.Map; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest(webEnvironment = RANDOM_PORT) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class TicketTest { + + @LocalServerPort + int serverPort; + + @BeforeEach + public void setup() { + RestAssured.port = serverPort; + } + + + @Test + @Order(1) + public void buyTicketTest() { + //400//no birthdate + Map<String, Object> parms1 = new HashMap<String, Object>(); + parms1.put("validFor", "1h");// + parms1.put("zone", "A"); + parms1.put("student", true); + parms1.put("discountCard", true); + parms1.put("disabled", true); + parms1.put("validFrom", "2022-05-20 10:00:00"); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms1).when().post("/tickets").then().statusCode(400); + + //200 + parms1.clear(); + parms1.put("birthdate", "1992-01-01"); + parms1.put("validFor", "1d"); + parms1.put("zone", "A"); + parms1.put("student", true); + parms1.put("discountCard", true); + parms1.put("disabled", true); + parms1.put("validFrom", "2022-05-20 10:00:00"); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms1).when().post("/tickets").then().statusCode(200); + + parms1.clear(); + parms1.put("birthdate", "1992-01-01"); + parms1.put("validFor", "30d"); + parms1.put("zone", "A"); + parms1.put("student", true); + parms1.put("discountCard", true); + parms1.put("disabled", true); + parms1.put("validFrom", "2022-05-20 10:00:00"); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms1).when().post("/tickets").then().statusCode(200); + + + + } + + @Test + @Order(2) + public void validateTicketTest() { + String path = "/tickets/validate"; + Long ticketId =0L; + Map<String, Object> parms = new HashMap<String, Object>(); + //400 //格式不对,缺少必要信息 + parms.clear(); + parms.put("ticketId", ticketId); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms).when().post(path).then().statusCode(400); + + //403 //ticketid不对 + parms.clear(); + parms.put("ticketId", ticketId); + parms.put("birthdate", "1992-01-01"); + parms.put("zone", "A"); + parms.put("student", true); + parms.put("disabled", true); + parms.put("date", "2022-05-22 10:00:00"); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms).when().post(path).then().statusCode(403); + + //403//时间过期 + ticketId = DataService.ticketList.get(1).getId(); + parms.clear(); + parms.put("ticketId", ticketId); + parms.put("birthdate", "1992-01-01"); + parms.put("zone", "A"); + parms.put("student", true); + parms.put("disabled", true); + parms.put("date", "2022-05-22 10:00:00"); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms).when().post(path).then().statusCode(403); + + + //200//信息一致,且有效期内 + ticketId = DataService.ticketList.get(1).getId(); + parms.clear(); + parms.put("ticketId", ticketId); + parms.put("birthdate", "1992-01-01"); + parms.put("zone", "A"); + parms.put("student", true); + parms.put("disabled", true); + parms.put("date", "2022-05-20 12:00:00"); + RestAssured.given().header("content-Type", "application/json").and() + .body(parms).when().post(path).then().statusCode(200); + + + + } + +} + + + + + +