Skip to content

Commit 64bdb21

Browse files
committed
Add find course endpoint
1 parent ef008f3 commit 64bdb21

File tree

15 files changed

+219
-1
lines changed

15 files changed

+219
-1
lines changed

apps/main/tv/codely/apps/backoffice/backend/controller/courses/CoursesGetController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package tv.codely.apps.backoffice.backend.controller.courses;
22

3+
import org.springframework.http.HttpStatus;
34
import org.springframework.web.bind.annotation.*;
45
import tv.codely.backoffice.courses.application.BackofficeCoursesResponse;
56
import tv.codely.backoffice.courses.application.search_by_criteria.SearchBackofficeCoursesByCriteriaQuery;
7+
import tv.codely.shared.domain.DomainError;
68
import tv.codely.shared.domain.bus.command.CommandBus;
79
import tv.codely.shared.domain.bus.query.QueryBus;
810
import tv.codely.shared.domain.bus.query.QueryHandlerExecutionError;
@@ -44,6 +46,11 @@ public List<HashMap<String, String>> index(
4446
}}).collect(Collectors.toList());
4547
}
4648

49+
@Override
50+
protected HashMap<Class<? extends DomainError>, HttpStatus> errorMapping() {
51+
return null;
52+
}
53+
4754
private List<HashMap<String, String>> parseFilters(HashMap<String, Serializable> params) {
4855
int maxParams = params.size();
4956

apps/main/tv/codely/apps/backoffice/backend/controller/health_check/HealthCheckGetController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package tv.codely.apps.backoffice.backend.controller.health_check;
22

3+
import org.springframework.http.HttpStatus;
34
import org.springframework.web.bind.annotation.GetMapping;
45
import org.springframework.web.bind.annotation.RestController;
6+
import tv.codely.shared.domain.DomainError;
57
import tv.codely.shared.domain.bus.command.CommandBus;
68
import tv.codely.shared.domain.bus.query.QueryBus;
79
import tv.codely.shared.infrastructure.spring.ApiController;
@@ -25,4 +27,9 @@ public HashMap<String, String> index() {
2527

2628
return status;
2729
}
30+
31+
@Override
32+
protected HashMap<Class<? extends DomainError>, HttpStatus> errorMapping() {
33+
return null;
34+
}
2835
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package tv.codely.apps.mooc.backend.controller.courses;
2+
3+
import org.springframework.http.HttpStatus;
4+
import org.springframework.http.ResponseEntity;
5+
import org.springframework.web.bind.annotation.GetMapping;
6+
import org.springframework.web.bind.annotation.PathVariable;
7+
import org.springframework.web.bind.annotation.RestController;
8+
import tv.codely.mooc.courses.application.CourseResponse;
9+
import tv.codely.mooc.courses.application.find.FindCourseQuery;
10+
import tv.codely.shared.domain.DomainError;
11+
import tv.codely.shared.domain.bus.command.CommandBus;
12+
import tv.codely.shared.domain.bus.query.QueryBus;
13+
import tv.codely.shared.domain.bus.query.QueryHandlerExecutionError;
14+
import tv.codely.shared.domain.bus.query.QueryNotRegisteredError;
15+
import tv.codely.shared.infrastructure.spring.ApiController;
16+
17+
import java.io.Serializable;
18+
import java.util.HashMap;
19+
20+
@RestController
21+
public final class CourseGetController extends ApiController {
22+
public CourseGetController(
23+
QueryBus queryBus,
24+
CommandBus commandBus
25+
) {
26+
super(queryBus, commandBus);
27+
}
28+
29+
@GetMapping("/courses/{id}")
30+
public ResponseEntity<HashMap<String, Serializable>> index(@PathVariable String id) throws QueryHandlerExecutionError, QueryNotRegisteredError {
31+
CourseResponse course = ask(new FindCourseQuery(id));
32+
33+
return ResponseEntity.ok().body(new HashMap<String, Serializable>() {{
34+
put("id", course.id());
35+
put("name", course.name());
36+
put("duration", course.duration());
37+
}});
38+
}
39+
40+
@Override
41+
protected HashMap<Class<? extends DomainError>, HttpStatus> errorMapping() {
42+
return null;
43+
}
44+
}

apps/main/tv/codely/apps/mooc/backend/controller/courses/CoursesPutController.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77
import org.springframework.web.bind.annotation.RequestBody;
88
import org.springframework.web.bind.annotation.RestController;
99
import tv.codely.mooc.courses.application.create.CreateCourseCommand;
10+
import tv.codely.shared.domain.DomainError;
1011
import tv.codely.shared.domain.bus.command.CommandBus;
1112
import tv.codely.shared.domain.bus.command.CommandHandlerExecutionError;
1213
import tv.codely.shared.domain.bus.command.CommandNotRegisteredError;
1314
import tv.codely.shared.domain.bus.query.QueryBus;
1415
import tv.codely.shared.infrastructure.spring.ApiController;
1516

17+
import java.util.HashMap;
18+
1619
@RestController
1720
public final class CoursesPutController extends ApiController {
1821
public CoursesPutController(
@@ -31,6 +34,11 @@ public ResponseEntity<String> index(
3134

3235
return new ResponseEntity<>(HttpStatus.CREATED);
3336
}
37+
38+
@Override
39+
protected HashMap<Class<? extends DomainError>, HttpStatus> errorMapping() {
40+
return null;
41+
}
3442
}
3543

3644
final class Request {

apps/main/tv/codely/apps/mooc/backend/controller/courses_counter/CoursesCounterGetController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package tv.codely.apps.mooc.backend.controller.courses_counter;
22

3+
import org.springframework.http.HttpStatus;
34
import org.springframework.web.bind.annotation.GetMapping;
45
import org.springframework.web.bind.annotation.RestController;
56
import tv.codely.mooc.courses_counter.application.find.CoursesCounterResponse;
67
import tv.codely.mooc.courses_counter.application.find.FindCoursesCounterQuery;
8+
import tv.codely.shared.domain.DomainError;
79
import tv.codely.shared.domain.bus.command.CommandBus;
810
import tv.codely.shared.domain.bus.query.QueryBus;
911
import tv.codely.shared.domain.bus.query.QueryHandlerExecutionError;
@@ -26,4 +28,9 @@ public HashMap<String, Integer> index() throws QueryNotRegisteredError, QueryHan
2628
put("total", response.total());
2729
}};
2830
}
31+
32+
@Override
33+
protected HashMap<Class<? extends DomainError>, HttpStatus> errorMapping() {
34+
return null;
35+
}
2936
}

