diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ca7ca075..8dcdf5b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,10 @@ name: CI -on: [push] +on: + push: + branches: + - main + pull_request: jobs: build: @@ -8,17 +12,20 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - - name: Start all the environment - run: docker-compose up -d + - name: 🐳 Start all the environment + run: make start - - name: Wait for the environment to get up + - name: 🔦 Lint + run: make lint + + - name: 🦭 Wait for the environment to get up run: | while ! make ping-mysql &>/dev/null; do echo "Waiting for database connection..." sleep 2 done - - name: Run the tests + - name: ✅ Run the tests run: make test diff --git a/Dockerfile b/Dockerfile index d8ec44c8..98f0b27c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,2 +1,15 @@ FROM openjdk:21-slim-buster WORKDIR /app + +RUN apt update && apt install -y curl git + +ENV NVM_DIR /usr/local/nvm +ENV NODE_VERSION 18.0.0 + +RUN mkdir -p $NVM_DIR +RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash + +RUN . $NVM_DIR/nvm.sh && nvm install $NODE_VERSION && nvm alias default $NODE_VERSION && nvm use default + +ENV NODE_PATH $NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules +ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH diff --git a/Makefile b/Makefile index 0f7981e5..959d60c7 100644 --- a/Makefile +++ b/Makefile @@ -1,35 +1,29 @@ -.PHONY: all all: build -.PHONY: up -up: - @docker-compose up -d +start: + @docker compose up -d -.PHONY: build build: @./gradlew build --warning-mode all -.PHONY: run-tests +lint: + @docker exec codelytv-ddd_example-java ./gradlew spotlessCheck + run-tests: @./gradlew test --warning-mode all -.PHONY: test test: @docker exec codelytv-ddd_example-java ./gradlew test --warning-mode all -.PHONY: run run: @./gradlew :run -.PHONY: ping-mysql ping-mysql: @docker exec codelytv-java_ddd_example-mysql mysqladmin --user=root --password= --host "127.0.0.1" ping --silent # Start the app -.PHONY: start-mooc_backend start-mooc_backend: @./gradlew bootRun --args='mooc_backend server' -.PHONY: start-backoffice_frontend start-backoffice_frontend: @./gradlew bootRun --args='backoffice_frontend server' diff --git a/apps/main/tv/codely/apps/Starter.java b/apps/main/tv/codely/apps/Starter.java index 3e596a74..64ad963b 100644 --- a/apps/main/tv/codely/apps/Starter.java +++ b/apps/main/tv/codely/apps/Starter.java @@ -1,92 +1,96 @@ package tv.codely.apps; +import java.util.Arrays; +import java.util.HashMap; + import org.springframework.boot.SpringApplication; import org.springframework.boot.WebApplicationType; import org.springframework.context.ConfigurableApplicationContext; + import tv.codely.apps.backoffice.backend.BackofficeBackendApplication; import tv.codely.apps.backoffice.frontend.BackofficeFrontendApplication; import tv.codely.apps.mooc.backend.MoocBackendApplication; import tv.codely.shared.infrastructure.cli.ConsoleCommand; -import java.util.Arrays; -import java.util.HashMap; - public class Starter { - public static void main(String[] args) { - if (args.length < 2) { - throw new RuntimeException("There are not enough arguments"); - } - - String applicationName = args[0]; - String commandName = args[1]; - boolean isServerCommand = commandName.equals("server"); - - ensureApplicationExist(applicationName); - ensureCommandExist(applicationName, commandName); - - Class applicationClass = applications().get(applicationName); - - SpringApplication app = new SpringApplication(applicationClass); - - if (!isServerCommand) { - app.setWebApplicationType(WebApplicationType.NONE); - } - - ConfigurableApplicationContext context = app.run(args); - - if (!isServerCommand) { - ConsoleCommand command = (ConsoleCommand) context.getBean( - commands().get(applicationName).get(commandName) - ); - - command.execute(Arrays.copyOfRange(args, 2, args.length)); - } - } - - private static void ensureApplicationExist(String applicationName) { - if (!applications().containsKey(applicationName)) { - throw new RuntimeException(String.format( - "The application <%s> doesn't exist. Valids:\n- %s", - applicationName, - String.join("\n- ", applications().keySet()) - )); - } - } - - private static void ensureCommandExist(String applicationName, String commandName) { - if (!"server".equals(commandName) && !existCommand(applicationName, commandName)) { - throw new RuntimeException(String.format( - "The command <%s> for application <%s> doesn't exist. Valids (application.command):\n- api\n- %s", - commandName, - applicationName, - String.join("\n- ", commands().get(applicationName).keySet()) - )); - } - } - - private static HashMap> applications() { - HashMap> applications = new HashMap<>(); - - applications.put("mooc_backend", MoocBackendApplication.class); - applications.put("backoffice_backend", BackofficeBackendApplication.class); - applications.put("backoffice_frontend", BackofficeFrontendApplication.class); - - return applications; - } - - private static HashMap>> commands() { - HashMap>> commands = new HashMap<>(); - - commands.put("mooc_backend", MoocBackendApplication.commands()); - commands.put("backoffice_backend", BackofficeBackendApplication.commands()); - commands.put("backoffice_frontend", BackofficeFrontendApplication.commands()); - - return commands; - } - - private static Boolean existCommand(String applicationName, String commandName) { - HashMap>> commands = commands(); - - return commands.containsKey(applicationName) && commands.get(applicationName).containsKey(commandName); - } + + public static void main(String[] args) { + if (args.length < 2) { + throw new RuntimeException("There are not enough arguments"); + } + + String applicationName = args[0]; + String commandName = args[1]; + boolean isServerCommand = commandName.equals("server"); + + ensureApplicationExist(applicationName); + ensureCommandExist(applicationName, commandName); + + Class applicationClass = applications().get(applicationName); + + SpringApplication app = new SpringApplication(applicationClass); + + if (!isServerCommand) { + app.setWebApplicationType(WebApplicationType.NONE); + } + + ConfigurableApplicationContext context = app.run(args); + + if (!isServerCommand) { + ConsoleCommand command = (ConsoleCommand) context.getBean(commands().get(applicationName).get(commandName)); + + command.execute(Arrays.copyOfRange(args, 2, args.length)); + } + } + + private static void ensureApplicationExist(String applicationName) { + if (!applications().containsKey(applicationName)) { + throw new RuntimeException( + String.format( + "The application <%s> doesn't exist. Valids:\n- %s", + applicationName, + String.join("\n- ", applications().keySet()) + ) + ); + } + } + + private static void ensureCommandExist(String applicationName, String commandName) { + if (!"server".equals(commandName) && !existCommand(applicationName, commandName)) { + throw new RuntimeException( + String.format( + "The command <%s> for application <%s> doesn't exist. Valids (application.command):\n- api\n- %s", + commandName, + applicationName, + String.join("\n- ", commands().get(applicationName).keySet()) + ) + ); + } + } + + private static HashMap> applications() { + HashMap> applications = new HashMap<>(); + + applications.put("mooc_backend", MoocBackendApplication.class); + applications.put("backoffice_backend", BackofficeBackendApplication.class); + applications.put("backoffice_frontend", BackofficeFrontendApplication.class); + + return applications; + } + + private static HashMap>> commands() { + HashMap>> commands = new HashMap<>(); + + commands.put("mooc_backend", MoocBackendApplication.commands()); + commands.put("backoffice_backend", BackofficeBackendApplication.commands()); + commands.put("backoffice_frontend", BackofficeFrontendApplication.commands()); + + return commands; + } + + private static Boolean existCommand(String applicationName, String commandName) { + HashMap>> commands = commands(); + + return commands.containsKey(applicationName) && commands.get(applicationName).containsKey(commandName); + } } diff --git a/apps/main/tv/codely/apps/backoffice/backend/BackofficeBackendApplication.java b/apps/main/tv/codely/apps/backoffice/backend/BackofficeBackendApplication.java index 16e2fa5e..873122f3 100644 --- a/apps/main/tv/codely/apps/backoffice/backend/BackofficeBackendApplication.java +++ b/apps/main/tv/codely/apps/backoffice/backend/BackofficeBackendApplication.java @@ -1,21 +1,24 @@ package tv.codely.apps.backoffice.backend; +import java.util.HashMap; + import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; -import tv.codely.shared.domain.Service; -import java.util.HashMap; +import tv.codely.shared.domain.Service; @SpringBootApplication(exclude = HibernateJpaAutoConfiguration.class) @ComponentScan( - includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Service.class), - value = {"tv.codely.shared", "tv.codely.backoffice", "tv.codely.apps.backoffice.backend"} + includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Service.class), + value = { "tv.codely.shared", "tv.codely.backoffice", "tv.codely.apps.backoffice.backend" } ) public class BackofficeBackendApplication { - public static HashMap> commands() { - return new HashMap>() {{ - }}; - } + + public static HashMap> commands() { + return new HashMap>() { + {} + }; + } } diff --git a/apps/main/tv/codely/apps/backoffice/backend/config/BackofficeBackendServerConfiguration.java b/apps/main/tv/codely/apps/backoffice/backend/config/BackofficeBackendServerConfiguration.java index bf5dbf0b..80314c26 100644 --- a/apps/main/tv/codely/apps/backoffice/backend/config/BackofficeBackendServerConfiguration.java +++ b/apps/main/tv/codely/apps/backoffice/backend/config/BackofficeBackendServerConfiguration.java @@ -3,24 +3,26 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; + import tv.codely.apps.backoffice.backend.middleware.BasicHttpAuthMiddleware; import tv.codely.shared.domain.bus.command.CommandBus; @Configuration public class BackofficeBackendServerConfiguration { - private final CommandBus bus; - public BackofficeBackendServerConfiguration(CommandBus bus) { - this.bus = bus; - } + private final CommandBus bus; + + public BackofficeBackendServerConfiguration(CommandBus bus) { + this.bus = bus; + } - @Bean - public FilterRegistrationBean basicHttpAuthMiddleware() { - FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + @Bean + public FilterRegistrationBean basicHttpAuthMiddleware() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); - registrationBean.setFilter(new BasicHttpAuthMiddleware(bus)); - registrationBean.addUrlPatterns("/health-check"); + registrationBean.setFilter(new BasicHttpAuthMiddleware(bus)); + registrationBean.addUrlPatterns("/health-check"); - return registrationBean; - } + return registrationBean; + } } diff --git a/apps/main/tv/codely/apps/backoffice/backend/config/BackofficeBackendServerPortCustomizer.java b/apps/main/tv/codely/apps/backoffice/backend/config/BackofficeBackendServerPortCustomizer.java index aa3fe2eb..8c46d553 100644 --- a/apps/main/tv/codely/apps/backoffice/backend/config/BackofficeBackendServerPortCustomizer.java +++ b/apps/main/tv/codely/apps/backoffice/backend/config/BackofficeBackendServerPortCustomizer.java @@ -3,23 +3,26 @@ import org.springframework.boot.web.server.ConfigurableWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.stereotype.Component; + import tv.codely.shared.infrastructure.config.Parameter; import tv.codely.shared.infrastructure.config.ParameterNotExist; @Component -public final class BackofficeBackendServerPortCustomizer implements WebServerFactoryCustomizer { - private final Parameter param; +public final class BackofficeBackendServerPortCustomizer + implements WebServerFactoryCustomizer { + + private final Parameter param; - public BackofficeBackendServerPortCustomizer(Parameter param) { - this.param = param; - } + public BackofficeBackendServerPortCustomizer(Parameter param) { + this.param = param; + } - @Override - public void customize(ConfigurableWebServerFactory factory) { - try { - factory.setPort(param.getInt("BACKOFFICE_BACKEND_SERVER_PORT")); - } catch (ParameterNotExist parameterNotExist) { - parameterNotExist.printStackTrace(); - } - } + @Override + public void customize(ConfigurableWebServerFactory factory) { + try { + factory.setPort(param.getInt("BACKOFFICE_BACKEND_SERVER_PORT")); + } catch (ParameterNotExist parameterNotExist) { + parameterNotExist.printStackTrace(); + } + } } diff --git a/apps/main/tv/codely/apps/backoffice/backend/controller/courses/CoursesGetController.java b/apps/main/tv/codely/apps/backoffice/backend/controller/courses/CoursesGetController.java index 9cfd24e0..48bb8b47 100644 --- a/apps/main/tv/codely/apps/backoffice/backend/controller/courses/CoursesGetController.java +++ b/apps/main/tv/codely/apps/backoffice/backend/controller/courses/CoursesGetController.java @@ -1,7 +1,15 @@ package tv.codely.apps.backoffice.backend.controller.courses; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; + import tv.codely.backoffice.courses.application.BackofficeCoursesResponse; import tv.codely.backoffice.courses.application.search_by_criteria.SearchBackofficeCoursesByCriteriaQuery; import tv.codely.shared.domain.DomainError; @@ -10,63 +18,68 @@ import tv.codely.shared.domain.bus.query.QueryHandlerExecutionError; import tv.codely.shared.infrastructure.spring.ApiController; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - @RestController -@CrossOrigin(origins = "*", methods = {RequestMethod.GET}) +@CrossOrigin(origins = "*", methods = { RequestMethod.GET }) public final class CoursesGetController extends ApiController { - public CoursesGetController(QueryBus queryBus, CommandBus commandBus) { - super(queryBus, commandBus); - } - @GetMapping("/courses") - public List> index( - @RequestParam HashMap params - ) throws QueryHandlerExecutionError { - BackofficeCoursesResponse courses = ask( - new SearchBackofficeCoursesByCriteriaQuery( - parseFilters(params), - Optional.ofNullable((String) params.get("order_by")), - Optional.ofNullable((String) params.get("order")), - Optional.ofNullable((Integer) params.get("limit")), - Optional.ofNullable((Integer) params.get("offset")) - ) - ); + public CoursesGetController(QueryBus queryBus, CommandBus commandBus) { + super(queryBus, commandBus); + } + + @GetMapping("/courses") + public List> index(@RequestParam HashMap params) + throws QueryHandlerExecutionError { + BackofficeCoursesResponse courses = ask( + new SearchBackofficeCoursesByCriteriaQuery( + parseFilters(params), + Optional.ofNullable((String) params.get("order_by")), + Optional.ofNullable((String) params.get("order")), + Optional.ofNullable((Integer) params.get("limit")), + Optional.ofNullable((Integer) params.get("offset")) + ) + ); - return courses.courses().stream().map(response -> new HashMap() {{ - put("id", response.id()); - put("name", response.name()); - put("duration", response.duration()); - }}).collect(Collectors.toList()); - } + return courses + .courses() + .stream() + .map(response -> + new HashMap() { + { + put("id", response.id()); + put("name", response.name()); + put("duration", response.duration()); + } + } + ) + .collect(Collectors.toList()); + } - @Override - public HashMap, HttpStatus> errorMapping() { - return null; - } + @Override + public HashMap, HttpStatus> errorMapping() { + return null; + } - private List> parseFilters(HashMap params) { - int maxParams = params.size(); + private List> parseFilters(HashMap params) { + int maxParams = params.size(); - List> filters = new ArrayList<>(); + List> filters = new ArrayList<>(); - for (int possibleFilterKey = 0; possibleFilterKey < maxParams; possibleFilterKey++) { - if (params.containsKey(String.format("filters[%s][field]", possibleFilterKey))) { - int key = possibleFilterKey; + for (int possibleFilterKey = 0; possibleFilterKey < maxParams; possibleFilterKey++) { + if (params.containsKey(String.format("filters[%s][field]", possibleFilterKey))) { + int key = possibleFilterKey; - filters.add(new HashMap() {{ - put("field", (String) params.get(String.format("filters[%s][field]", key))); - put("operator", (String) params.get(String.format("filters[%s][operator]", key))); - put("value", (String) params.get(String.format("filters[%s][value]", key))); - }}); - } - } + filters.add( + new HashMap() { + { + put("field", (String) params.get(String.format("filters[%s][field]", key))); + put("operator", (String) params.get(String.format("filters[%s][operator]", key))); + put("value", (String) params.get(String.format("filters[%s][value]", key))); + } + } + ); + } + } - return filters; - } + return filters; + } } diff --git a/apps/main/tv/codely/apps/backoffice/backend/controller/health_check/HealthCheckGetController.java b/apps/main/tv/codely/apps/backoffice/backend/controller/health_check/HealthCheckGetController.java index 2524dbaf..bef9ec0b 100644 --- a/apps/main/tv/codely/apps/backoffice/backend/controller/health_check/HealthCheckGetController.java +++ b/apps/main/tv/codely/apps/backoffice/backend/controller/health_check/HealthCheckGetController.java @@ -1,35 +1,34 @@ package tv.codely.apps.backoffice.backend.controller.health_check; +import java.util.HashMap; + import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; + import tv.codely.shared.domain.DomainError; import tv.codely.shared.domain.bus.command.CommandBus; import tv.codely.shared.domain.bus.query.QueryBus; import tv.codely.shared.infrastructure.spring.ApiController; -import java.util.HashMap; - @RestController public final class HealthCheckGetController extends ApiController { - public HealthCheckGetController( - QueryBus queryBus, - CommandBus commandBus - ) { - super(queryBus, commandBus); - } - - @GetMapping("/health-check") - public HashMap index() { - HashMap status = new HashMap<>(); - status.put("application", "backoffice_backend"); - status.put("status", "ok"); - - return status; - } - - @Override - public HashMap, HttpStatus> errorMapping() { - return null; - } + + public HealthCheckGetController(QueryBus queryBus, CommandBus commandBus) { + super(queryBus, commandBus); + } + + @GetMapping("/health-check") + public HashMap index() { + HashMap status = new HashMap<>(); + status.put("application", "backoffice_backend"); + status.put("status", "ok"); + + return status; + } + + @Override + public HashMap, HttpStatus> errorMapping() { + return null; + } } diff --git a/apps/main/tv/codely/apps/backoffice/backend/middleware/BasicHttpAuthMiddleware.java b/apps/main/tv/codely/apps/backoffice/backend/middleware/BasicHttpAuthMiddleware.java index 268539c5..2ce6a903 100644 --- a/apps/main/tv/codely/apps/backoffice/backend/middleware/BasicHttpAuthMiddleware.java +++ b/apps/main/tv/codely/apps/backoffice/backend/middleware/BasicHttpAuthMiddleware.java @@ -1,78 +1,77 @@ package tv.codely.apps.backoffice.backend.middleware; +import java.io.IOException; +import java.util.Base64; + +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + import tv.codely.backoffice.auth.application.authenticate.AuthenticateUserCommand; import tv.codely.backoffice.auth.domain.InvalidAuthCredentials; import tv.codely.backoffice.auth.domain.InvalidAuthUsername; import tv.codely.shared.domain.bus.command.CommandBus; import tv.codely.shared.domain.bus.command.CommandHandlerExecutionError; -import jakarta.servlet.*; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Base64; - public final class BasicHttpAuthMiddleware implements Filter { - private final CommandBus bus; - - public BasicHttpAuthMiddleware(CommandBus bus) { - this.bus = bus; - } - - @Override - public void doFilter( - ServletRequest request, - ServletResponse response, - FilterChain chain - ) throws IOException, ServletException { - String authorizationHeader = ((HttpServletRequest) request).getHeader("authorization"); - - if (hasIntroducedCredentials(authorizationHeader)) { - authenticate(authorizationHeader, chain, request, response); - } else { - askForCredentials(response); - } - } - - private boolean hasIntroducedCredentials(String authorizationHeader) { - return null != authorizationHeader; - } - - private void authenticate( - String authorizationHeader, - FilterChain chain, - ServletRequest request, - ServletResponse response - ) throws IOException, ServletException { - String[] auth = decodeAuth(authorizationHeader); - String user = auth[0]; - String pass = auth[1]; - - try { - bus.dispatch(new AuthenticateUserCommand(user, pass)); - - request.setAttribute("authentication_username", user); - - chain.doFilter(request, response); - } catch (InvalidAuthUsername | InvalidAuthCredentials | CommandHandlerExecutionError error) { - setInvalidCredentials(response); - } - } - - private String[] decodeAuth(String authString) { - return new String(Base64.getDecoder().decode(authString.split("\\s+")[1])).split(":"); - } - - private void setInvalidCredentials(ServletResponse response) { - HttpServletResponse httpServletResponse = (HttpServletResponse) response; - httpServletResponse.reset(); - httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); - } - - private void askForCredentials(ServletResponse response) { - HttpServletResponse httpServletResponse = (HttpServletResponse) response; - httpServletResponse.reset(); - httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - httpServletResponse.setHeader("WWW-Authenticate", "Basic realm=\"CodelyTV\""); - } + + private final CommandBus bus; + + public BasicHttpAuthMiddleware(CommandBus bus) { + this.bus = bus; + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + String authorizationHeader = ((HttpServletRequest) request).getHeader("authorization"); + + if (hasIntroducedCredentials(authorizationHeader)) { + authenticate(authorizationHeader, chain, request, response); + } else { + askForCredentials(response); + } + } + + private boolean hasIntroducedCredentials(String authorizationHeader) { + return null != authorizationHeader; + } + + private void authenticate( + String authorizationHeader, + FilterChain chain, + ServletRequest request, + ServletResponse response + ) throws IOException, ServletException { + String[] auth = decodeAuth(authorizationHeader); + String user = auth[0]; + String pass = auth[1]; + + try { + bus.dispatch(new AuthenticateUserCommand(user, pass)); + + request.setAttribute("authentication_username", user); + + chain.doFilter(request, response); + } catch (InvalidAuthUsername | InvalidAuthCredentials | CommandHandlerExecutionError error) { + setInvalidCredentials(response); + } + } + + private String[] decodeAuth(String authString) { + return new String(Base64.getDecoder().decode(authString.split("\\s+")[1])).split(":"); + } + + private void setInvalidCredentials(ServletResponse response) { + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + httpServletResponse.reset(); + httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); + } + + private void askForCredentials(ServletResponse response) { + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + httpServletResponse.reset(); + httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + httpServletResponse.setHeader("WWW-Authenticate", "Basic realm=\"CodelyTV\""); + } } diff --git a/apps/main/tv/codely/apps/backoffice/frontend/BackofficeFrontendApplication.java b/apps/main/tv/codely/apps/backoffice/frontend/BackofficeFrontendApplication.java index d9250da2..ae42787f 100644 --- a/apps/main/tv/codely/apps/backoffice/frontend/BackofficeFrontendApplication.java +++ b/apps/main/tv/codely/apps/backoffice/frontend/BackofficeFrontendApplication.java @@ -1,21 +1,24 @@ package tv.codely.apps.backoffice.frontend; +import java.util.HashMap; + import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; -import tv.codely.shared.domain.Service; -import java.util.HashMap; +import tv.codely.shared.domain.Service; @SpringBootApplication(exclude = HibernateJpaAutoConfiguration.class) @ComponentScan( - includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Service.class), - value = {"tv.codely.shared", "tv.codely.backoffice", "tv.codely.mooc", "tv.codely.apps.backoffice.frontend"} + includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Service.class), + value = { "tv.codely.shared", "tv.codely.backoffice", "tv.codely.mooc", "tv.codely.apps.backoffice.frontend" } ) public class BackofficeFrontendApplication { - public static HashMap> commands() { - return new HashMap>() {{ - }}; - } + + public static HashMap> commands() { + return new HashMap>() { + {} + }; + } } diff --git a/apps/main/tv/codely/apps/backoffice/frontend/config/BackofficeFrontendServerPortCustomizer.java b/apps/main/tv/codely/apps/backoffice/frontend/config/BackofficeFrontendServerPortCustomizer.java index a200075f..6cfbd81e 100644 --- a/apps/main/tv/codely/apps/backoffice/frontend/config/BackofficeFrontendServerPortCustomizer.java +++ b/apps/main/tv/codely/apps/backoffice/frontend/config/BackofficeFrontendServerPortCustomizer.java @@ -3,23 +3,26 @@ import org.springframework.boot.web.server.ConfigurableWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.stereotype.Component; + import tv.codely.shared.infrastructure.config.Parameter; import tv.codely.shared.infrastructure.config.ParameterNotExist; @Component -public final class BackofficeFrontendServerPortCustomizer implements WebServerFactoryCustomizer { - private final Parameter param; +public final class BackofficeFrontendServerPortCustomizer + implements WebServerFactoryCustomizer { + + private final Parameter param; - public BackofficeFrontendServerPortCustomizer(Parameter param) { - this.param = param; - } + public BackofficeFrontendServerPortCustomizer(Parameter param) { + this.param = param; + } - @Override - public void customize(ConfigurableWebServerFactory factory) { - try { - factory.setPort(param.getInt("BACKOFFICE_FRONTEND_SERVER_PORT")); - } catch (ParameterNotExist parameterNotExist) { - parameterNotExist.printStackTrace(); - } - } + @Override + public void customize(ConfigurableWebServerFactory factory) { + try { + factory.setPort(param.getInt("BACKOFFICE_FRONTEND_SERVER_PORT")); + } catch (ParameterNotExist parameterNotExist) { + parameterNotExist.printStackTrace(); + } + } } diff --git a/apps/main/tv/codely/apps/backoffice/frontend/config/BackofficeFrontendWebConfig.java b/apps/main/tv/codely/apps/backoffice/frontend/config/BackofficeFrontendWebConfig.java index 12a8a4bb..31405d6f 100644 --- a/apps/main/tv/codely/apps/backoffice/frontend/config/BackofficeFrontendWebConfig.java +++ b/apps/main/tv/codely/apps/backoffice/frontend/config/BackofficeFrontendWebConfig.java @@ -13,33 +13,34 @@ @Configuration @EnableWebMvc public class BackofficeFrontendWebConfig implements WebMvcConfigurer { - @Override - public void configureViewResolvers(ViewResolverRegistry registry) { - registry.freeMarker(); - } - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler("/**").addResourceLocations("classpath:/backoffice_frontend/public/"); - } + @Override + public void configureViewResolvers(ViewResolverRegistry registry) { + registry.freeMarker(); + } - @Bean - public ViewResolver getViewResolver() { - FreeMarkerViewResolver resolver = new FreeMarkerViewResolver(); - resolver.setCache(false); - resolver.setSuffix(".ftl"); - return resolver; - } + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/**").addResourceLocations("classpath:/backoffice_frontend/public/"); + } - @Bean - public FreeMarkerConfigurer freeMarkerConfigurer() { - FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); - configurer.setTemplateLoaderPath("classpath:/backoffice_frontend/templates/"); - configurer.setDefaultEncoding("UTF-8"); -// configurer.setFreemarkerVariables(new HashMap() {{ -// put("flash", new Flash()); -// }}); + @Bean + public ViewResolver getViewResolver() { + FreeMarkerViewResolver resolver = new FreeMarkerViewResolver(); + resolver.setCache(false); + resolver.setSuffix(".ftl"); + return resolver; + } - return configurer; - } + @Bean + public FreeMarkerConfigurer freeMarkerConfigurer() { + FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); + configurer.setTemplateLoaderPath("classpath:/backoffice_frontend/templates/"); + configurer.setDefaultEncoding("UTF-8"); + // configurer.setFreemarkerVariables(new HashMap() {{ + // put("flash", new Flash()); + // }}); + + return configurer; + } } diff --git a/apps/main/tv/codely/apps/backoffice/frontend/controller/courses/CoursesGetWebController.java b/apps/main/tv/codely/apps/backoffice/frontend/controller/courses/CoursesGetWebController.java index bec4c90b..95ff91c8 100644 --- a/apps/main/tv/codely/apps/backoffice/frontend/controller/courses/CoursesGetWebController.java +++ b/apps/main/tv/codely/apps/backoffice/frontend/controller/courses/CoursesGetWebController.java @@ -1,41 +1,48 @@ package tv.codely.apps.backoffice.frontend.controller.courses; +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.servlet.ModelAndView; + import tv.codely.mooc.courses_counter.application.find.CoursesCounterResponse; import tv.codely.mooc.courses_counter.application.find.FindCoursesCounterQuery; import tv.codely.shared.domain.bus.query.QueryBus; import tv.codely.shared.domain.bus.query.QueryHandlerExecutionError; -import java.io.Serializable; -import java.util.HashMap; -import java.util.List; -import java.util.UUID; - @Controller public final class CoursesGetWebController { - private final QueryBus bus; - - public CoursesGetWebController(QueryBus bus) { - this.bus = bus; - } - - @GetMapping("/courses") - public ModelAndView index( - @ModelAttribute("inputs") HashMap inputs, - @ModelAttribute("errors") HashMap> errors - ) throws QueryHandlerExecutionError { - CoursesCounterResponse counterResponse = bus.ask(new FindCoursesCounterQuery()); - - return new ModelAndView("pages/courses/courses", new HashMap() {{ - put("title", "Courses"); - put("description", "Courses CodelyTV - Backoffice"); - put("courses_counter", counterResponse.total()); - put("inputs", inputs); - put("errors", errors); - put("generated_uuid", UUID.randomUUID().toString()); - }}); - } + + private final QueryBus bus; + + public CoursesGetWebController(QueryBus bus) { + this.bus = bus; + } + + @GetMapping("/courses") + public ModelAndView index( + @ModelAttribute("inputs") HashMap inputs, + @ModelAttribute("errors") HashMap> errors + ) throws QueryHandlerExecutionError { + CoursesCounterResponse counterResponse = bus.ask(new FindCoursesCounterQuery()); + + return new ModelAndView( + "pages/courses/courses", + new HashMap() { + { + put("title", "Courses"); + put("description", "Courses CodelyTV - Backoffice"); + put("courses_counter", counterResponse.total()); + put("inputs", inputs); + put("errors", errors); + put("generated_uuid", UUID.randomUUID().toString()); + } + } + ); + } } diff --git a/apps/main/tv/codely/apps/backoffice/frontend/controller/courses/CoursesPostWebController.java b/apps/main/tv/codely/apps/backoffice/frontend/controller/courses/CoursesPostWebController.java index d39c052a..927dd411 100644 --- a/apps/main/tv/codely/apps/backoffice/frontend/controller/courses/CoursesPostWebController.java +++ b/apps/main/tv/codely/apps/backoffice/frontend/controller/courses/CoursesPostWebController.java @@ -1,63 +1,67 @@ package tv.codely.apps.backoffice.frontend.controller.courses; +import java.io.Serializable; +import java.util.HashMap; + import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.servlet.view.RedirectView; + import tv.codely.mooc.courses.application.create.CreateCourseCommand; import tv.codely.shared.domain.bus.command.CommandBus; import tv.codely.shared.domain.bus.command.CommandHandlerExecutionError; import tv.codely.shared.infrastructure.validation.ValidationResponse; import tv.codely.shared.infrastructure.validation.Validator; -import java.io.Serializable; -import java.util.HashMap; - @Controller public final class CoursesPostWebController { - private final CommandBus bus; - private final HashMap rules = new HashMap() {{ - put("id", "required|not_empty|uuid"); - put("name", "required|not_empty|string"); - put("duration", "required|not_empty|string"); - }}; - - public CoursesPostWebController(CommandBus bus) { - this.bus = bus; - } - - @PostMapping(value = "/courses", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) - public RedirectView index( - @RequestParam HashMap request, - RedirectAttributes attributes - ) throws Exception { - ValidationResponse validationResponse = Validator.validate(request, rules); - - return validationResponse.hasErrors() - ? redirectWithErrors(validationResponse, request, attributes) - : createCourse(request); - } - - private RedirectView redirectWithErrors( - ValidationResponse validationResponse, - HashMap request, - RedirectAttributes attributes - ) { - attributes.addFlashAttribute("errors", validationResponse.errors()); - attributes.addFlashAttribute("inputs", request); - - return new RedirectView("/courses"); - } - - private RedirectView createCourse(HashMap request) throws CommandHandlerExecutionError { - bus.dispatch(new CreateCourseCommand( - request.get("id").toString(), - request.get("name").toString(), - request.get("duration").toString() - )); - - return new RedirectView("/courses"); - } + + private final CommandBus bus; + private final HashMap rules = new HashMap() { + { + put("id", "required|not_empty|uuid"); + put("name", "required|not_empty|string"); + put("duration", "required|not_empty|string"); + } + }; + + public CoursesPostWebController(CommandBus bus) { + this.bus = bus; + } + + @PostMapping(value = "/courses", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + public RedirectView index(@RequestParam HashMap request, RedirectAttributes attributes) + throws Exception { + ValidationResponse validationResponse = Validator.validate(request, rules); + + return validationResponse.hasErrors() + ? redirectWithErrors(validationResponse, request, attributes) + : createCourse(request); + } + + private RedirectView redirectWithErrors( + ValidationResponse validationResponse, + HashMap request, + RedirectAttributes attributes + ) { + attributes.addFlashAttribute("errors", validationResponse.errors()); + attributes.addFlashAttribute("inputs", request); + + return new RedirectView("/courses"); + } + + private RedirectView createCourse(HashMap request) throws CommandHandlerExecutionError { + bus.dispatch( + new CreateCourseCommand( + request.get("id").toString(), + request.get("name").toString(), + request.get("duration").toString() + ) + ); + + return new RedirectView("/courses"); + } } diff --git a/apps/main/tv/codely/apps/backoffice/frontend/controller/health_check/HealthCheckGetController.java b/apps/main/tv/codely/apps/backoffice/frontend/controller/health_check/HealthCheckGetController.java index 2bd0f3c9..9c06c15d 100644 --- a/apps/main/tv/codely/apps/backoffice/frontend/controller/health_check/HealthCheckGetController.java +++ b/apps/main/tv/codely/apps/backoffice/frontend/controller/health_check/HealthCheckGetController.java @@ -1,18 +1,19 @@ package tv.codely.apps.backoffice.frontend.controller.health_check; +import java.util.HashMap; + import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.HashMap; - @RestController public final class HealthCheckGetController { - @GetMapping("/health-check") - public HashMap index() { - HashMap status = new HashMap<>(); - status.put("application", "backoffice_frontend"); - status.put("status", "ok"); - return status; - } + @GetMapping("/health-check") + public HashMap index() { + HashMap status = new HashMap<>(); + status.put("application", "backoffice_frontend"); + status.put("status", "ok"); + + return status; + } } diff --git a/apps/main/tv/codely/apps/backoffice/frontend/controller/home/HomeGetWebController.java b/apps/main/tv/codely/apps/backoffice/frontend/controller/home/HomeGetWebController.java index 4dfbd4ea..254fba9b 100644 --- a/apps/main/tv/codely/apps/backoffice/frontend/controller/home/HomeGetWebController.java +++ b/apps/main/tv/codely/apps/backoffice/frontend/controller/home/HomeGetWebController.java @@ -1,19 +1,25 @@ package tv.codely.apps.backoffice.frontend.controller.home; +import java.io.Serializable; +import java.util.HashMap; + import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.servlet.ModelAndView; -import java.io.Serializable; -import java.util.HashMap; - @Controller public final class HomeGetWebController { - @GetMapping("/") - public ModelAndView index() { - return new ModelAndView("pages/home", new HashMap() {{ - put("title", "Welcome"); - put("description", "CodelyTV - Backoffice"); - }}); - } + + @GetMapping("/") + public ModelAndView index() { + return new ModelAndView( + "pages/home", + new HashMap() { + { + put("title", "Welcome"); + put("description", "CodelyTV - Backoffice"); + } + } + ); + } } diff --git a/apps/main/tv/codely/apps/mooc/backend/MoocBackendApplication.java b/apps/main/tv/codely/apps/mooc/backend/MoocBackendApplication.java index bdc107d4..b9e04482 100644 --- a/apps/main/tv/codely/apps/mooc/backend/MoocBackendApplication.java +++ b/apps/main/tv/codely/apps/mooc/backend/MoocBackendApplication.java @@ -1,25 +1,29 @@ package tv.codely.apps.mooc.backend; +import java.util.HashMap; + import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; + import tv.codely.apps.mooc.backend.command.ConsumeMySqlDomainEventsCommand; import tv.codely.apps.mooc.backend.command.ConsumeRabbitMqDomainEventsCommand; import tv.codely.shared.domain.Service; -import java.util.HashMap; - @SpringBootApplication(exclude = HibernateJpaAutoConfiguration.class) @ComponentScan( - includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Service.class), - value = {"tv.codely.shared", "tv.codely.mooc", "tv.codely.apps.mooc.backend"} + includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Service.class), + value = { "tv.codely.shared", "tv.codely.mooc", "tv.codely.apps.mooc.backend" } ) public class MoocBackendApplication { - public static HashMap> commands() { - return new HashMap>() {{ - put("domain-events:mysql:consume", ConsumeMySqlDomainEventsCommand.class); - put("domain-events:rabbitmq:consume", ConsumeRabbitMqDomainEventsCommand.class); - }}; - } + + public static HashMap> commands() { + return new HashMap>() { + { + put("domain-events:mysql:consume", ConsumeMySqlDomainEventsCommand.class); + put("domain-events:rabbitmq:consume", ConsumeRabbitMqDomainEventsCommand.class); + } + }; + } } diff --git a/apps/main/tv/codely/apps/mooc/backend/command/ConsumeMySqlDomainEventsCommand.java b/apps/main/tv/codely/apps/mooc/backend/command/ConsumeMySqlDomainEventsCommand.java index a9102a2f..78eaf411 100644 --- a/apps/main/tv/codely/apps/mooc/backend/command/ConsumeMySqlDomainEventsCommand.java +++ b/apps/main/tv/codely/apps/mooc/backend/command/ConsumeMySqlDomainEventsCommand.java @@ -4,14 +4,15 @@ import tv.codely.shared.infrastructure.cli.ConsoleCommand; public final class ConsumeMySqlDomainEventsCommand extends ConsoleCommand { - private final MySqlDomainEventsConsumer consumer; - public ConsumeMySqlDomainEventsCommand(MySqlDomainEventsConsumer consumer) { - this.consumer = consumer; - } + private final MySqlDomainEventsConsumer consumer; - @Override - public void execute(String[] args) { - consumer.consume(); - } + public ConsumeMySqlDomainEventsCommand(MySqlDomainEventsConsumer consumer) { + this.consumer = consumer; + } + + @Override + public void execute(String[] args) { + consumer.consume(); + } } diff --git a/apps/main/tv/codely/apps/mooc/backend/command/ConsumeRabbitMqDomainEventsCommand.java b/apps/main/tv/codely/apps/mooc/backend/command/ConsumeRabbitMqDomainEventsCommand.java index ef50fb48..993dcd5b 100644 --- a/apps/main/tv/codely/apps/mooc/backend/command/ConsumeRabbitMqDomainEventsCommand.java +++ b/apps/main/tv/codely/apps/mooc/backend/command/ConsumeRabbitMqDomainEventsCommand.java @@ -4,14 +4,15 @@ import tv.codely.shared.infrastructure.cli.ConsoleCommand; public final class ConsumeRabbitMqDomainEventsCommand extends ConsoleCommand { - private final RabbitMqDomainEventsConsumer consumer; - public ConsumeRabbitMqDomainEventsCommand(RabbitMqDomainEventsConsumer consumer) { - this.consumer = consumer; - } + private final RabbitMqDomainEventsConsumer consumer; - @Override - public void execute(String[] args) { - consumer.consume(); - } + public ConsumeRabbitMqDomainEventsCommand(RabbitMqDomainEventsConsumer consumer) { + this.consumer = consumer; + } + + @Override + public void execute(String[] args) { + consumer.consume(); + } } diff --git a/apps/main/tv/codely/apps/mooc/backend/config/MoocBackendServerConfiguration.java b/apps/main/tv/codely/apps/mooc/backend/config/MoocBackendServerConfiguration.java index f5c6ef6b..9974cddc 100644 --- a/apps/main/tv/codely/apps/mooc/backend/config/MoocBackendServerConfiguration.java +++ b/apps/main/tv/codely/apps/mooc/backend/config/MoocBackendServerConfiguration.java @@ -4,22 +4,24 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + import tv.codely.shared.infrastructure.spring.ApiExceptionMiddleware; @Configuration public class MoocBackendServerConfiguration { - private final RequestMappingHandlerMapping mapping; - public MoocBackendServerConfiguration(RequestMappingHandlerMapping mapping) { - this.mapping = mapping; - } + private final RequestMappingHandlerMapping mapping; + + public MoocBackendServerConfiguration(RequestMappingHandlerMapping mapping) { + this.mapping = mapping; + } - @Bean - public FilterRegistrationBean apiExceptionMiddleware() { - FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + @Bean + public FilterRegistrationBean apiExceptionMiddleware() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); - registrationBean.setFilter(new ApiExceptionMiddleware(mapping)); + registrationBean.setFilter(new ApiExceptionMiddleware(mapping)); - return registrationBean; - } + return registrationBean; + } } diff --git a/apps/main/tv/codely/apps/mooc/backend/config/MoocBackendServerPortCustomizer.java b/apps/main/tv/codely/apps/mooc/backend/config/MoocBackendServerPortCustomizer.java index 96efccee..3d61c275 100644 --- a/apps/main/tv/codely/apps/mooc/backend/config/MoocBackendServerPortCustomizer.java +++ b/apps/main/tv/codely/apps/mooc/backend/config/MoocBackendServerPortCustomizer.java @@ -3,23 +3,25 @@ import org.springframework.boot.web.server.ConfigurableWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.stereotype.Component; + import tv.codely.shared.infrastructure.config.Parameter; import tv.codely.shared.infrastructure.config.ParameterNotExist; @Component public final class MoocBackendServerPortCustomizer implements WebServerFactoryCustomizer { - private final Parameter param; - public MoocBackendServerPortCustomizer(Parameter param) { - this.param = param; - } + private final Parameter param; + + public MoocBackendServerPortCustomizer(Parameter param) { + this.param = param; + } - @Override - public void customize(ConfigurableWebServerFactory factory) { - try { - factory.setPort(param.getInt("MOOC_BACKEND_SERVER_PORT")); - } catch (ParameterNotExist parameterNotExist) { - parameterNotExist.printStackTrace(); - } - } + @Override + public void customize(ConfigurableWebServerFactory factory) { + try { + factory.setPort(param.getInt("MOOC_BACKEND_SERVER_PORT")); + } catch (ParameterNotExist parameterNotExist) { + parameterNotExist.printStackTrace(); + } + } } diff --git a/apps/main/tv/codely/apps/mooc/backend/controller/courses/CourseGetController.java b/apps/main/tv/codely/apps/mooc/backend/controller/courses/CourseGetController.java index 4a7fa716..838783b1 100644 --- a/apps/main/tv/codely/apps/mooc/backend/controller/courses/CourseGetController.java +++ b/apps/main/tv/codely/apps/mooc/backend/controller/courses/CourseGetController.java @@ -1,10 +1,14 @@ package tv.codely.apps.mooc.backend.controller.courses; +import java.io.Serializable; +import java.util.HashMap; + import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; + import tv.codely.mooc.courses.application.CourseResponse; import tv.codely.mooc.courses.application.find.FindCourseQuery; import tv.codely.mooc.courses.domain.CourseNotExist; @@ -14,33 +18,37 @@ import tv.codely.shared.domain.bus.query.QueryHandlerExecutionError; import tv.codely.shared.infrastructure.spring.ApiController; -import java.io.Serializable; -import java.util.HashMap; - @RestController public final class CourseGetController extends ApiController { - public CourseGetController( - QueryBus queryBus, - CommandBus commandBus - ) { - super(queryBus, commandBus); - } - - @GetMapping("/courses/{id}") - public ResponseEntity> index(@PathVariable String id) throws QueryHandlerExecutionError { - CourseResponse course = ask(new FindCourseQuery(id)); - - return ResponseEntity.ok().body(new HashMap() {{ - put("id", course.id()); - put("name", course.name()); - put("duration", course.duration()); - }}); - } - - @Override - public HashMap, HttpStatus> errorMapping() { - return new HashMap, HttpStatus>() {{ - put(CourseNotExist.class, HttpStatus.NOT_FOUND); - }}; - } + + public CourseGetController(QueryBus queryBus, CommandBus commandBus) { + super(queryBus, commandBus); + } + + @GetMapping("/courses/{id}") + public ResponseEntity> index(@PathVariable String id) + throws QueryHandlerExecutionError { + CourseResponse course = ask(new FindCourseQuery(id)); + + return ResponseEntity + .ok() + .body( + new HashMap() { + { + put("id", course.id()); + put("name", course.name()); + put("duration", course.duration()); + } + } + ); + } + + @Override + public HashMap, HttpStatus> errorMapping() { + return new HashMap, HttpStatus>() { + { + put(CourseNotExist.class, HttpStatus.NOT_FOUND); + } + }; + } } diff --git a/apps/main/tv/codely/apps/mooc/backend/controller/courses/CoursesPutController.java b/apps/main/tv/codely/apps/mooc/backend/controller/courses/CoursesPutController.java index 5c8b0171..54bc2044 100644 --- a/apps/main/tv/codely/apps/mooc/backend/controller/courses/CoursesPutController.java +++ b/apps/main/tv/codely/apps/mooc/backend/controller/courses/CoursesPutController.java @@ -1,11 +1,14 @@ package tv.codely.apps.mooc.backend.controller.courses; +import java.util.HashMap; + import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; + import tv.codely.mooc.courses.application.create.CreateCourseCommand; import tv.codely.shared.domain.DomainError; import tv.codely.shared.domain.bus.command.CommandBus; @@ -13,50 +16,45 @@ import tv.codely.shared.domain.bus.query.QueryBus; import tv.codely.shared.infrastructure.spring.ApiController; -import java.util.HashMap; - @RestController public final class CoursesPutController extends ApiController { - public CoursesPutController( - QueryBus queryBus, - CommandBus commandBus - ) { - super(queryBus, commandBus); - } - - @PutMapping(value = "/courses/{id}") - public ResponseEntity index( - @PathVariable String id, - @RequestBody Request request - ) throws CommandHandlerExecutionError { - dispatch(new CreateCourseCommand(id, request.name(), request.duration())); - - return new ResponseEntity<>(HttpStatus.CREATED); - } - - @Override - public HashMap, HttpStatus> errorMapping() { - return null; - } + + public CoursesPutController(QueryBus queryBus, CommandBus commandBus) { + super(queryBus, commandBus); + } + + @PutMapping(value = "/courses/{id}") + public ResponseEntity index(@PathVariable String id, @RequestBody Request request) + throws CommandHandlerExecutionError { + dispatch(new CreateCourseCommand(id, request.name(), request.duration())); + + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Override + public HashMap, HttpStatus> errorMapping() { + return null; + } } final class Request { - private String name; - private String duration; - public void setDuration(String duration) { - this.duration = duration; - } + private String name; + private String duration; + + public void setDuration(String duration) { + this.duration = duration; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - String name() { - return name; - } + String name() { + return name; + } - String duration() { - return duration; - } + String duration() { + return duration; + } } diff --git a/apps/main/tv/codely/apps/mooc/backend/controller/courses_counter/CoursesCounterGetController.java b/apps/main/tv/codely/apps/mooc/backend/controller/courses_counter/CoursesCounterGetController.java index f74ebb2b..88a932f8 100644 --- a/apps/main/tv/codely/apps/mooc/backend/controller/courses_counter/CoursesCounterGetController.java +++ b/apps/main/tv/codely/apps/mooc/backend/controller/courses_counter/CoursesCounterGetController.java @@ -1,8 +1,11 @@ package tv.codely.apps.mooc.backend.controller.courses_counter; +import java.util.HashMap; + import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; + import tv.codely.mooc.courses_counter.application.find.CoursesCounterResponse; import tv.codely.mooc.courses_counter.application.find.FindCoursesCounterQuery; import tv.codely.shared.domain.DomainError; @@ -11,25 +14,26 @@ import tv.codely.shared.domain.bus.query.QueryHandlerExecutionError; import tv.codely.shared.infrastructure.spring.ApiController; -import java.util.HashMap; - @RestController public final class CoursesCounterGetController extends ApiController { - public CoursesCounterGetController(QueryBus queryBus, CommandBus commandBus) { - super(queryBus, commandBus); - } - - @GetMapping("/courses-counter") - public HashMap index() throws QueryHandlerExecutionError { - CoursesCounterResponse response = ask(new FindCoursesCounterQuery()); - - return new HashMap() {{ - put("total", response.total()); - }}; - } - - @Override - public HashMap, HttpStatus> errorMapping() { - return null; - } + + public CoursesCounterGetController(QueryBus queryBus, CommandBus commandBus) { + super(queryBus, commandBus); + } + + @GetMapping("/courses-counter") + public HashMap index() throws QueryHandlerExecutionError { + CoursesCounterResponse response = ask(new FindCoursesCounterQuery()); + + return new HashMap() { + { + put("total", response.total()); + } + }; + } + + @Override + public HashMap, HttpStatus> errorMapping() { + return null; + } } diff --git a/apps/main/tv/codely/apps/mooc/backend/controller/health_check/HealthCheckGetController.java b/apps/main/tv/codely/apps/mooc/backend/controller/health_check/HealthCheckGetController.java index 7ad7e56c..43461f91 100644 --- a/apps/main/tv/codely/apps/mooc/backend/controller/health_check/HealthCheckGetController.java +++ b/apps/main/tv/codely/apps/mooc/backend/controller/health_check/HealthCheckGetController.java @@ -1,35 +1,34 @@ package tv.codely.apps.mooc.backend.controller.health_check; +import java.util.HashMap; + import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; + import tv.codely.shared.domain.DomainError; import tv.codely.shared.domain.bus.command.CommandBus; import tv.codely.shared.domain.bus.query.QueryBus; import tv.codely.shared.infrastructure.spring.ApiController; -import java.util.HashMap; - @RestController public final class HealthCheckGetController extends ApiController { - public HealthCheckGetController( - QueryBus queryBus, - CommandBus commandBus - ) { - super(queryBus, commandBus); - } - - @GetMapping("/health-check") - public HashMap index() { - HashMap status = new HashMap<>(); - status.put("application", "mooc_backend"); - status.put("status", "ok"); - - return status; - } - - @Override - public HashMap, HttpStatus> errorMapping() { - return null; - } + + public HealthCheckGetController(QueryBus queryBus, CommandBus commandBus) { + super(queryBus, commandBus); + } + + @GetMapping("/health-check") + public HashMap index() { + HashMap status = new HashMap<>(); + status.put("application", "mooc_backend"); + status.put("status", "ok"); + + return status; + } + + @Override + public HashMap, HttpStatus> errorMapping() { + return null; + } } diff --git a/apps/main/tv/codely/apps/mooc/backend/controller/notifications/NewsletterNotificationPutController.java b/apps/main/tv/codely/apps/mooc/backend/controller/notifications/NewsletterNotificationPutController.java index 13042fa5..3fbcd681 100644 --- a/apps/main/tv/codely/apps/mooc/backend/controller/notifications/NewsletterNotificationPutController.java +++ b/apps/main/tv/codely/apps/mooc/backend/controller/notifications/NewsletterNotificationPutController.java @@ -1,40 +1,36 @@ package tv.codely.apps.mooc.backend.controller.notifications; +import java.util.HashMap; + import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RestController; + import tv.codely.mooc.notifications.application.send_new_courses_newsletter.SendNewCoursesNewsletterCommand; import tv.codely.shared.domain.DomainError; import tv.codely.shared.domain.bus.command.CommandBus; import tv.codely.shared.domain.bus.command.CommandHandlerExecutionError; -import tv.codely.shared.domain.bus.command.CommandNotRegisteredError; import tv.codely.shared.domain.bus.query.QueryBus; import tv.codely.shared.infrastructure.spring.ApiController; -import java.util.HashMap; - @RestController public final class NewsletterNotificationPutController extends ApiController { - public NewsletterNotificationPutController( - QueryBus queryBus, - CommandBus commandBus - ) { - super(queryBus, commandBus); - } - - @PutMapping(value = "/newsletter/{id}") - public ResponseEntity index( - @PathVariable String id - ) throws CommandHandlerExecutionError { - dispatch(new SendNewCoursesNewsletterCommand(id)); - - return new ResponseEntity<>(HttpStatus.CREATED); - } - - @Override - public HashMap, HttpStatus> errorMapping() { - return null; - } + + public NewsletterNotificationPutController(QueryBus queryBus, CommandBus commandBus) { + super(queryBus, commandBus); + } + + @PutMapping(value = "/newsletter/{id}") + public ResponseEntity index(@PathVariable String id) throws CommandHandlerExecutionError { + dispatch(new SendNewCoursesNewsletterCommand(id)); + + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Override + public HashMap, HttpStatus> errorMapping() { + return null; + } } diff --git a/apps/test/tv/codely/apps/ApplicationTestCase.java b/apps/test/tv/codely/apps/ApplicationTestCase.java index c61f3cde..d3568189 100644 --- a/apps/test/tv/codely/apps/ApplicationTestCase.java +++ b/apps/test/tv/codely/apps/ApplicationTestCase.java @@ -1,5 +1,13 @@ package tv.codely.apps; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.Arrays; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -7,80 +15,53 @@ import org.springframework.http.HttpMethod; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultMatcher; + import tv.codely.shared.domain.bus.event.DomainEvent; import tv.codely.shared.domain.bus.event.EventBus; -import java.util.Arrays; - -import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @SpringBootTest @AutoConfigureMockMvc public abstract class ApplicationTestCase { - @Autowired - private MockMvc mockMvc; - @Autowired - private EventBus eventBus; - protected void assertResponse( - String endpoint, - Integer expectedStatusCode, - String expectedResponse - ) throws Exception { - ResultMatcher response = expectedResponse.isEmpty() - ? content().string("") - : content().json(expectedResponse); + @Autowired + private MockMvc mockMvc; + + @Autowired + private EventBus eventBus; + + protected void assertResponse(String endpoint, Integer expectedStatusCode, String expectedResponse) throws Exception { + ResultMatcher response = expectedResponse.isEmpty() ? content().string("") : content().json(expectedResponse); - mockMvc - .perform(get(endpoint)) - .andExpect(status().is(expectedStatusCode)) - .andExpect(response); - } + mockMvc.perform(get(endpoint)).andExpect(status().is(expectedStatusCode)).andExpect(response); + } - protected void assertResponse( - String endpoint, - Integer expectedStatusCode, - String expectedResponse, - HttpHeaders headers - ) throws Exception { - ResultMatcher response = expectedResponse.isEmpty() - ? content().string("") - : content().json(expectedResponse); + protected void assertResponse( + String endpoint, + Integer expectedStatusCode, + String expectedResponse, + HttpHeaders headers + ) throws Exception { + ResultMatcher response = expectedResponse.isEmpty() ? content().string("") : content().json(expectedResponse); - mockMvc - .perform(get(endpoint).headers(headers)) - .andExpect(status().is(expectedStatusCode)) - .andExpect(response); - } + mockMvc.perform(get(endpoint).headers(headers)).andExpect(status().is(expectedStatusCode)).andExpect(response); + } - protected void assertRequestWithBody( - String method, - String endpoint, - String body, - Integer expectedStatusCode - ) throws Exception { - mockMvc - .perform(request(HttpMethod.valueOf(method), endpoint).content(body).contentType(APPLICATION_JSON)) - .andExpect(status().is(expectedStatusCode)) - .andExpect(content().string("")); - } + protected void assertRequestWithBody(String method, String endpoint, String body, Integer expectedStatusCode) + throws Exception { + mockMvc + .perform(request(HttpMethod.valueOf(method), endpoint).content(body).contentType(APPLICATION_JSON)) + .andExpect(status().is(expectedStatusCode)) + .andExpect(content().string("")); + } - protected void assertRequest( - String method, - String endpoint, - Integer expectedStatusCode - ) throws Exception { - mockMvc - .perform(request(HttpMethod.valueOf(method), endpoint)) - .andExpect(status().is(expectedStatusCode)) - .andExpect(content().string("")); - } + protected void assertRequest(String method, String endpoint, Integer expectedStatusCode) throws Exception { + mockMvc + .perform(request(HttpMethod.valueOf(method), endpoint)) + .andExpect(status().is(expectedStatusCode)) + .andExpect(content().string("")); + } - protected void givenISendEventsToTheBus(DomainEvent... domainEvents) { - eventBus.publish(Arrays.asList(domainEvents)); - } + protected void givenISendEventsToTheBus(DomainEvent... domainEvents) { + eventBus.publish(Arrays.asList(domainEvents)); + } } diff --git a/apps/test/tv/codely/apps/backoffice/BackofficeApplicationTestCase.java b/apps/test/tv/codely/apps/backoffice/BackofficeApplicationTestCase.java index a52bcc04..195b5537 100644 --- a/apps/test/tv/codely/apps/backoffice/BackofficeApplicationTestCase.java +++ b/apps/test/tv/codely/apps/backoffice/BackofficeApplicationTestCase.java @@ -1,8 +1,8 @@ package tv.codely.apps.backoffice; import org.springframework.transaction.annotation.Transactional; + import tv.codely.apps.ApplicationTestCase; @Transactional("backoffice-transaction_manager") -public abstract class BackofficeApplicationTestCase extends ApplicationTestCase { -} +public abstract class BackofficeApplicationTestCase extends ApplicationTestCase {} diff --git a/apps/test/tv/codely/apps/backoffice/backend/controller/health_check/HealthCheckGetControllerShould.java b/apps/test/tv/codely/apps/backoffice/backend/controller/health_check/HealthCheckGetControllerShould.java index a3f104ea..add71d8c 100644 --- a/apps/test/tv/codely/apps/backoffice/backend/controller/health_check/HealthCheckGetControllerShould.java +++ b/apps/test/tv/codely/apps/backoffice/backend/controller/health_check/HealthCheckGetControllerShould.java @@ -2,35 +2,37 @@ import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; + import tv.codely.apps.ApplicationTestCase; final class HealthCheckGetControllerShould extends ApplicationTestCase { - @Test - void check_the_app_is_working_ok_with_valid_credentials() throws Exception { - HttpHeaders headers = new HttpHeaders(); - headers.setBasicAuth("javi", "barbitas"); - - assertResponse("/health-check", 200, "{'application':'backoffice_backend','status':'ok'}", headers); - } - - @Test - void not_check_the_app_is_working_ok_with_invalid_credentials() throws Exception { - HttpHeaders headers = new HttpHeaders(); - headers.setBasicAuth("tipo_de_incognito", "homer.sampson"); - - assertResponse("/health-check", 403, "", headers); - } - - @Test - void not_check_the_app_is_working_ok_with_invalid_credentials_of_an_existing_user() throws Exception { - HttpHeaders headers = new HttpHeaders(); - headers.setBasicAuth("rafa", "incorrect.password"); - - assertResponse("/health-check", 403, "", headers); - } - - @Test - void not_check_the_app_is_working_ok_with_no_credentials() throws Exception { - assertResponse("/health-check", 401, ""); - } + + @Test + void check_the_app_is_working_ok_with_valid_credentials() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.setBasicAuth("javi", "barbitas"); + + assertResponse("/health-check", 200, "{'application':'backoffice_backend','status':'ok'}", headers); + } + + @Test + void not_check_the_app_is_working_ok_with_invalid_credentials() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.setBasicAuth("tipo_de_incognito", "homer.sampson"); + + assertResponse("/health-check", 403, "", headers); + } + + @Test + void not_check_the_app_is_working_ok_with_invalid_credentials_of_an_existing_user() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.setBasicAuth("rafa", "incorrect.password"); + + assertResponse("/health-check", 403, "", headers); + } + + @Test + void not_check_the_app_is_working_ok_with_no_credentials() throws Exception { + assertResponse("/health-check", 401, ""); + } } diff --git a/apps/test/tv/codely/apps/backoffice/frontend/controller/health_check/HealthCheckGetControllerShould.java b/apps/test/tv/codely/apps/backoffice/frontend/controller/health_check/HealthCheckGetControllerShould.java index 9d6e9356..c5a9747b 100644 --- a/apps/test/tv/codely/apps/backoffice/frontend/controller/health_check/HealthCheckGetControllerShould.java +++ b/apps/test/tv/codely/apps/backoffice/frontend/controller/health_check/HealthCheckGetControllerShould.java @@ -1,11 +1,13 @@ package tv.codely.apps.backoffice.frontend.controller.health_check; import org.junit.jupiter.api.Test; + import tv.codely.apps.ApplicationTestCase; final class HealthCheckGetControllerShould extends ApplicationTestCase { - @Test - void check_the_app_is_working_ok() throws Exception { - assertResponse("/health-check", 200, "{'application':'backoffice_frontend','status':'ok'}"); - } + + @Test + void check_the_app_is_working_ok() throws Exception { + assertResponse("/health-check", 200, "{'application':'backoffice_frontend','status':'ok'}"); + } } diff --git a/apps/test/tv/codely/apps/mooc/MoocApplicationTestCase.java b/apps/test/tv/codely/apps/mooc/MoocApplicationTestCase.java index d805b14a..90dc231d 100644 --- a/apps/test/tv/codely/apps/mooc/MoocApplicationTestCase.java +++ b/apps/test/tv/codely/apps/mooc/MoocApplicationTestCase.java @@ -1,8 +1,8 @@ package tv.codely.apps.mooc; import org.springframework.transaction.annotation.Transactional; + import tv.codely.apps.ApplicationTestCase; @Transactional("mooc-transaction_manager") -public abstract class MoocApplicationTestCase extends ApplicationTestCase { -} +public abstract class MoocApplicationTestCase extends ApplicationTestCase {} diff --git a/apps/test/tv/codely/apps/mooc/backend/controller/courses/CourseGetControllerShould.java b/apps/test/tv/codely/apps/mooc/backend/controller/courses/CourseGetControllerShould.java index dcc8d551..0ebbcc4a 100644 --- a/apps/test/tv/codely/apps/mooc/backend/controller/courses/CourseGetControllerShould.java +++ b/apps/test/tv/codely/apps/mooc/backend/controller/courses/CourseGetControllerShould.java @@ -1,28 +1,31 @@ package tv.codely.apps.mooc.backend.controller.courses; import org.junit.jupiter.api.Test; + import tv.codely.apps.mooc.MoocApplicationTestCase; final class CourseGetControllerShould extends MoocApplicationTestCase { - @Test - void find_an_existing_course() throws Exception { - String id = "99ad55f5-6eab-4d73-b383-c63268e251e8"; - String body = "{\"name\": \"The best course\", \"duration\": \"5 hours\"}"; - givenThereIsACourse(id, body); + @Test + void find_an_existing_course() throws Exception { + String id = "99ad55f5-6eab-4d73-b383-c63268e251e8"; + String body = "{\"name\": \"The best course\", \"duration\": \"5 hours\"}"; + + givenThereIsACourse(id, body); - assertResponse(String.format("/courses/%s", id), 200, body); - } + assertResponse(String.format("/courses/%s", id), 200, body); + } - @Test - void no_find_a_non_existing_course() throws Exception { - String id = "4ecc0cb3-05b2-4238-b7e1-1fbb0d5d3661"; - String body = "{\"error_code\": \"course_not_exist\", \"message\": \"The course <4ecc0cb3-05b2-4238-b7e1-1fbb0d5d3661> doesn't exist\"}"; + @Test + void no_find_a_non_existing_course() throws Exception { + String id = "4ecc0cb3-05b2-4238-b7e1-1fbb0d5d3661"; + String body = + "{\"error_code\": \"course_not_exist\", \"message\": \"The course <4ecc0cb3-05b2-4238-b7e1-1fbb0d5d3661> doesn't exist\"}"; - assertResponse(String.format("/courses/%s", id), 404, body); - } + assertResponse(String.format("/courses/%s", id), 404, body); + } - private void givenThereIsACourse(String id, String body) throws Exception { - assertRequestWithBody("PUT", String.format("/courses/%s", id), body, 201); - } + private void givenThereIsACourse(String id, String body) throws Exception { + assertRequestWithBody("PUT", String.format("/courses/%s", id), body, 201); + } } diff --git a/apps/test/tv/codely/apps/mooc/backend/controller/courses/CoursesPutControllerShould.java b/apps/test/tv/codely/apps/mooc/backend/controller/courses/CoursesPutControllerShould.java index bc2a92fb..9dcbe3d4 100644 --- a/apps/test/tv/codely/apps/mooc/backend/controller/courses/CoursesPutControllerShould.java +++ b/apps/test/tv/codely/apps/mooc/backend/controller/courses/CoursesPutControllerShould.java @@ -1,16 +1,18 @@ package tv.codely.apps.mooc.backend.controller.courses; import org.junit.jupiter.api.Test; + import tv.codely.apps.mooc.MoocApplicationTestCase; public final class CoursesPutControllerShould extends MoocApplicationTestCase { - @Test - void create_a_valid_non_existing_course() throws Exception { - assertRequestWithBody( - "PUT", - "/courses/1aab45ba-3c7a-4344-8936-78466eca77fa", - "{\"name\": \"The best course\", \"duration\": \"5 hours\"}", - 201 - ); - } + + @Test + void create_a_valid_non_existing_course() throws Exception { + assertRequestWithBody( + "PUT", + "/courses/1aab45ba-3c7a-4344-8936-78466eca77fa", + "{\"name\": \"The best course\", \"duration\": \"5 hours\"}", + 201 + ); + } } diff --git a/apps/test/tv/codely/apps/mooc/backend/controller/courses_counter/CoursesCounterGetControllerShould.java b/apps/test/tv/codely/apps/mooc/backend/controller/courses_counter/CoursesCounterGetControllerShould.java index dcb24b55..29276780 100644 --- a/apps/test/tv/codely/apps/mooc/backend/controller/courses_counter/CoursesCounterGetControllerShould.java +++ b/apps/test/tv/codely/apps/mooc/backend/controller/courses_counter/CoursesCounterGetControllerShould.java @@ -1,44 +1,46 @@ package tv.codely.apps.mooc.backend.controller.courses_counter; import org.junit.jupiter.api.Test; + import tv.codely.apps.mooc.MoocApplicationTestCase; import tv.codely.shared.domain.course.CourseCreatedDomainEvent; public final class CoursesCounterGetControllerShould extends MoocApplicationTestCase { - @Test - void get_the_counter_with_one_course() throws Exception { - givenISendEventsToTheBus( - new CourseCreatedDomainEvent("8f34bc99-e0e2-4296-a008-75f51f03aeb4", "DDD en Java", "7 days") - ); - - assertResponse("/courses-counter", 200, "{'total': 1}"); - } - - @Test - void get_the_counter_with_more_than_one_course() throws Exception { - givenISendEventsToTheBus( - new CourseCreatedDomainEvent("8f34bc99-e0e2-4296-a008-75f51f03aeb4", "DDD en Java", "7 days"), - new CourseCreatedDomainEvent("3642f700-868a-4778-9317-a2d542d01785", "DDD en PHP", "6 days"), - new CourseCreatedDomainEvent("92dd8402-69f3-4900-b569-3f2c2797065f", "DDD en Cobol", "10 years") - ); - - assertResponse("/courses-counter", 200, "{'total': 3}"); - } - - @Test - void get_the_counter_with_more_than_one_course_having_duplicated_events() throws Exception { - givenISendEventsToTheBus( - new CourseCreatedDomainEvent("8f34bc99-e0e2-4296-a008-75f51f03aeb4", "DDD en Java", "7 days"), - new CourseCreatedDomainEvent("8f34bc99-e0e2-4296-a008-75f51f03aeb4", "DDD en Java", "7 days"), - new CourseCreatedDomainEvent("8f34bc99-e0e2-4296-a008-75f51f03aeb4", "DDD en Java", "7 days"), - new CourseCreatedDomainEvent("3642f700-868a-4778-9317-a2d542d01785", "DDD en PHP", "6 days"), - new CourseCreatedDomainEvent("3642f700-868a-4778-9317-a2d542d01785", "DDD en PHP", "6 days"), - new CourseCreatedDomainEvent("3642f700-868a-4778-9317-a2d542d01785", "DDD en PHP", "6 days"), - new CourseCreatedDomainEvent("3642f700-868a-4778-9317-a2d542d01785", "DDD en PHP", "6 days"), - new CourseCreatedDomainEvent("92dd8402-69f3-4900-b569-3f2c2797065f", "DDD en Cobol", "10 years"), - new CourseCreatedDomainEvent("92dd8402-69f3-4900-b569-3f2c2797065f", "DDD en Cobol", "10 years") - ); - - assertResponse("/courses-counter", 200, "{'total': 3}"); - } + + @Test + void get_the_counter_with_one_course() throws Exception { + givenISendEventsToTheBus( + new CourseCreatedDomainEvent("8f34bc99-e0e2-4296-a008-75f51f03aeb4", "DDD en Java", "7 days") + ); + + assertResponse("/courses-counter", 200, "{'total': 1}"); + } + + @Test + void get_the_counter_with_more_than_one_course() throws Exception { + givenISendEventsToTheBus( + new CourseCreatedDomainEvent("8f34bc99-e0e2-4296-a008-75f51f03aeb4", "DDD en Java", "7 days"), + new CourseCreatedDomainEvent("3642f700-868a-4778-9317-a2d542d01785", "DDD en PHP", "6 days"), + new CourseCreatedDomainEvent("92dd8402-69f3-4900-b569-3f2c2797065f", "DDD en Cobol", "10 years") + ); + + assertResponse("/courses-counter", 200, "{'total': 3}"); + } + + @Test + void get_the_counter_with_more_than_one_course_having_duplicated_events() throws Exception { + givenISendEventsToTheBus( + new CourseCreatedDomainEvent("8f34bc99-e0e2-4296-a008-75f51f03aeb4", "DDD en Java", "7 days"), + new CourseCreatedDomainEvent("8f34bc99-e0e2-4296-a008-75f51f03aeb4", "DDD en Java", "7 days"), + new CourseCreatedDomainEvent("8f34bc99-e0e2-4296-a008-75f51f03aeb4", "DDD en Java", "7 days"), + new CourseCreatedDomainEvent("3642f700-868a-4778-9317-a2d542d01785", "DDD en PHP", "6 days"), + new CourseCreatedDomainEvent("3642f700-868a-4778-9317-a2d542d01785", "DDD en PHP", "6 days"), + new CourseCreatedDomainEvent("3642f700-868a-4778-9317-a2d542d01785", "DDD en PHP", "6 days"), + new CourseCreatedDomainEvent("3642f700-868a-4778-9317-a2d542d01785", "DDD en PHP", "6 days"), + new CourseCreatedDomainEvent("92dd8402-69f3-4900-b569-3f2c2797065f", "DDD en Cobol", "10 years"), + new CourseCreatedDomainEvent("92dd8402-69f3-4900-b569-3f2c2797065f", "DDD en Cobol", "10 years") + ); + + assertResponse("/courses-counter", 200, "{'total': 3}"); + } } diff --git a/apps/test/tv/codely/apps/mooc/backend/controller/health_check/HealthCheckGetControllerShould.java b/apps/test/tv/codely/apps/mooc/backend/controller/health_check/HealthCheckGetControllerShould.java index dc78d6bd..94069bf5 100644 --- a/apps/test/tv/codely/apps/mooc/backend/controller/health_check/HealthCheckGetControllerShould.java +++ b/apps/test/tv/codely/apps/mooc/backend/controller/health_check/HealthCheckGetControllerShould.java @@ -1,11 +1,13 @@ package tv.codely.apps.mooc.backend.controller.health_check; import org.junit.jupiter.api.Test; + import tv.codely.apps.mooc.MoocApplicationTestCase; final class HealthCheckGetControllerShould extends MoocApplicationTestCase { - @Test - void check_the_app_is_working_ok() throws Exception { - assertResponse("/health-check", 200, "{'application':'mooc_backend','status':'ok'}"); - } + + @Test + void check_the_app_is_working_ok() throws Exception { + assertResponse("/health-check", 200, "{'application':'mooc_backend','status':'ok'}"); + } } diff --git a/apps/test/tv/codely/apps/mooc/backend/controller/notifications/NewsletterNotificationPutControllerShould.java b/apps/test/tv/codely/apps/mooc/backend/controller/notifications/NewsletterNotificationPutControllerShould.java index 68be2c60..8f011e9f 100644 --- a/apps/test/tv/codely/apps/mooc/backend/controller/notifications/NewsletterNotificationPutControllerShould.java +++ b/apps/test/tv/codely/apps/mooc/backend/controller/notifications/NewsletterNotificationPutControllerShould.java @@ -1,15 +1,13 @@ package tv.codely.apps.mooc.backend.controller.notifications; import org.junit.jupiter.api.Test; + import tv.codely.apps.mooc.MoocApplicationTestCase; final class NewsletterNotificationPutControllerShould extends MoocApplicationTestCase { - @Test - void create_a_valid_non_existing_course() throws Exception { - assertRequest( - "PUT", - "/newsletter/6eebbe60-50e7-400a-810c-3e0af0943ee6", - 201 - ); - } + + @Test + void create_a_valid_non_existing_course() throws Exception { + assertRequest("PUT", "/newsletter/6eebbe60-50e7-400a-810c-3e0af0943ee6", 201); + } } diff --git a/build.gradle b/build.gradle index 85617be9..508fb39e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,31 @@ +// Main project (located in apps/) +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath('org.springframework.boot:spring-boot-gradle-plugin:3.1.5') + } +} + +plugins { + id "com.diffplug.spotless" version "6.22.0" +} + +spotless { + java { + prettier(['prettier': '2.8.8', 'prettier-plugin-java': '2.2.0']) + .config(['parser': 'java', 'useTabs': true, 'printWidth': 120]) + + importOrder('\\#', 'java', '', 'tv.codely') + removeUnusedImports() + + endWithNewline() + + formatAnnotations() + } +} + // Common for all projects allprojects { apply plugin: 'java' @@ -9,6 +37,7 @@ allprojects { targetCompatibility = JavaVersion.VERSION_21 } + repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } @@ -110,15 +139,6 @@ subprojects { } } -// Main project (located in apps/) -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath('org.springframework.boot:spring-boot-gradle-plugin:3.1.5') - } -} sourceSets { main { @@ -138,6 +158,7 @@ bootJar { duplicatesStrategy = DuplicatesStrategy.EXCLUDE } + dependencies { implementation 'org.springframework.boot:spring-boot-starter-web:3.1.5'