diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index de84db9..050ab36 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,12 +3,7 @@ name: Java CI Pipeline on: push: branches: - - main - - dev - pull_request: - branches: - - main - - dev + - "**" workflow_dispatch: jobs: @@ -89,4 +84,4 @@ jobs: ./gradlew jacocoTestReport env: PRODUCTION: test - # (Optional) Add steps for generating coverage report and other post-test tasks + # (Optional) Add steps for generating coverage report and other post-test tasks \ No newline at end of file diff --git a/.monitoring/prometheus/prometheus.yml b/.monitoring/prometheus/prometheus.yml index 94f2cfe..f454fff 100644 --- a/.monitoring/prometheus/prometheus.yml +++ b/.monitoring/prometheus/prometheus.yml @@ -1,8 +1,11 @@ scrape_configs: - - job_name: 'MyAppMetrics' + - job_name: 'Snackscription Metrics' metrics_path: '/actuator/prometheus' scrape_interval: 3s static_configs: - targets: ['host.docker.internal:8080'] labels: - application: 'Snackscription Review' \ No newline at end of file + application: 'Snackscription Review' + - targets: ['34.124.152.90'] + labels: + application: 'Snackscription Review (deployed)' \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 01cc3e8..80f5ddc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,10 +27,11 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-thymeleaf") implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-actuator") + implementation("io.micrometer:micrometer-registry-prometheus") + implementation("io.micrometer:micrometer-core") compileOnly("org.projectlombok:lombok") developmentOnly("org.springframework.boot:spring-boot-devtools") runtimeOnly("org.postgresql:postgresql") - runtimeOnly("io.micrometer:micrometer-registry-prometheus") annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") annotationProcessor("org.projectlombok:lombok") testImplementation("org.springframework.boot:spring-boot-starter-test") @@ -50,7 +51,8 @@ tasks.jacocoTestReport { })) dependsOn(tasks.test) reports { - xml.required.set(false) + xml.required.set(true) + html.required.set(true) csv.required.set(false) html.outputLocation.set(layout.buildDirectory.dir("jacocoHtml")) } diff --git a/src/main/java/snackscription/review/controller/ReviewController.java b/src/main/java/snackscription/review/controller/ReviewController.java index bd802cd..4342da7 100644 --- a/src/main/java/snackscription/review/controller/ReviewController.java +++ b/src/main/java/snackscription/review/controller/ReviewController.java @@ -15,6 +15,10 @@ public class ReviewController { private ReviewService reviewService; + public static final String BODY_AUTHOR = "author"; + public static final String BODY_CONTENT = "content"; + public static final String BODY_RATING = "rating"; + public ReviewController(ReviewService reviewService) { this.reviewService = reviewService; } @@ -27,9 +31,9 @@ public ResponseEntity reviewPage() { @PostMapping("/subscription-boxes/{subsbox}") public ResponseEntity createSubsboxReview(@RequestBody Map body, @PathVariable String subsbox) { try { - String author = body.get("author"); - int rating = Integer.parseInt(body.get("rating")); - String content = body.get("content"); + String author = body.get(BODY_AUTHOR); + int rating = Integer.parseInt(body.get(BODY_RATING)); + String content = body.get(BODY_CONTENT); Review review = reviewService.createReview(rating, content, subsbox, author); return new ResponseEntity<>(review, HttpStatus.CREATED); @@ -51,7 +55,7 @@ public ResponseEntity> getPublicSubsboxReview(@PathVariable String @GetMapping("/subscription-boxes/{subsbox}/users/{user}") public ResponseEntity getSelfSubsboxReview(@RequestBody Map body, @PathVariable String subsbox, @PathVariable String user) { try { - String sender = body.get("author"); // TODO: nanti pakai JWT token untuk ambil sendernya + String sender = body.get(BODY_AUTHOR); if (!authenticate(sender, user)) { return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } @@ -65,13 +69,13 @@ public ResponseEntity getSelfSubsboxReview(@RequestBody Map editReview(@RequestBody Map body, @PathVariable String subsbox, @PathVariable String user) { try { - String sender = body.get("author"); // TODO: nanti pakai JWT token untuk ambil sendernya + String sender = body.get(BODY_AUTHOR); if (!authenticate(sender, user)) { return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } - int rating = Integer.parseInt(body.get("rating")); - String content = body.get("content"); + int rating = Integer.parseInt(body.get(BODY_RATING)); + String content = body.get(BODY_CONTENT); Review review = reviewService.editReview(rating, content, subsbox, user); return new ResponseEntity<>(review, HttpStatus.OK); diff --git a/src/test/java/snackscription/review/controller/ReviewControllerTest.java b/src/test/java/snackscription/review/controller/ReviewControllerTest.java index bf0ccca..8e3035e 100644 --- a/src/test/java/snackscription/review/controller/ReviewControllerTest.java +++ b/src/test/java/snackscription/review/controller/ReviewControllerTest.java @@ -146,44 +146,6 @@ public void readSelfSubscriptionBoxReview() throws Exception { verify(reviewService).getReview(subsbox, author); } -// @Test -// public void testEditSelfSubscriptionBoxReview() throws Exception { -// Review review = reviews.getFirst(); -// String subsboxId = review.getSubsbox(); -// String userId = review.getAuthor(); -// -// int newRating = 4; -// String newContent = "Awikwok"; -// when(reviewService.editReview(newRating, newContent, subsboxId, userId)).thenReturn(new Review(newRating, newContent, userId, subsboxId)); -// -// ResultActions result = mockMvc.perform(put("/reviews/subscription-boxes/{subscriptionBoxId}/users/self", subsboxId) -// .contentType(MediaType.APPLICATION_JSON) -// .content("{\"rating\": 4, \"content\": \"Awikwok\", \"userId\": \"user_123\"}")) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.rating", is(newRating))) -// .andExpect(jsonPath("$.content", is(newContent))) -// .andExpect(jsonPath("$.userId", is(review.getAuthor()))) -// .andExpect(jsonPath("$.subscriptionBoxId", is(review.getSubsbox()))); -// -// verify(reviewService).editReview(newRating, newContent, subsboxId, userId); -// } -// -// @Test -// public void testDeleteSelfSubscriptionBoxReview() throws Exception { -// Review review = reviews.getFirst(); -// String subsboxId = review.getSubsbox(); -// String userId = review.getAuthor(); -// -// doNothing().when(reviewService).deleteReview(subsboxId, userId); -// -// ResultActions result = mockMvc.perform(delete("/subscription-boxes/{subscriptionBoxId}/users/self", subsboxId) -// .contentType(MediaType.APPLICATION_JSON) -// .content("{\"userId\": \"user_123\"}")) -// .andExpect(status().isNoContent()); -// -// verify(reviewService).deleteReview(subsboxId, userId); -// } - @Test public void testDeleteUserSubscriptionBoxReview() throws Exception { Review review = reviews.getFirst(); @@ -238,100 +200,4 @@ public void testRejectReview() throws Exception { verify(reviewService).approveReview(review.getSubsbox(), review.getAuthor()); } - -// @Test -// public void testGetAllSubscriptionBoxReview() { -// String subsboxId = "subsboxId"; - -// ArrayList reviews = new ArrayList<>(); -// reviews.add(new Review(5, "amazing", "user1", subsboxId)); -// reviews.add(new Review(4, "good", "user2", subsboxId)); - -// when(reviewService.testGetAllSubscriptionBoxReview(subsboxId)).thenReturn(reviews); - -// ResultActions result = mockMvc.perform(get("/api/subscription-boxes/{subsboxId}", subsboxId)) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$", hasSize(2))) -// .andExpect(jsonPath("$[0].rating", is(5))) -// .andExpect(jsonPath("$[0].content", is("amazing"))) -// .andExpect(jsonPath("$[0].userId", is("user1"))) -// .andExpect(jsonPath("$[0].subscriptionBoxId", is(subsboxId))) -// .andExpect(jsonPath("$[1].rating", is(4))) -// .andExpect(jsonPath("$[1].content", is("good"))) -// .andExpect(jsonPath("$[1].userId", is("user2"))) -// .andExpect(jsonPath("$[1].subscriptionBoxId", is(subsboxId))); - -// verify(reviewService).testGetAllSubscriptionBoxReview(subsboxId); -// } - -// @Test -// public void testGetById() throws Exception { -// Review review = new Review( -// 5, "amazing", "user1", "subsboxId" -// ); -// String reviewId = review.getId(); - -// when(reviewService.findById(reviewId)).thenReturn(review); - -// ResultActions result = mockMvc.perform(get("/api/reviews/{reviewId}", reviewId)) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.rating", is(5))) -// .andExpect(jsonPath("$.content", is("amazing"))) -// .andExpect(jsonPath("$.userId", is("user1"))) -// .andExpect(jsonPath("$.subscriptionBoxId", is("subsboxId"))); - -// verify(reviewService).findById(reviewId); -// } - -// @Test -// public void testGetBySubscriptionBoxId() throws Exception { -// List curReviews = new ArrayList<>(); - -// String subscriptionBoxId = this.reviews.getFirst().getSubsbox(); -// for (Review review : this.reviews) { -// if (review.getSubsbox().equals(subscriptionBoxId)) { -// curReviews.add(review); -// } -// } - -// when(reviewService.findBySubscriptionBoxId(subscriptionBoxId)).thenReturn(curReviews); - -// String result = mockMvc.perform(get("/api/subscription-boxes/{subscriptionBoxId}", subscriptionBoxId)) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$", hasSize(curReviews.size()))) -// .andReturn() -// .getResponse() -// .getContentAsString(); - -// List foundReviews = new ArrayList(); -// for (int i=0; i cmp = new Comparator() { -// @Override -// public int compare(Review o1, Review o2) { -// return o1.getAuthor().compareTo(o2.getAuthor()); -// } -// }; - -// curReviews.sort(cmp); -// foundReviews.sort(cmp); - -// for (int i=0; i curReviews = new ArrayList<>(); String subscriptionBoxId = this.reviews.getFirst().getSubsbox();