apps/main/tv/codely/apps/mooc/backend/controller/health_check/HealthCheckGetController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package tv.codely.apps.mooc.backend.controller.health_check;
22

3+
import org.springframework.http.HttpStatus;
34
import org.springframework.web.bind.annotation.GetMapping;
45
import org.springframework.web.bind.annotation.RestController;
6+
import tv.codely.shared.domain.DomainError;
57
import tv.codely.shared.domain.bus.command.CommandBus;
68
import tv.codely.shared.domain.bus.query.QueryBus;
79
import tv.codely.shared.infrastructure.spring.ApiController;
@@ -25,4 +27,9 @@ public HashMap<String, String> index() {
2527

2628
return status;
2729
}
30+
31+
@Override
32+
protected HashMap<Class<? extends DomainError>, HttpStatus> errorMapping() {
33+
return null;
34+
}
2835
}

apps/main/tv/codely/apps/mooc/backend/controller/notifications/NewsletterNotificationPutController.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66
import org.springframework.web.bind.annotation.PutMapping;
77
import org.springframework.web.bind.annotation.RestController;
88
import tv.codely.mooc.notifications.application.send_new_courses_newsletter.SendNewCoursesNewsletterCommand;
9+
import tv.codely.shared.domain.DomainError;
910
import tv.codely.shared.domain.bus.command.CommandBus;
1011
import tv.codely.shared.domain.bus.command.CommandHandlerExecutionError;
1112
import tv.codely.shared.domain.bus.command.CommandNotRegisteredError;
1213
import tv.codely.shared.domain.bus.query.QueryBus;
1314
import tv.codely.shared.infrastructure.spring.ApiController;
1415

16+
import java.util.HashMap;
17+
1518
@RestController
1619
public final class NewsletterNotificationPutController extends ApiController {
1720
public NewsletterNotificationPutController(
@@ -29,4 +32,9 @@ public ResponseEntity<String> index(
2932

3033
return new ResponseEntity<>(HttpStatus.CREATED);
3134
}
35+
36+
@Override
37+
protected HashMap<Class<? extends DomainError>, HttpStatus> errorMapping() {
38+
return null;
39+
}
3240
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package tv.codely.apps.mooc.backend.controller.courses;
2+
3+
import org.junit.jupiter.api.Test;
4+
import tv.codely.apps.mooc.MoocApplicationTestCase;
5+
6+
final class CourseGetControllerShould extends MoocApplicationTestCase {
7+
@Test
8+
void find_an_existing_course() throws Exception {
9+
String id = "99ad55f5-6eab-4d73-b383-c63268e251e8";
10+
String body = "{\"name\": \"The best course\", \"duration\": \"5 hours\"}";
11+
12+
givenThereIsACourse(id, body);
13+
14+
assertResponse(String.format("/courses/%s", id), 200, body);
15+
}
16+
17+
private void givenThereIsACourse(String id, String body) throws Exception {
18+
assertRequestWithBody("PUT", String.format("/courses/%s", id), body, 201);
19+
}
20+
}

src/mooc/main/tv/codely/mooc/courses/application/CourseResponse.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,16 @@ public CourseResponse(String id, String name, String duration) {
1717
public static CourseResponse fromAggregate(Course course) {
1818
return new CourseResponse(course.id().value(), course.name().value(), course.duration().value());
1919
}
20+
21+
public String id() {
22+
return id;
23+
}
24+
25+
public String name() {
26+
return name;
27+
}
28+
29+
public String duration() {
30+
return duration;
31+
}
2032
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package tv.codely.mooc.courses.application.find;
2+
3+
import tv.codely.mooc.courses.application.CourseResponse;
4+
import tv.codely.mooc.courses.domain.CourseId;
5+
import tv.codely.mooc.courses.domain.CourseNotExist;
6+
import tv.codely.mooc.courses.domain.CourseRepository;
7+
import tv.codely.shared.domain.Service;
8+
9+
@Service
10+
public final class CourseFinder {
11+
private final CourseRepository repository;
12+
13+
public CourseFinder(CourseRepository repository) {
14+
this.repository = repository;
15+
}
16+
17+
public CourseResponse find(CourseId id) throws CourseNotExist {
18+
return repository.search(id)
19+
.map(CourseResponse::fromAggregate)
20+
.orElseThrow(() -> new CourseNotExist(id));
21+
}
22+
}

0 commit comments

Comments
 (0)