diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 804430c..328fe50 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,14 +13,30 @@ env: JAVA_VERSION: 21 jobs: - test: + unit-test: runs-on: [ ubuntu-latest ] steps: - uses: actions/checkout@v4 + with: + ref: ${{ inputs.version }} - uses: actions/setup-java@v4 with: cache: gradle distribution: ${{ env.JAVA_DISTRIBUTION }} java-version: ${{ env.JAVA_VERSION }} + - run: ./gradlew clean test spotlessCheck --exclude-task :chucknorris-integration-test:test + + integration-test: + runs-on: [ ubuntu-latest ] + steps: + - uses: actions/checkout@v4 + with: ref: ${{ inputs.version }} - - run: ./gradlew test spotlessCheck \ No newline at end of file + - uses: actions/setup-java@v4 + with: + cache: gradle + distribution: ${{ env.JAVA_DISTRIBUTION }} + java-version: ${{ env.JAVA_VERSION }} + - name: Run Integration Test + shell: bash + run: ./chucknorris-integration-test/script/run-integration-test.sh \ No newline at end of file diff --git a/.gitignore b/.gitignore index aa32b2b..7a36286 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ out/ hs_err_pid* # Gradle +bin/ .gradle build/ gradle-app.setting diff --git a/.sdkmanrc b/.sdkmanrc new file mode 100644 index 0000000..ce350cb --- /dev/null +++ b/.sdkmanrc @@ -0,0 +1 @@ +java=17.0.11-zulu \ No newline at end of file diff --git a/build.gradle b/build.gradle index a754ba0..89c65c5 100644 --- a/build.gradle +++ b/build.gradle @@ -10,8 +10,6 @@ buildscript { } } -version = Git.commitHash() - subprojects { Project project -> apply plugin: 'com.diffplug.spotless' apply plugin: 'io.spring.dependency-management' @@ -19,7 +17,6 @@ subprojects { Project project -> sourceCompatibility = 17 targetCompatibility = 17 - version Git.commitHash() dependencyManagement { imports { mavenBom("org.springframework.boot:spring-boot-dependencies:${Version.SPRING_BOOT}") } @@ -39,7 +36,7 @@ subprojects { Project project -> spotless { java { - googleJavaFormat() + eclipse().configFile('../format.xml') } } } \ No newline at end of file diff --git a/buildSrc/src/main/groovy/Version.groovy b/buildSrc/src/main/groovy/Version.groovy index 80168f9..c66b9bf 100644 --- a/buildSrc/src/main/groovy/Version.groovy +++ b/buildSrc/src/main/groovy/Version.groovy @@ -1,4 +1,7 @@ interface Version { - public static final String SPRING_BOOT = '2.7.18' + public static final String LOMBOK = '1.18.30' + public static final String JUNIT = '5.10.2' + public static final String REST_ASSURED = '5.4.0' public static final String SPOTLESS = '7.0.0.BETA1' + public static final String SPRING_BOOT = '2.7.18' } \ No newline at end of file diff --git a/chucknorris-integration-test/build.gradle b/chucknorris-integration-test/build.gradle index 7d82dc7..6d2dc87 100644 --- a/chucknorris-integration-test/build.gradle +++ b/chucknorris-integration-test/build.gradle @@ -1,2 +1,14 @@ dependencies { + testImplementation 'commons-logging:commons-logging:1.3.2' + + testImplementation "org.junit.jupiter:junit-jupiter-api:${Version.JUNIT}" + testImplementation "org.junit.jupiter:junit-jupiter:${Version.JUNIT}" + testImplementation("io.rest-assured:json-path:${Version.REST_ASSURED}") { + exclude group: "org.apache.groovy", module: "groovy" + exclude group: "org.apache.groovy", module: "groovy-xml" + } + testImplementation("io.rest-assured:rest-assured:${Version.REST_ASSURED}") { + exclude group: "org.apache.groovy", module: "groovy" + exclude group: "org.apache.groovy", module: "groovy-xml" + } } diff --git a/chucknorris-integration-test/docker-compose.yml b/chucknorris-integration-test/docker-compose.yml index e159f27..6ad0bfd 100644 --- a/chucknorris-integration-test/docker-compose.yml +++ b/chucknorris-integration-test/docker-compose.yml @@ -5,15 +5,15 @@ services: image: chucknorrisio/postgres container_name: chucknorris-database healthcheck: - interval: 30s + interval: 5s retries: 5 - start_period: 80s + start_period: 20s test: [ "CMD-SHELL", "pg_isready", "-d", "db_prod" ] timeout: 60s ports: - '5432:5432' - service: + test-subject: environment: - APPLICATION_EVENT_SNS_TOPIC_ARN=my-application-event-sns-topic-arn - AWS_ACCESS_KEY_ID=my-aws-access-key-id @@ -34,5 +34,25 @@ services: depends_on: database: condition: service_healthy + healthcheck: + interval: 5s + retries: 5 + start_period: 20s + test: wget --no-verbose --tries=1 --spider http://localhost:8080 || exit 1 + timeout: 60s ports: - '8080:8080' + + integration-test: + command: "./gradlew :chucknorris-integration-test:test --stacktrace" + container_name: "integration-test" + depends_on: + test-subject: + condition: service_healthy + environment: + - TEST_SUBJECT_BASE_URI=http://test-subject + - TEST_SUBJECT_PORT=8080 + image: "azul/zulu-openjdk-alpine:21-jre-headless-latest" + volumes: + - "../:/home/gradle/project" + working_dir: /home/gradle/project diff --git a/chucknorris-integration-test/script/run-integration-test.sh b/chucknorris-integration-test/script/run-integration-test.sh index 74243ed..12cf7f4 100755 --- a/chucknorris-integration-test/script/run-integration-test.sh +++ b/chucknorris-integration-test/script/run-integration-test.sh @@ -4,13 +4,9 @@ readonly SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) readonly MODULE_DIR=$(cd "${SCRIPT_DIR}/.." && pwd) readonly PROJECT_DIR=$(cd "${SCRIPT_DIR}/../.." && pwd) -./gradlew --build-file "$PROJECT_DIR/build.gradle" clean dockerTagCurrent +./gradlew --build-file "$PROJECT_DIR/chucknorris-web/build.gradle" clean docker -# docker-compose --file "$MODULE_DIR/docker-compose.yml" up \ -# --exit-code-from "integration-test" \ -# --quiet-pull \ -# --remove-orphans - -docker-compose --file "$MODULE_DIR/docker-compose.yml" up \ - --quiet-pull \ - --remove-orphans \ No newline at end of file + docker-compose --file "$MODULE_DIR/docker-compose.yml" up \ + --exit-code-from "integration-test" \ + --quiet-pull \ + --remove-orphans \ No newline at end of file diff --git a/chucknorris-integration-test/src/test/java/io/chucknorris/integration_test/AbstractEndpointTest.java b/chucknorris-integration-test/src/test/java/io/chucknorris/integration_test/AbstractEndpointTest.java new file mode 100644 index 0000000..2c85f34 --- /dev/null +++ b/chucknorris-integration-test/src/test/java/io/chucknorris/integration_test/AbstractEndpointTest.java @@ -0,0 +1,21 @@ +package io.chucknorris.integration_test; + +import io.restassured.RestAssured; +import org.junit.jupiter.api.BeforeAll; + +import java.util.Optional; + +public abstract class AbstractEndpointTest { + + @BeforeAll + public static void beforeAll() { + RestAssured.baseURI = Optional + .ofNullable(System.getenv("TEST_SUBJECT_BASE_URI")) + .orElse("http://localhost"); + + RestAssured.port = Optional + .ofNullable(System.getenv("TEST_SUBJECT_PORT")) + .map(Integer::parseInt) + .orElse(8080); + } +} diff --git a/chucknorris-integration-test/src/test/java/io/chucknorris/integration_test/health/HealthEndpointTest.java b/chucknorris-integration-test/src/test/java/io/chucknorris/integration_test/health/HealthEndpointTest.java new file mode 100644 index 0000000..ddc4e96 --- /dev/null +++ b/chucknorris-integration-test/src/test/java/io/chucknorris/integration_test/health/HealthEndpointTest.java @@ -0,0 +1,30 @@ +package io.chucknorris.integration_test.health; + +import io.chucknorris.integration_test.AbstractEndpointTest; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; + +class HealthEndpointTest extends AbstractEndpointTest { + + @DisplayName("Should return joke") + @Test + void shouldReturnJoke() { + var specification = given() + .log().all() + .accept("application/json"); + + var response = specification.when().get("/health"); + + response.then() + .log().all() + .statusCode(200) + .assertThat() + .header("Content-Type", Matchers.equalTo("application/json")) + .body("status", Matchers.is("UP")) + .body("start_time", Matchers.isA(String.class)) + .body("uptime", Matchers.isA(String.class)); + } +} diff --git a/chucknorris-integration-test/src/test/java/io/chucknorris/integration_test/joke/JokeEndpointTest.java b/chucknorris-integration-test/src/test/java/io/chucknorris/integration_test/joke/JokeEndpointTest.java new file mode 100644 index 0000000..d8f738e --- /dev/null +++ b/chucknorris-integration-test/src/test/java/io/chucknorris/integration_test/joke/JokeEndpointTest.java @@ -0,0 +1,54 @@ +package io.chucknorris.integration_test.joke; + +import static io.restassured.RestAssured.given; + +import io.chucknorris.integration_test.AbstractEndpointTest; +import java.util.List; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class JokeEndpointTest extends AbstractEndpointTest { + + @DisplayName("Should return joke") + @Test + void shouldReturnJoke() { + var specification = given() + .log().all() + .accept("application/json"); + + var response = specification.when().get("/jokes/random"); + + response.then() + .log().all() + .statusCode(200) + .assertThat() + .header("Content-Type", Matchers.equalTo("application/json")) + .body("categories", Matchers.isA(List.class)) + .body("created_at", Matchers.isA(String.class)) + .body("icon_url", Matchers.isA(String.class)) + .body("id", Matchers.isA(String.class)) + .body("updated_at", Matchers.isA(String.class)) + .body("url", Matchers.isA(String.class)) + .body("value", Matchers.isA(String.class)); + } + + @DisplayName("Should include CORS headers") + @Test + void shouldIncludeCORSHeaders() { + var specification = given() + .log().all() + .accept("application/json") + .header("Origin", "http://localhost:3000"); + + var response = specification.when().get("/jokes/random"); + + response.then() + .log().all() + .statusCode(200) + .assertThat() + .header("Access-Control-Allow-Origin", Matchers.equalTo("*")) + .header("Access-Control-Expose-Headers", Matchers.equalTo("Access-Control-Allow-Origin Access-Control-Allow-Credentials")) + .header("Content-Type", Matchers.equalTo("application/json")); + } +} diff --git a/chucknorris-web/build.gradle b/chucknorris-web/build.gradle index c847cc2..a5ec490 100644 --- a/chucknorris-web/build.gradle +++ b/chucknorris-web/build.gradle @@ -3,15 +3,8 @@ plugins { id 'org.springframework.boot' } -repositories { - mavenCentral() -} - -// versions -def lombokVersion = "1.18.30" - dependencies { - annotationProcessor "org.projectlombok:lombok:${lombokVersion}" + annotationProcessor "org.projectlombok:lombok:${Version.LOMBOK}" implementation "com.amazonaws:aws-java-sdk:1.11.561" implementation "com.fasterxml.jackson.core:jackson-core:2.17.1" @@ -20,7 +13,7 @@ dependencies { implementation "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:2.3.0" implementation "org.hibernate:hibernate-validator:6.0.16.Final" implementation "org.postgresql:postgresql:42.2.9" - implementation "org.projectlombok:lombok:${lombokVersion}" + implementation "org.projectlombok:lombok:${Version.LOMBOK}" implementation "org.springframework.boot:spring-boot-starter-data-jpa" implementation "org.springframework.boot:spring-boot-starter-thymeleaf" implementation "org.springframework.boot:spring-boot-starter-web" @@ -35,7 +28,6 @@ tasks { manifest.attributes("Multi-Release": "true") archiveBaseName.set(project.name) - archiveVersion.set(project.version) if (project.hasProperty("archiveName")) { archiveFileName.set(project.properties["archiveName"] as String) @@ -45,25 +37,12 @@ tasks { docker { dependsOn bootJar - def imageName = "${project.properties.group}/${project.name}" - name = "${imageName}:latest" + name = "${project.properties.group}/${project.name}" - tag("current", "${imageName}:${project.version}") - tag("latest", "${imageName}:latest") tag("herokuProduction", "registry.heroku.com/chucky/web") dockerfile file("${projectDir}/src/main/docker/Dockerfile") files tasks.bootJar.outputs - buildArgs([JAR_FILE: bootJar.getArchiveFileName().get()]) - } - - springBoot { - buildInfo { - properties { - artifact = "${project.name}-${project.version}.jar" - version = project.version - name = project.name - } - } + buildArgs([JAR_FILE: bootJar.getArchiveFileName().get()] as Map) } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/Application.java b/chucknorris-web/src/main/java/io/chucknorris/api/Application.java index 5b6e859..5d25d61 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/Application.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/Application.java @@ -5,12 +5,12 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -@ComponentScan(basePackages = {"io.chucknorris"}) +@ComponentScan(basePackages = { "io.chucknorris" }) @EnableJpaAuditing @SpringBootApplication public class Application { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/ApplicationExceptionHandler.java b/chucknorris-web/src/main/java/io/chucknorris/api/ApplicationExceptionHandler.java index 2419ec5..341ca97 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/ApplicationExceptionHandler.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/ApplicationExceptionHandler.java @@ -16,38 +16,38 @@ @ControllerAdvice public class ApplicationExceptionHandler extends ResponseEntityExceptionHandler { - @ExceptionHandler(value = {ConstraintViolationException.class}) - protected ResponseEntity handleConstraintViolationException( - ConstraintViolationException exception, ServletWebRequest request) { - switch (request.getHeader(HttpHeaders.ACCEPT)) { - case MediaType.TEXT_PLAIN_VALUE: - StringBuilder stringBuilder = new StringBuilder(); - for (ConstraintViolation violation : exception.getConstraintViolations()) { - stringBuilder.append( - violation.getPropertyPath().toString() + ": " + violation.getMessage() + '\n'); - } + @ExceptionHandler(value = { ConstraintViolationException.class }) + protected ResponseEntity handleConstraintViolationException( + ConstraintViolationException exception, ServletWebRequest request) { + switch (request.getHeader(HttpHeaders.ACCEPT)) { + case MediaType.TEXT_PLAIN_VALUE: + StringBuilder stringBuilder = new StringBuilder(); + for (ConstraintViolation violation : exception.getConstraintViolations()) { + stringBuilder.append( + violation.getPropertyPath().toString() + ": " + violation.getMessage() + '\n'); + } - return handleExceptionInternal( - exception, - stringBuilder.toString(), - new HttpHeaders(), - HttpStatus.BAD_REQUEST, - request); - default: - LinkedHashMap constraintViolations = new LinkedHashMap<>(); - for (ConstraintViolation violation : exception.getConstraintViolations()) { - constraintViolations.put(violation.getPropertyPath().toString(), violation.getMessage()); - } + return handleExceptionInternal( + exception, + stringBuilder.toString(), + new HttpHeaders(), + HttpStatus.BAD_REQUEST, + request); + default: + LinkedHashMap constraintViolations = new LinkedHashMap<>(); + for (ConstraintViolation violation : exception.getConstraintViolations()) { + constraintViolations.put(violation.getPropertyPath().toString(), violation.getMessage()); + } - LinkedHashMap body = new LinkedHashMap<>(); - body.put("timestamp", new Date()); - body.put("status", HttpStatus.BAD_REQUEST.value()); - body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase()); - body.put("message", exception.getMessage()); - body.put("violations", constraintViolations); + LinkedHashMap body = new LinkedHashMap<>(); + body.put("timestamp", new Date()); + body.put("status", HttpStatus.BAD_REQUEST.value()); + body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase()); + body.put("message", exception.getMessage()); + body.put("violations", constraintViolations); - return handleExceptionInternal( - exception, body, new HttpHeaders(), HttpStatus.BAD_REQUEST, request); + return handleExceptionInternal( + exception, body, new HttpHeaders(), HttpStatus.BAD_REQUEST, request); + } } - } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/AmazonWebServicesConfig.java b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/AmazonWebServicesConfig.java index 54e495f..edfafab 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/AmazonWebServicesConfig.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/AmazonWebServicesConfig.java @@ -13,29 +13,29 @@ @Configuration public class AmazonWebServicesConfig { - @Value("${aws.access_key_id}") - private String accessKeyId; + @Value("${aws.access_key_id}") + private String accessKeyId; - @Value("${aws.access_key_secret}") - private String accessKeySecret; + @Value("${aws.access_key_secret}") + private String accessKeySecret; - @Value("${aws.region}") - private String region; + @Value("${aws.region}") + private String region; - /** Returns a new {@link AmazonS3} instance. */ - public @Bean AmazonS3 amazonS3() { - AWSCredentials credentials = new BasicAWSCredentials(accessKeyId, accessKeySecret); + /** Returns a new {@link AmazonS3} instance. */ + public @Bean AmazonS3 amazonS3() { + AWSCredentials credentials = new BasicAWSCredentials(accessKeyId, accessKeySecret); - return AmazonS3ClientBuilder.standard() - .withCredentials(new AWSStaticCredentialsProvider(credentials)) - .withRegion(region) - .build(); - } + return AmazonS3ClientBuilder.standard() + .withCredentials(new AWSStaticCredentialsProvider(credentials)) + .withRegion(region) + .build(); + } - /** Returns a new {@link AmazonSNSClient} instance. */ - public @Bean AmazonSNSClient snsClient() { - AWSCredentials credentials = new BasicAWSCredentials(accessKeyId, accessKeySecret); + /** Returns a new {@link AmazonSNSClient} instance. */ + public @Bean AmazonSNSClient snsClient() { + AWSCredentials credentials = new BasicAWSCredentials(accessKeyId, accessKeySecret); - return new AmazonSNSClient(credentials); - } + return new AmazonSNSClient(credentials); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DataSourceConfiguration.java b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DataSourceConfiguration.java index f91d676..b789379 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DataSourceConfiguration.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DataSourceConfiguration.java @@ -15,22 +15,21 @@ @Slf4j public class DataSourceConfiguration { - @Bean - public DataSource dataSource(DataSourceProperties dataSourceProperties) { - log.info( - "Loading data source properties from {}", dataSourceProperties.getClass().getSimpleName()); + @Bean + public DataSource dataSource(DataSourceProperties dataSourceProperties) { + log.info( + "Loading data source properties from {}", dataSourceProperties.getClass().getSimpleName()); - DataSource datasource = - DataSourceBuilder.create() - .driverClassName(dataSourceProperties.getDriverClassName()) - .password(dataSourceProperties.getPassword()) - .type(HikariDataSource.class) - .url(dataSourceProperties.getUrl()) - .username(dataSourceProperties.getUsername()) - .build(); + DataSource datasource = DataSourceBuilder.create() + .driverClassName(dataSourceProperties.getDriverClassName()) + .password(dataSourceProperties.getPassword()) + .type(HikariDataSource.class) + .url(dataSourceProperties.getUrl()) + .username(dataSourceProperties.getUsername()) + .build(); - log.info(String.format("DataSource({url=%s})", dataSourceProperties.getUrl())); + log.info(String.format("DataSource({url=%s})", dataSourceProperties.getUrl())); - return datasource; - } + return datasource; + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DataSourceProperties.java b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DataSourceProperties.java index 5cd59dd..e239a6b 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DataSourceProperties.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DataSourceProperties.java @@ -5,11 +5,11 @@ @Configuration public abstract class DataSourceProperties { - abstract String getDriverClassName(); + abstract String getDriverClassName(); - abstract String getPassword(); + abstract String getPassword(); - abstract String getUrl(); + abstract String getUrl(); - abstract String getUsername(); + abstract String getUsername(); } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DefaultDataSourceProperties.java b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DefaultDataSourceProperties.java index 06b6138..078703b 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DefaultDataSourceProperties.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/DefaultDataSourceProperties.java @@ -12,19 +12,19 @@ @Getter public class DefaultDataSourceProperties extends DataSourceProperties { - private String driverClassName; - private String password; - private String url; - private String username; + private String driverClassName; + private String password; + private String url; + private String username; - public DefaultDataSourceProperties( - @Value("${spring.datasource.driver-class-name}") String driverClassName, - @Value("${spring.datasource.password}") String password, - @Value("${spring.datasource.url}") String url, - @Value("${spring.datasource.username}") String username) { - this.driverClassName = driverClassName; - this.password = password; - this.url = url; - this.username = username; - } + public DefaultDataSourceProperties( + @Value("${spring.datasource.driver-class-name}") String driverClassName, + @Value("${spring.datasource.password}") String password, + @Value("${spring.datasource.url}") String url, + @Value("${spring.datasource.username}") String username) { + this.driverClassName = driverClassName; + this.password = password; + this.url = url; + this.username = username; + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/HerokuDataSourceProperties.java b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/HerokuDataSourceProperties.java index 4fbabfb..f6ac4c8 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/HerokuDataSourceProperties.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/HerokuDataSourceProperties.java @@ -13,37 +13,36 @@ @Getter public class HerokuDataSourceProperties extends DataSourceProperties { - private static final String SCHEMA_POSTGRESQL = "postgresql"; - - private String driverClassName; - private String password; - private String url; - private String username; - - public HerokuDataSourceProperties( - @Value("${spring.datasource.driver-class-name}") String driverClassName, - @Value("${spring.datasource.uri}") String uniformResourceIdentifier) { - URI uri = URI.create(uniformResourceIdentifier); - - String[] userInfo = uri.getUserInfo().split(":"); - - this.driverClassName = driverClassName; - this.password = userInfo[1]; - this.url = - String.format( - "jdbc:%s://%s:%s/%s", - this.scheme(uri), - uri.getHost().replace("/", ""), - uri.getPort(), - uri.getPath().replace("/", "")); - this.username = userInfo[0]; - } - - private String scheme(URI uri) { - if ("postgres".compareToIgnoreCase(uri.getScheme()) == 0) { - return SCHEMA_POSTGRESQL; + private static final String SCHEMA_POSTGRESQL = "postgresql"; + + private String driverClassName; + private String password; + private String url; + private String username; + + public HerokuDataSourceProperties( + @Value("${spring.datasource.driver-class-name}") String driverClassName, + @Value("${spring.datasource.uri}") String uniformResourceIdentifier) { + URI uri = URI.create(uniformResourceIdentifier); + + String[] userInfo = uri.getUserInfo().split(":"); + + this.driverClassName = driverClassName; + this.password = userInfo[1]; + this.url = String.format( + "jdbc:%s://%s:%s/%s", + this.scheme(uri), + uri.getHost().replace("/", ""), + uri.getPort(), + uri.getPath().replace("/", "")); + this.username = userInfo[0]; } - throw new RuntimeException(String.format("Unsupported schema %s given", uri.getScheme())); - } + private String scheme(URI uri) { + if ("postgres".compareToIgnoreCase(uri.getScheme()) == 0) { + return SCHEMA_POSTGRESQL; + } + + throw new RuntimeException(String.format("Unsupported schema %s given", uri.getScheme())); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/LayoutConfig.java b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/LayoutConfig.java index 028b7ee..a622cf7 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/LayoutConfig.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/LayoutConfig.java @@ -7,8 +7,8 @@ @Configuration public class LayoutConfig { - @Bean - public LayoutDialect layoutDialect() { - return new LayoutDialect(); - } + @Bean + public LayoutDialect layoutDialect() { + return new LayoutDialect(); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/MailchimpConfig.java b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/MailchimpConfig.java index b52e285..6a637ac 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/MailchimpConfig.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/MailchimpConfig.java @@ -8,14 +8,14 @@ @Configuration public class MailchimpConfig { - @Value("${mailchimp.api_key}") - private String apiKey; + @Value("${mailchimp.api_key}") + private String apiKey; - /** Returns a new {@link MailchimpService} instance. */ - public @Bean MailchimpService mailchimpService() { - String dataCenter = apiKey.substring(apiKey.length() - 4); - String baseUrl = "https://" + dataCenter + ".api.mailchimp.com"; + /** Returns a new {@link MailchimpService} instance. */ + public @Bean MailchimpService mailchimpService() { + String dataCenter = apiKey.substring(apiKey.length() - 4); + String baseUrl = "https://" + dataCenter + ".api.mailchimp.com"; - return new MailchimpService(apiKey, baseUrl); - } + return new MailchimpService(apiKey, baseUrl); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/ResolverConfig.java b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/ResolverConfig.java index ebb25e1..d12f395 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/ResolverConfig.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/ResolverConfig.java @@ -9,7 +9,7 @@ @Configuration public class ResolverConfig implements WebMvcConfigurer { - public void addArgumentResolvers(List argumentResolvers) { - argumentResolvers.add(new RequestArgumentResolver()); - } + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(new RequestArgumentResolver()); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/RestTemplateConfig.java b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/RestTemplateConfig.java index 3721d5f..1c040fb 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/RestTemplateConfig.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/RestTemplateConfig.java @@ -7,7 +7,7 @@ @Configuration public class RestTemplateConfig { - public @Bean RestTemplate restTemplate() { - return new RestTemplate(); - } + public @Bean RestTemplate restTemplate() { + return new RestTemplate(); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/WebConfig.java b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/WebConfig.java index 034d37c..d3d7135 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/configuration/WebConfig.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/configuration/WebConfig.java @@ -8,18 +8,18 @@ @Configuration public class WebConfig { - @Bean - public WebMvcConfigurer corsConfigurer() { - return new WebMvcConfigurer() { - @Override - public void addCorsMappings(CorsRegistry registry) { - registry - .addMapping("/**") - .allowedHeaders("*") - .allowedMethods("*") - .allowedOrigins("*") - .exposedHeaders("Access-Control-Allow-Origin Access-Control-Allow-Credentials"); - } - }; - } + @Bean + public WebMvcConfigurer corsConfigurer() { + return new WebMvcConfigurer() { + @Override + public void addCorsMappings(CorsRegistry registry) { + registry + .addMapping("/**") + .allowedHeaders("*") + .allowedMethods("*") + .allowedOrigins("*") + .exposedHeaders("Access-Control-Allow-Origin Access-Control-Allow-Credentials"); + } + }; + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/feed/FeedController.java b/chucknorris-web/src/main/java/io/chucknorris/api/feed/FeedController.java index 0282387..f971a51 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/feed/FeedController.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/feed/FeedController.java @@ -21,98 +21,87 @@ @RestController public class FeedController { - private DailyChuckService dailyChuckService; - private DateUtil dateUtil; - private EventService eventService; - private MailchimpService mailchimpService; - - @Value("${mailchimp.dailychuck.list_id}") - private String dailyChuckListId; - - /** Returns a new FeedController {@link FeedController} instance. */ - public FeedController( - DailyChuckService dailyChuckService, - DateUtil dateUtil, - EventService eventService, - MailchimpService mailchimpService) { - this.dailyChuckService = dailyChuckService; - this.dateUtil = dateUtil; - this.eventService = eventService; - this.mailchimpService = mailchimpService; - } - - /** - * Returns a new DailyChuck {@link DailyChuck} instance. - * - * @return dailyChuck - * @throws IOException Thrown if {@link DailyChuck} can't ber persisted. - */ - public @RequestMapping( - value = {"/feed/daily-chuck.json", "/feed/daily-chuck"}, - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) DailyChuck dailyChuckJson() throws IOException { - DailyChuck dailyChuck = dailyChuckService.getDailyChuck(); - - Date now = dateUtil.now(); - if (dailyChuck.findIssueByDate(now) instanceof DailyChuckIssue) { - return dailyChuck; + private DailyChuckService dailyChuckService; + private DateUtil dateUtil; + private EventService eventService; + private MailchimpService mailchimpService; + + @Value("${mailchimp.dailychuck.list_id}") + private String dailyChuckListId; + + /** Returns a new FeedController {@link FeedController} instance. */ + public FeedController( + DailyChuckService dailyChuckService, + DateUtil dateUtil, + EventService eventService, + MailchimpService mailchimpService) { + this.dailyChuckService = dailyChuckService; + this.dateUtil = dateUtil; + this.eventService = eventService; + this.mailchimpService = mailchimpService; } - DailyChuckIssue dailyChuckIssue = - dailyChuckService.composeDailyChuckIssue(dailyChuck.getIssues()); - dailyChuck.addIssue(dailyChuckIssue); - - dailyChuckService.persist(dailyChuck); - - eventService.publishEvent(new DailyChuckPublishedEvent(dailyChuckIssue)); - - return dailyChuck; - } - - /** - * Returns Stats about the DailyChuck. - * - * @return - */ - public @RequestMapping( - value = "/feed/daily-chuck/stats", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) MailingListStatistic dailyChuckStats() { - MailingListStatistic mailingListStatistic = mailchimpService.fetchListStats(dailyChuckListId); - - return mailingListStatistic; - } - - /** - * Returns the current DailyChuck in RSS format. - * - * @return dailyChuck - * @throws IOException Thrown if {@link DailyChuck} can't ber persisted. - */ - public @RequestMapping( - value = {"/feed/daily-chuck.xml", "/feed/daily-chuck"}, - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_XML_VALUE, - produces = MediaType.APPLICATION_RSS_XML_VALUE) View dailyChuckRss() throws IOException { - DailyChuck dailyChuck = dailyChuckService.getDailyChuck(); - - MailingListStatistic mailingListStatistic = mailchimpService.fetchListStats(dailyChuckListId); - - Date now = dateUtil.now(); - if (dailyChuck.findIssueByDate(now) instanceof DailyChuckIssue) { - return dailyChuckService.toRss(dailyChuck); + /** + * Returns a new DailyChuck {@link DailyChuck} instance. + * + * @return dailyChuck + * @throws IOException Thrown if {@link DailyChuck} can't ber persisted. + */ + public @RequestMapping(value = { "/feed/daily-chuck.json", "/feed/daily-chuck" }, method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + + MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) DailyChuck dailyChuckJson() throws IOException { + DailyChuck dailyChuck = dailyChuckService.getDailyChuck(); + + Date now = dateUtil.now(); + if (dailyChuck.findIssueByDate(now) instanceof DailyChuckIssue) { + return dailyChuck; + } + + DailyChuckIssue dailyChuckIssue = dailyChuckService.composeDailyChuckIssue(dailyChuck.getIssues()); + dailyChuck.addIssue(dailyChuckIssue); + + dailyChuckService.persist(dailyChuck); + + eventService.publishEvent(new DailyChuckPublishedEvent(dailyChuckIssue)); + + return dailyChuck; + } + + /** + * Returns Stats about the DailyChuck. + * + * @return + */ + public @RequestMapping(value = "/feed/daily-chuck/stats", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + + MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) MailingListStatistic dailyChuckStats() { + MailingListStatistic mailingListStatistic = mailchimpService.fetchListStats(dailyChuckListId); + + return mailingListStatistic; } - DailyChuckIssue dailyChuckIssue = - dailyChuckService.composeDailyChuckIssue(dailyChuck.getIssues()); - dailyChuck.addIssue(dailyChuckIssue); + /** + * Returns the current DailyChuck in RSS format. + * + * @return dailyChuck + * @throws IOException Thrown if {@link DailyChuck} can't ber persisted. + */ + public @RequestMapping(value = { "/feed/daily-chuck.xml", "/feed/daily-chuck" }, method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + + MediaType.TEXT_XML_VALUE, produces = MediaType.APPLICATION_RSS_XML_VALUE) View dailyChuckRss() throws IOException { + DailyChuck dailyChuck = dailyChuckService.getDailyChuck(); + + MailingListStatistic mailingListStatistic = mailchimpService.fetchListStats(dailyChuckListId); - dailyChuckService.persist(dailyChuck); + Date now = dateUtil.now(); + if (dailyChuck.findIssueByDate(now) instanceof DailyChuckIssue) { + return dailyChuckService.toRss(dailyChuck); + } - eventService.publishEvent(new DailyChuckPublishedEvent(dailyChuckIssue)); + DailyChuckIssue dailyChuckIssue = dailyChuckService.composeDailyChuckIssue(dailyChuck.getIssues()); + dailyChuck.addIssue(dailyChuckIssue); - return dailyChuckService.toRss(dailyChuck); - } + dailyChuckService.persist(dailyChuck); + + eventService.publishEvent(new DailyChuckPublishedEvent(dailyChuckIssue)); + + return dailyChuckService.toRss(dailyChuck); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuck.java b/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuck.java index 76ba12e..dd24f90 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuck.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuck.java @@ -7,53 +7,52 @@ @Data public class DailyChuck { - private Long issueNumber; - private DailyChuckIssue[] issues; - - /** - * Adds a DailyChuckIssue {@link DailyChuckIssue} to the DailyChuck instance and increases the - * issue number {@link DailyChuck#issueNumber} by one. - */ - public void addIssue(DailyChuckIssue dailyChuckIssue) { - DailyChuckIssue[] dailyChuckIssues = new DailyChuckIssue[issues.length + 1]; - - for (int i = 0; i < issues.length; i++) { - dailyChuckIssues[i] = issues[i]; - } + private Long issueNumber; + private DailyChuckIssue[] issues; + + /** + * Adds a DailyChuckIssue {@link DailyChuckIssue} to the DailyChuck instance and increases the + * issue number {@link DailyChuck#issueNumber} by one. + */ + public void addIssue(DailyChuckIssue dailyChuckIssue) { + DailyChuckIssue[] dailyChuckIssues = new DailyChuckIssue[issues.length + 1]; - dailyChuckIssues[issues.length] = dailyChuckIssue; + for (int i = 0; i < issues.length; i++) { + dailyChuckIssues[i] = issues[i]; + } - issues = dailyChuckIssues; - issueNumber += 1; - } + dailyChuckIssues[issues.length] = dailyChuckIssue; + + issues = dailyChuckIssues; + issueNumber += 1; + } - /** Finds an issue {@link DailyChuckIssue} by joke id. */ - public DailyChuckIssue findIssueByJokeId(String jokeId) { - for (DailyChuckIssue issue : issues) { - if (issue.getJokeId().equals(jokeId)) { - return issue; - } + /** Finds an issue {@link DailyChuckIssue} by joke id. */ + public DailyChuckIssue findIssueByJokeId(String jokeId) { + for (DailyChuckIssue issue : issues) { + if (issue.getJokeId().equals(jokeId)) { + return issue; + } + } + return null; } - return null; - } - /** Finds an issue {@link DailyChuckIssue} by a given date. */ - public DailyChuckIssue findIssueByDate(Date date) { - Calendar cal1 = Calendar.getInstance(); - cal1.setTime(date); + /** Finds an issue {@link DailyChuckIssue} by a given date. */ + public DailyChuckIssue findIssueByDate(Date date) { + Calendar cal1 = Calendar.getInstance(); + cal1.setTime(date); - for (DailyChuckIssue issue : issues) { - Calendar cal2 = Calendar.getInstance(); - cal2.setTime(issue.getDate()); + for (DailyChuckIssue issue : issues) { + Calendar cal2 = Calendar.getInstance(); + cal2.setTime(issue.getDate()); - boolean isSameDay = - cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR) - && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR); + boolean isSameDay = cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR) + && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR); - if (isSameDay) { - return issue; - } + if (isSameDay) { + return issue; + } + } + return null; } - return null; - } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckIssue.java b/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckIssue.java index 1d15a11..c0d3ca3 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckIssue.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckIssue.java @@ -6,6 +6,6 @@ @Data public class DailyChuckIssue { - private Date date; - private String jokeId; + private Date date; + private String jokeId; } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckPublishedEvent.java b/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckPublishedEvent.java index 13ac38c..0142b3a 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckPublishedEvent.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckPublishedEvent.java @@ -4,7 +4,7 @@ public class DailyChuckPublishedEvent extends BaseEvent { - public DailyChuckPublishedEvent(DailyChuckIssue dailyChuckIssue) { - super("DailyChuckPublishedEvent", dailyChuckIssue); - } + public DailyChuckPublishedEvent(DailyChuckIssue dailyChuckIssue) { + super("DailyChuckPublishedEvent", dailyChuckIssue); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckRss.java b/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckRss.java index d408930..5e73bc9 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckRss.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckRss.java @@ -16,52 +16,50 @@ public class DailyChuckRss extends AbstractRssFeedView { - private String baseUrl; - private DailyChuck dailyChuck; - private JokeRepository jokeRepository; + private String baseUrl; + private DailyChuck dailyChuck; + private JokeRepository jokeRepository; - /** Instantiates a new DailyChuckRss {@link DailyChuckRss}. */ - public DailyChuckRss(String baseUrl, DailyChuck dailyChuck, JokeRepository jokeRepository) { - this.baseUrl = baseUrl; - this.dailyChuck = dailyChuck; - this.jokeRepository = jokeRepository; - } + /** Instantiates a new DailyChuckRss {@link DailyChuckRss}. */ + public DailyChuckRss(String baseUrl, DailyChuck dailyChuck, JokeRepository jokeRepository) { + this.baseUrl = baseUrl; + this.dailyChuck = dailyChuck; + this.jokeRepository = jokeRepository; + } - @Override - protected void buildFeedMetadata( - Map model, Channel feed, HttpServletRequest request) { - feed.setTitle("The Daily Chuck"); - feed.setDescription( - "Get your daily dose of the best #ChuckNorrisFacts " - + "every morning straight into your inbox."); - feed.setLink("https://" + baseUrl + "/feed/daily-chuck.xml"); - } + @Override + protected void buildFeedMetadata( + Map model, Channel feed, HttpServletRequest request) { + feed.setTitle("The Daily Chuck"); + feed.setDescription( + "Get your daily dose of the best #ChuckNorrisFacts " + + "every morning straight into your inbox."); + feed.setLink("https://" + baseUrl + "/feed/daily-chuck.xml"); + } - @Override - protected List buildFeedItems( - Map model, HttpServletRequest request, HttpServletResponse response) { - DailyChuckIssue[] dailyChuckIssues = dailyChuck.getIssues(); - Arrays.sort(dailyChuck.getIssues(), Comparator.comparing(DailyChuckIssue::getDate).reversed()); + @Override + protected List buildFeedItems( + Map model, HttpServletRequest request, HttpServletResponse response) { + DailyChuckIssue[] dailyChuckIssues = dailyChuck.getIssues(); + Arrays.sort(dailyChuck.getIssues(), Comparator.comparing(DailyChuckIssue::getDate).reversed()); - DailyChuckIssue currentIssue = dailyChuckIssues[0]; - Joke joke = - jokeRepository - .findById(currentIssue.getJokeId()) - .orElseThrow( - () -> - new EntityNotFoundException( - "Joke with id \"" + currentIssue.getJokeId() + "\" not found.")); + DailyChuckIssue currentIssue = dailyChuckIssues[0]; + Joke joke = jokeRepository + .findById(currentIssue.getJokeId()) + .orElseThrow( + () -> new EntityNotFoundException( + "Joke with id \"" + currentIssue.getJokeId() + "\" not found.")); - Long issueNumber = dailyChuck.getIssueNumber(); - Item entry = new Item(); - entry.setTitle(issueNumber.toString()); - entry.setLink("https://" + baseUrl + "/jokes/" + joke.getId()); - entry.setPubDate(currentIssue.getDate()); + Long issueNumber = dailyChuck.getIssueNumber(); + Item entry = new Item(); + entry.setTitle(issueNumber.toString()); + entry.setLink("https://" + baseUrl + "/jokes/" + joke.getId()); + entry.setPubDate(currentIssue.getDate()); - Content content = new Content(); - content.setValue(joke.getValue()); - entry.setContent(content); + Content content = new Content(); + content.setValue(joke.getValue()); + entry.setContent(content); - return Arrays.asList(entry); - } + return Arrays.asList(entry); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckService.java b/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckService.java index e0a067d..65147ee 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckService.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/feed/dailychuck/DailyChuckService.java @@ -20,97 +20,96 @@ @Service public class DailyChuckService { - private AmazonS3 amazonS3; - private JokeRepository jokeRepository; - - @Value("${dailychuck.bucket_name}") - private String bucketName; - - @Value("${application.base_url}") - private String baseUrl; - - @Value("${dailychuck.key_name}") - private String keyName; - - /** - * Instantiates a new Daily chuck service. - * - * @param amazonS3 the amazon s 3 - * @param jokeRepository the joke repository - */ - public DailyChuckService(AmazonS3 amazonS3, JokeRepository jokeRepository) { - this.amazonS3 = amazonS3; - this.jokeRepository = jokeRepository; - } - - /** - * Composes a daily chuck issue {@link DailyChuck}. - * - * @param excludedIssues Array of issues to be excluded - * @return dailyChuckIssue - */ - public DailyChuckIssue composeDailyChuckIssue(DailyChuckIssue[] excludedIssues) { - Joke joke = jokeRepository.getRandomJoke(); - - Boolean isIncluded = false; - for (DailyChuckIssue dailyChuckIssue : excludedIssues) { - if (dailyChuckIssue.getJokeId().equals(joke.getId())) { - isIncluded = true; - break; - } + private AmazonS3 amazonS3; + private JokeRepository jokeRepository; + + @Value("${dailychuck.bucket_name}") + private String bucketName; + + @Value("${application.base_url}") + private String baseUrl; + + @Value("${dailychuck.key_name}") + private String keyName; + + /** + * Instantiates a new Daily chuck service. + * + * @param amazonS3 the amazon s 3 + * @param jokeRepository the joke repository + */ + public DailyChuckService(AmazonS3 amazonS3, JokeRepository jokeRepository) { + this.amazonS3 = amazonS3; + this.jokeRepository = jokeRepository; } - if (!isIncluded) { - DailyChuckIssue dailyChuckIssue = new DailyChuckIssue(); - dailyChuckIssue.setDate(new Date()); - dailyChuckIssue.setJokeId(joke.getId()); + /** + * Composes a daily chuck issue {@link DailyChuck}. + * + * @param excludedIssues Array of issues to be excluded + * @return dailyChuckIssue + */ + public DailyChuckIssue composeDailyChuckIssue(DailyChuckIssue[] excludedIssues) { + Joke joke = jokeRepository.getRandomJoke(); + + Boolean isIncluded = false; + for (DailyChuckIssue dailyChuckIssue : excludedIssues) { + if (dailyChuckIssue.getJokeId().equals(joke.getId())) { + isIncluded = true; + break; + } + } + + if (!isIncluded) { + DailyChuckIssue dailyChuckIssue = new DailyChuckIssue(); + dailyChuckIssue.setDate(new Date()); + dailyChuckIssue.setJokeId(joke.getId()); + + return dailyChuckIssue; + } else { + return composeDailyChuckIssue(excludedIssues); + } + } + + /** + * Gets the current daily chuck issue {@link DailyChuck}. + * + * @return dailyChuck + * @throws IOException Thrown by {@link ObjectMapper#readValue} + */ + public DailyChuck getDailyChuck() throws IOException { + GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, keyName); + S3Object object = amazonS3.getObject(getObjectRequest); + + ObjectMapper mapper = new ObjectMapper(); + DailyChuck dailyChuck = mapper.readValue(object.getObjectContent(), DailyChuck.class); + + return dailyChuck; + } + + /** + * Persists daily chuck {@link DailyChuck} and returns the S3 result {@link PutObjectResult}. + * + * @return putObjectResult + * @throws IOException Thrown by {@link ObjectMapper#writeValueAsString} + */ + public PutObjectResult persist(DailyChuck dailyChuck) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String fileContentString = mapper.writeValueAsString(dailyChuck); + byte[] fileContentBytes = fileContentString.getBytes(StandardCharsets.UTF_8); + + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentType(MediaType.APPLICATION_JSON_VALUE); + metadata.setContentLength(fileContentBytes.length); + + PutObjectRequest request = new PutObjectRequest( + bucketName, keyName, new ByteArrayInputStream(fileContentBytes), metadata); + + return amazonS3.putObject(request); + } - return dailyChuckIssue; - } else { - return composeDailyChuckIssue(excludedIssues); + public DailyChuckRss toRss(DailyChuck dailyChuck) { + return new DailyChuckRss(baseUrl, dailyChuck, jokeRepository); } - } - - /** - * Gets the current daily chuck issue {@link DailyChuck}. - * - * @return dailyChuck - * @throws IOException Thrown by {@link ObjectMapper#readValue} - */ - public DailyChuck getDailyChuck() throws IOException { - GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, keyName); - S3Object object = amazonS3.getObject(getObjectRequest); - - ObjectMapper mapper = new ObjectMapper(); - DailyChuck dailyChuck = mapper.readValue(object.getObjectContent(), DailyChuck.class); - - return dailyChuck; - } - - /** - * Persists daily chuck {@link DailyChuck} and returns the S3 result {@link PutObjectResult}. - * - * @return putObjectResult - * @throws IOException Thrown by {@link ObjectMapper#writeValueAsString} - */ - public PutObjectResult persist(DailyChuck dailyChuck) throws IOException { - ObjectMapper mapper = new ObjectMapper(); - - String fileContentString = mapper.writeValueAsString(dailyChuck); - byte[] fileContentBytes = fileContentString.getBytes(StandardCharsets.UTF_8); - - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentType(MediaType.APPLICATION_JSON_VALUE); - metadata.setContentLength(fileContentBytes.length); - - PutObjectRequest request = - new PutObjectRequest( - bucketName, keyName, new ByteArrayInputStream(fileContentBytes), metadata); - - return amazonS3.putObject(request); - } - - public DailyChuckRss toRss(DailyChuck dailyChuck) { - return new DailyChuckRss(baseUrl, dailyChuck, jokeRepository); - } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/health/HealthController.java b/chucknorris-web/src/main/java/io/chucknorris/api/health/HealthController.java new file mode 100644 index 0000000..2a48d0a --- /dev/null +++ b/chucknorris-web/src/main/java/io/chucknorris/api/health/HealthController.java @@ -0,0 +1,23 @@ +package io.chucknorris.api.health; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.lang.management.ManagementFactory; +import java.util.Map; +import java.util.Optional; + +@RestController +public class HealthController { + + @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE, value = "/health") + public Map show() { + var runtime = ManagementFactory.getRuntimeMXBean(); + + return Map.of( + "status", "UP", + "start_time", Optional.of(runtime.getStartTime()).map(String::valueOf).orElse("undefined"), + "uptime", Optional.of(runtime.getUptime()).map(String::valueOf).orElse("undefined")); + } +} diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/home/HomeController.java b/chucknorris-web/src/main/java/io/chucknorris/api/home/HomeController.java index 00cfdb0..5d1ff8b 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/home/HomeController.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/home/HomeController.java @@ -12,25 +12,21 @@ @Controller public class HomeController { - private JokeRepository jokeRepository; - private SlackService slackService; + private JokeRepository jokeRepository; + private SlackService slackService; - /** Instantiates a new HomeController {@link HomeController}. */ - public HomeController(JokeRepository jokeRepository, SlackService slackService) { - this.jokeRepository = jokeRepository; - this.slackService = slackService; - } + /** Instantiates a new HomeController {@link HomeController}. */ + public HomeController(JokeRepository jokeRepository, SlackService slackService) { + this.jokeRepository = jokeRepository; + this.slackService = slackService; + } - /** Returns the model for the home view. */ - public @RequestMapping( - value = "/", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_HTML_VALUE, - produces = MediaType.TEXT_HTML_VALUE) ModelAndView view() { - ModelAndView modelAndView = new ModelAndView("home"); - modelAndView.addObject("joke", jokeRepository.getRandomJoke()); - modelAndView.addObject("slack_authorize_url", slackService.composeAuthorizeUri()); + /** Returns the model for the home view. */ + public @RequestMapping(value = "/", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_HTML_VALUE, produces = MediaType.TEXT_HTML_VALUE) ModelAndView view() { + ModelAndView modelAndView = new ModelAndView("home"); + modelAndView.addObject("joke", jokeRepository.getRandomJoke()); + modelAndView.addObject("slack_authorize_url", slackService.composeAuthorizeUri()); - return modelAndView; - } + return modelAndView; + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/joke/Joke.java b/chucknorris-web/src/main/java/io/chucknorris/api/joke/Joke.java index 4e7fe8f..e3dc5d9 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/joke/Joke.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/joke/Joke.java @@ -23,28 +23,29 @@ @JsonSerialize(using = JokeSerializer.class) @NoArgsConstructor @Table(name = "joke") -@TypeDefs({@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)}) +@TypeDefs({ @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) }) public class Joke implements Serializable { - @Column(name = "categories", columnDefinition = "jsonb") - @Type(type = "jsonb") - private String[] categories; + @Column(name = "categories", columnDefinition = "jsonb") + @Type(type = "jsonb") + private String[] categories; - @Column(name = "created_at") - private String createdAt; + @Column(name = "created_at") + private String createdAt; - @Transient - private final String iconUrl = "https://assets.chucknorris.host/img/avatar/chuck-norris.png"; + @Transient + private final String iconUrl = "https://api.chucknorris.io/img/avatar/chuck-norris.png"; - @Id - @Column(name = "joke_id", updatable = false, nullable = false) - private String id; + @Id + @Column(name = "joke_id", updatable = false, nullable = false) + private String id; - @Column(name = "updated_at") - private String updatedAt; + @Column(name = "updated_at") + private String updatedAt; - @Transient private String url; + @Transient + private String url; - @Column(name = "value") - private String value; + @Column(name = "value") + private String value; } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeController.java b/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeController.java index b741586..e04845a 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeController.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeController.java @@ -22,228 +22,199 @@ @Validated public class JokeController { - private JokeRepository jokeRepository; - - /** Returns a new JokeController {@link JokeController} instance. */ - public JokeController(JokeRepository jokeRepository) { - this.jokeRepository = jokeRepository; - } - - @RequestMapping( - value = "/categories", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - public @ResponseBody String[] getCategories() { - return jokeRepository.findAllCategories(); - } - - /** Returns all joke categories delimited by a new line. */ - public @ResponseBody @RequestMapping( - value = "/categories", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_PLAIN_VALUE, - produces = MediaType.TEXT_PLAIN_VALUE) String getCategoryValues() { - StringBuilder stringBuilder = new StringBuilder(); - - for (String category : jokeRepository.findAllCategories()) { - stringBuilder.append(category + '\n'); - } + private JokeRepository jokeRepository; - return stringBuilder.toString(); - } - - /** - * Returns a Joke {@link Joke} by id. - * - * @param id The joke id - * @return joke - */ - public @ResponseBody @RequestMapping( - value = "/{id}", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) Joke getJoke(@PathVariable String id) { - return jokeRepository - .findById(id) - .orElseThrow(() -> new EntityNotFoundException("Joke with id \"" + id + "\" not found.")); - } - - /** - * Returns a joke value by id. - * - * @param id The joke id - * @return string - */ - public @ResponseBody @RequestMapping( - value = "/{id}", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_PLAIN_VALUE, - produces = MediaType.TEXT_PLAIN_VALUE) String getJokeValue( - @PathVariable String id, HttpServletResponse response) { - try { - return jokeRepository - .findById(id) - .orElseThrow(() -> new EntityNotFoundException("Joke with id \"" + id + "\" not found.")) - .getValue(); - } catch (EntityNotFoundException e) { - response.setStatus(HttpStatus.NOT_FOUND.value()); - return ""; - } - } - - /** Returns the model for the joke view. */ - public @RequestMapping( - value = "/{id}", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_HTML_VALUE, - produces = MediaType.TEXT_HTML_VALUE) ModelAndView getJokeView(@PathVariable String id) { - Joke joke = - jokeRepository - .findById(id) - .orElseThrow( - () -> new EntityNotFoundException("Joke with id \"" + id + "\" not found.")); - - String[] ids = jokeRepository.getJokeWindow(id).split(","); - - ModelAndView model = new ModelAndView("joke"); - model.addObject("joke", joke); - model.addObject("next_joke_url", "/jokes/" + ids[1]); - model.addObject("current_joke_url", "/jokes/" + id); - model.addObject("prev_joke_url", "/jokes/" + ids[2]); - - return model; - } - - /** - * Returns a random Joke {@link Joke}. - * - * @return joke - */ - public @ResponseBody @RequestMapping( - value = "/random", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) Joke getRandomJoke( - @RequestParam(value = "category", required = false) String categoryString, - @RequestParam(value = "name", required = false) String name) { - if (categoryString == null && name == null) { - return jokeRepository.getRandomJoke(); + /** Returns a new JokeController {@link JokeController} instance. */ + public JokeController(JokeRepository jokeRepository) { + this.jokeRepository = jokeRepository; } - if (categoryString == null && name != null) { - Joke joke = jokeRepository.getRandomPersonalizedJoke(name); - if (!(joke instanceof Joke)) { - throw new EntityNotFoundException("No personalized jokes for name \"" + name + "\" found."); - } - return joke; + @RequestMapping(value = "/categories", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public @ResponseBody String[] getCategories() { + return jokeRepository.findAllCategories(); } - String[] availableCategories = jokeRepository.findAllCategories(); - List categories = Arrays.asList(categoryString.split(",")); - for (String category : categories) { - if (!Arrays.asList(availableCategories).contains(category)) { - throw new EntityNotFoundException("No jokes for category \"" + category + "\" found."); - } + /** Returns all joke categories delimited by a new line. */ + public @ResponseBody @RequestMapping(value = "/categories", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + + MediaType.TEXT_PLAIN_VALUE, produces = MediaType.TEXT_PLAIN_VALUE) String getCategoryValues() { + StringBuilder stringBuilder = new StringBuilder(); + + for (String category : jokeRepository.findAllCategories()) { + stringBuilder.append(category + '\n'); + } + + return stringBuilder.toString(); } - if (name != null) { - Joke joke = jokeRepository.getRandomPersonalizedJokeByCategories(name, categoryString); - if (!(joke instanceof Joke)) { - throw new EntityNotFoundException( - "No personalized jokes for name \"" - + name - + "\" and category \"" - + categoryString - + "\" found."); - } - return joke; + /** + * Returns a Joke {@link Joke} by id. + * + * @param id The joke id + * @return joke + */ + public @ResponseBody @RequestMapping(value = "/{id}", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + + MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) Joke getJoke(@PathVariable String id) { + return jokeRepository + .findById(id) + .orElseThrow(() -> new EntityNotFoundException("Joke with id \"" + id + "\" not found.")); } - return categories.size() <= 1 - ? jokeRepository.getRandomJokeByCategory(categories.get(0)) - : jokeRepository.getRandomJokeByCategories(categoryString); - } - - /** - * Returns a random joke value. - * - * @return string - */ - public @ResponseBody @RequestMapping( - value = "/random", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_PLAIN_VALUE, - produces = MediaType.TEXT_PLAIN_VALUE) String getRandomJokeValue( - @RequestParam(value = "category", required = false) final String categoryString, - @RequestParam(value = "name", required = false) final String name, - HttpServletResponse response) { - if (categoryString == null && name == null) { - return jokeRepository.getRandomJoke().getValue(); + /** + * Returns a joke value by id. + * + * @param id The joke id + * @return string + */ + public @ResponseBody @RequestMapping(value = "/{id}", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + + MediaType.TEXT_PLAIN_VALUE, produces = MediaType.TEXT_PLAIN_VALUE) String getJokeValue( + @PathVariable String id, HttpServletResponse response) { + try { + return jokeRepository + .findById(id) + .orElseThrow(() -> new EntityNotFoundException("Joke with id \"" + id + "\" not found.")) + .getValue(); + } catch (EntityNotFoundException e) { + response.setStatus(HttpStatus.NOT_FOUND.value()); + return ""; + } } - if (categoryString == null && name != null) { - Joke joke = jokeRepository.getRandomPersonalizedJoke(name); - if (!(joke instanceof Joke)) { - response.setStatus(HttpStatus.NOT_FOUND.value()); - return ""; - } - return joke.getValue(); + /** Returns the model for the joke view. */ + public @RequestMapping(value = "/{id}", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_HTML_VALUE, produces = MediaType.TEXT_HTML_VALUE) ModelAndView getJokeView( + @PathVariable String id) { + Joke joke = jokeRepository + .findById(id) + .orElseThrow( + () -> new EntityNotFoundException("Joke with id \"" + id + "\" not found.")); + + String[] ids = jokeRepository.getJokeWindow(id).split(","); + + ModelAndView model = new ModelAndView("joke"); + model.addObject("joke", joke); + model.addObject("next_joke_url", "/jokes/" + ids[1]); + model.addObject("current_joke_url", "/jokes/" + id); + model.addObject("prev_joke_url", "/jokes/" + ids[2]); + + return model; } - String[] availableCategories = jokeRepository.findAllCategories(); - List categories = Arrays.asList(categoryString.split(",")); - for (String category : categories) { - if (!Arrays.asList(availableCategories).contains(category)) { - response.setStatus(HttpStatus.NOT_FOUND.value()); - return ""; - } + /** + * Returns a random Joke {@link Joke}. + * + * @return joke + */ + public @ResponseBody @RequestMapping(value = "/random", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + + MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) Joke getRandomJoke( + @RequestParam(value = "category", required = false) String categoryString, + @RequestParam(value = "name", required = false) String name) { + if (categoryString == null && name == null) { + return jokeRepository.getRandomJoke(); + } + + if (categoryString == null && name != null) { + Joke joke = jokeRepository.getRandomPersonalizedJoke(name); + if (!(joke instanceof Joke)) { + throw new EntityNotFoundException("No personalized jokes for name \"" + name + "\" found."); + } + return joke; + } + + String[] availableCategories = jokeRepository.findAllCategories(); + List categories = Arrays.asList(categoryString.split(",")); + for (String category : categories) { + if (!Arrays.asList(availableCategories).contains(category)) { + throw new EntityNotFoundException("No jokes for category \"" + category + "\" found."); + } + } + + if (name != null) { + Joke joke = jokeRepository.getRandomPersonalizedJokeByCategories(name, categoryString); + if (!(joke instanceof Joke)) { + throw new EntityNotFoundException( + "No personalized jokes for name \"" + + name + + "\" and category \"" + + categoryString + + "\" found."); + } + return joke; + } + + return categories.size() <= 1 + ? jokeRepository.getRandomJokeByCategory(categories.get(0)) + : jokeRepository.getRandomJokeByCategories(categoryString); } - if (name != null) { - Joke joke = jokeRepository.getRandomPersonalizedJokeByCategories(name, categoryString); - if (!(joke instanceof Joke)) { - response.setStatus(HttpStatus.NOT_FOUND.value()); - return ""; - } - return joke.getValue(); + /** + * Returns a random joke value. + * + * @return string + */ + public @ResponseBody @RequestMapping(value = "/random", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + + MediaType.TEXT_PLAIN_VALUE, produces = MediaType.TEXT_PLAIN_VALUE) String getRandomJokeValue( + @RequestParam(value = "category", required = false) final String categoryString, + @RequestParam(value = "name", required = false) final String name, + HttpServletResponse response) { + if (categoryString == null && name == null) { + return jokeRepository.getRandomJoke().getValue(); + } + + if (categoryString == null && name != null) { + Joke joke = jokeRepository.getRandomPersonalizedJoke(name); + if (!(joke instanceof Joke)) { + response.setStatus(HttpStatus.NOT_FOUND.value()); + return ""; + } + return joke.getValue(); + } + + String[] availableCategories = jokeRepository.findAllCategories(); + List categories = Arrays.asList(categoryString.split(",")); + for (String category : categories) { + if (!Arrays.asList(availableCategories).contains(category)) { + response.setStatus(HttpStatus.NOT_FOUND.value()); + return ""; + } + } + + if (name != null) { + Joke joke = jokeRepository.getRandomPersonalizedJokeByCategories(name, categoryString); + if (!(joke instanceof Joke)) { + response.setStatus(HttpStatus.NOT_FOUND.value()); + return ""; + } + return joke.getValue(); + } + + return categories.size() <= 1 + ? jokeRepository.getRandomJokeByCategory(categories.get(0)).getValue() + : jokeRepository.getRandomJokeByCategories(categoryString).getValue(); } - return categories.size() <= 1 - ? jokeRepository.getRandomJokeByCategory(categories.get(0)).getValue() - : jokeRepository.getRandomJokeByCategories(categoryString).getValue(); - } - - /** - * Returns a JokeSearchResult {@link JokeSearchResult}. - * - * @param query The search query - * @return jokeSearchResult - */ - public @ResponseBody @RequestMapping( - value = "/search", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) JokeSearchResult search( - @RequestParam(value = "query") @Size(min = 3, max = 120) final String query) { - Joke[] jokes = jokeRepository.searchByQuery(query); - return new JokeSearchResult(jokes); - } - - /** Returns a search result delimited by a new line. */ - public @ResponseBody @RequestMapping( - value = "/search", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_PLAIN_VALUE, - produces = MediaType.TEXT_PLAIN_VALUE) String searchValues( - @RequestParam(value = "query") @Size(min = 3, max = 120) final String query) { - Joke[] jokes = jokeRepository.searchByQuery(query); - StringBuilder stringBuilder = new StringBuilder(); - - for (Joke joke : jokes) { - stringBuilder.append(joke.getValue() + '\n'); + /** + * Returns a JokeSearchResult {@link JokeSearchResult}. + * + * @param query The search query + * @return jokeSearchResult + */ + public @ResponseBody @RequestMapping(value = "/search", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + + MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) JokeSearchResult search( + @RequestParam(value = "query") @Size(min = 3, max = 120) final String query) { + Joke[] jokes = jokeRepository.searchByQuery(query); + return new JokeSearchResult(jokes); } - return stringBuilder.toString(); - } + /** Returns a search result delimited by a new line. */ + public @ResponseBody @RequestMapping(value = "/search", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + + MediaType.TEXT_PLAIN_VALUE, produces = MediaType.TEXT_PLAIN_VALUE) String searchValues( + @RequestParam(value = "query") @Size(min = 3, max = 120) final String query) { + Joke[] jokes = jokeRepository.searchByQuery(query); + StringBuilder stringBuilder = new StringBuilder(); + + for (Joke joke : jokes) { + stringBuilder.append(joke.getValue() + '\n'); + } + + return stringBuilder.toString(); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeRepository.java b/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeRepository.java index a78f3de..19e1181 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeRepository.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeRepository.java @@ -11,105 +11,74 @@ import org.springframework.stereotype.Repository; @Repository -@TypeDefs({@TypeDef(name = "string-array", typeClass = StringArrayType.class)}) +@TypeDefs({ @TypeDef(name = "string-array", typeClass = StringArrayType.class) }) public interface JokeRepository extends JpaRepository { - @Query( - value = - "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " - + "FROM joke AS j " - + "WHERE lower(j.value) LIKE CONCAT('%', lower(:query), '%')", - nativeQuery = true) - Page findByValueContains(@Param("query") final String query, Pageable pageable); + @Query(value = "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " + + "FROM joke AS j " + + "WHERE lower(j.value) LIKE CONCAT('%', lower(:query), '%')", nativeQuery = true) + Page findByValueContains(@Param("query") final String query, Pageable pageable); - @Query( - value = - "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " - + "FROM find_by_by_value_contains_and_filter(:query, :categories) AS j", - countQuery = - "SELECT count(*) " + "FROM find_by_by_value_contains_and_filter(:query, :categories)", - nativeQuery = true) - Page findByValueContainsAndFilter( - @Param("query") final String query, - @Param("categories") final String categories, - Pageable pageable); + @Query(value = "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " + + "FROM find_by_by_value_contains_and_filter(:query, :categories) AS j", countQuery = "SELECT count(*) " + + "FROM find_by_by_value_contains_and_filter(:query, :categories)", nativeQuery = true) + Page findByValueContainsAndFilter( + @Param("query") final String query, + @Param("categories") final String categories, + Pageable pageable); - @Query( - value = - "SELECT j.categories->>0 FROM joke j WHERE j.categories IS NOT NULL " - + "GROUP BY j.categories->>0 " - + "ORDER BY j.categories->>0 ASC", - nativeQuery = true) - String[] findAllCategories(); + @Query(value = "SELECT j.categories->>0 FROM joke j WHERE j.categories IS NOT NULL " + + "GROUP BY j.categories->>0 " + + "ORDER BY j.categories->>0 ASC", nativeQuery = true) + String[] findAllCategories(); - @Query( - value = - "WITH joke AS( SELECT joke_id, ROW_NUMBER() OVER (ORDER BY joke.created_at ASC," - + " joke.joke_id ASC) AS row_number FROM joke), current AS ( SELECT * FROM" - + " joke WHERE joke_id = :id LIMIT 1 ), prev AS ( SELECT (CASE WHEN (SELECT" - + " min(row_number) FROM joke) >= current.row_number - 1 THEN (SELECT" - + " joke_id FROM joke WHERE row_number = (SELECT max(row_number) FROM" - + " joke)) ELSE (SELECT joke_id FROM joke WHERE row_number =" - + " current.row_number - 1) END) AS joke_id FROM joke, current LIMIT 1 )," - + " next AS ( SELECT (CASE WHEN (SELECT max(row_number) FROM joke) <=" - + " current.row_number + 1 THEN (SELECT joke_id FROM joke WHERE row_number" - + " = (SELECT min(row_number) FROM joke)) ELSE (SELECT joke_id FROM joke" - + " WHERE row_number = current.row_number + 1) END) AS joke_id FROM joke," - + " current LIMIT 1 ) SELECT current.joke_id AS current_joke_id," - + " next.joke_id AS next_joke_id, prev.joke_id AS prev_joke_id FROM" - + " current, prev, next;", - nativeQuery = true) - String getJokeWindow(@Param("id") final String id); + @Query(value = "WITH joke AS( SELECT joke_id, ROW_NUMBER() OVER (ORDER BY joke.created_at ASC," + + " joke.joke_id ASC) AS row_number FROM joke), current AS ( SELECT * FROM" + + " joke WHERE joke_id = :id LIMIT 1 ), prev AS ( SELECT (CASE WHEN (SELECT" + + " min(row_number) FROM joke) >= current.row_number - 1 THEN (SELECT" + + " joke_id FROM joke WHERE row_number = (SELECT max(row_number) FROM" + + " joke)) ELSE (SELECT joke_id FROM joke WHERE row_number =" + + " current.row_number - 1) END) AS joke_id FROM joke, current LIMIT 1 )," + + " next AS ( SELECT (CASE WHEN (SELECT max(row_number) FROM joke) <=" + + " current.row_number + 1 THEN (SELECT joke_id FROM joke WHERE row_number" + + " = (SELECT min(row_number) FROM joke)) ELSE (SELECT joke_id FROM joke" + + " WHERE row_number = current.row_number + 1) END) AS joke_id FROM joke," + + " current LIMIT 1 ) SELECT current.joke_id AS current_joke_id," + + " next.joke_id AS next_joke_id, prev.joke_id AS prev_joke_id FROM" + + " current, prev, next;", nativeQuery = true) + String getJokeWindow(@Param("id") final String id); - @Query( - value = - "SELECT " - + "j.categories, j.created_at, j.joke_id, j.updated_at, j.value " - + "FROM joke AS j " - + "ORDER BY RANDOM() LIMIT 1;", - nativeQuery = true) - Joke getRandomJoke(); + @Query(value = "SELECT " + + "j.categories, j.created_at, j.joke_id, j.updated_at, j.value " + + "FROM joke AS j " + + "ORDER BY RANDOM() LIMIT 1;", nativeQuery = true) + Joke getRandomJoke(); - @Query( - value = - "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " - + "FROM get_random_personalized_joke(:substitute, null) AS j;", - nativeQuery = true) - Joke getRandomPersonalizedJoke(@Param("substitute") final String substitute); + @Query(value = "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " + + "FROM get_random_personalized_joke(:substitute, null) AS j;", nativeQuery = true) + Joke getRandomPersonalizedJoke(@Param("substitute") final String substitute); - @Query( - value = - "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " - + "FROM get_random_personalized_joke(:substitute, :categories) AS j;", - nativeQuery = true) - Joke getRandomPersonalizedJokeByCategories( - @Param("substitute") final String substitute, @Param("categories") final String categories); + @Query(value = "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " + + "FROM get_random_personalized_joke(:substitute, :categories) AS j;", nativeQuery = true) + Joke getRandomPersonalizedJokeByCategories( + @Param("substitute") final String substitute, @Param("categories") final String categories); - @Query( - value = - "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " - + "FROM joke AS j " - + "WHERE j.categories IS NOT NULL AND j.categories->>0 = :category " - + "ORDER BY RANDOM() LIMIT 1;", - nativeQuery = true) - Joke getRandomJokeByCategory(@Param("category") final String category); + @Query(value = "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " + + "FROM joke AS j " + + "WHERE j.categories IS NOT NULL AND j.categories->>0 = :category " + + "ORDER BY RANDOM() LIMIT 1;", nativeQuery = true) + Joke getRandomJokeByCategory(@Param("category") final String category); - /** - * Gets a random joke by a comma separated list of categories. Matches if any of the joke's - * categories equals one of the provided categories. - */ - @Query( - value = - "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " - + "FROM get_joke_random_by_categories(:categories) AS j;", - nativeQuery = true) - Joke getRandomJokeByCategories(@Param("categories") final String categories); + /** + * Gets a random joke by a comma separated list of categories. Matches if any of the joke's + * categories equals one of the provided categories. + */ + @Query(value = "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " + + "FROM get_joke_random_by_categories(:categories) AS j;", nativeQuery = true) + Joke getRandomJokeByCategories(@Param("categories") final String categories); - @Query( - value = - "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " - + "FROM joke AS j " - + "WHERE lower(j.value) LIKE CONCAT('%', lower(:query), '%');", - nativeQuery = true) - Joke[] searchByQuery(@Param("query") final String query); + @Query(value = "SELECT j.categories, j.created_at, j.joke_id, j.updated_at, j.value " + + "FROM joke AS j " + + "WHERE lower(j.value) LIKE CONCAT('%', lower(:query), '%');", nativeQuery = true) + Joke[] searchByQuery(@Param("query") final String query); } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeSearchResult.java b/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeSearchResult.java index e23a4ba..b75cb12 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeSearchResult.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeSearchResult.java @@ -5,30 +5,30 @@ public class JokeSearchResult implements Serializable { - @JsonProperty("total") - private int total; + @JsonProperty("total") + private int total; - @JsonProperty("result") - private Joke[] result; + @JsonProperty("result") + private Joke[] result; - public JokeSearchResult(Joke[] jokes) { - this.total = jokes.length; - this.result = jokes; - } + public JokeSearchResult(Joke[] jokes) { + this.total = jokes.length; + this.result = jokes; + } - public int getTotal() { - return total; - } + public int getTotal() { + return total; + } - public void setTotal(int total) { - this.total = total; - } + public void setTotal(int total) { + this.total = total; + } - public Joke[] getResult() { - return result; - } + public Joke[] getResult() { + return result; + } - public void setResult(Joke[] result) { - this.result = result; - } + public void setResult(Joke[] result) { + this.result = result; + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeSerializer.java b/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeSerializer.java index 8eb6b0e..c9d9462 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeSerializer.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeSerializer.java @@ -8,38 +8,37 @@ public class JokeSerializer extends StdSerializer { - @Value("${application.base_url}") - private String baseUrl; - - public JokeSerializer() { - this(null); - } - - public JokeSerializer(Class t) { - super(t); - } - - @Override - public void serialize(Joke joke, JsonGenerator jsonGenerator, SerializerProvider provider) - throws IOException { - jsonGenerator.writeStartObject(); - - String[] categories = - joke.getCategories() != null && joke.getCategories().length > 0 - ? joke.getCategories() - : new String[0]; - jsonGenerator.writeArrayFieldStart("categories"); - for (String category : categories) { - jsonGenerator.writeString(category); + @Value("${application.base_url}") + private String baseUrl; + + public JokeSerializer() { + this(null); + } + + public JokeSerializer(Class t) { + super(t); + } + + @Override + public void serialize(Joke joke, JsonGenerator jsonGenerator, SerializerProvider provider) + throws IOException { + jsonGenerator.writeStartObject(); + + String[] categories = joke.getCategories() != null && joke.getCategories().length > 0 + ? joke.getCategories() + : new String[0]; + jsonGenerator.writeArrayFieldStart("categories"); + for (String category : categories) { + jsonGenerator.writeString(category); + } + jsonGenerator.writeEndArray(); + + jsonGenerator.writeStringField("created_at", joke.getCreatedAt()); + jsonGenerator.writeStringField("icon_url", joke.getIconUrl()); + jsonGenerator.writeStringField("id", joke.getId()); + jsonGenerator.writeStringField("updated_at", joke.getUpdatedAt()); + jsonGenerator.writeStringField("url", "https://" + baseUrl + "/jokes/" + joke.getId()); + jsonGenerator.writeStringField("value", joke.getValue()); + jsonGenerator.writeEndObject(); } - jsonGenerator.writeEndArray(); - - jsonGenerator.writeStringField("created_at", joke.getCreatedAt()); - jsonGenerator.writeStringField("icon_url", joke.getIconUrl()); - jsonGenerator.writeStringField("id", joke.getId()); - jsonGenerator.writeStringField("updated_at", joke.getUpdatedAt()); - jsonGenerator.writeStringField("url", "https://" + baseUrl + "/jokes/" + joke.getId()); - jsonGenerator.writeStringField("value", joke.getValue()); - jsonGenerator.writeEndObject(); - } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeService.java b/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeService.java index fc0ed79..f91139e 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeService.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/joke/JokeService.java @@ -6,33 +6,33 @@ @Service public class JokeService { - private JokeRepository jokeRepository; + private JokeRepository jokeRepository; - public JokeService(JokeRepository jokeRepository) { - this.jokeRepository = jokeRepository; - } + public JokeService(JokeRepository jokeRepository) { + this.jokeRepository = jokeRepository; + } - /** Returns a random joke filtered by a given category. */ - public Joke randomJokeByCategory(final String category) { - return jokeRepository.getRandomJokeByCategory(category); - } + /** Returns a random joke filtered by a given category. */ + public Joke randomJokeByCategory(final String category) { + return jokeRepository.getRandomJokeByCategory(category); + } - /** Returns a random joke filtered by a given array of categories. */ - public Joke randomJokeByCategories(final String[] categories) { - return jokeRepository.getRandomJokeByCategories(String.join(",", categories)); - } + /** Returns a random joke filtered by a given array of categories. */ + public Joke randomJokeByCategories(final String[] categories) { + return jokeRepository.getRandomJokeByCategories(String.join(",", categories)); + } - /** Returns a random personalized joke filtered by a given array of categories. */ - public Joke randomPersonalizedJokeByCategories( - final String substitute, final String[] categories) { - return jokeRepository.getRandomPersonalizedJokeByCategories( - substitute, String.join(",", categories)); - } + /** Returns a random personalized joke filtered by a given array of categories. */ + public Joke randomPersonalizedJokeByCategories( + final String substitute, final String[] categories) { + return jokeRepository.getRandomPersonalizedJokeByCategories( + substitute, String.join(",", categories)); + } - /** Search jokes by query and with category filter. */ - public Page searchWithCategoryFilter( - final String query, final String[] categories, final Pageable pageable) { - return jokeRepository.findByValueContainsAndFilter( - query, String.join(",", categories), pageable); - } + /** Search jokes by query and with category filter. */ + public Page searchWithCategoryFilter( + final String query, final String[] categories, final Pageable pageable) { + return jokeRepository.findByValueContainsAndFilter( + query, String.join(",", categories), pageable); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/postcard/PostcardController.java b/chucknorris-web/src/main/java/io/chucknorris/api/postcard/PostcardController.java index f93c373..6c3a478 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/postcard/PostcardController.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/postcard/PostcardController.java @@ -1,3 +1,4 @@ package io.chucknorris.api.postcard; -public class PostcardController {} +public class PostcardController { +} diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/privacy/PrivacyController.java b/chucknorris-web/src/main/java/io/chucknorris/api/privacy/PrivacyController.java index 3159d21..aa3c9c0 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/privacy/PrivacyController.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/privacy/PrivacyController.java @@ -9,12 +9,8 @@ @Controller public class PrivacyController { - /** Returns privacy view. */ - public @RequestMapping( - value = "/privacy", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_HTML_VALUE, - produces = MediaType.TEXT_HTML_VALUE) String get() { - return "privacy"; - } + /** Returns privacy view. */ + public @RequestMapping(value = "/privacy", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_HTML_VALUE, produces = MediaType.TEXT_HTML_VALUE) String get() { + return "privacy"; + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/AccessToken.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/AccessToken.java index 640bc5f..7abf9ae 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/AccessToken.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/AccessToken.java @@ -7,21 +7,21 @@ @Data public class AccessToken implements Serializable { - @JsonProperty("access_token") - private String accessToken; + @JsonProperty("access_token") + private String accessToken; - @JsonProperty("scope") - private String scope; + @JsonProperty("scope") + private String scope; - @JsonProperty("team_id") - private String teamId; + @JsonProperty("team_id") + private String teamId; - @JsonProperty("team_name") - private String teamName; + @JsonProperty("team_name") + private String teamName; - @JsonProperty("user_id") - private String userId; + @JsonProperty("user_id") + private String userId; - @JsonProperty("user_name") - private String userName; + @JsonProperty("user_name") + private String userName; } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/CommandResponse.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/CommandResponse.java index b9ebcbf..8c27ffb 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/CommandResponse.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/CommandResponse.java @@ -7,15 +7,15 @@ @Data public class CommandResponse implements SlackCommandResponse, Serializable { - @JsonProperty("icon_url") - private String iconUrl = "https://assets.chucknorris.host/img/avatar/chuck-norris.png"; + @JsonProperty("icon_url") + private String iconUrl = "https://assets.chucknorris.host/img/avatar/chuck-norris.png"; - @JsonProperty("text") - private String text; + @JsonProperty("text") + private String text; - @JsonProperty("attachments") - private SlackCommandResponseAttachment[] attachments; + @JsonProperty("attachments") + private SlackCommandResponseAttachment[] attachments; - @JsonProperty("response_type") - private String responseType = ResponseType.IN_CHANNEL; + @JsonProperty("response_type") + private String responseType = ResponseType.IN_CHANNEL; } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/CommandResponseAttachment.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/CommandResponseAttachment.java index 121f1e3..7663142 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/CommandResponseAttachment.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/CommandResponseAttachment.java @@ -7,18 +7,18 @@ @Data public class CommandResponseAttachment implements Serializable, SlackCommandResponseAttachment { - @JsonProperty("fallback") - private String fallback; + @JsonProperty("fallback") + private String fallback; - @JsonProperty("mrkdwn_in") - private String[] mrkdownIn = new String[] {"text"}; + @JsonProperty("mrkdwn_in") + private String[] mrkdownIn = new String[] { "text" }; - @JsonProperty("text") - private String text; + @JsonProperty("text") + private String text; - @JsonProperty("title") - private String title; + @JsonProperty("title") + private String title; - @JsonProperty("title_link") - private String titleLink; + @JsonProperty("title_link") + private String titleLink; } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/Help.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/Help.java index 0eda6f4..db4eb6c 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/Help.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/Help.java @@ -6,69 +6,68 @@ @Value public class Help implements SlackCommandResponse { - @JsonProperty("attachments") - private CommandResponseAttachment[] attachments; + @JsonProperty("attachments") + private CommandResponseAttachment[] attachments; - @JsonProperty("icon_url") - private String iconUrl = "https://assets.chucknorris.host/img/avatar/chuck-norris.png"; + @JsonProperty("icon_url") + private String iconUrl = "https://assets.chucknorris.host/img/avatar/chuck-norris.png"; - @JsonProperty("response_type") - private String responseType = ResponseType.EPHEMERAL; + @JsonProperty("response_type") + private String responseType = ResponseType.EPHEMERAL; - @JsonProperty("text") - private String text = "*Available commands:*"; + @JsonProperty("text") + private String text = "*Available commands:*"; - /** Instantiates a new Help {@link Help}. */ - public Help() { - CommandResponseAttachment newsletter = new CommandResponseAttachment(); - newsletter.setTitle("The Daily Chuck"); - newsletter.setText( - ":facepunch: Sign up for *The Daily Chuck* and get your daily dose of the best" - + " #ChuckNorrisFacts every morning straight int your inbox!" - + " https://mailchi.mp/5a19a2898bf7/the-daily-chuck"); + /** Instantiates a new Help {@link Help}. */ + public Help() { + CommandResponseAttachment newsletter = new CommandResponseAttachment(); + newsletter.setTitle("The Daily Chuck"); + newsletter.setText( + ":facepunch: Sign up for *The Daily Chuck* and get your daily dose of the best" + + " #ChuckNorrisFacts every morning straight int your inbox!" + + " https://mailchi.mp/5a19a2898bf7/the-daily-chuck"); - CommandResponseAttachment randomJoke = new CommandResponseAttachment(); - randomJoke.setText("Type `/chuck` to get a random joke."); - randomJoke.setTitle("Random joke"); + CommandResponseAttachment randomJoke = new CommandResponseAttachment(); + randomJoke.setText("Type `/chuck` to get a random joke."); + randomJoke.setTitle("Random joke"); - CommandResponseAttachment search = new CommandResponseAttachment(); - search.setText( - "Type `/chuck ? {search_term}` to search within tens of thousands Chuck Norris" - + " jokes."); - search.setTitle("Free text search"); + CommandResponseAttachment search = new CommandResponseAttachment(); + search.setText( + "Type `/chuck ? {search_term}` to search within tens of thousands Chuck Norris" + + " jokes."); + search.setTitle("Free text search"); - CommandResponseAttachment randomJokePersonalized = new CommandResponseAttachment(); - randomJokePersonalized.setText( - "Type `/chuck @ {user_name}` to get a random personalized joke."); - randomJokePersonalized.setTitle("Random personalized joke"); + CommandResponseAttachment randomJokePersonalized = new CommandResponseAttachment(); + randomJokePersonalized.setText( + "Type `/chuck @ {user_name}` to get a random personalized joke."); + randomJokePersonalized.setTitle("Random personalized joke"); - CommandResponseAttachment randomJokeFromCategory = new CommandResponseAttachment(); - randomJokeFromCategory.setText( - "Type `/chuck {category_name}` to get a random joke from within a given category."); - randomJokeFromCategory.setTitle("Random joke from category"); + CommandResponseAttachment randomJokeFromCategory = new CommandResponseAttachment(); + randomJokeFromCategory.setText( + "Type `/chuck {category_name}` to get a random joke from within a given category."); + randomJokeFromCategory.setTitle("Random joke from category"); - CommandResponseAttachment categories = new CommandResponseAttachment(); - categories.setText("Type `/chuck -cat` to retrieve a list of all categories."); - categories.setTitle("Categories"); + CommandResponseAttachment categories = new CommandResponseAttachment(); + categories.setText("Type `/chuck -cat` to retrieve a list of all categories."); + categories.setTitle("Categories"); - CommandResponseAttachment jokeById = new CommandResponseAttachment(); - jokeById.setText("Type `/chuck : {joke_id}` to retrieve get a joke by a given `id`."); - jokeById.setTitle("Get joke by id"); + CommandResponseAttachment jokeById = new CommandResponseAttachment(); + jokeById.setText("Type `/chuck : {joke_id}` to retrieve get a joke by a given `id`."); + jokeById.setTitle("Get joke by id"); - CommandResponseAttachment help = new CommandResponseAttachment(); - help.setText("Type `/chuck help` to display a list of available commands."); - help.setTitle("Help"); + CommandResponseAttachment help = new CommandResponseAttachment(); + help.setText("Type `/chuck help` to display a list of available commands."); + help.setTitle("Help"); - attachments = - new CommandResponseAttachment[] { - newsletter, - randomJoke, - search, - randomJokePersonalized, - randomJokeFromCategory, - categories, - jokeById, - help + attachments = new CommandResponseAttachment[] { + newsletter, + randomJoke, + search, + randomJokePersonalized, + randomJokeFromCategory, + categories, + jokeById, + help }; - } + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/Request.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/Request.java index 7d5d904..5f947a1 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/Request.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/Request.java @@ -10,66 +10,66 @@ @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class Request implements Serializable { - @JsonProperty("channel_id") - private String channelId; + @JsonProperty("channel_id") + private String channelId; - @JsonProperty("channel_name") - private String channelName; + @JsonProperty("channel_name") + private String channelName; - /** - * The command that was typed in to trigger this request. This value can be useful if you want to - * use a single Request URL to service multiple Slash Commands, as it lets you tell them apart. - */ - @JsonProperty("command") - private String command; + /** + * The command that was typed in to trigger this request. This value can be useful if you want to + * use a single Request URL to service multiple Slash Commands, as it lets you tell them apart. + */ + @JsonProperty("command") + private String command; - @JsonProperty("enterprise_id") - private String enterpriseId; + @JsonProperty("enterprise_id") + private String enterpriseId; - @JsonProperty("enterprise_name") - private String enterpriseName; + @JsonProperty("enterprise_name") + private String enterpriseName; - /** A URL that you can use to respond to the command. */ - @JsonProperty("enterprise_url") - private String responseUrl; + /** A URL that you can use to respond to the command. */ + @JsonProperty("enterprise_url") + private String responseUrl; - @JsonProperty("team_domain") - private String teamDomain; + @JsonProperty("team_domain") + private String teamDomain; - @JsonProperty("team_id") - private String teamId; + @JsonProperty("team_id") + private String teamId; - /** - * This is the part of the Slash Command after the command itself, and it can contain absolutely - * anything that the user might decide to type. It is common to use this text parameter to provide - * extra context for the command. - */ - @JsonProperty("text") - private String text; + /** + * This is the part of the Slash Command after the command itself, and it can contain absolutely + * anything that the user might decide to type. It is common to use this text parameter to provide + * extra context for the command. + */ + @JsonProperty("text") + private String text; - /** - * This is a verification token, a deprecated feature that you shouldn't use any more. It was used - * to verify that requests were legitimately being sent by Slack to your app, but you should use - * the signed secrets functionality to do this instead. - */ - @JsonProperty("token") - private String token; + /** + * This is a verification token, a deprecated feature that you shouldn't use any more. It was used + * to verify that requests were legitimately being sent by Slack to your app, but you should use + * the signed secrets functionality to do this instead. + */ + @JsonProperty("token") + private String token; - /** - * If you need to respond to the command by opening a dialog, you'll need this trigger ID to get - * it to work. You can use this ID with dialog.open up to 3000ms after this data payload is sent. - */ - @JsonProperty("trigger_id") - private String triggerId; + /** + * If you need to respond to the command by opening a dialog, you'll need this trigger ID to get + * it to work. You can use this ID with dialog.open up to 3000ms after this data payload is sent. + */ + @JsonProperty("trigger_id") + private String triggerId; - /** The ID of the user who triggered the command. */ - @JsonProperty("user_id") - private String userId; + /** The ID of the user who triggered the command. */ + @JsonProperty("user_id") + private String userId; - /** - * The plain text name of the user who triggered the command. As above, do not rely on this field - * as it is being phased out, use the user_id instead. - */ - @JsonProperty("user_name") - private String userName; + /** + * The plain text name of the user who triggered the command. As above, do not rely on this field + * as it is being phased out, use the user_id instead. + */ + @JsonProperty("user_name") + private String userName; } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/RequestArgumentResolver.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/RequestArgumentResolver.java index 4b7763d..d9ab02a 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/RequestArgumentResolver.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/RequestArgumentResolver.java @@ -8,33 +8,33 @@ public class RequestArgumentResolver implements HandlerMethodArgumentResolver { - @Override - public boolean supportsParameter(MethodParameter methodParameter) { - return methodParameter.getParameterType().equals(Request.class); - } + @Override + public boolean supportsParameter(MethodParameter methodParameter) { + return methodParameter.getParameterType().equals(Request.class); + } - @Override - public Object resolveArgument( - MethodParameter methodParameter, - ModelAndViewContainer modelAndViewContainer, - NativeWebRequest nativeWebRequest, - WebDataBinderFactory webDataBinderFactory) { - Request request = new Request(); + @Override + public Object resolveArgument( + MethodParameter methodParameter, + ModelAndViewContainer modelAndViewContainer, + NativeWebRequest nativeWebRequest, + WebDataBinderFactory webDataBinderFactory) { + Request request = new Request(); - request.setChannelId(nativeWebRequest.getParameter("channel_id")); - request.setChannelName(nativeWebRequest.getParameter("channel_name")); - request.setCommand(nativeWebRequest.getParameter("command")); - request.setEnterpriseId(nativeWebRequest.getParameter("enterprise_id")); - request.setEnterpriseName(nativeWebRequest.getParameter("enterprise_name")); - request.setResponseUrl(nativeWebRequest.getParameter("response_url")); - request.setTeamDomain(nativeWebRequest.getParameter("team_domain")); - request.setTeamId(nativeWebRequest.getParameter("team_id")); - request.setText(nativeWebRequest.getParameter("text")); - request.setToken(nativeWebRequest.getParameter("token")); - request.setTriggerId(nativeWebRequest.getParameter("trigger_id")); - request.setUserId(nativeWebRequest.getParameter("user_id")); - request.setUserName(nativeWebRequest.getParameter("user_name")); + request.setChannelId(nativeWebRequest.getParameter("channel_id")); + request.setChannelName(nativeWebRequest.getParameter("channel_name")); + request.setCommand(nativeWebRequest.getParameter("command")); + request.setEnterpriseId(nativeWebRequest.getParameter("enterprise_id")); + request.setEnterpriseName(nativeWebRequest.getParameter("enterprise_name")); + request.setResponseUrl(nativeWebRequest.getParameter("response_url")); + request.setTeamDomain(nativeWebRequest.getParameter("team_domain")); + request.setTeamId(nativeWebRequest.getParameter("team_id")); + request.setText(nativeWebRequest.getParameter("text")); + request.setToken(nativeWebRequest.getParameter("token")); + request.setTriggerId(nativeWebRequest.getParameter("trigger_id")); + request.setUserId(nativeWebRequest.getParameter("user_id")); + request.setUserName(nativeWebRequest.getParameter("user_name")); - return request; - } + return request; + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/ResponseType.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/ResponseType.java index 096f728..1b378c9 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/ResponseType.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/ResponseType.java @@ -2,6 +2,6 @@ public class ResponseType { - public static final String EPHEMERAL = "ephemeral"; - public static final String IN_CHANNEL = "in_channel"; + public static final String EPHEMERAL = "ephemeral"; + public static final String IN_CHANNEL = "in_channel"; } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackCommandResponse.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackCommandResponse.java index d78af01..02a8e7e 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackCommandResponse.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackCommandResponse.java @@ -2,11 +2,11 @@ public interface SlackCommandResponse { - SlackCommandResponseAttachment[] getAttachments(); + SlackCommandResponseAttachment[] getAttachments(); - String getIconUrl(); + String getIconUrl(); - String getResponseType(); + String getResponseType(); - String getText(); + String getText(); } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackCommandResponseAttachment.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackCommandResponseAttachment.java index 1fa9eb8..f2541fb 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackCommandResponseAttachment.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackCommandResponseAttachment.java @@ -2,23 +2,23 @@ public interface SlackCommandResponseAttachment { - String getFallback(); + String getFallback(); - void setFallback(String fallback); + void setFallback(String fallback); - String[] getMrkdownIn(); + String[] getMrkdownIn(); - void setMrkdownIn(String[] mrkdownIn); + void setMrkdownIn(String[] mrkdownIn); - String getText(); + String getText(); - void setText(String text); + void setText(String text); - String getTitle(); + String getTitle(); - void setTitle(String title); + void setTitle(String title); - String getTitleLink(); + String getTitleLink(); - void setTitleLink(String titleLink); + void setTitleLink(String titleLink); } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackConnectEvent.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackConnectEvent.java index 59942f5..c106538 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackConnectEvent.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackConnectEvent.java @@ -4,7 +4,7 @@ public class SlackConnectEvent extends BaseEvent { - public SlackConnectEvent(AccessToken accessToken) { - super("SlackConnectEvent", accessToken); - } + public SlackConnectEvent(AccessToken accessToken) { + super("SlackConnectEvent", accessToken); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackController.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackController.java index 6de0159..f80cb78 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackController.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackController.java @@ -32,315 +32,304 @@ @RestController public class SlackController { - private static final Logger logger = LoggerFactory.getLogger(SlackController.class); - - @Value("${application.base_url}") - private String baseUrl; - - private EventService eventService; - private JokeRepository jokeRepository; - private JokeService jokeService; - private SlackService slackService; - - /** Returns a new {@link SlackController} instance. */ - public SlackController( - EventService eventService, - JokeRepository jokeRepository, - JokeService jokeService, - SlackService slackService) { - this.eventService = eventService; - this.jokeRepository = jokeRepository; - this.jokeService = jokeService; - this.slackService = slackService; - } - - /** Returns the model for the connect/slack view. */ - public @RequestMapping( - value = "/connect/slack", - method = RequestMethod.GET, - headers = HttpHeaders.ACCEPT + "=" + MediaType.TEXT_HTML_VALUE, - produces = MediaType.TEXT_HTML_VALUE) ModelAndView connect( - @RequestParam(value = "code", required = false) final String code) - throws JsonProcessingException { - AccessToken accessToken = slackService.requestAccessToken(code); - - ModelAndView model = new ModelAndView("connect/slack"); - if (accessToken.getAccessToken() != null) { - model.setStatus(HttpStatus.OK); - model.addObject( - "page_title", "Congrats, the app was successfully installed for your Slack team!"); - model.addObject("error", false); - model.addObject("message", null); - - SlackConnectEvent slackConnectEvent = new SlackConnectEvent(accessToken); - eventService.publishEvent(slackConnectEvent); - - } else { - model.setStatus(HttpStatus.UNAUTHORIZED); - model.addObject("page_title", "Oops, an error has occurred."); - model.addObject("error", true); - model.addObject("message", "Oops, an error has occurred. Please try again later!"); + private static final Logger logger = LoggerFactory.getLogger(SlackController.class); + + @Value("${application.base_url}") + private String baseUrl; + + private EventService eventService; + private JokeRepository jokeRepository; + private JokeService jokeService; + private SlackService slackService; + + /** Returns a new {@link SlackController} instance. */ + public SlackController( + EventService eventService, + JokeRepository jokeRepository, + JokeService jokeService, + SlackService slackService) { + this.eventService = eventService; + this.jokeRepository = jokeRepository; + this.jokeService = jokeService; + this.slackService = slackService; } - return model; - } - - /** - * Returns a {@link SlackCommandResponse}. - * - * @param request The slack request {@link Request} - * @return slackCommandResponse - */ - public @ResponseBody @RequestMapping( - value = {"/integration/slack", "/jokes/slack"}, - method = RequestMethod.POST, - headers = { - HttpHeaders.ACCEPT + "=" + MediaType.APPLICATION_JSON_VALUE, - HttpHeaders.CONTENT_TYPE + "=" + MediaType.APPLICATION_FORM_URLENCODED_VALUE - }, - produces = MediaType.APPLICATION_JSON_VALUE) SlackCommandResponse command(Request request) { - logger.info(request.toString()); - - if (request.getText() == null || request.getText().isEmpty()) { - MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); - urlQueryParams.set("utm_source", "slack"); - urlQueryParams.set("utm_medium", "api"); - urlQueryParams.set("utm_term", request.getTeamDomain()); - urlQueryParams.set("utm_campaign", "random+joke"); - - Joke joke = jokeService.randomJokeByCategories(slackService.getWhitelistedCategories()); - - return composeJokeResponse(joke, urlQueryParams); + /** Returns the model for the connect/slack view. */ + public @RequestMapping(value = "/connect/slack", method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + + MediaType.TEXT_HTML_VALUE, produces = MediaType.TEXT_HTML_VALUE) ModelAndView connect( + @RequestParam(value = "code", required = false) final String code) + throws JsonProcessingException { + AccessToken accessToken = slackService.requestAccessToken(code); + + ModelAndView model = new ModelAndView("connect/slack"); + if (accessToken.getAccessToken() != null) { + model.setStatus(HttpStatus.OK); + model.addObject( + "page_title", "Congrats, the app was successfully installed for your Slack team!"); + model.addObject("error", false); + model.addObject("message", null); + + SlackConnectEvent slackConnectEvent = new SlackConnectEvent(accessToken); + eventService.publishEvent(slackConnectEvent); + + } else { + model.setStatus(HttpStatus.UNAUTHORIZED); + model.addObject("page_title", "Oops, an error has occurred."); + model.addObject("error", true); + model.addObject("message", "Oops, an error has occurred. Please try again later!"); + } + + return model; } - if (request.getText().equals("help")) { - return new Help(); + /** + * Returns a {@link SlackCommandResponse}. + * + * @param request The slack request {@link Request} + * @return slackCommandResponse + */ + public @ResponseBody @RequestMapping(value = { "/integration/slack", "/jokes/slack" }, method = RequestMethod.POST, headers = { + HttpHeaders.ACCEPT + "=" + MediaType.APPLICATION_JSON_VALUE, + HttpHeaders.CONTENT_TYPE + "=" + MediaType.APPLICATION_FORM_URLENCODED_VALUE + }, produces = MediaType.APPLICATION_JSON_VALUE) SlackCommandResponse command(Request request) { + logger.info(request.toString()); + + if (request.getText() == null || request.getText().isEmpty()) { + MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); + urlQueryParams.set("utm_source", "slack"); + urlQueryParams.set("utm_medium", "api"); + urlQueryParams.set("utm_term", request.getTeamDomain()); + urlQueryParams.set("utm_campaign", "random+joke"); + + Joke joke = jokeService.randomJokeByCategories(slackService.getWhitelistedCategories()); + + return composeJokeResponse(joke, urlQueryParams); + } + + if (request.getText().equals("help")) { + return new Help(); + } + + if (request.getText().equals("-cat")) { + String[] categories = jokeRepository.findAllCategories(); + String[] whitelistedCategories = slackService.filterNonWhitelistedCategories(categories); + + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("Available categories are: `"); + stringBuilder.append(String.join("`, `", whitelistedCategories)); + stringBuilder.append( + "`. Type `/chuck {category_name}` to retrieve a " + + "random joke from within the given category."); + + CommandResponse response = new CommandResponse(); + response.setText(stringBuilder.toString()); + response.setResponseType(ResponseType.EPHEMERAL); + + return response; + } + + if (request.getText().startsWith(":")) { + String id = request.getText().substring(1).trim(); + Optional joke = jokeRepository.findById(id); + + if (!joke.isPresent()) { + CommandResponse response = new CommandResponse(); + response.setText("Sorry dude ¯\\_(ツ)_/¯ , no joke with id (\"" + id + "\") found."); + response.setResponseType(ResponseType.EPHEMERAL); + + return response; + } + + MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); + urlQueryParams.set("utm_source", "slack"); + urlQueryParams.set("utm_medium", "api"); + urlQueryParams.set("utm_term", request.getTeamDomain()); + urlQueryParams.set("utm_campaign", "joke+by+id"); + + return composeJokeResponse(joke.get(), urlQueryParams); + } + + if (request.getText().startsWith("@")) { + MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); + urlQueryParams.set("utm_source", "slack"); + urlQueryParams.set("utm_medium", "api"); + urlQueryParams.set("utm_term", request.getTeamDomain()); + urlQueryParams.set("utm_campaign", "random+personalized+joke"); + + String[] categories = jokeRepository.findAllCategories(); + String[] whitelistedCategories = slackService.filterNonWhitelistedCategories(categories); + + String substitute = request.getText().substring(1).trim(); + Joke joke = jokeService.randomPersonalizedJokeByCategories(substitute, whitelistedCategories); + + if (joke == null) { + CommandResponse response = new CommandResponse(); + response.setText( + "Your search for *\"" + + substitute + + "\"* did not match any joke ¯\\_(ツ)_/¯. Make sure that all words" + + " are spelled correctly. Try different keywords. Try more general" + + " keywords."); + response.setResponseType(ResponseType.EPHEMERAL); + return response; + } + + return composeJokeResponse(joke, urlQueryParams); + } + + if (request.getText().startsWith("?")) { + String query = ""; + Matcher queryMatcher = Pattern.compile("/?\\s?([a-zA-Z0-9]+)").matcher(request.getText()); + if (queryMatcher.find()) { + query = queryMatcher.group(0).trim(); + } + + int page = 0; + int pageDisplayValue = 0; // Using a display value because PageRequest#of is zero-base indexed + Matcher pageMatcher = Pattern.compile("--page\\s?(\\d+)").matcher(request.getText()); + if (pageMatcher.find()) { + pageDisplayValue = Integer.parseInt(pageMatcher.group(1).trim()); + page = pageDisplayValue <= 1 ? 0 : pageDisplayValue - 1; + } + + int itemsPerPage = 5; + Pageable pageable = PageRequest.of(page, itemsPerPage); + + String[] categories = jokeRepository.findAllCategories(); + String[] whitelistedCategories = slackService.filterNonWhitelistedCategories(categories); + Page jokes = jokeService.searchWithCategoryFilter(query, whitelistedCategories, pageable); + + if (jokes.getContent().size() < 1) { + CommandResponse response = new CommandResponse(); + response.setText( + "Your search for *\"" + + query + + "\"* did not match any joke ¯\\_(ツ)_/¯. Make sure that all words" + + " are spelled correctly. Try different keywords. Try more general" + + " keywords."); + response.setResponseType(ResponseType.EPHEMERAL); + + return response; + } + + MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); + urlQueryParams.set("utm_source", "slack"); + urlQueryParams.set("utm_medium", "api"); + urlQueryParams.set("utm_term", request.getTeamDomain()); + urlQueryParams.set("utm_campaign", "search+joke"); + + SlackCommandResponseAttachment[] attachments = new CommandResponseAttachment[jokes.getContent().size()]; + for (int i = 0; i < jokes.getContent().size(); i++) { + Joke joke = jokes.getContent().get(i); + + UriComponents uriComponents = UriComponentsBuilder.newInstance() + .scheme("https") + .host(baseUrl) + .path("/jokes/" + joke.getId()) + .queryParams(urlQueryParams) + .build() + .encode(); + + SlackCommandResponseAttachment attachment = new CommandResponseAttachment(); + attachment.setFallback(joke.getValue()); + attachment.setText(joke.getValue()); + attachment.setTitle("(" + ((page * itemsPerPage + 1) + i) + ")"); + attachment.setTitleLink(uriComponents.toUriString()); + + attachments[i] = attachment; + } + + CommandResponse response = new CommandResponse(); + if (!jokes.isLast()) { + response.setText( + "*Search results: " + + (page * itemsPerPage + 1) + + " - " + + (page * itemsPerPage + jokes.getContent().size()) + + " of " + + jokes.getTotalElements() + + "*. " + + "Type `/chuck ? " + + query + + " --page " + + (page + 1 + 1) + + "` to see more results."); + } else { + response.setText( + "*Search results: " + + (page * itemsPerPage + 1) + + " - " + + (page * 5 + jokes.getNumberOfElements()) + + " of " + + jokes.getTotalElements() + + "*."); + } + + response.setAttachments(attachments); + + return response; + } + + if (!request.getText().isEmpty()) { + if (!slackService.isWhitelistedCategory(request.getText())) { + CommandResponse response = new CommandResponse(); + response.setText( + "Sorry dude ¯\\_(ツ)_/¯ , the given category (\"" + + request.getText() + + "\") is not whitelisted. Type `/chuck -cat` to see available" + + " categories or search by query `/chuck ? {search_term}`"); + response.setResponseType(ResponseType.EPHEMERAL); + + return response; + } + + String[] categories = jokeRepository.findAllCategories(); + String[] whitelistedCategories = slackService.filterNonWhitelistedCategories(categories); + if (!Arrays.stream(whitelistedCategories).anyMatch(request.getText()::equals)) { + CommandResponse response = new CommandResponse(); + response.setText( + "Sorry dude ¯\\_(ツ)_/¯ , we've found no jokes for the given category (\"" + + request.getText() + + "\"). Type `/chuck -cat` to see available categories or search by" + + " query `/chuck ? {search_term}`"); + response.setResponseType(ResponseType.EPHEMERAL); + + return response; + } + + MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); + urlQueryParams.set("utm_source", "slack"); + urlQueryParams.set("utm_medium", "api"); + urlQueryParams.set("utm_term", request.getTeamDomain()); + urlQueryParams.set("utm_campaign", "random+joke+category"); + + Joke joke = jokeService.randomJokeByCategory(request.getText()); + + return composeJokeResponse(joke, urlQueryParams); + } + + return new CommandResponse(); } - if (request.getText().equals("-cat")) { - String[] categories = jokeRepository.findAllCategories(); - String[] whitelistedCategories = slackService.filterNonWhitelistedCategories(categories); - - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("Available categories are: `"); - stringBuilder.append(String.join("`, `", whitelistedCategories)); - stringBuilder.append( - "`. Type `/chuck {category_name}` to retrieve a " - + "random joke from within the given category."); - - CommandResponse response = new CommandResponse(); - response.setText(stringBuilder.toString()); - response.setResponseType(ResponseType.EPHEMERAL); - - return response; - } - - if (request.getText().startsWith(":")) { - String id = request.getText().substring(1).trim(); - Optional joke = jokeRepository.findById(id); - - if (!joke.isPresent()) { - CommandResponse response = new CommandResponse(); - response.setText("Sorry dude ¯\\_(ツ)_/¯ , no joke with id (\"" + id + "\") found."); - response.setResponseType(ResponseType.EPHEMERAL); - - return response; - } - - MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); - urlQueryParams.set("utm_source", "slack"); - urlQueryParams.set("utm_medium", "api"); - urlQueryParams.set("utm_term", request.getTeamDomain()); - urlQueryParams.set("utm_campaign", "joke+by+id"); - - return composeJokeResponse(joke.get(), urlQueryParams); - } - - if (request.getText().startsWith("@")) { - MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); - urlQueryParams.set("utm_source", "slack"); - urlQueryParams.set("utm_medium", "api"); - urlQueryParams.set("utm_term", request.getTeamDomain()); - urlQueryParams.set("utm_campaign", "random+personalized+joke"); - - String[] categories = jokeRepository.findAllCategories(); - String[] whitelistedCategories = slackService.filterNonWhitelistedCategories(categories); - - String substitute = request.getText().substring(1).trim(); - Joke joke = jokeService.randomPersonalizedJokeByCategories(substitute, whitelistedCategories); - - if (joke == null) { - CommandResponse response = new CommandResponse(); - response.setText( - "Your search for *\"" - + substitute - + "\"* did not match any joke ¯\\_(ツ)_/¯. Make sure that all words" - + " are spelled correctly. Try different keywords. Try more general" - + " keywords."); - response.setResponseType(ResponseType.EPHEMERAL); - return response; - } - - return composeJokeResponse(joke, urlQueryParams); - } - - if (request.getText().startsWith("?")) { - String query = ""; - Matcher queryMatcher = Pattern.compile("/?\\s?([a-zA-Z0-9]+)").matcher(request.getText()); - if (queryMatcher.find()) { - query = queryMatcher.group(0).trim(); - } - - int page = 0; - int pageDisplayValue = 0; // Using a display value because PageRequest#of is zero-base indexed - Matcher pageMatcher = Pattern.compile("--page\\s?(\\d+)").matcher(request.getText()); - if (pageMatcher.find()) { - pageDisplayValue = Integer.parseInt(pageMatcher.group(1).trim()); - page = pageDisplayValue <= 1 ? 0 : pageDisplayValue - 1; - } - - int itemsPerPage = 5; - Pageable pageable = PageRequest.of(page, itemsPerPage); - - String[] categories = jokeRepository.findAllCategories(); - String[] whitelistedCategories = slackService.filterNonWhitelistedCategories(categories); - Page jokes = - jokeService.searchWithCategoryFilter(query, whitelistedCategories, pageable); - - if (jokes.getContent().size() < 1) { - CommandResponse response = new CommandResponse(); - response.setText( - "Your search for *\"" - + query - + "\"* did not match any joke ¯\\_(ツ)_/¯. Make sure that all words" - + " are spelled correctly. Try different keywords. Try more general" - + " keywords."); - response.setResponseType(ResponseType.EPHEMERAL); - - return response; - } - - MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); - urlQueryParams.set("utm_source", "slack"); - urlQueryParams.set("utm_medium", "api"); - urlQueryParams.set("utm_term", request.getTeamDomain()); - urlQueryParams.set("utm_campaign", "search+joke"); - - SlackCommandResponseAttachment[] attachments = - new CommandResponseAttachment[jokes.getContent().size()]; - for (int i = 0; i < jokes.getContent().size(); i++) { - Joke joke = jokes.getContent().get(i); - - UriComponents uriComponents = - UriComponentsBuilder.newInstance() + private SlackCommandResponse composeJokeResponse( + Joke joke, MultiValueMap urlParams) { + UriComponents uriComponents = UriComponentsBuilder.newInstance() .scheme("https") .host(baseUrl) .path("/jokes/" + joke.getId()) - .queryParams(urlQueryParams) + .queryParams(urlParams) .build() .encode(); SlackCommandResponseAttachment attachment = new CommandResponseAttachment(); attachment.setFallback(joke.getValue()); attachment.setText(joke.getValue()); - attachment.setTitle("(" + ((page * itemsPerPage + 1) + i) + ")"); + attachment.setTitle("[permalink]"); attachment.setTitleLink(uriComponents.toUriString()); - attachments[i] = attachment; - } - - CommandResponse response = new CommandResponse(); - if (!jokes.isLast()) { - response.setText( - "*Search results: " - + (page * itemsPerPage + 1) - + " - " - + (page * itemsPerPage + jokes.getContent().size()) - + " of " - + jokes.getTotalElements() - + "*. " - + "Type `/chuck ? " - + query - + " --page " - + (page + 1 + 1) - + "` to see more results."); - } else { - response.setText( - "*Search results: " - + (page * itemsPerPage + 1) - + " - " - + (page * 5 + jokes.getNumberOfElements()) - + " of " - + jokes.getTotalElements() - + "*."); - } - - response.setAttachments(attachments); - - return response; - } - - if (!request.getText().isEmpty()) { - if (!slackService.isWhitelistedCategory(request.getText())) { - CommandResponse response = new CommandResponse(); - response.setText( - "Sorry dude ¯\\_(ツ)_/¯ , the given category (\"" - + request.getText() - + "\") is not whitelisted. Type `/chuck -cat` to see available" - + " categories or search by query `/chuck ? {search_term}`"); - response.setResponseType(ResponseType.EPHEMERAL); - - return response; - } - - String[] categories = jokeRepository.findAllCategories(); - String[] whitelistedCategories = slackService.filterNonWhitelistedCategories(categories); - if (!Arrays.stream(whitelistedCategories).anyMatch(request.getText()::equals)) { CommandResponse response = new CommandResponse(); - response.setText( - "Sorry dude ¯\\_(ツ)_/¯ , we've found no jokes for the given category (\"" - + request.getText() - + "\"). Type `/chuck -cat` to see available categories or search by" - + " query `/chuck ? {search_term}`"); - response.setResponseType(ResponseType.EPHEMERAL); + response.setAttachments(new SlackCommandResponseAttachment[] { attachment }); return response; - } - - MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); - urlQueryParams.set("utm_source", "slack"); - urlQueryParams.set("utm_medium", "api"); - urlQueryParams.set("utm_term", request.getTeamDomain()); - urlQueryParams.set("utm_campaign", "random+joke+category"); - - Joke joke = jokeService.randomJokeByCategory(request.getText()); - - return composeJokeResponse(joke, urlQueryParams); } - - return new CommandResponse(); - } - - private SlackCommandResponse composeJokeResponse( - Joke joke, MultiValueMap urlParams) { - UriComponents uriComponents = - UriComponentsBuilder.newInstance() - .scheme("https") - .host(baseUrl) - .path("/jokes/" + joke.getId()) - .queryParams(urlParams) - .build() - .encode(); - - SlackCommandResponseAttachment attachment = new CommandResponseAttachment(); - attachment.setFallback(joke.getValue()); - attachment.setText(joke.getValue()); - attachment.setTitle("[permalink]"); - attachment.setTitleLink(uriComponents.toUriString()); - - CommandResponse response = new CommandResponse(); - response.setAttachments(new SlackCommandResponseAttachment[] {attachment}); - - return response; - } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackService.java b/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackService.java index 8cecc5a..2708822 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackService.java +++ b/chucknorris-web/src/main/java/io/chucknorris/api/slack/SlackService.java @@ -19,79 +19,79 @@ @Service public class SlackService { - @Value("${slack.oauth.client_id}") - private String clientId; - - @Value("${slack.oauth.client_secret}") - private String clientSecret; - - @Value("${slack.oauth.redirect_uri}") - private String redirectUrl; - - @Autowired private RestTemplate restTemplate; - - @Value("${slack.content.whitelisted_categories}") - private String whitelistedCategories; - - /** Composes the authorize uri. */ - public UriComponents composeAuthorizeUri() { - // @see https://api.slack.com/docs/oauth-scopes - MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); - urlQueryParams.set("client_id", clientId); - urlQueryParams.set("redirect_uri", redirectUrl); - urlQueryParams.set("scope", "commands"); - - return UriComponentsBuilder.newInstance() - .scheme("https") - .host("slack.com") - .path("/oauth/v2/authorize/") - .queryParams(urlQueryParams) - .build() - .encode(); - } - - /** Filters all non-whitelisted categories from array. */ - public String[] filterNonWhitelistedCategories(String[] categories) { - return Arrays.stream(categories) - .filter(category -> isWhitelistedCategory(category)) - .toArray(String[]::new); - } - - /** Returns an array of whitelisted categories. */ - public String[] getWhitelistedCategories() { - return whitelistedCategories != null ? whitelistedCategories.split(",") : new String[] {}; - } - - /** Checks if a given category is whitelisted. */ - public Boolean isWhitelistedCategory(String category) { - return Arrays.asList(getWhitelistedCategories()).contains(category); - } - - /** Requests an access token from Slack. */ - public AccessToken requestAccessToken(final String code) { - HttpHeaders headers = new HttpHeaders(); - headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE); - headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.add("client_id", clientId); - map.add("client_secret", clientSecret); - map.add("code", code); - map.add("redirect_uri", redirectUrl); - - try { - ResponseEntity responseEntity = - restTemplate.exchange( - "https://slack.com/api/oauth.v2.access", - HttpMethod.POST, - new HttpEntity<>(map, headers), - AccessToken.class); - - return responseEntity.getBody(); - } catch (RestClientException exception) { - exception.printStackTrace(); - - return new AccessToken(); + @Value("${slack.oauth.client_id}") + private String clientId; + + @Value("${slack.oauth.client_secret}") + private String clientSecret; + + @Value("${slack.oauth.redirect_uri}") + private String redirectUrl; + + @Autowired + private RestTemplate restTemplate; + + @Value("${slack.content.whitelisted_categories}") + private String whitelistedCategories; + + /** Composes the authorize uri. */ + public UriComponents composeAuthorizeUri() { + // @see https://api.slack.com/docs/oauth-scopes + MultiValueMap urlQueryParams = new LinkedMultiValueMap<>(); + urlQueryParams.set("client_id", clientId); + urlQueryParams.set("redirect_uri", redirectUrl); + urlQueryParams.set("scope", "commands"); + + return UriComponentsBuilder.newInstance() + .scheme("https") + .host("slack.com") + .path("/oauth/v2/authorize/") + .queryParams(urlQueryParams) + .build() + .encode(); + } + + /** Filters all non-whitelisted categories from array. */ + public String[] filterNonWhitelistedCategories(String[] categories) { + return Arrays.stream(categories) + .filter(category -> isWhitelistedCategory(category)) + .toArray(String[]::new); + } + + /** Returns an array of whitelisted categories. */ + public String[] getWhitelistedCategories() { + return whitelistedCategories != null ? whitelistedCategories.split(",") : new String[] {}; + } + + /** Checks if a given category is whitelisted. */ + public Boolean isWhitelistedCategory(String category) { + return Arrays.asList(getWhitelistedCategories()).contains(category); + } + + /** Requests an access token from Slack. */ + public AccessToken requestAccessToken(final String code) { + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE); + headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); + + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("client_id", clientId); + map.add("client_secret", clientSecret); + map.add("code", code); + map.add("redirect_uri", redirectUrl); + + try { + ResponseEntity responseEntity = restTemplate.exchange( + "https://slack.com/api/oauth.v2.access", + HttpMethod.POST, + new HttpEntity<>(map, headers), + AccessToken.class); + + return responseEntity.getBody(); + } catch (RestClientException exception) { + exception.printStackTrace(); + + return new AccessToken(); + } } - } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/lib/DateUtil.java b/chucknorris-web/src/main/java/io/chucknorris/lib/DateUtil.java index 6e848f5..6ad92bf 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/lib/DateUtil.java +++ b/chucknorris-web/src/main/java/io/chucknorris/lib/DateUtil.java @@ -6,7 +6,7 @@ @Service public class DateUtil { - public Date now() { - return new Date(); - } + public Date now() { + return new Date(); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/lib/event/BaseEvent.java b/chucknorris-web/src/main/java/io/chucknorris/lib/event/BaseEvent.java index 00ab18c..59397bb 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/lib/event/BaseEvent.java +++ b/chucknorris-web/src/main/java/io/chucknorris/lib/event/BaseEvent.java @@ -6,11 +6,11 @@ @Getter public class BaseEvent implements Event, Serializable { - private String name; - private Object payload; + private String name; + private Object payload; - public BaseEvent(String name, Object payload) { - this.name = name; - this.payload = payload; - } + public BaseEvent(String name, Object payload) { + this.name = name; + this.payload = payload; + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/lib/event/Event.java b/chucknorris-web/src/main/java/io/chucknorris/lib/event/Event.java index e5c4d43..b58d5f6 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/lib/event/Event.java +++ b/chucknorris-web/src/main/java/io/chucknorris/lib/event/Event.java @@ -4,7 +4,7 @@ public interface Event extends Serializable { - String getName(); + String getName(); - Object getPayload(); + Object getPayload(); } diff --git a/chucknorris-web/src/main/java/io/chucknorris/lib/event/EventService.java b/chucknorris-web/src/main/java/io/chucknorris/lib/event/EventService.java index cd9d935..0319356 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/lib/event/EventService.java +++ b/chucknorris-web/src/main/java/io/chucknorris/lib/event/EventService.java @@ -14,45 +14,45 @@ @Service public class EventService { - private static final Logger logger = LoggerFactory.getLogger(EventService.class); - - private AmazonSNSClient snsClient; - - @Value("${application.event.sns_topic_arn}") - private String topicArn; - - public EventService(AmazonSNSClient snsClient) { - this.snsClient = snsClient; - } - - /** - * Publishes an event {@link Event} to an AWS SNS topic specified in - * "application.event.sns_topic_arn" and returns the result {@link PublishResult}. - * - * @param event The event being published {@link Event} - * @return publishResult - * @throws JsonProcessingException Thrown in case of problems encountered when processing JSON - * content that are not pure I/O problems. - */ - public PublishResult publishEvent(Event event) throws JsonProcessingException { - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.setDateFormat(simpleDateFormat); - - String message = objectMapper.writeValueAsString(event); - PublishRequest publishRequest = new PublishRequest(topicArn, message); - - PublishResult publishResult = snsClient.publish(publishRequest); - - logger.info( - "[event_published] " - + "event_message_id: \"" - + publishResult.getMessageId() - + "\" " - + "event_message: \"" - + message - + "\""); - - return publishResult; - } + private static final Logger logger = LoggerFactory.getLogger(EventService.class); + + private AmazonSNSClient snsClient; + + @Value("${application.event.sns_topic_arn}") + private String topicArn; + + public EventService(AmazonSNSClient snsClient) { + this.snsClient = snsClient; + } + + /** + * Publishes an event {@link Event} to an AWS SNS topic specified in + * "application.event.sns_topic_arn" and returns the result {@link PublishResult}. + * + * @param event The event being published {@link Event} + * @return publishResult + * @throws JsonProcessingException Thrown in case of problems encountered when processing JSON + * content that are not pure I/O problems. + */ + public PublishResult publishEvent(Event event) throws JsonProcessingException { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setDateFormat(simpleDateFormat); + + String message = objectMapper.writeValueAsString(event); + PublishRequest publishRequest = new PublishRequest(topicArn, message); + + PublishResult publishResult = snsClient.publish(publishRequest); + + logger.info( + "[event_published] " + + "event_message_id: \"" + + publishResult.getMessageId() + + "\" " + + "event_message: \"" + + message + + "\""); + + return publishResult; + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/lib/exception/EntityNotFoundException.java b/chucknorris-web/src/main/java/io/chucknorris/lib/exception/EntityNotFoundException.java index da9c6ab..5a7fc3e 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/lib/exception/EntityNotFoundException.java +++ b/chucknorris-web/src/main/java/io/chucknorris/lib/exception/EntityNotFoundException.java @@ -6,7 +6,7 @@ @ResponseStatus(value = HttpStatus.NOT_FOUND) public class EntityNotFoundException extends RuntimeException { - public EntityNotFoundException(String message) { - super(message); - } + public EntityNotFoundException(String message) { + super(message); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailchimpService.java b/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailchimpService.java index 08eeb93..9f5d945 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailchimpService.java +++ b/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailchimpService.java @@ -10,39 +10,39 @@ public class MailchimpService { - private String apiKey; - private String baseUrl; - - @Autowired private RestTemplate restTemplate; - - public MailchimpService(String apiKey, String baseUrl) { - this.apiKey = apiKey; - this.baseUrl = baseUrl; - } - - /** - * Fetch mailing list stats by a given list id. - * - * @param listId The list id - * @return list - */ - public MailingListStatistic fetchListStats(final String listId) { - return fetchList(listId).getMailingListStatistic(); - } - - private MailingList fetchList(final String listId) { - HttpHeaders headers = new HttpHeaders(); - headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE); - headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); - headers.add(HttpHeaders.AUTHORIZATION, "apikey " + this.apiKey); - - ResponseEntity responseEntity = - restTemplate.exchange( - baseUrl + "/3.0/lists/" + listId, - HttpMethod.GET, - new HttpEntity<>(null, headers), - MailingList.class); - - return responseEntity.getBody(); - } + private String apiKey; + private String baseUrl; + + @Autowired + private RestTemplate restTemplate; + + public MailchimpService(String apiKey, String baseUrl) { + this.apiKey = apiKey; + this.baseUrl = baseUrl; + } + + /** + * Fetch mailing list stats by a given list id. + * + * @param listId The list id + * @return list + */ + public MailingListStatistic fetchListStats(final String listId) { + return fetchList(listId).getMailingListStatistic(); + } + + private MailingList fetchList(final String listId) { + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE); + headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); + headers.add(HttpHeaders.AUTHORIZATION, "apikey " + this.apiKey); + + ResponseEntity responseEntity = restTemplate.exchange( + baseUrl + "/3.0/lists/" + listId, + HttpMethod.GET, + new HttpEntity<>(null, headers), + MailingList.class); + + return responseEntity.getBody(); + } } diff --git a/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailingList.java b/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailingList.java index 726a95e..adc290f 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailingList.java +++ b/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailingList.java @@ -7,12 +7,12 @@ @Data public class MailingList implements Serializable { - @JsonProperty("id") - private String id; + @JsonProperty("id") + private String id; - @JsonProperty("stats") - private MailingListStatistic mailingListStatistic; + @JsonProperty("stats") + private MailingListStatistic mailingListStatistic; - @JsonProperty("name") - private String name; + @JsonProperty("name") + private String name; } diff --git a/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailingListStatistic.java b/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailingListStatistic.java index fc108c6..56e54bc 100644 --- a/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailingListStatistic.java +++ b/chucknorris-web/src/main/java/io/chucknorris/lib/mailchimp/MailingListStatistic.java @@ -10,51 +10,51 @@ @Data public class MailingListStatistic implements Serializable { - @JsonProperty("member_count") - private AtomicInteger memberCount; + @JsonProperty("member_count") + private AtomicInteger memberCount; - @JsonProperty("unsubscribe_count") - private AtomicInteger unsubscribeCount; + @JsonProperty("unsubscribe_count") + private AtomicInteger unsubscribeCount; - @JsonProperty("cleaned_count") - private AtomicInteger cleanedCount; + @JsonProperty("cleaned_count") + private AtomicInteger cleanedCount; - @JsonProperty("member_count_since_send") - private AtomicInteger memberCountSinceSend; + @JsonProperty("member_count_since_send") + private AtomicInteger memberCountSinceSend; - @JsonProperty("unsubscribe_count_since_send") - private AtomicInteger unsubscribeCountSinceSend; + @JsonProperty("unsubscribe_count_since_send") + private AtomicInteger unsubscribeCountSinceSend; - @JsonProperty("cleaned_count_since_send") - private AtomicInteger cleanedCountSinceSend; + @JsonProperty("cleaned_count_since_send") + private AtomicInteger cleanedCountSinceSend; - @JsonProperty("campaign_count") - private AtomicInteger campaignCount; + @JsonProperty("campaign_count") + private AtomicInteger campaignCount; - @JsonProperty("campaign_last_sent") - private Date campaignLastSent; + @JsonProperty("campaign_last_sent") + private Date campaignLastSent; - @JsonProperty("merge_field_count") - private AtomicInteger mergeFieldCount; + @JsonProperty("merge_field_count") + private AtomicInteger mergeFieldCount; - @JsonProperty("avg_sub_rate") - private AtomicInteger avgSubRate; + @JsonProperty("avg_sub_rate") + private AtomicInteger avgSubRate; - @JsonProperty("avg_unsub_rate") - private AtomicInteger avgUnsubRate; + @JsonProperty("avg_unsub_rate") + private AtomicInteger avgUnsubRate; - @JsonProperty("target_sub_rate") - private AtomicInteger targetSubRate; + @JsonProperty("target_sub_rate") + private AtomicInteger targetSubRate; - @JsonProperty("openRate") - private AtomicDouble openRate; + @JsonProperty("openRate") + private AtomicDouble openRate; - @JsonProperty("click_rate") - private AtomicDouble clickRate; + @JsonProperty("click_rate") + private AtomicDouble clickRate; - @JsonProperty("last_sub_date") - private Date lastDubDate; + @JsonProperty("last_sub_date") + private Date lastDubDate; - @JsonProperty("last_unsub_date") - private Date lastUnsubDate; + @JsonProperty("last_unsub_date") + private Date lastUnsubDate; } diff --git a/chucknorris-web/src/test/java/io/chucknorris/api/configuration/HerokuDataSourcePropertiesTest.java b/chucknorris-web/src/test/java/io/chucknorris/api/configuration/HerokuDataSourcePropertiesTest.java index 42ce91d..5410b2c 100644 --- a/chucknorris-web/src/test/java/io/chucknorris/api/configuration/HerokuDataSourcePropertiesTest.java +++ b/chucknorris-web/src/test/java/io/chucknorris/api/configuration/HerokuDataSourcePropertiesTest.java @@ -6,24 +6,23 @@ public class HerokuDataSourcePropertiesTest { - @Test - public void testShouldCreateDataSourcePostgres() { - // given: - String driverClassName = "org.postgresql.Driver"; + @Test + public void testShouldCreateDataSourcePostgres() { + // given: + String driverClassName = "org.postgresql.Driver"; - // and: - String uri = - "postgres://username:password@ec2-00-000-00-000.eu-west-1.compute.amazonaws.com:5432/d409qm4ujtafvk"; + // and: + String uri = "postgres://username:password@ec2-00-000-00-000.eu-west-1.compute.amazonaws.com:5432/d409qm4ujtafvk"; - // when: - HerokuDataSourceProperties actual = new HerokuDataSourceProperties(driverClassName, uri); + // when: + HerokuDataSourceProperties actual = new HerokuDataSourceProperties(driverClassName, uri); - // then: - assertEquals("org.postgresql.Driver", actual.getDriverClassName()); - assertEquals("password", actual.getPassword()); - assertEquals( - "jdbc:postgresql://ec2-00-000-00-000.eu-west-1.compute.amazonaws.com:5432/d409qm4ujtafvk", - actual.getUrl()); - assertEquals("username", actual.getUsername()); - } + // then: + assertEquals("org.postgresql.Driver", actual.getDriverClassName()); + assertEquals("password", actual.getPassword()); + assertEquals( + "jdbc:postgresql://ec2-00-000-00-000.eu-west-1.compute.amazonaws.com:5432/d409qm4ujtafvk", + actual.getUrl()); + assertEquals("username", actual.getUsername()); + } } diff --git a/chucknorris-web/src/test/java/io/chucknorris/api/feed/FeedControllerTest.java b/chucknorris-web/src/test/java/io/chucknorris/api/feed/FeedControllerTest.java index e5cb774..dafae51 100644 --- a/chucknorris-web/src/test/java/io/chucknorris/api/feed/FeedControllerTest.java +++ b/chucknorris-web/src/test/java/io/chucknorris/api/feed/FeedControllerTest.java @@ -30,52 +30,58 @@ @RunWith(MockitoJUnitRunner.class) public class FeedControllerTest { - private DailyChuck dailyChuck; + private DailyChuck dailyChuck; - private DailyChuckIssue dailyChuckIssue; + private DailyChuckIssue dailyChuckIssue; - @Mock private DailyChuckService dailyChuckService; + @Mock + private DailyChuckService dailyChuckService; - @Mock private DateUtil dateUtil; + @Mock + private DateUtil dateUtil; - private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); + private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); - @Mock private EventService eventService; + @Mock + private EventService eventService; - @InjectMocks private FeedController feedController; + @InjectMocks + private FeedController feedController; - @Mock private JokeRepository jokeRepository; + @Mock + private JokeRepository jokeRepository; - @Mock private MailchimpService mailchimpService; + @Mock + private MailchimpService mailchimpService; - private MailingListStatistic mailingListStatistic; + private MailingListStatistic mailingListStatistic; - private String mailingListId; + private String mailingListId; - @Before - public void setUp() throws ParseException { - dailyChuckIssue = new DailyChuckIssue(); - dailyChuckIssue.setDate(dateFormat.parse("2019-01-01")); - dailyChuckIssue.setJokeId("c5k7tulvqjs76evwb3brfg"); + @Before + public void setUp() throws ParseException { + dailyChuckIssue = new DailyChuckIssue(); + dailyChuckIssue.setDate(dateFormat.parse("2019-01-01")); + dailyChuckIssue.setJokeId("c5k7tulvqjs76evwb3brfg"); - dailyChuck = new DailyChuck(); - dailyChuck.setIssues(new DailyChuckIssue[] {dailyChuckIssue}); - dailyChuck.setIssueNumber(Long.valueOf(1)); + dailyChuck = new DailyChuck(); + dailyChuck.setIssues(new DailyChuckIssue[] { dailyChuckIssue }); + dailyChuck.setIssueNumber(Long.valueOf(1)); - ReflectionTestUtils.setField(feedController, "dailyChuckListId", "xxxxxxxxxx"); + ReflectionTestUtils.setField(feedController, "dailyChuckListId", "xxxxxxxxxx"); - mailingListId = "xxxxxxxxxx"; - mailingListStatistic = new MailingListStatistic(); - mailingListStatistic.setMemberCount(new AtomicInteger(228)); - mailingListStatistic.setUnsubscribeCount(new AtomicInteger(122)); - mailingListStatistic.setCleanedCount(new AtomicInteger(48)); - mailingListStatistic.setCampaignCount(new AtomicInteger(465)); - mailingListStatistic.setAvgSubRate(new AtomicInteger(23)); - mailingListStatistic.setAvgUnsubRate(new AtomicInteger(7)); - mailingListStatistic.setClickRate(new AtomicDouble(0.30748722)); + mailingListId = "xxxxxxxxxx"; + mailingListStatistic = new MailingListStatistic(); + mailingListStatistic.setMemberCount(new AtomicInteger(228)); + mailingListStatistic.setUnsubscribeCount(new AtomicInteger(122)); + mailingListStatistic.setCleanedCount(new AtomicInteger(48)); + mailingListStatistic.setCampaignCount(new AtomicInteger(465)); + mailingListStatistic.setAvgSubRate(new AtomicInteger(23)); + mailingListStatistic.setAvgUnsubRate(new AtomicInteger(7)); + mailingListStatistic.setClickRate(new AtomicDouble(0.30748722)); - when(mailchimpService.fetchListStats(mailingListId)).thenReturn(mailingListStatistic); - } + when(mailchimpService.fetchListStats(mailingListId)).thenReturn(mailingListStatistic); + } @Test public void testDailyChuckJsonReturnsDailyChuckWithoutComposingANewIssueIfItHasAlreadyBeenIssued() @@ -95,88 +101,88 @@ public void testDailyChuckJsonReturnsDailyChuckWithoutComposingANewIssueIfItHasA verifyNoMoreInteractions(eventService); } - @Test - public void testDailyChuckJsonReturnsDailyChuckWithComposingANewIssue() - throws IOException, ParseException { - DailyChuckIssue newDailyChuckIssue = new DailyChuckIssue(); + @Test + public void testDailyChuckJsonReturnsDailyChuckWithComposingANewIssue() + throws IOException, ParseException { + DailyChuckIssue newDailyChuckIssue = new DailyChuckIssue(); - when(dailyChuckService.getDailyChuck()).thenReturn(dailyChuck); - when(dateUtil.now()).thenReturn(dateFormat.parse("2019-01-02")); - when(dailyChuckService.composeDailyChuckIssue(any())).thenReturn(newDailyChuckIssue); + when(dailyChuckService.getDailyChuck()).thenReturn(dailyChuck); + when(dateUtil.now()).thenReturn(dateFormat.parse("2019-01-02")); + when(dailyChuckService.composeDailyChuckIssue(any())).thenReturn(newDailyChuckIssue); - assertEquals(dailyChuck, feedController.dailyChuckJson()); + assertEquals(dailyChuck, feedController.dailyChuckJson()); - verify(dailyChuckService, times(1)).getDailyChuck(); - verify(dailyChuckService, times(1)).composeDailyChuckIssue(any()); - verify(dailyChuckService, times(1)).persist(dailyChuck); - verifyNoMoreInteractions(dailyChuckService); + verify(dailyChuckService, times(1)).getDailyChuck(); + verify(dailyChuckService, times(1)).composeDailyChuckIssue(any()); + verify(dailyChuckService, times(1)).persist(dailyChuck); + verifyNoMoreInteractions(dailyChuckService); - verify(dateUtil, times(1)).now(); - verifyNoMoreInteractions(dateUtil); + verify(dateUtil, times(1)).now(); + verifyNoMoreInteractions(dateUtil); - verify(eventService, times(1)).publishEvent(any()); - verifyNoMoreInteractions(eventService); - } + verify(eventService, times(1)).publishEvent(any()); + verifyNoMoreInteractions(eventService); + } - @Test - public void testDailyChuckRssReturnsDailyChuckWithoutComposingANewIssueIfItHasAlreadyBeenIssued() - throws IOException, ParseException { - DailyChuckRss dailyChuckRss = new DailyChuckRss("", dailyChuck, jokeRepository); + @Test + public void testDailyChuckRssReturnsDailyChuckWithoutComposingANewIssueIfItHasAlreadyBeenIssued() + throws IOException, ParseException { + DailyChuckRss dailyChuckRss = new DailyChuckRss("", dailyChuck, jokeRepository); - when(dailyChuckService.getDailyChuck()).thenReturn(dailyChuck); - when(dateUtil.now()).thenReturn(dateFormat.parse("2019-01-01")); - when(dailyChuckService.toRss(dailyChuck)).thenReturn(dailyChuckRss); + when(dailyChuckService.getDailyChuck()).thenReturn(dailyChuck); + when(dateUtil.now()).thenReturn(dateFormat.parse("2019-01-01")); + when(dailyChuckService.toRss(dailyChuck)).thenReturn(dailyChuckRss); - assertEquals(dailyChuckRss, feedController.dailyChuckRss()); + assertEquals(dailyChuckRss, feedController.dailyChuckRss()); - verify(dailyChuckService, times(1)).getDailyChuck(); - verify(dailyChuckService, times(1)).toRss(dailyChuck); + verify(dailyChuckService, times(1)).getDailyChuck(); + verify(dailyChuckService, times(1)).toRss(dailyChuck); - verify(dateUtil, times(1)).now(); - verifyNoMoreInteractions(dateUtil); + verify(dateUtil, times(1)).now(); + verifyNoMoreInteractions(dateUtil); - verify(eventService, times(0)).publishEvent(any()); - verifyNoMoreInteractions(eventService); + verify(eventService, times(0)).publishEvent(any()); + verifyNoMoreInteractions(eventService); - verify(mailchimpService, times(1)).fetchListStats(mailingListId); - verifyNoMoreInteractions(mailchimpService); - } + verify(mailchimpService, times(1)).fetchListStats(mailingListId); + verifyNoMoreInteractions(mailchimpService); + } - @Test - public void testDailyChuckRssReturnsDailyChuckWithComposingANewIssue() - throws IOException, ParseException { - DailyChuckRss dailyChuckRss = new DailyChuckRss("", dailyChuck, jokeRepository); - DailyChuckIssue newDailyChuckIssue = new DailyChuckIssue(); + @Test + public void testDailyChuckRssReturnsDailyChuckWithComposingANewIssue() + throws IOException, ParseException { + DailyChuckRss dailyChuckRss = new DailyChuckRss("", dailyChuck, jokeRepository); + DailyChuckIssue newDailyChuckIssue = new DailyChuckIssue(); - when(dailyChuckService.getDailyChuck()).thenReturn(dailyChuck); - when(dateUtil.now()).thenReturn(dateFormat.parse("2019-01-02")); - when(dailyChuckService.composeDailyChuckIssue(any())).thenReturn(newDailyChuckIssue); - when(dailyChuckService.toRss(dailyChuck)).thenReturn(dailyChuckRss); + when(dailyChuckService.getDailyChuck()).thenReturn(dailyChuck); + when(dateUtil.now()).thenReturn(dateFormat.parse("2019-01-02")); + when(dailyChuckService.composeDailyChuckIssue(any())).thenReturn(newDailyChuckIssue); + when(dailyChuckService.toRss(dailyChuck)).thenReturn(dailyChuckRss); - assertEquals(dailyChuckRss, feedController.dailyChuckRss()); + assertEquals(dailyChuckRss, feedController.dailyChuckRss()); - verify(dailyChuckService, times(1)).getDailyChuck(); - verify(dailyChuckService, times(1)).composeDailyChuckIssue(any()); - verify(dailyChuckService, times(1)).persist(dailyChuck); - verify(dailyChuckService, times(1)).toRss(dailyChuck); - verifyNoMoreInteractions(dailyChuckService); + verify(dailyChuckService, times(1)).getDailyChuck(); + verify(dailyChuckService, times(1)).composeDailyChuckIssue(any()); + verify(dailyChuckService, times(1)).persist(dailyChuck); + verify(dailyChuckService, times(1)).toRss(dailyChuck); + verifyNoMoreInteractions(dailyChuckService); - verify(dateUtil, times(1)).now(); - verifyNoMoreInteractions(dateUtil); + verify(dateUtil, times(1)).now(); + verifyNoMoreInteractions(dateUtil); - verify(eventService, times(1)).publishEvent(any()); - verifyNoMoreInteractions(eventService); + verify(eventService, times(1)).publishEvent(any()); + verifyNoMoreInteractions(eventService); - verify(mailchimpService, times(1)).fetchListStats(mailingListId); - verifyNoMoreInteractions(mailchimpService); - } + verify(mailchimpService, times(1)).fetchListStats(mailingListId); + verifyNoMoreInteractions(mailchimpService); + } - @Test - public void testDailyChuckStatsReturnsStats() { - MailingListStatistic response = feedController.dailyChuckStats(); - assertEquals(response, mailingListStatistic); + @Test + public void testDailyChuckStatsReturnsStats() { + MailingListStatistic response = feedController.dailyChuckStats(); + assertEquals(response, mailingListStatistic); - verify(mailchimpService, times(1)).fetchListStats(mailingListId); - verifyNoMoreInteractions(mailchimpService); - } + verify(mailchimpService, times(1)).fetchListStats(mailingListId); + verifyNoMoreInteractions(mailchimpService); + } } diff --git a/chucknorris-web/src/test/java/io/chucknorris/api/feed/dailychuck/DailyChuckRssTest.java b/chucknorris-web/src/test/java/io/chucknorris/api/feed/dailychuck/DailyChuckRssTest.java index f547b6e..eeff208 100644 --- a/chucknorris-web/src/test/java/io/chucknorris/api/feed/dailychuck/DailyChuckRssTest.java +++ b/chucknorris-web/src/test/java/io/chucknorris/api/feed/dailychuck/DailyChuckRssTest.java @@ -1 +1,2 @@ -public class DailyChuckRssTest {} +public class DailyChuckRssTest { +} diff --git a/chucknorris-web/src/test/java/io/chucknorris/api/feed/dailychuck/DailyChuckTest.java b/chucknorris-web/src/test/java/io/chucknorris/api/feed/dailychuck/DailyChuckTest.java index 758222c..fd64f3b 100644 --- a/chucknorris-web/src/test/java/io/chucknorris/api/feed/dailychuck/DailyChuckTest.java +++ b/chucknorris-web/src/test/java/io/chucknorris/api/feed/dailychuck/DailyChuckTest.java @@ -11,37 +11,37 @@ public class DailyChuckTest { - private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); - private DailyChuck dailyChuck; - private DailyChuckIssue dailyChuckIssue; - - @Before - public void setUp() throws ParseException { - dailyChuckIssue = new DailyChuckIssue(); - dailyChuckIssue.setDate(dateFormat.parse("2019-01-01")); - dailyChuckIssue.setJokeId("c5k7tulvqjs76evwb3brfg"); - - dailyChuck = new DailyChuck(); - dailyChuck.setIssues(new DailyChuckIssue[] {dailyChuckIssue}); - } - - @Test - public void testFindIssueByJokeIdReturnsNullDoesNotExist() { - assertEquals(dailyChuck.findIssueByJokeId("does-not-exist"), null); - } - - @Test - public void testFindIssueByJokeIdReturnsDailyChuckIssueIfDoesExist() { - assertEquals(dailyChuck.findIssueByJokeId("c5k7tulvqjs76evwb3brfg"), dailyChuckIssue); - } - - @Test - public void testFindIssueByDateReturnsNullDoesNotExist() throws ParseException { - assertEquals(dailyChuck.findIssueByDate(dateFormat.parse("2019-01-02")), null); - } - - @Test - public void testFindIssueByDateDailyChuckIssueIfDoesExist() throws ParseException { - assertEquals(dailyChuck.findIssueByDate(dateFormat.parse("2019-01-01")), dailyChuckIssue); - } + private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); + private DailyChuck dailyChuck; + private DailyChuckIssue dailyChuckIssue; + + @Before + public void setUp() throws ParseException { + dailyChuckIssue = new DailyChuckIssue(); + dailyChuckIssue.setDate(dateFormat.parse("2019-01-01")); + dailyChuckIssue.setJokeId("c5k7tulvqjs76evwb3brfg"); + + dailyChuck = new DailyChuck(); + dailyChuck.setIssues(new DailyChuckIssue[] { dailyChuckIssue }); + } + + @Test + public void testFindIssueByJokeIdReturnsNullDoesNotExist() { + assertEquals(dailyChuck.findIssueByJokeId("does-not-exist"), null); + } + + @Test + public void testFindIssueByJokeIdReturnsDailyChuckIssueIfDoesExist() { + assertEquals(dailyChuck.findIssueByJokeId("c5k7tulvqjs76evwb3brfg"), dailyChuckIssue); + } + + @Test + public void testFindIssueByDateReturnsNullDoesNotExist() throws ParseException { + assertEquals(dailyChuck.findIssueByDate(dateFormat.parse("2019-01-02")), null); + } + + @Test + public void testFindIssueByDateDailyChuckIssueIfDoesExist() throws ParseException { + assertEquals(dailyChuck.findIssueByDate(dateFormat.parse("2019-01-01")), dailyChuckIssue); + } } diff --git a/chucknorris-web/src/test/java/io/chucknorris/api/joke/JokeControllerTest.java b/chucknorris-web/src/test/java/io/chucknorris/api/joke/JokeControllerTest.java index 58fea09..2de99b1 100644 --- a/chucknorris-web/src/test/java/io/chucknorris/api/joke/JokeControllerTest.java +++ b/chucknorris-web/src/test/java/io/chucknorris/api/joke/JokeControllerTest.java @@ -21,21 +21,24 @@ @RunWith(MockitoJUnitRunner.class) public class JokeControllerTest { - private static String jokeId, jokeValue; - private static Joke joke; + private static String jokeId, jokeValue; + private static Joke joke; - @InjectMocks private JokeController jokeController; + @InjectMocks + private JokeController jokeController; - @Mock private JokeRepository jokeRepository; + @Mock + private JokeRepository jokeRepository; - @Mock private MockHttpServletResponse httpServletResponse; + @Mock + private MockHttpServletResponse httpServletResponse; - @Before - public void setUp() { - jokeId = "ys--0t_-rrifz5jtcparbg"; - jokeValue = "Some people ask for a Kleenex when they sneeze, Chuck Norris asks for a body bag."; - joke = Joke.builder().categories(new String[] {"dev"}).id(jokeId).value(jokeValue).build(); - } + @Before + public void setUp() { + jokeId = "ys--0t_-rrifz5jtcparbg"; + jokeValue = "Some people ask for a Kleenex when they sneeze, Chuck Norris asks for a body bag."; + joke = Joke.builder().categories(new String[] { "dev" }).id(jokeId).value(jokeValue).build(); + } @Test public void testGetCategories() { @@ -179,51 +182,51 @@ public void testGetRandomJokeReturnsJokeByMultipleCategoriesThrowsException() { verifyNoMoreInteractions(jokeRepository); } - @Test - public void testGetRandomPersonalisedJokeReturnsJoke() { - joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); - when(jokeRepository.getRandomPersonalizedJoke("Bob")).thenReturn(joke); + @Test + public void testGetRandomPersonalisedJokeReturnsJoke() { + joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); + when(jokeRepository.getRandomPersonalizedJoke("Bob")).thenReturn(joke); - Joke joke = jokeController.getRandomJoke(null, "Bob"); - assertEquals(JokeControllerTest.joke, joke); + Joke joke = jokeController.getRandomJoke(null, "Bob"); + assertEquals(JokeControllerTest.joke, joke); - verify(jokeRepository, times(1)).getRandomPersonalizedJoke("Bob"); - verifyNoMoreInteractions(jokeRepository); - } + verify(jokeRepository, times(1)).getRandomPersonalizedJoke("Bob"); + verifyNoMoreInteractions(jokeRepository); + } - @Test - public void testGetRandomPersonalisedJokeByCategoryReturnsJoke() { - joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); - when(jokeRepository.findAllCategories()).thenReturn(new String[] {"dev"}); - when(jokeRepository.getRandomPersonalizedJokeByCategories("Bob", "dev")).thenReturn(joke); + @Test + public void testGetRandomPersonalisedJokeByCategoryReturnsJoke() { + joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); + when(jokeRepository.findAllCategories()).thenReturn(new String[] { "dev" }); + when(jokeRepository.getRandomPersonalizedJokeByCategories("Bob", "dev")).thenReturn(joke); - Joke joke = jokeController.getRandomJoke("dev", "Bob"); - assertEquals(JokeControllerTest.joke, joke); + Joke joke = jokeController.getRandomJoke("dev", "Bob"); + assertEquals(JokeControllerTest.joke, joke); - verify(jokeRepository, times(1)).findAllCategories(); - verify(jokeRepository, times(1)).getRandomPersonalizedJokeByCategories("Bob", "dev"); - verifyNoMoreInteractions(jokeRepository); - } + verify(jokeRepository, times(1)).findAllCategories(); + verify(jokeRepository, times(1)).getRandomPersonalizedJokeByCategories("Bob", "dev"); + verifyNoMoreInteractions(jokeRepository); + } - @Test(expected = EntityNotFoundException.class) - public void testGetRandomPersonalisedJokeByCategoryThrowsException() { - joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); - when(jokeRepository.findAllCategories()).thenReturn(new String[] {"dev"}); - when(jokeRepository.getRandomPersonalizedJokeByCategories("Bob", "dev")).thenReturn(null); + @Test(expected = EntityNotFoundException.class) + public void testGetRandomPersonalisedJokeByCategoryThrowsException() { + joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); + when(jokeRepository.findAllCategories()).thenReturn(new String[] { "dev" }); + when(jokeRepository.getRandomPersonalizedJokeByCategories("Bob", "dev")).thenReturn(null); - jokeController.getRandomJoke("dev", "Bob"); - } + jokeController.getRandomJoke("dev", "Bob"); + } - @Test(expected = EntityNotFoundException.class) - public void testGetRandomPersonalisedJokeThrowsException() { - joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); - when(jokeRepository.getRandomPersonalizedJoke("Bob")).thenReturn(null); + @Test(expected = EntityNotFoundException.class) + public void testGetRandomPersonalisedJokeThrowsException() { + joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); + when(jokeRepository.getRandomPersonalizedJoke("Bob")).thenReturn(null); - jokeController.getRandomJoke(null, "Bob"); + jokeController.getRandomJoke(null, "Bob"); - verify(jokeRepository, times(1)).getRandomPersonalizedJoke("Bob"); - verifyNoMoreInteractions(jokeRepository); - } + verify(jokeRepository, times(1)).getRandomPersonalizedJoke("Bob"); + verifyNoMoreInteractions(jokeRepository); + } @Test public void testGetRandomJokeReturnsJokeValue() { @@ -276,59 +279,59 @@ public void testGetRandomJokeValueReturnsEmptyStringIfCategoryDoesNotExist() { verifyNoMoreInteractions(jokeRepository); } - @Test - public void testGetRandomPersonalisedJokeValueReturnsJokeValue() { - joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); - when(jokeRepository.getRandomPersonalizedJoke("Bob")).thenReturn(joke); - - String jokeValue = jokeController.getRandomJokeValue(null, "Bob", this.httpServletResponse); - assertEquals(joke.getValue(), jokeValue); - - verify(jokeRepository, times(1)).getRandomPersonalizedJoke("Bob"); - verifyNoMoreInteractions(jokeRepository); - } - - @Test - public void testGetRandomPersonalisedJokeValueEmptyStringIfNoJokeWasFound() { - joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); - when(jokeRepository.getRandomPersonalizedJoke("Bob")).thenReturn(null); - - String jokeValue = jokeController.getRandomJokeValue(null, "Bob", this.httpServletResponse); - assertEquals("", jokeValue); - - verify(jokeRepository, times(1)).getRandomPersonalizedJoke("Bob"); - verify(this.httpServletResponse).setStatus(404); - verifyNoMoreInteractions(jokeRepository); - } - - @Test - public void testGetRandomPersonalisedJokeValueByCategoryReturnsJokeValue() { - joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); - when(jokeRepository.findAllCategories()).thenReturn(new String[] {"dev"}); - when(jokeRepository.getRandomPersonalizedJokeByCategories("Bob", "dev")).thenReturn(joke); - - String jokeValue = jokeController.getRandomJokeValue("dev", "Bob", this.httpServletResponse); - assertEquals(joke.getValue(), jokeValue); - - verify(jokeRepository, times(1)).findAllCategories(); - verify(jokeRepository, times(1)).getRandomPersonalizedJokeByCategories("Bob", "dev"); - verifyNoMoreInteractions(jokeRepository); - } - - @Test - public void testGetRandomPersonalisedJokeValueByCategoryEmptyStringIfNoJokeWasFound() { - joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); - when(jokeRepository.findAllCategories()).thenReturn(new String[] {"dev"}); - when(jokeRepository.getRandomPersonalizedJokeByCategories("Bob", "dev")).thenReturn(null); - - String jokeValue = jokeController.getRandomJokeValue("dev", "Bob", this.httpServletResponse); - assertEquals("", jokeValue); - - verify(jokeRepository, times(1)).findAllCategories(); - verify(jokeRepository, times(1)).getRandomPersonalizedJokeByCategories("Bob", "dev"); - verify(this.httpServletResponse).setStatus(404); - verifyNoMoreInteractions(jokeRepository); - } + @Test + public void testGetRandomPersonalisedJokeValueReturnsJokeValue() { + joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); + when(jokeRepository.getRandomPersonalizedJoke("Bob")).thenReturn(joke); + + String jokeValue = jokeController.getRandomJokeValue(null, "Bob", this.httpServletResponse); + assertEquals(joke.getValue(), jokeValue); + + verify(jokeRepository, times(1)).getRandomPersonalizedJoke("Bob"); + verifyNoMoreInteractions(jokeRepository); + } + + @Test + public void testGetRandomPersonalisedJokeValueEmptyStringIfNoJokeWasFound() { + joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); + when(jokeRepository.getRandomPersonalizedJoke("Bob")).thenReturn(null); + + String jokeValue = jokeController.getRandomJokeValue(null, "Bob", this.httpServletResponse); + assertEquals("", jokeValue); + + verify(jokeRepository, times(1)).getRandomPersonalizedJoke("Bob"); + verify(this.httpServletResponse).setStatus(404); + verifyNoMoreInteractions(jokeRepository); + } + + @Test + public void testGetRandomPersonalisedJokeValueByCategoryReturnsJokeValue() { + joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); + when(jokeRepository.findAllCategories()).thenReturn(new String[] { "dev" }); + when(jokeRepository.getRandomPersonalizedJokeByCategories("Bob", "dev")).thenReturn(joke); + + String jokeValue = jokeController.getRandomJokeValue("dev", "Bob", this.httpServletResponse); + assertEquals(joke.getValue(), jokeValue); + + verify(jokeRepository, times(1)).findAllCategories(); + verify(jokeRepository, times(1)).getRandomPersonalizedJokeByCategories("Bob", "dev"); + verifyNoMoreInteractions(jokeRepository); + } + + @Test + public void testGetRandomPersonalisedJokeValueByCategoryEmptyStringIfNoJokeWasFound() { + joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); + when(jokeRepository.findAllCategories()).thenReturn(new String[] { "dev" }); + when(jokeRepository.getRandomPersonalizedJokeByCategories("Bob", "dev")).thenReturn(null); + + String jokeValue = jokeController.getRandomJokeValue("dev", "Bob", this.httpServletResponse); + assertEquals("", jokeValue); + + verify(jokeRepository, times(1)).findAllCategories(); + verify(jokeRepository, times(1)).getRandomPersonalizedJokeByCategories("Bob", "dev"); + verify(this.httpServletResponse).setStatus(404); + verifyNoMoreInteractions(jokeRepository); + } @Test public void testSearch() { diff --git a/chucknorris-web/src/test/java/io/chucknorris/api/joke/JokeServiceTest.java b/chucknorris-web/src/test/java/io/chucknorris/api/joke/JokeServiceTest.java index baf5080..da3e89e 100644 --- a/chucknorris-web/src/test/java/io/chucknorris/api/joke/JokeServiceTest.java +++ b/chucknorris-web/src/test/java/io/chucknorris/api/joke/JokeServiceTest.java @@ -19,19 +19,21 @@ @RunWith(MockitoJUnitRunner.class) public class JokeServiceTest { - private static String jokeId, jokeValue; - private static Joke joke; + private static String jokeId, jokeValue; + private static Joke joke; - @Mock private JokeRepository jokeRepository; + @Mock + private JokeRepository jokeRepository; - @InjectMocks private JokeService jokeService; + @InjectMocks + private JokeService jokeService; - @Before - public void setUp() throws Exception { - jokeId = "ys--0t_-rrifz5jtcparbg"; - jokeValue = "Some people ask for a Kleenex when they sneeze, Chuck Norris asks for a body bag."; - joke = Joke.builder().categories(new String[] {"dev"}).id(jokeId).value(jokeValue).build(); - } + @Before + public void setUp() throws Exception { + jokeId = "ys--0t_-rrifz5jtcparbg"; + jokeValue = "Some people ask for a Kleenex when they sneeze, Chuck Norris asks for a body bag."; + joke = Joke.builder().categories(new String[] { "dev" }).id(jokeId).value(jokeValue).build(); + } @Test public void testRandomJokeByCategoriesReturnsJoke() { @@ -44,34 +46,34 @@ public void testRandomJokeByCategoriesReturnsJoke() { verifyNoMoreInteractions(jokeRepository); } - @Test - public void testRandomPersonalizedJokeByCategoriesReturnsJoke() { - String substitute = "Bob"; - String[] categories = new String[] {"dev", "movie"}; + @Test + public void testRandomPersonalizedJokeByCategoriesReturnsJoke() { + String substitute = "Bob"; + String[] categories = new String[] { "dev", "movie" }; - joke.setValue(joke.getValue().replace("Chuck Norris", substitute)); - when(jokeRepository.getRandomPersonalizedJokeByCategories(substitute, "dev,movie")) - .thenReturn(joke); + joke.setValue(joke.getValue().replace("Chuck Norris", substitute)); + when(jokeRepository.getRandomPersonalizedJokeByCategories(substitute, "dev,movie")) + .thenReturn(joke); - Joke joke = jokeService.randomPersonalizedJokeByCategories(substitute, categories); - assertEquals(JokeServiceTest.joke, joke); + Joke joke = jokeService.randomPersonalizedJokeByCategories(substitute, categories); + assertEquals(JokeServiceTest.joke, joke); - verify(jokeRepository, times(1)).getRandomPersonalizedJokeByCategories(substitute, "dev,movie"); - verifyNoMoreInteractions(jokeRepository); - } + verify(jokeRepository, times(1)).getRandomPersonalizedJokeByCategories(substitute, "dev,movie"); + verifyNoMoreInteractions(jokeRepository); + } - @Test - public void testSearchWithCategoryFilter() { - String query = "Kleenex"; - String[] categories = new String[] {"dev", "movie"}; - Pageable pageable = PageRequest.of(1, 5); + @Test + public void testSearchWithCategoryFilter() { + String query = "Kleenex"; + String[] categories = new String[] { "dev", "movie" }; + Pageable pageable = PageRequest.of(1, 5); - when(jokeRepository.findByValueContainsAndFilter(query, "dev,movie", pageable)) - .thenReturn(Page.empty()); + when(jokeRepository.findByValueContainsAndFilter(query, "dev,movie", pageable)) + .thenReturn(Page.empty()); - jokeService.searchWithCategoryFilter(query, categories, pageable); + jokeService.searchWithCategoryFilter(query, categories, pageable); - verify(jokeRepository, times(1)).findByValueContainsAndFilter(query, "dev,movie", pageable); - verifyNoMoreInteractions(jokeRepository); - } + verify(jokeRepository, times(1)).findByValueContainsAndFilter(query, "dev,movie", pageable); + verifyNoMoreInteractions(jokeRepository); + } } diff --git a/chucknorris-web/src/test/java/io/chucknorris/api/slack/SlackControllerTest.java b/chucknorris-web/src/test/java/io/chucknorris/api/slack/SlackControllerTest.java index d0669be..99bda28 100644 --- a/chucknorris-web/src/test/java/io/chucknorris/api/slack/SlackControllerTest.java +++ b/chucknorris-web/src/test/java/io/chucknorris/api/slack/SlackControllerTest.java @@ -29,164 +29,168 @@ @RunWith(MockitoJUnitRunner.class) public class SlackControllerTest { - private static String iconUrl, jokeId, jokeValue; - private static Joke joke; + private static String iconUrl, jokeId, jokeValue; + private static Joke joke; - @Mock private EventService eventService; + @Mock + private EventService eventService; - @Mock JokeService jokeService; + @Mock + JokeService jokeService; - @Mock private JokeRepository jokeRepository; + @Mock + private JokeRepository jokeRepository; - @InjectMocks private SlackController slackController; + @InjectMocks + private SlackController slackController; - @Mock private SlackService slackService; + @Mock + private SlackService slackService; - private String[] whiteListedCategories = - new String[] {"career", "dev", "fashion", "food", "money", "movie", "travel"}; + private String[] whiteListedCategories = new String[] { "career", "dev", "fashion", "food", "money", "movie", "travel" }; - @Before - public void setUp() { - ReflectionTestUtils.setField(slackController, "baseUrl", "localhost"); + @Before + public void setUp() { + ReflectionTestUtils.setField(slackController, "baseUrl", "localhost"); - iconUrl = "https://assets.chucknorris.host/img/avatar/chuck-norris.png"; - jokeId = "bg_h3xursougaxzprcrl0q"; - jokeValue = "Chuck Norris programs do not accept input."; - joke = Joke.builder().categories(new String[] {"dev"}).id(jokeId).value(jokeValue).build(); + iconUrl = "https://assets.chucknorris.host/img/avatar/chuck-norris.png"; + jokeId = "bg_h3xursougaxzprcrl0q"; + jokeValue = "Chuck Norris programs do not accept input."; + joke = Joke.builder().categories(new String[] { "dev" }).id(jokeId).value(jokeValue).build(); - when(slackService.getWhitelistedCategories()).thenReturn(whiteListedCategories); + when(slackService.getWhitelistedCategories()).thenReturn(whiteListedCategories); - when(slackService.filterNonWhitelistedCategories(new String[] {"dev", "fashion", "food"})) - .thenReturn(new String[] {"dev", "fashion", "food"}); + when(slackService.filterNonWhitelistedCategories(new String[] { "dev", "fashion", "food" })) + .thenReturn(new String[] { "dev", "fashion", "food" }); - when(slackService.filterNonWhitelistedCategories( - new String[] {"dev", "explicit", "fashion", "food"})) - .thenReturn(new String[] {"dev", "fashion", "food"}); - } - - @Test - public void testConnect() throws JsonProcessingException { - AccessToken accessToken = new AccessToken(); - accessToken.setAccessToken("23BE2D81-35B6-4B73-BCC9-8B6731D2540E"); - accessToken.setTeamName("ACME"); - - when(slackService.requestAccessToken("my-super-secret-code")).thenReturn(accessToken); - when(eventService.publishEvent(any(SlackConnectEvent.class))).thenReturn(null); - - ModelAndView view = slackController.connect("my-super-secret-code"); - assertEquals(HttpStatus.OK, view.getStatus()); - assertEquals( - "Congrats, the app was successfully installed for your Slack team!", - view.getModel().get("page_title")); - assertEquals(false, view.getModel().get("error")); - assertEquals(null, view.getModel().get("message")); + when(slackService.filterNonWhitelistedCategories( + new String[] { "dev", "explicit", "fashion", "food" })) + .thenReturn(new String[] { "dev", "fashion", "food" }); + } - verify(slackService, times(1)).requestAccessToken("my-super-secret-code"); - verifyNoMoreInteractions(slackService); + @Test + public void testConnect() throws JsonProcessingException { + AccessToken accessToken = new AccessToken(); + accessToken.setAccessToken("23BE2D81-35B6-4B73-BCC9-8B6731D2540E"); + accessToken.setTeamName("ACME"); - verify(eventService, times(1)).publishEvent(any(SlackConnectEvent.class)); - verifyNoMoreInteractions(eventService); - } + when(slackService.requestAccessToken("my-super-secret-code")).thenReturn(accessToken); + when(eventService.publishEvent(any(SlackConnectEvent.class))).thenReturn(null); - @Test - public void testConnectSetsErrorIfAuthenticationTokenIsNull() throws JsonProcessingException { - AccessToken accessToken = new AccessToken(); + ModelAndView view = slackController.connect("my-super-secret-code"); + assertEquals(HttpStatus.OK, view.getStatus()); + assertEquals( + "Congrats, the app was successfully installed for your Slack team!", + view.getModel().get("page_title")); + assertEquals(false, view.getModel().get("error")); + assertEquals(null, view.getModel().get("message")); - when(slackService.requestAccessToken("my-super-secret-code")).thenReturn(accessToken); + verify(slackService, times(1)).requestAccessToken("my-super-secret-code"); + verifyNoMoreInteractions(slackService); - ModelAndView view = slackController.connect("my-super-secret-code"); - assertEquals(HttpStatus.UNAUTHORIZED, view.getStatus()); - assertEquals("Oops, an error has occurred.", view.getModel().get("page_title")); - assertEquals(true, view.getModel().get("error")); - assertEquals( - "Oops, an error has occurred. Please try again later!", view.getModel().get("message")); + verify(eventService, times(1)).publishEvent(any(SlackConnectEvent.class)); + verifyNoMoreInteractions(eventService); + } - verify(slackService, times(1)).requestAccessToken("my-super-secret-code"); - verifyNoMoreInteractions(slackService); + @Test + public void testConnectSetsErrorIfAuthenticationTokenIsNull() throws JsonProcessingException { + AccessToken accessToken = new AccessToken(); - verify(eventService, times(0)).publishEvent(any()); - verifyNoMoreInteractions(eventService); - } + when(slackService.requestAccessToken("my-super-secret-code")).thenReturn(accessToken); - @Test - public void testReturnHelpIfTextEqualsHelp() { - Request request = new Request(); - request.setText("help"); + ModelAndView view = slackController.connect("my-super-secret-code"); + assertEquals(HttpStatus.UNAUTHORIZED, view.getStatus()); + assertEquals("Oops, an error has occurred.", view.getModel().get("page_title")); + assertEquals(true, view.getModel().get("error")); + assertEquals( + "Oops, an error has occurred. Please try again later!", view.getModel().get("message")); - SlackCommandResponse response = slackController.command(request); - assertEquals(iconUrl, response.getIconUrl()); - assertEquals("*Available commands:*", response.getText()); - assertEquals(ResponseType.EPHEMERAL, response.getResponseType()); + verify(slackService, times(1)).requestAccessToken("my-super-secret-code"); + verifyNoMoreInteractions(slackService); - SlackCommandResponseAttachment newsletter = response.getAttachments()[0]; - assertEquals(null, newsletter.getFallback()); - assertEquals( - ":facepunch: Sign up for *The Daily Chuck* and get your daily dose of the best" - + " #ChuckNorrisFacts every morning straight int your inbox!" - + " https://mailchi.mp/5a19a2898bf7/the-daily-chuck", - newsletter.getText()); - assertEquals("The Daily Chuck", newsletter.getTitle()); - assertEquals(null, newsletter.getTitleLink()); - assertArrayEquals(new String[] {"text"}, newsletter.getMrkdownIn()); - - SlackCommandResponseAttachment randomJoke = response.getAttachments()[1]; - assertEquals(null, randomJoke.getFallback()); - assertEquals("Type `/chuck` to get a random joke.", randomJoke.getText()); - assertEquals("Random joke", randomJoke.getTitle()); - assertEquals(null, randomJoke.getTitleLink()); - assertArrayEquals(new String[] {"text"}, randomJoke.getMrkdownIn()); - - SlackCommandResponseAttachment search = response.getAttachments()[2]; - assertEquals(null, search.getFallback()); - assertEquals( - "Type `/chuck ? {search_term}` to search within tens of thousands Chuck Norris" + " jokes.", - search.getText()); - assertEquals("Free text search", search.getTitle()); - assertEquals(null, search.getTitleLink()); - assertArrayEquals(new String[] {"text"}, search.getMrkdownIn()); - - SlackCommandResponseAttachment randomJokePersonalized = response.getAttachments()[3]; - assertEquals(null, randomJokePersonalized.getFallback()); - assertEquals( - "Type `/chuck @ {user_name}` to get a random personalized joke.", - randomJokePersonalized.getText()); - assertEquals("Random personalized joke", randomJokePersonalized.getTitle()); - assertEquals(null, randomJokePersonalized.getTitleLink()); - assertArrayEquals(new String[] {"text"}, randomJokePersonalized.getMrkdownIn()); - - SlackCommandResponseAttachment randomJokeFromCategory = response.getAttachments()[4]; - assertEquals(null, randomJokeFromCategory.getFallback()); - assertEquals( - "Type `/chuck {category_name}` to get a random joke from within a given category.", - randomJokeFromCategory.getText()); - assertEquals("Random joke from category", randomJokeFromCategory.getTitle()); - assertEquals(null, randomJokeFromCategory.getTitleLink()); - assertArrayEquals(new String[] {"text"}, randomJokeFromCategory.getMrkdownIn()); - - SlackCommandResponseAttachment categories = response.getAttachments()[5]; - assertEquals(null, categories.getFallback()); - assertEquals("Type `/chuck -cat` to retrieve a list of all categories.", categories.getText()); - assertEquals("Categories", categories.getTitle()); - assertEquals(null, categories.getTitleLink()); - assertArrayEquals(new String[] {"text"}, categories.getMrkdownIn()); - - SlackCommandResponseAttachment help = response.getAttachments()[6]; - assertEquals(null, help.getFallback()); - assertEquals( - "Type `/chuck : {joke_id}` to retrieve get a joke by a given `id`.", help.getText()); - assertEquals("Get joke by id", help.getTitle()); - assertEquals(null, help.getTitleLink()); - assertArrayEquals(new String[] {"text"}, help.getMrkdownIn()); - - SlackCommandResponseAttachment jokeById = response.getAttachments()[7]; - assertEquals(null, jokeById.getFallback()); - assertEquals("Type `/chuck help` to display a list of available commands.", jokeById.getText()); - assertEquals("Help", jokeById.getTitle()); - assertEquals(null, jokeById.getTitleLink()); - assertArrayEquals(new String[] {"text"}, jokeById.getMrkdownIn()); + verify(eventService, times(0)).publishEvent(any()); + verifyNoMoreInteractions(eventService); + } - verifyNoMoreInteractions(jokeRepository); - } + @Test + public void testReturnHelpIfTextEqualsHelp() { + Request request = new Request(); + request.setText("help"); + + SlackCommandResponse response = slackController.command(request); + assertEquals(iconUrl, response.getIconUrl()); + assertEquals("*Available commands:*", response.getText()); + assertEquals(ResponseType.EPHEMERAL, response.getResponseType()); + + SlackCommandResponseAttachment newsletter = response.getAttachments()[0]; + assertEquals(null, newsletter.getFallback()); + assertEquals( + ":facepunch: Sign up for *The Daily Chuck* and get your daily dose of the best" + + " #ChuckNorrisFacts every morning straight int your inbox!" + + " https://mailchi.mp/5a19a2898bf7/the-daily-chuck", + newsletter.getText()); + assertEquals("The Daily Chuck", newsletter.getTitle()); + assertEquals(null, newsletter.getTitleLink()); + assertArrayEquals(new String[] { "text" }, newsletter.getMrkdownIn()); + + SlackCommandResponseAttachment randomJoke = response.getAttachments()[1]; + assertEquals(null, randomJoke.getFallback()); + assertEquals("Type `/chuck` to get a random joke.", randomJoke.getText()); + assertEquals("Random joke", randomJoke.getTitle()); + assertEquals(null, randomJoke.getTitleLink()); + assertArrayEquals(new String[] { "text" }, randomJoke.getMrkdownIn()); + + SlackCommandResponseAttachment search = response.getAttachments()[2]; + assertEquals(null, search.getFallback()); + assertEquals( + "Type `/chuck ? {search_term}` to search within tens of thousands Chuck Norris" + " jokes.", + search.getText()); + assertEquals("Free text search", search.getTitle()); + assertEquals(null, search.getTitleLink()); + assertArrayEquals(new String[] { "text" }, search.getMrkdownIn()); + + SlackCommandResponseAttachment randomJokePersonalized = response.getAttachments()[3]; + assertEquals(null, randomJokePersonalized.getFallback()); + assertEquals( + "Type `/chuck @ {user_name}` to get a random personalized joke.", + randomJokePersonalized.getText()); + assertEquals("Random personalized joke", randomJokePersonalized.getTitle()); + assertEquals(null, randomJokePersonalized.getTitleLink()); + assertArrayEquals(new String[] { "text" }, randomJokePersonalized.getMrkdownIn()); + + SlackCommandResponseAttachment randomJokeFromCategory = response.getAttachments()[4]; + assertEquals(null, randomJokeFromCategory.getFallback()); + assertEquals( + "Type `/chuck {category_name}` to get a random joke from within a given category.", + randomJokeFromCategory.getText()); + assertEquals("Random joke from category", randomJokeFromCategory.getTitle()); + assertEquals(null, randomJokeFromCategory.getTitleLink()); + assertArrayEquals(new String[] { "text" }, randomJokeFromCategory.getMrkdownIn()); + + SlackCommandResponseAttachment categories = response.getAttachments()[5]; + assertEquals(null, categories.getFallback()); + assertEquals("Type `/chuck -cat` to retrieve a list of all categories.", categories.getText()); + assertEquals("Categories", categories.getTitle()); + assertEquals(null, categories.getTitleLink()); + assertArrayEquals(new String[] { "text" }, categories.getMrkdownIn()); + + SlackCommandResponseAttachment help = response.getAttachments()[6]; + assertEquals(null, help.getFallback()); + assertEquals( + "Type `/chuck : {joke_id}` to retrieve get a joke by a given `id`.", help.getText()); + assertEquals("Get joke by id", help.getTitle()); + assertEquals(null, help.getTitleLink()); + assertArrayEquals(new String[] { "text" }, help.getMrkdownIn()); + + SlackCommandResponseAttachment jokeById = response.getAttachments()[7]; + assertEquals(null, jokeById.getFallback()); + assertEquals("Type `/chuck help` to display a list of available commands.", jokeById.getText()); + assertEquals("Help", jokeById.getTitle()); + assertEquals(null, jokeById.getTitleLink()); + assertArrayEquals(new String[] { "text" }, jokeById.getMrkdownIn()); + + verifyNoMoreInteractions(jokeRepository); + } @Test public void testReturnRandomJokeIfTextIsEmpty() { @@ -238,42 +242,42 @@ public void testReturnRandomJokeIfTextIsNull() { verifyNoMoreInteractions(slackService); } - @Test - public void testReturnRandomJokeFromACategoryIfTextContainsCategory() { - String[] categories = new String[] {"dev"}; - - when(jokeRepository.findAllCategories()).thenReturn(categories); - when(jokeService.randomJokeByCategory("dev")).thenReturn(joke); - when(slackService.isWhitelistedCategory("dev")).thenReturn(true); - when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); - - Request request = new Request(); - request.setText("dev"); - request.setTeamDomain("ACME"); - - SlackCommandResponse response = slackController.command(request); - assertEquals(iconUrl, response.getIconUrl()); - assertEquals(null, response.getText()); - assertEquals(ResponseType.IN_CHANNEL, response.getResponseType()); - - SlackCommandResponseAttachment commandResponseAttachment = response.getAttachments()[0]; - assertEquals(jokeValue, commandResponseAttachment.getFallback()); - assertEquals(jokeValue, commandResponseAttachment.getText()); - assertEquals("[permalink]", commandResponseAttachment.getTitle()); - assertEquals( - "https://localhost/jokes/bg_h3xursougaxzprcrl0q?utm_source=slack&utm_medium=api&utm_term=ACME&utm_campaign=random+joke+category", - commandResponseAttachment.getTitleLink()); - - verify(slackService, times(1)).isWhitelistedCategory("dev"); - verify(slackService, times(1)).filterNonWhitelistedCategories(categories); - verifyNoMoreInteractions(slackService); - - verify(jokeRepository, times(1)).findAllCategories(); - verifyNoMoreInteractions(jokeRepository); - - verify(jokeService, times(1)).randomJokeByCategory("dev"); - verifyNoMoreInteractions(jokeService); - } + @Test + public void testReturnRandomJokeFromACategoryIfTextContainsCategory() { + String[] categories = new String[] { "dev" }; + + when(jokeRepository.findAllCategories()).thenReturn(categories); + when(jokeService.randomJokeByCategory("dev")).thenReturn(joke); + when(slackService.isWhitelistedCategory("dev")).thenReturn(true); + when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); + + Request request = new Request(); + request.setText("dev"); + request.setTeamDomain("ACME"); + + SlackCommandResponse response = slackController.command(request); + assertEquals(iconUrl, response.getIconUrl()); + assertEquals(null, response.getText()); + assertEquals(ResponseType.IN_CHANNEL, response.getResponseType()); + + SlackCommandResponseAttachment commandResponseAttachment = response.getAttachments()[0]; + assertEquals(jokeValue, commandResponseAttachment.getFallback()); + assertEquals(jokeValue, commandResponseAttachment.getText()); + assertEquals("[permalink]", commandResponseAttachment.getTitle()); + assertEquals( + "https://localhost/jokes/bg_h3xursougaxzprcrl0q?utm_source=slack&utm_medium=api&utm_term=ACME&utm_campaign=random+joke+category", + commandResponseAttachment.getTitleLink()); + + verify(slackService, times(1)).isWhitelistedCategory("dev"); + verify(slackService, times(1)).filterNonWhitelistedCategories(categories); + verifyNoMoreInteractions(slackService); + + verify(jokeRepository, times(1)).findAllCategories(); + verifyNoMoreInteractions(jokeRepository); + + verify(jokeService, times(1)).randomJokeByCategory("dev"); + verifyNoMoreInteractions(jokeService); + } @Test public void testReturnErrorIfCategoryIsNotWhitelisted() { @@ -296,34 +300,34 @@ public void testReturnErrorIfCategoryIsNotWhitelisted() { verifyNoMoreInteractions(slackService); } - @Test - public void testReturnErrorIfCategoryDoesNotExist() { - String[] categories = new String[] {"dev"}; - - when(slackService.isWhitelistedCategory("does-not-exist")).thenReturn(true); - when(jokeRepository.findAllCategories()).thenReturn(categories); - when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); - - Request request = new Request(); - request.setText("does-not-exist"); - - SlackCommandResponse response = slackController.command(request); - assertEquals(null, response.getAttachments()); - assertEquals(iconUrl, response.getIconUrl()); - assertEquals( - "Sorry dude ¯\\_(ツ)_/¯ , we've found no jokes for the given category" - + " (\"does-not-exist\"). Type `/chuck -cat` to see available categories or" - + " search by query `/chuck ? {search_term}`", - response.getText()); - assertEquals(ResponseType.EPHEMERAL, response.getResponseType()); - - verify(jokeRepository, times(1)).findAllCategories(); - verifyNoMoreInteractions(jokeRepository); - - verify(slackService, times(1)).isWhitelistedCategory("does-not-exist"); - verify(slackService, times(1)).filterNonWhitelistedCategories(categories); - verifyNoMoreInteractions(slackService); - } + @Test + public void testReturnErrorIfCategoryDoesNotExist() { + String[] categories = new String[] { "dev" }; + + when(slackService.isWhitelistedCategory("does-not-exist")).thenReturn(true); + when(jokeRepository.findAllCategories()).thenReturn(categories); + when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); + + Request request = new Request(); + request.setText("does-not-exist"); + + SlackCommandResponse response = slackController.command(request); + assertEquals(null, response.getAttachments()); + assertEquals(iconUrl, response.getIconUrl()); + assertEquals( + "Sorry dude ¯\\_(ツ)_/¯ , we've found no jokes for the given category" + + " (\"does-not-exist\"). Type `/chuck -cat` to see available categories or" + + " search by query `/chuck ? {search_term}`", + response.getText()); + assertEquals(ResponseType.EPHEMERAL, response.getResponseType()); + + verify(jokeRepository, times(1)).findAllCategories(); + verifyNoMoreInteractions(jokeRepository); + + verify(slackService, times(1)).isWhitelistedCategory("does-not-exist"); + verify(slackService, times(1)).filterNonWhitelistedCategories(categories); + verifyNoMoreInteractions(slackService); + } @Test public void testReturnListOfCategories() { @@ -405,206 +409,206 @@ public void testReturnErrorIfJokeDoesNotExist() { verifyNoMoreInteractions(jokeRepository); } - @Test - public void testReturnRandomPersonalizedJoke() { - String substitute = "Bob"; - String[] categories = new String[] {"dev", "explicit", "fashion", "food"}; - - joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); - - when(jokeRepository.findAllCategories()).thenReturn(categories); - when(jokeService.randomPersonalizedJokeByCategories( - substitute, new String[] {"dev", "fashion", "food"})) - .thenReturn(joke); - - Request request = new Request(); - request.setText("@Bob"); - request.setTeamDomain("ACME"); - - SlackCommandResponse response = slackController.command(request); - assertEquals(iconUrl, response.getIconUrl()); - assertEquals(null, response.getText()); - assertEquals(ResponseType.IN_CHANNEL, response.getResponseType()); - - SlackCommandResponseAttachment commandResponseAttachment = response.getAttachments()[0]; - assertEquals("Bob programs do not accept input.", commandResponseAttachment.getFallback()); - assertEquals("Bob programs do not accept input.", commandResponseAttachment.getText()); - assertEquals("[permalink]", commandResponseAttachment.getTitle()); - assertEquals( - "https://localhost/jokes/bg_h3xursougaxzprcrl0q?utm_source=slack&utm_medium=api&utm_term=ACME&utm_campaign=random+personalized+joke", - commandResponseAttachment.getTitleLink()); - - verify(jokeRepository, times(1)).findAllCategories(); - verifyNoMoreInteractions(jokeRepository); - - verify(slackService, times(1)) - .filterNonWhitelistedCategories(new String[] {"dev", "explicit", "fashion", "food"}); - verifyNoMoreInteractions(slackService); - - verify(jokeService, times(1)) - .randomPersonalizedJokeByCategories("Bob", new String[] {"dev", "fashion", "food"}); - verifyNoMoreInteractions(jokeService); - } - - @Test - public void testReturnSearchResultWithLessThanFiveJokes() { - String query = "Kleenex"; - String[] categories = new String[] {"dev", "movie"}; - - Pageable pageable = PageRequest.of(0, 5, Sort.unsorted()); - - when(jokeRepository.findAllCategories()).thenReturn(categories); - when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); - when(jokeService.searchWithCategoryFilter(query, categories, pageable)) - .thenReturn(new PageImpl<>(Arrays.asList(joke, joke, joke))); - - Request request = new Request(); - request.setText("? " + query); - request.setTeamDomain("ACME"); - - SlackCommandResponse response = slackController.command(request); - assertEquals(iconUrl, response.getIconUrl()); - assertEquals("*Search results: 1 - 3 of 3*.", response.getText()); - assertEquals(ResponseType.IN_CHANNEL, response.getResponseType()); - - for (int i = 0; i < response.getAttachments().length; i++) { - SlackCommandResponseAttachment commandResponseAttachment = response.getAttachments()[i]; - assertEquals(jokeValue, commandResponseAttachment.getFallback()); - assertEquals(jokeValue, commandResponseAttachment.getText()); - assertEquals("(" + (i + 1) + ")", commandResponseAttachment.getTitle()); - assertEquals( - "https://localhost/jokes/bg_h3xursougaxzprcrl0q?utm_source=slack&utm_medium=api&utm_term=ACME&utm_campaign=search+joke", - commandResponseAttachment.getTitleLink()); + @Test + public void testReturnRandomPersonalizedJoke() { + String substitute = "Bob"; + String[] categories = new String[] { "dev", "explicit", "fashion", "food" }; + + joke = joke.toBuilder().value(joke.getValue().replace("Chuck Norris", "Bob")).build(); + + when(jokeRepository.findAllCategories()).thenReturn(categories); + when(jokeService.randomPersonalizedJokeByCategories( + substitute, new String[] { "dev", "fashion", "food" })) + .thenReturn(joke); + + Request request = new Request(); + request.setText("@Bob"); + request.setTeamDomain("ACME"); + + SlackCommandResponse response = slackController.command(request); + assertEquals(iconUrl, response.getIconUrl()); + assertEquals(null, response.getText()); + assertEquals(ResponseType.IN_CHANNEL, response.getResponseType()); + + SlackCommandResponseAttachment commandResponseAttachment = response.getAttachments()[0]; + assertEquals("Bob programs do not accept input.", commandResponseAttachment.getFallback()); + assertEquals("Bob programs do not accept input.", commandResponseAttachment.getText()); + assertEquals("[permalink]", commandResponseAttachment.getTitle()); + assertEquals( + "https://localhost/jokes/bg_h3xursougaxzprcrl0q?utm_source=slack&utm_medium=api&utm_term=ACME&utm_campaign=random+personalized+joke", + commandResponseAttachment.getTitleLink()); + + verify(jokeRepository, times(1)).findAllCategories(); + verifyNoMoreInteractions(jokeRepository); + + verify(slackService, times(1)) + .filterNonWhitelistedCategories(new String[] { "dev", "explicit", "fashion", "food" }); + verifyNoMoreInteractions(slackService); + + verify(jokeService, times(1)) + .randomPersonalizedJokeByCategories("Bob", new String[] { "dev", "fashion", "food" }); + verifyNoMoreInteractions(jokeService); } - verify(jokeRepository, times(1)).findAllCategories(); - verifyNoMoreInteractions(jokeRepository); - - verify(slackService, times(1)).filterNonWhitelistedCategories(categories); - verifyNoMoreInteractions(slackService); - - verify(jokeService, times(1)).searchWithCategoryFilter(query, categories, pageable); - verifyNoMoreInteractions(jokeService); - } - - @Test - public void testReturnSearchResultWithMoreThanFiveJokes() { - String query = "Kleenex"; - String[] categories = new String[] {"dev", "movie"}; - - Pageable pageable = PageRequest.of(0, 5, Sort.unsorted()); - - when(jokeRepository.findAllCategories()).thenReturn(categories); - when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); - when(jokeService.searchWithCategoryFilter(query, categories, pageable)) - .thenReturn(new PageImpl(Arrays.asList(joke, joke, joke, joke, joke), pageable, 6)); - - Request request = new Request(); - request.setText("? " + query); - request.setTeamDomain("ACME"); - - SlackCommandResponse response = slackController.command(request); - assertEquals(iconUrl, response.getIconUrl()); - assertEquals( - "*Search results: 1 - 5 of 6*. Type `/chuck ? " + query + " --page 2` to see more results.", - response.getText()); - assertEquals(ResponseType.IN_CHANNEL, response.getResponseType()); - - for (int i = 0; i < response.getAttachments().length; i++) { - SlackCommandResponseAttachment commandResponseAttachment = response.getAttachments()[i]; - assertEquals(jokeValue, commandResponseAttachment.getFallback()); - assertEquals(jokeValue, commandResponseAttachment.getText()); - assertEquals("(" + (i + 1) + ")", commandResponseAttachment.getTitle()); - assertEquals( - "https://localhost/jokes/bg_h3xursougaxzprcrl0q?utm_source=slack&utm_medium=api&utm_term=ACME&utm_campaign=search+joke", - commandResponseAttachment.getTitleLink()); + @Test + public void testReturnSearchResultWithLessThanFiveJokes() { + String query = "Kleenex"; + String[] categories = new String[] { "dev", "movie" }; + + Pageable pageable = PageRequest.of(0, 5, Sort.unsorted()); + + when(jokeRepository.findAllCategories()).thenReturn(categories); + when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); + when(jokeService.searchWithCategoryFilter(query, categories, pageable)) + .thenReturn(new PageImpl<>(Arrays.asList(joke, joke, joke))); + + Request request = new Request(); + request.setText("? " + query); + request.setTeamDomain("ACME"); + + SlackCommandResponse response = slackController.command(request); + assertEquals(iconUrl, response.getIconUrl()); + assertEquals("*Search results: 1 - 3 of 3*.", response.getText()); + assertEquals(ResponseType.IN_CHANNEL, response.getResponseType()); + + for (int i = 0; i < response.getAttachments().length; i++) { + SlackCommandResponseAttachment commandResponseAttachment = response.getAttachments()[i]; + assertEquals(jokeValue, commandResponseAttachment.getFallback()); + assertEquals(jokeValue, commandResponseAttachment.getText()); + assertEquals("(" + (i + 1) + ")", commandResponseAttachment.getTitle()); + assertEquals( + "https://localhost/jokes/bg_h3xursougaxzprcrl0q?utm_source=slack&utm_medium=api&utm_term=ACME&utm_campaign=search+joke", + commandResponseAttachment.getTitleLink()); + } + + verify(jokeRepository, times(1)).findAllCategories(); + verifyNoMoreInteractions(jokeRepository); + + verify(slackService, times(1)).filterNonWhitelistedCategories(categories); + verifyNoMoreInteractions(slackService); + + verify(jokeService, times(1)).searchWithCategoryFilter(query, categories, pageable); + verifyNoMoreInteractions(jokeService); } - verify(slackService, times(1)).filterNonWhitelistedCategories(categories); - verifyNoMoreInteractions(slackService); - - verify(jokeService, times(1)).searchWithCategoryFilter(query, categories, pageable); - verifyNoMoreInteractions(jokeService); - } - - @Test - public void testReturnSearchResultWithMoreThanFiveJokesSecondPage() { - String query = "Kleenex"; - String[] categories = new String[] {"dev", "movie"}; - Pageable pageable = PageRequest.of(1, 5, Sort.unsorted()); - - when(jokeRepository.findAllCategories()).thenReturn(categories); - when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); - when(jokeService.searchWithCategoryFilter(query, categories, pageable)) - .thenReturn(new PageImpl(Arrays.asList(joke, joke, joke, joke, joke), pageable, 15)); - - Request request = new Request(); - request.setText("? " + query + " --page 2"); - request.setTeamDomain("ACME"); - - SlackCommandResponse response = slackController.command(request); - assertEquals(iconUrl, response.getIconUrl()); - assertEquals( - "*Search results: 6 - 10 of 15*. Type `/chuck ? " - + query - + " --page 3` to see more results.", - response.getText()); - assertEquals(ResponseType.IN_CHANNEL, response.getResponseType()); + @Test + public void testReturnSearchResultWithMoreThanFiveJokes() { + String query = "Kleenex"; + String[] categories = new String[] { "dev", "movie" }; + + Pageable pageable = PageRequest.of(0, 5, Sort.unsorted()); + + when(jokeRepository.findAllCategories()).thenReturn(categories); + when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); + when(jokeService.searchWithCategoryFilter(query, categories, pageable)) + .thenReturn(new PageImpl(Arrays.asList(joke, joke, joke, joke, joke), pageable, 6)); + + Request request = new Request(); + request.setText("? " + query); + request.setTeamDomain("ACME"); + + SlackCommandResponse response = slackController.command(request); + assertEquals(iconUrl, response.getIconUrl()); + assertEquals( + "*Search results: 1 - 5 of 6*. Type `/chuck ? " + query + " --page 2` to see more results.", + response.getText()); + assertEquals(ResponseType.IN_CHANNEL, response.getResponseType()); + + for (int i = 0; i < response.getAttachments().length; i++) { + SlackCommandResponseAttachment commandResponseAttachment = response.getAttachments()[i]; + assertEquals(jokeValue, commandResponseAttachment.getFallback()); + assertEquals(jokeValue, commandResponseAttachment.getText()); + assertEquals("(" + (i + 1) + ")", commandResponseAttachment.getTitle()); + assertEquals( + "https://localhost/jokes/bg_h3xursougaxzprcrl0q?utm_source=slack&utm_medium=api&utm_term=ACME&utm_campaign=search+joke", + commandResponseAttachment.getTitleLink()); + } + + verify(slackService, times(1)).filterNonWhitelistedCategories(categories); + verifyNoMoreInteractions(slackService); + + verify(jokeService, times(1)).searchWithCategoryFilter(query, categories, pageable); + verifyNoMoreInteractions(jokeService); + } - for (int i = 0; i < response.getAttachments().length; i++) { - SlackCommandResponseAttachment commandResponseAttachment = response.getAttachments()[i]; - assertEquals(jokeValue, commandResponseAttachment.getFallback()); - assertEquals(jokeValue, commandResponseAttachment.getText()); - assertEquals("(" + (i + 1 + 5) + ")", commandResponseAttachment.getTitle()); - assertEquals( - "https://localhost/jokes/bg_h3xursougaxzprcrl0q?utm_source=slack&utm_medium=api&utm_term=ACME&utm_campaign=search+joke", - commandResponseAttachment.getTitleLink()); + @Test + public void testReturnSearchResultWithMoreThanFiveJokesSecondPage() { + String query = "Kleenex"; + String[] categories = new String[] { "dev", "movie" }; + Pageable pageable = PageRequest.of(1, 5, Sort.unsorted()); + + when(jokeRepository.findAllCategories()).thenReturn(categories); + when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); + when(jokeService.searchWithCategoryFilter(query, categories, pageable)) + .thenReturn(new PageImpl(Arrays.asList(joke, joke, joke, joke, joke), pageable, 15)); + + Request request = new Request(); + request.setText("? " + query + " --page 2"); + request.setTeamDomain("ACME"); + + SlackCommandResponse response = slackController.command(request); + assertEquals(iconUrl, response.getIconUrl()); + assertEquals( + "*Search results: 6 - 10 of 15*. Type `/chuck ? " + + query + + " --page 3` to see more results.", + response.getText()); + assertEquals(ResponseType.IN_CHANNEL, response.getResponseType()); + + for (int i = 0; i < response.getAttachments().length; i++) { + SlackCommandResponseAttachment commandResponseAttachment = response.getAttachments()[i]; + assertEquals(jokeValue, commandResponseAttachment.getFallback()); + assertEquals(jokeValue, commandResponseAttachment.getText()); + assertEquals("(" + (i + 1 + 5) + ")", commandResponseAttachment.getTitle()); + assertEquals( + "https://localhost/jokes/bg_h3xursougaxzprcrl0q?utm_source=slack&utm_medium=api&utm_term=ACME&utm_campaign=search+joke", + commandResponseAttachment.getTitleLink()); + } + + verify(jokeRepository, times(1)).findAllCategories(); + verifyNoMoreInteractions(jokeRepository); + + verify(slackService, times(1)).filterNonWhitelistedCategories(categories); + verifyNoMoreInteractions(slackService); + + verify(jokeService, times(1)).searchWithCategoryFilter(query, categories, pageable); + verifyNoMoreInteractions(jokeService); } - verify(jokeRepository, times(1)).findAllCategories(); - verifyNoMoreInteractions(jokeRepository); + @Test + public void testReturnErrorIfSearchResultIsEmpty() { + String query = "poop"; + String[] categories = new String[] { "dev", "movie" }; - verify(slackService, times(1)).filterNonWhitelistedCategories(categories); - verifyNoMoreInteractions(slackService); + Pageable pageable = PageRequest.of(0, 5, Sort.unsorted()); - verify(jokeService, times(1)).searchWithCategoryFilter(query, categories, pageable); - verifyNoMoreInteractions(jokeService); - } + when(jokeRepository.findAllCategories()).thenReturn(categories); + when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); + when(jokeService.searchWithCategoryFilter(query, categories, pageable)) + .thenReturn(new PageImpl<>(new ArrayList<>())); - @Test - public void testReturnErrorIfSearchResultIsEmpty() { - String query = "poop"; - String[] categories = new String[] {"dev", "movie"}; + Request request = new Request(); + request.setText("? " + query); - Pageable pageable = PageRequest.of(0, 5, Sort.unsorted()); + SlackCommandResponse response = slackController.command(request); + assertArrayEquals(null, response.getAttachments()); + assertEquals(iconUrl, response.getIconUrl()); - when(jokeRepository.findAllCategories()).thenReturn(categories); - when(slackService.filterNonWhitelistedCategories(categories)).thenReturn(categories); - when(jokeService.searchWithCategoryFilter(query, categories, pageable)) - .thenReturn(new PageImpl<>(new ArrayList<>())); + assertEquals( + "Your search for *\"" + + query + + "\"* did not match any joke ¯\\_(ツ)_/¯. Make sure that all words are" + + " spelled correctly. Try different keywords. Try more general keywords.", + response.getText()); + assertEquals(ResponseType.EPHEMERAL, response.getResponseType()); - Request request = new Request(); - request.setText("? " + query); + verify(jokeRepository, times(1)).findAllCategories(); + verifyNoMoreInteractions(jokeRepository); - SlackCommandResponse response = slackController.command(request); - assertArrayEquals(null, response.getAttachments()); - assertEquals(iconUrl, response.getIconUrl()); + verify(slackService, times(1)).filterNonWhitelistedCategories(categories); + verifyNoMoreInteractions(slackService); - assertEquals( - "Your search for *\"" - + query - + "\"* did not match any joke ¯\\_(ツ)_/¯. Make sure that all words are" - + " spelled correctly. Try different keywords. Try more general keywords.", - response.getText()); - assertEquals(ResponseType.EPHEMERAL, response.getResponseType()); - - verify(jokeRepository, times(1)).findAllCategories(); - verifyNoMoreInteractions(jokeRepository); - - verify(slackService, times(1)).filterNonWhitelistedCategories(categories); - verifyNoMoreInteractions(slackService); - - verify(jokeService, times(1)).searchWithCategoryFilter(query, categories, pageable); - verifyNoMoreInteractions(jokeService); - } + verify(jokeService, times(1)).searchWithCategoryFilter(query, categories, pageable); + verifyNoMoreInteractions(jokeService); + } } diff --git a/chucknorris-web/src/test/java/io/chucknorris/api/slack/SlackServiceTest.java b/chucknorris-web/src/test/java/io/chucknorris/api/slack/SlackServiceTest.java index 15b6d1c..c1dff72 100644 --- a/chucknorris-web/src/test/java/io/chucknorris/api/slack/SlackServiceTest.java +++ b/chucknorris-web/src/test/java/io/chucknorris/api/slack/SlackServiceTest.java @@ -30,93 +30,95 @@ @RunWith(MockitoJUnitRunner.class) public class SlackServiceTest { - @InjectMocks private SlackService slackService = new SlackService(); - - @Mock private RestTemplate restTemplate; - - @Before - public void setUp() { - ReflectionTestUtils.setField( - slackService, - "whitelistedCategories", - "career,celebrity,dev,fashion,food,money,movie,travel"); - ReflectionTestUtils.setField(slackService, "clientId", "slack.oauth.client_id"); - ReflectionTestUtils.setField(slackService, "clientSecret", "slack.oauth.client_secret"); - ReflectionTestUtils.setField(slackService, "redirectUrl", "slack.oauth.redirect_uri"); - } - - @Test - public void testComposeAuthorizeUri() { - UriComponents authorizeUri = slackService.composeAuthorizeUri(); - - assertEquals( - "https://slack.com/oauth/v2/authorize/?client_id=slack.oauth.client_id&redirect_uri=slack.oauth.redirect_uri&scope=commands", - authorizeUri.toUriString()); - } - - @Test - public void testFilterNonWhitelistedCategories() { - assertArrayEquals( - slackService.filterNonWhitelistedCategories( - new String[] { - "career", - "celebrity", - "dev", - "explicit", - "fashion", - "food", - "money", - "movie", - "travel" - }), - new String[] {"career", "celebrity", "dev", "fashion", "food", "money", "movie", "travel"}); - } - - @Test - public void testGetWhitelistedCategoriesReturnsArrayOfCategories() { - assertArrayEquals( - slackService.getWhitelistedCategories(), - new String[] {"career", "celebrity", "dev", "fashion", "food", "money", "movie", "travel"}); - } - - @Test - public void testIfGivenCategoryIsWhitelisted() { - assertFalse(slackService.isWhitelistedCategory("explicit")); - assertFalse(slackService.isWhitelistedCategory("religion")); - assertTrue(slackService.isWhitelistedCategory("dev")); - } - - @Test - public void testRequestAccessTokenSendsRequestAndRetunsToken() { - String code = "my-super-secret-code"; - AccessToken accessToken = new AccessToken(); - - HttpHeaders headers = new HttpHeaders(); - headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE); - headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.add("client_id", "slack.oauth.client_id"); - map.add("client_secret", "slack.oauth.client_secret"); - map.add("code", code); - map.add("redirect_uri", "slack.oauth.redirect_uri"); - - when(restTemplate.exchange( - "https://slack.com/api/oauth.v2.access", - HttpMethod.POST, - new HttpEntity>(map, headers), - AccessToken.class)) - .thenReturn(new ResponseEntity(accessToken, HttpStatus.OK)); - - AccessToken response = slackService.requestAccessToken(code); - assertEquals(accessToken, response); - - verify(restTemplate, times(1)) - .exchange( - "https://slack.com/api/oauth.v2.access", - HttpMethod.POST, - new HttpEntity>(map, headers), - AccessToken.class); - verifyNoMoreInteractions(restTemplate); - } + @InjectMocks + private SlackService slackService = new SlackService(); + + @Mock + private RestTemplate restTemplate; + + @Before + public void setUp() { + ReflectionTestUtils.setField( + slackService, + "whitelistedCategories", + "career,celebrity,dev,fashion,food,money,movie,travel"); + ReflectionTestUtils.setField(slackService, "clientId", "slack.oauth.client_id"); + ReflectionTestUtils.setField(slackService, "clientSecret", "slack.oauth.client_secret"); + ReflectionTestUtils.setField(slackService, "redirectUrl", "slack.oauth.redirect_uri"); + } + + @Test + public void testComposeAuthorizeUri() { + UriComponents authorizeUri = slackService.composeAuthorizeUri(); + + assertEquals( + "https://slack.com/oauth/v2/authorize/?client_id=slack.oauth.client_id&redirect_uri=slack.oauth.redirect_uri&scope=commands", + authorizeUri.toUriString()); + } + + @Test + public void testFilterNonWhitelistedCategories() { + assertArrayEquals( + slackService.filterNonWhitelistedCategories( + new String[] { + "career", + "celebrity", + "dev", + "explicit", + "fashion", + "food", + "money", + "movie", + "travel" + }), + new String[] { "career", "celebrity", "dev", "fashion", "food", "money", "movie", "travel" }); + } + + @Test + public void testGetWhitelistedCategoriesReturnsArrayOfCategories() { + assertArrayEquals( + slackService.getWhitelistedCategories(), + new String[] { "career", "celebrity", "dev", "fashion", "food", "money", "movie", "travel" }); + } + + @Test + public void testIfGivenCategoryIsWhitelisted() { + assertFalse(slackService.isWhitelistedCategory("explicit")); + assertFalse(slackService.isWhitelistedCategory("religion")); + assertTrue(slackService.isWhitelistedCategory("dev")); + } + + @Test + public void testRequestAccessTokenSendsRequestAndRetunsToken() { + String code = "my-super-secret-code"; + AccessToken accessToken = new AccessToken(); + + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE); + headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); + + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("client_id", "slack.oauth.client_id"); + map.add("client_secret", "slack.oauth.client_secret"); + map.add("code", code); + map.add("redirect_uri", "slack.oauth.redirect_uri"); + + when(restTemplate.exchange( + "https://slack.com/api/oauth.v2.access", + HttpMethod.POST, + new HttpEntity>(map, headers), + AccessToken.class)) + .thenReturn(new ResponseEntity(accessToken, HttpStatus.OK)); + + AccessToken response = slackService.requestAccessToken(code); + assertEquals(accessToken, response); + + verify(restTemplate, times(1)) + .exchange( + "https://slack.com/api/oauth.v2.access", + HttpMethod.POST, + new HttpEntity>(map, headers), + AccessToken.class); + verifyNoMoreInteractions(restTemplate); + } } diff --git a/chucknorris-web/src/test/java/io/chucknorris/lib/event/EventServiceTest.java b/chucknorris-web/src/test/java/io/chucknorris/lib/event/EventServiceTest.java index 291d0d7..ae61f4c 100644 --- a/chucknorris-web/src/test/java/io/chucknorris/lib/event/EventServiceTest.java +++ b/chucknorris-web/src/test/java/io/chucknorris/lib/event/EventServiceTest.java @@ -8,8 +8,10 @@ @RunWith(MockitoJUnitRunner.class) public class EventServiceTest { - @InjectMocks private EventService eventService; + @InjectMocks + private EventService eventService; - @Test - public void testPublish() {} + @Test + public void testPublish() { + } } diff --git a/format.xml b/format.xml new file mode 100644 index 0000000..cb81266 --- /dev/null +++ b/format.xml @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file