chore: add drone-ci-tests and docker build (#1)
continuous-integration/drone/push Build is passing Details

Co-authored-by: Davide Polonio <poloniodavide@gmail.com>
Reviewed-on: #1
Co-authored-by: polpetta <polpetta@poldebra.me>
Co-committed-by: polpetta <polpetta@poldebra.me>
devel
Davide Polonio 2023-03-27 17:16:29 +02:00
parent d1f44bc070
commit cea9f3222a
35 changed files with 346 additions and 225 deletions

View File

@ -1,9 +1,71 @@
kind: pipeline kind: pipeline
type: docker type: docker
name: default name: commit
steps: steps:
- name: Build - name: checks
image: eclipse-temurin:17-jdk image: eclipse-temurin:17-jdk
commands: commands:
- ./mvnw package -B -DskipTests=true - apt-get update -qq && apt-get install -qy python3 pip git && pip install pre-commit
- pre-commit run --all-files
---
kind: pipeline
type: docker
name: pr
steps:
- name: tests
image: quay.io/testcontainers/dind-drone-plugin
environment:
CI_WORKSPACE: "/drone/src"
settings:
cmd: ./mvnw -B test
build_image: eclipse-temurin:17-jdk
prefetch_images:
- "postgres:13-alpine"
volumes:
- name: dockersock
path: /var/run
# Specify docker:dind as a service
services:
- name: docker
image: docker:dind
privileged: true
volumes:
- name: dockersock
path: /var/run
volumes:
- name: dockersock
temp: {}
trigger:
event:
- pull_request
- cron
---
kind: pipeline
type: docker
name: artifacts
steps:
- name: packaging
image: eclipse-temurin:17-jdk
commands:
- ./mvnw package -B -DskipTests=true -Dmaven.test.skip=true -Dmaven.site.skip=true -Dmaven.javadoc.skip=true
- name: dockerfile
image: thegeeklab/drone-docker-buildx:23
privileged: true
settings:
pull_image: true
dry_run: true
trigger:
branch:
- devel
event:
- push
- tag

2
.markdownlint.yaml Normal file
View File

@ -0,0 +1,2 @@
MD013:
line_length: 120

33
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,33 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
exclude: "mvnw"
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
exclude: "^.*\\.vm$"
- id: check-yaml
args: [--allow-multiple-documents]
- id: check-added-large-files
- id: check-toml
- id: mixed-line-ending
- repo: https://github.com/gruntwork-io/pre-commit
rev: v0.1.17
hooks:
- id: shellcheck
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.4.0
hooks:
- id: pretty-format-java
args: [--autofix]
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.32.2
hooks:
- id: markdownlint
- id: markdownlint-fix
- repo: https://github.com/jorisroovers/gitlint
rev: v0.17.0
hooks:
- id: gitlint

View File

@ -14,14 +14,17 @@ Keep in mind that Mezzotre is meant to be run behind a reverse proxy handling al
In the root of the project you can find a `docker-compose.yml` file that can be a useful starting point to generate your In the root of the project you can find a `docker-compose.yml` file that can be a useful starting point to generate your
configuration. Finally, you can use the same docker-compose definition as a developer to have a live version running. configuration. Finally, you can use the same docker-compose definition as a developer to have a live version running.
Simply run: Simply run:
```shell ```shell
DEBUG_OPTS=debug- docker-compose up -d --build && docker-compose logs -f DEBUG_OPTS=debug- docker-compose up -d --build && docker-compose logs -f
``` ```
to run a debug instance. Omit the `DEBUG_OPTS` env variable for a "production" style environment. Note that this to run a debug instance. Omit the `DEBUG_OPTS` env variable for a "production" style environment. Note that this
configuration requires an `.env` file (that is not committed for obvious reasons) containing the database password and a configuration requires an `.env` file (that is not committed for obvious reasons) containing the database password and a
valid Telegram Bot token. valid Telegram Bot token.
To configure Webhook configuration for your bot, open up a terminal and type: To configure Webhook configuration for your bot, open up a terminal and type:
```shell ```shell
curl -F "url=https://example.com/api/tg" https://api.telegram.org/bot<YOUR BOT TOKEN>/setWebhook curl -F "url=https://example.com/api/tg" https://api.telegram.org/bot<YOUR BOT TOKEN>/setWebhook
``` ```
@ -29,6 +32,7 @@ curl -F "url=https://example.com/api/tg" https://api.telegram.org/bot<YOUR BOT T
## Building ## Building
Build is achieved through Maven. To build a `jar` run: Build is achieved through Maven. To build a `jar` run:
```shell ```shell
mvn package -DskipTests=true -Dmaven.test.skip=true -Dmaven.site.skip=true -Dmaven.javadoc.skip=true mvn package -DskipTests=true -Dmaven.test.skip=true -Dmaven.site.skip=true -Dmaven.javadoc.skip=true
``` ```

View File

@ -1,7 +1,9 @@
package com.github.polpetta.mezzotre; package com.github.polpetta.mezzotre;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides;import io.jooby.Jooby;import org.slf4j.Logger; import com.google.inject.Provides;
import io.jooby.Jooby;
import org.slf4j.Logger;
public class InjectionModule extends AbstractModule { public class InjectionModule extends AbstractModule {
private final Jooby jooby; private final Jooby jooby;

View File

@ -1,5 +1,7 @@
package com.github.polpetta.mezzotre.i18n; package com.github.polpetta.mezzotre.i18n;
import java.util.Locale;
import javax.inject.Inject;
import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.resource.loader.JarResourceLoader; import org.apache.velocity.runtime.resource.loader.JarResourceLoader;
import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.Scope;
@ -8,8 +10,6 @@ import org.apache.velocity.tools.ToolManager;
import org.apache.velocity.tools.config.FactoryConfiguration; import org.apache.velocity.tools.config.FactoryConfiguration;
import org.apache.velocity.tools.config.ToolConfiguration; import org.apache.velocity.tools.config.ToolConfiguration;
import org.apache.velocity.tools.config.ToolboxConfiguration; import org.apache.velocity.tools.config.ToolboxConfiguration;
import javax.inject.Inject;
import java.util.Locale;
public class LocalizedMessageFactory { public class LocalizedMessageFactory {
@ -22,8 +22,7 @@ public class LocalizedMessageFactory {
public ToolManager create(Locale locale) { public ToolManager create(Locale locale) {
// properties.setProperty("file.resource.loader.class", FileResourceLoader.class.getName());. // properties.setProperty("file.resource.loader.class", FileResourceLoader.class.getName());.
final ToolManager toolManager = new ToolManager(); final ToolManager toolManager = new ToolManager();
toolManager.setVelocityEngine(velocityEngine); toolManager.setVelocityEngine(velocityEngine);

View File

@ -1,8 +1,8 @@
package com.github.polpetta.mezzotre.i18n; package com.github.polpetta.mezzotre.i18n;
import java.util.Locale;
import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.DefaultKey;
import org.apache.velocity.tools.generic.ResourceTool; import org.apache.velocity.tools.generic.ResourceTool;
import java.util.Locale;
@DefaultKey("i18n") @DefaultKey("i18n")
public class LocalizedTool extends ResourceTool { public class LocalizedTool extends ResourceTool {

View File

@ -1,38 +1,46 @@
package com.github.polpetta.mezzotre.orm.di; package com.github.polpetta.mezzotre.orm.di;
import com.google.inject.AbstractModule;import com.google.inject.Provides;import com.google.inject.Singleton;import com.zaxxer.hikari.HikariConfig;import io.jooby.Extension;import io.jooby.ebean.EbeanModule;import io.jooby.flyway.FlywayModule;import io.jooby.hikari.HikariModule;import javax.inject.Named; import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.zaxxer.hikari.HikariConfig;
import io.jooby.Extension;
import io.jooby.ebean.EbeanModule;
import io.jooby.flyway.FlywayModule;
import io.jooby.hikari.HikariModule;
import javax.inject.Named;
public class Db extends AbstractModule { public class Db extends AbstractModule {
/** /**
* Returns null. This allows to fetch the configuration from file rather than fetch from other * Returns null. This allows to fetch the configuration from file rather than fetch from other
* environment * environment
* *
* @return a {@link HikariConfig} configuration if possible * @return a {@link HikariConfig} configuration if possible
*/ */
@Provides @Provides
@Singleton @Singleton
public HikariConfig getHikariConfig() { public HikariConfig getHikariConfig() {
return null; return null;
} }
@Provides @Provides
@Singleton @Singleton
@Named("hikariPoolExtension") @Named("hikariPoolExtension")
public Extension getHikariExtension() { public Extension getHikariExtension() {
return new HikariModule(); return new HikariModule();
} }
@Provides @Provides
@Singleton @Singleton
@Named("flyWayMigrationExtension") @Named("flyWayMigrationExtension")
public Extension getFlyWayMigrationExtension() { public Extension getFlyWayMigrationExtension() {
return new FlywayModule(); return new FlywayModule();
} }
@Provides @Provides
@Singleton @Singleton
@Named("ebeanExtension") @Named("ebeanExtension")
public Extension getEbeanExtension() { public Extension getEbeanExtension() {
return new EbeanModule(); return new EbeanModule();
} }
} }

View File

@ -3,11 +3,12 @@ package com.github.polpetta.mezzotre.orm.model;
import io.ebean.Model; import io.ebean.Model;
import io.ebean.annotation.WhenCreated; import io.ebean.annotation.WhenCreated;
import io.ebean.annotation.WhenModified; import io.ebean.annotation.WhenModified;
import javax.persistence.MappedSuperclass;
import java.time.Instant; import java.time.Instant;
import javax.persistence.MappedSuperclass;
/** /**
* Father class to all the database objects. It allows to add when an object has been created and modifies * Father class to all the database objects. It allows to add when an object has been created and
* modifies
* *
* @author Davide Polonio * @author Davide Polonio
* @since 1.0-SNAPSHOT * @since 1.0-SNAPSHOT

View File

@ -1,6 +1,6 @@
package com.github.polpetta.mezzotre.route; package com.github.polpetta.mezzotre.route;
public final class Constants { public final class Constants {
public final static String V1 = "v1"; public static final String V1 = "v1";
public final static String API = "api"; public static final String API = "api";
} }

View File

@ -21,7 +21,10 @@ public class Route extends AbstractModule {
.orElseThrow( .orElseThrow(
() -> () ->
new IllegalStateException( new IllegalStateException(
"Telegram token is required to make the application work. Please set 'telegram.key = \"value\"' in your application.conf file or as the application argument. Alternatively, you can set 'TELEGRAM_KEY' as an environment variable.")); "Telegram token is required to make the application work. Please set"
+ " 'telegram.key = \"value\"' in your application.conf file or as the"
+ " application argument. Alternatively, you can set 'TELEGRAM_KEY' as"
+ " an environment variable."));
return new TelegramBot(telegramKey); return new TelegramBot(telegramKey);
} }
} }

View File

@ -3,7 +3,6 @@ package com.github.polpetta.mezzotre.telegram.command;
import com.github.polpetta.mezzotre.orm.model.TgChat; import com.github.polpetta.mezzotre.orm.model.TgChat;
import com.pengrad.telegrambot.model.Update; import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.request.BaseRequest; import com.pengrad.telegrambot.request.BaseRequest;
import com.pengrad.telegrambot.request.SendMessage;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -27,10 +26,10 @@ public interface Executor {
/** /**
* Process the current update * Process the current update
* *
* @param chat the chat the {@link Executor} is currently replying to * @param chat the chat the {@link Executor} is currently replying to
* @param update the update to process * @param update the update to process
* @return a {@link CompletableFuture} with the result of the computation * @return a {@link CompletableFuture} with the result of the computation
*/ */
// FIXME cannot be void - we don't want pesky side effects! // FIXME cannot be void - we don't want pesky side effects!
CompletableFuture<Optional<BaseRequest<?,?>>> process(TgChat chat, Update update); CompletableFuture<Optional<BaseRequest<?, ?>>> process(TgChat chat, Update update);
} }

View File

@ -86,13 +86,13 @@ public class Start implements Executor {
.get(); .get();
log.trace("Start command - message to send back: " + message); log.trace("Start command - message to send back: " + message);
final ChatContext chatContext = chat.getChatContext(); final ChatContext chatContext = chat.getChatContext();
chatContext.setLastMessageSentId(update.message().messageId()); chatContext.setLastMessageSentId(update.message().messageId());
chatContext.setStage(getTriggerKeyword()); chatContext.setStage(getTriggerKeyword());
chatContext.setStep(0); chatContext.setStep(0);
chatContext.setPreviousMessageUnixTimestampInSeconds(update.message().date()); chatContext.setPreviousMessageUnixTimestampInSeconds(update.message().date());
chat.setChatContext(chatContext); chat.setChatContext(chatContext);
chat.save(); chat.save();
return Optional.of(new SendMessage(chat.getId(), message).parseMode(ParseMode.Markdown)); return Optional.of(new SendMessage(chat.getId(), message).parseMode(ParseMode.Markdown));
}, },

View File

@ -1,28 +1,31 @@
package com.github.polpetta.mezzotre.telegram.command.di; package com.github.polpetta.mezzotre.telegram.command.di;
import com.github.polpetta.mezzotre.telegram.command.Executor;import com.github.polpetta.mezzotre.telegram.command.Start;import com.google.common.io.Resources;import com.google.inject.AbstractModule;import com.google.inject.Provides;import org.apache.velocity.app.VelocityEngine; import com.github.polpetta.mezzotre.telegram.command.Executor;
import com.github.polpetta.mezzotre.telegram.command.Start;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import java.util.Set;
import javax.inject.Named;
import javax.inject.Singleton;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import javax.inject.Named;
import javax.inject.Singleton;import java.util.Set;
public class Command extends AbstractModule { public class Command extends AbstractModule {
@Provides @Provides
@Singleton @Singleton
@Named("commands") @Named("commands")
public Set<Executor> getCommandExecutors( public Set<Executor> getCommandExecutors(Start start) {
Start start return Set.of(start);
) { }
return Set.of(start);
}
@Provides @Provides
public VelocityEngine getVelocityEngine() { public VelocityEngine getVelocityEngine() {
final VelocityEngine velocityEngine = new VelocityEngine(); final VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
velocityEngine.setProperty( velocityEngine.setProperty(
"classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); "classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
velocityEngine.init(); velocityEngine.init();
return velocityEngine; return velocityEngine;
} }
} }

View File

@ -2,11 +2,11 @@ package com.github.polpetta.mezzotre.util.di;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import javax.inject.Named;
import javax.inject.Singleton;
public class ThreadPool extends AbstractModule { public class ThreadPool extends AbstractModule {
@Provides @Provides

View File

@ -21,4 +21,3 @@ create table registered_user (
-- foreign keys and indices -- foreign keys and indices
alter table registered_user add constraint fk_registered_user_telegram_id foreign key (telegram_id) references telegram_chat (id) on delete cascade on update restrict; alter table registered_user add constraint fk_registered_user_telegram_id foreign key (telegram_id) references telegram_chat (id) on delete cascade on update restrict;

View File

@ -3,21 +3,14 @@ package com.github.polpetta.mezzotre;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import com.github.polpetta.mezzotre.helper.IntegrationAppFactory; import com.github.polpetta.mezzotre.helper.IntegrationAppFactory;
import com.github.polpetta.mezzotre.helper.Loader;
import com.github.polpetta.mezzotre.helper.TestConfig;
import io.ebean.Database;
import io.jooby.JoobyTest; import io.jooby.JoobyTest;
import io.jooby.StatusCode; import io.jooby.StatusCode;
import java.io.IOException; import java.io.IOException;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@Tag("slow") @Tag("slow")
@Tag("database") @Tag("database")

View File

@ -1,7 +1,6 @@
package com.github.polpetta.mezzotre.helper; package com.github.polpetta.mezzotre.helper;
import com.github.polpetta.mezzotre.App; import com.github.polpetta.mezzotre.App;
import com.github.polpetta.mezzotre.InjectionModule;
import com.github.polpetta.mezzotre.route.di.Route; import com.github.polpetta.mezzotre.route.di.Route;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;

View File

@ -1,43 +1,52 @@
package com.github.polpetta.mezzotre.helper; package com.github.polpetta.mezzotre.helper;
import com.github.polpetta.mezzotre.App;import com.google.common.io.Resources;import com.zaxxer.hikari.HikariConfig;import com.zaxxer.hikari.HikariDataSource;import io.ebean.Database;import io.ebean.DatabaseFactory;import io.ebean.config.DatabaseConfig;import org.apache.commons.lang3.tuple.Pair;import org.testcontainers.containers.PostgreSQLContainer;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.util.Properties;public class Loader { import com.google.common.io.Resources;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.config.DatabaseConfig;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;
import org.apache.commons.lang3.tuple.Pair;
import org.testcontainers.containers.PostgreSQLContainer;
public static Pair<Properties, Properties> loadDefaultEbeanConfigWithPostgresSettings( public class Loader {
PostgreSQLContainer<?> container) throws IOException {
public static Pair<Properties, Properties> loadDefaultEbeanConfigWithPostgresSettings(
PostgreSQLContainer<?> container) throws IOException {
final URL ebeanRes = Resources.getResource("database-test.properties"); final URL ebeanRes = Resources.getResource("database-test.properties");
final URL hikariRes = Resources.getResource("hikari.properties"); final URL hikariRes = Resources.getResource("hikari.properties");
final Properties ebeanConnectionProperties = new Properties(); final Properties ebeanConnectionProperties = new Properties();
final Properties hikariConnectionProperties = new Properties(); final Properties hikariConnectionProperties = new Properties();
try (InputStream ebeanInputStream = ebeanRes.openStream(); try (InputStream ebeanInputStream = ebeanRes.openStream();
InputStream hikariInputStream = hikariRes.openStream()) { InputStream hikariInputStream = hikariRes.openStream()) {
hikariConnectionProperties.load(hikariInputStream); hikariConnectionProperties.load(hikariInputStream);
hikariConnectionProperties.put("username", container.getUsername()); hikariConnectionProperties.put("username", container.getUsername());
hikariConnectionProperties.put("password", container.getPassword()); hikariConnectionProperties.put("password", container.getPassword());
hikariConnectionProperties.put("jdbcUrl", container.getJdbcUrl()); hikariConnectionProperties.put("jdbcUrl", container.getJdbcUrl());
ebeanConnectionProperties.load(ebeanInputStream); ebeanConnectionProperties.load(ebeanInputStream);
ebeanConnectionProperties.put("datasource_db_username", container.getUsername()); ebeanConnectionProperties.put("datasource_db_username", container.getUsername());
ebeanConnectionProperties.put("datasource_db_password", container.getPassword()); ebeanConnectionProperties.put("datasource_db_password", container.getPassword());
ebeanConnectionProperties.put("datasource_db_databaseUrl", container.getJdbcUrl()); ebeanConnectionProperties.put("datasource_db_databaseUrl", container.getJdbcUrl());
ebeanConnectionProperties.put("datasource_db_databaseDriver", "org.postgresql.Driver"); ebeanConnectionProperties.put("datasource_db_databaseDriver", "org.postgresql.Driver");
}
return Pair.of(ebeanConnectionProperties, hikariConnectionProperties);
} }
return Pair.of(ebeanConnectionProperties, hikariConnectionProperties);
}
public static Database connectToDatabase( public static Database connectToDatabase(Properties ebean, Properties hikari) {
Properties ebean, final HikariDataSource hikariDataSource = new HikariDataSource(new HikariConfig(hikari));
Properties hikari final DatabaseConfig databaseConfig = new DatabaseConfig();
) { databaseConfig.loadFromProperties(ebean);
final HikariDataSource hikariDataSource = databaseConfig.setDataSource(hikariDataSource);
new HikariDataSource(new HikariConfig(hikari));
final DatabaseConfig databaseConfig = new DatabaseConfig();
databaseConfig.loadFromProperties(ebean);
databaseConfig.setDataSource(hikariDataSource);
return DatabaseFactory.create(databaseConfig); return DatabaseFactory.create(databaseConfig);
} }
public static Database connectToDatabase(Pair<Properties, Properties> connectionProperties) { public static Database connectToDatabase(Pair<Properties, Properties> connectionProperties) {
return connectToDatabase(connectionProperties.getLeft(), connectionProperties.getRight()); return connectToDatabase(connectionProperties.getLeft(), connectionProperties.getRight());
} }
} }

View File

@ -52,7 +52,8 @@ public class UserIntegrationTest {
final Timestamp timestampFromUnixEpoch = Clock.getTimestampFromUnixEpoch(1L); final Timestamp timestampFromUnixEpoch = Clock.getTimestampFromUnixEpoch(1L);
final String insertQuery = final String insertQuery =
"insert into registered_user (id, is_active, telegram_id, email_address, entry_created, entry_modified) values (?, ?, null, ?, ?, ?)"; "insert into registered_user (id, is_active, telegram_id, email_address, entry_created,"
+ " entry_modified) values (?, ?, null, ?, ?, ?)";
final int affectedRows = final int affectedRows =
database database
.sqlUpdate(insertQuery) .sqlUpdate(insertQuery)

View File

@ -78,30 +78,30 @@ class TelegramIntegrationTest {
final Context fakeContext = mock(Context.class); final Context fakeContext = mock(Context.class);
final Update update = final Update update =
gson.fromJson( gson.fromJson(
""" "{\n"
{ + "\"update_id\":10000,\n"
"update_id":10000, + "\"message\":{\n"
"message":{ + " \"date\":1441645532,\n"
"date":1441645532, + " \"chat\":{\n"
"chat":{ + " \"last_name\":\"Test Lastname\",\n"
"last_name":"Test Lastname", + " \"id\":1111111,\n"
"id":1111111, + " \"type\": \"private\",\n"
"type": "private", + " \"first_name\":\"Test Firstname\",\n"
"first_name":"Test Firstname", + " \"username\":\"Testusername\"\n"
"username":"Testusername" + " },\n"
}, + " \"message_id\":1365,\n"
"message_id":1365, + " \"from\":{\n"
"from":{ + " \"last_name\":\"Test Lastname\",\n"
"last_name":"Test Lastname", + " \"id\":1111111,\n"
"id":1111111, + " \"first_name\":\"Test Firstname\",\n"
"first_name":"Test Firstname", + " \"username\":\"Testusername\"\n"
"username":"Testusername" + " },\n"
}, + " \"text\":\"/start\"\n"
"text":"/start" + "}\n"
} + "}\n",
}""",
Update.class); Update.class);
final CompletableFuture<String> integerCompletableFuture = telegram.incomingUpdate(fakeContext, update); final CompletableFuture<String> integerCompletableFuture =
telegram.incomingUpdate(fakeContext, update);
verify(fakeContext, times(1)).setResponseType(MediaType.JSON); verify(fakeContext, times(1)).setResponseType(MediaType.JSON);
final String gotReply = integerCompletableFuture.get(); final String gotReply = integerCompletableFuture.get();
assertDoesNotThrow(() -> gotReply); assertDoesNotThrow(() -> gotReply);

View File

@ -1,22 +1,24 @@
package com.github.polpetta.mezzotre.telegram.command; package com.github.polpetta.mezzotre.telegram.command;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.github.polpetta.mezzotre.orm.model.TgChat; import com.github.polpetta.mezzotre.orm.model.TgChat;
import com.github.polpetta.types.json.ChatContext; import com.github.polpetta.types.json.ChatContext;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.pengrad.telegrambot.model.Update; import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.request.BaseRequest; import com.pengrad.telegrambot.request.BaseRequest;
import com.pengrad.telegrambot.request.SendMessage; import com.pengrad.telegrambot.request.SendMessage;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeAll;
import static org.mockito.ArgumentMatchers.any; import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.mock; import org.junit.jupiter.api.parallel.Execution;
import static org.mockito.Mockito.when; import org.junit.jupiter.api.parallel.ExecutionMode;
@Execution(ExecutionMode.CONCURRENT) @Execution(ExecutionMode.CONCURRENT)
class RouterTest { class RouterTest {

View File

@ -1,5 +1,7 @@
package com.github.polpetta.mezzotre.telegram.command; package com.github.polpetta.mezzotre.telegram.command;
import static org.junit.jupiter.api.Assertions.*;
import com.github.polpetta.mezzotre.helper.Loader; import com.github.polpetta.mezzotre.helper.Loader;
import com.github.polpetta.mezzotre.helper.TestConfig; import com.github.polpetta.mezzotre.helper.TestConfig;
import com.github.polpetta.mezzotre.i18n.LocalizedMessageFactory; import com.github.polpetta.mezzotre.i18n.LocalizedMessageFactory;
@ -11,6 +13,9 @@ import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.request.BaseRequest; import com.pengrad.telegrambot.request.BaseRequest;
import com.pengrad.telegrambot.request.SendMessage; import com.pengrad.telegrambot.request.SendMessage;
import io.ebean.Database; import io.ebean.Database;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
@ -24,12 +29,6 @@ import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import static org.junit.jupiter.api.Assertions.*;
@Tag("slow") @Tag("slow")
@Tag("database") @Tag("database")
@Tag("velocity") @Tag("velocity")
@ -76,28 +75,27 @@ class StartIntegrationTest {
final Update update = final Update update =
gson.fromJson( gson.fromJson(
""" "{\n"
{ + "\"update_id\":10000,\n"
"update_id":10000, + "\"message\":{\n"
"message":{ + " \"date\":1441645532,\n"
"date":1441645532, + " \"chat\":{\n"
"chat":{ + " \"last_name\":\"Test Lastname\",\n"
"last_name":"Test Lastname", + " \"id\":1111111,\n"
"id":1111111, + " \"type\": \"private\",\n"
"type": "private", + " \"first_name\":\"Test Firstname\",\n"
"first_name":"Test Firstname", + " \"username\":\"Testusername\"\n"
"username":"Testusername" + " },\n"
}, + " \"message_id\":1365,\n"
"message_id":1365, + " \"from\":{\n"
"from":{ + " \"last_name\":\"Test Lastname\",\n"
"last_name":"Test Lastname", + " \"id\":1111111,\n"
"id":1111111, + " \"first_name\":\"Test Firstname\",\n"
"first_name":"Test Firstname", + " \"username\":\"Testusername\"\n"
"username":"Testusername" + " },\n"
}, + " \"text\":\"/start\"\n"
"text":"/start" + "}\n"
} + "}",
}""",
Update.class); Update.class);
final CompletableFuture<Optional<BaseRequest<?, ?>>> gotFuture = start.process(tgChat, update); final CompletableFuture<Optional<BaseRequest<?, ?>>> gotFuture = start.process(tgChat, update);
@ -108,7 +106,9 @@ class StartIntegrationTest {
assertInstanceOf(SendMessage.class, gotMessage); assertInstanceOf(SendMessage.class, gotMessage);
final String message = (String) gotMessage.getParameters().get("text"); final String message = (String) gotMessage.getParameters().get("text");
assertEquals( assertEquals(
"**Hello Test Firstname! \uD83D\uDC4B**\n\nThis is _Mezzotre_, a simple bot focused on DnD content management! Please start by choosing a language down below. \uD83D\uDC47", "**Hello Test Firstname! \uD83D\uDC4B**\n\n"
+ "This is _Mezzotre_, a simple bot focused on DnD content management! Please start by"
+ " choosing a language down below. \uD83D\uDC47",
message); message);
assertEquals(1111111L, (Long) gotMessage.getParameters().get("chat_id")); assertEquals(1111111L, (Long) gotMessage.getParameters().get("chat_id"));

View File

@ -1,5 +1,8 @@
package com.github.polpetta.mezzotre.telegram.command; package com.github.polpetta.mezzotre.telegram.command;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import com.github.polpetta.mezzotre.i18n.LocalizedMessageFactory; import com.github.polpetta.mezzotre.i18n.LocalizedMessageFactory;
import com.github.polpetta.mezzotre.orm.model.TgChat; import com.github.polpetta.mezzotre.orm.model.TgChat;
import com.github.polpetta.types.json.ChatContext; import com.github.polpetta.types.json.ChatContext;
@ -7,6 +10,10 @@ import com.google.gson.Gson;
import com.pengrad.telegrambot.model.Update; import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.request.BaseRequest; import com.pengrad.telegrambot.request.BaseRequest;
import com.pengrad.telegrambot.request.SendMessage; import com.pengrad.telegrambot.request.SendMessage;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
@ -18,14 +25,6 @@ import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode; import org.junit.jupiter.api.parallel.ExecutionMode;
import org.slf4j.Logger; import org.slf4j.Logger;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
@Tag("velocity") @Tag("velocity")
@Execution(ExecutionMode.CONCURRENT) @Execution(ExecutionMode.CONCURRENT)
class StartTest { class StartTest {
@ -38,7 +37,9 @@ class StartTest {
@BeforeAll @BeforeAll
static void beforeAll() { static void beforeAll() {
gson = new Gson(); gson = new Gson();
}@BeforeEach }
@BeforeEach
void setUp() { void setUp() {
velocityEngine = new VelocityEngine(); velocityEngine = new VelocityEngine();
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADERS, "classpath"); velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADERS, "classpath");
@ -61,28 +62,27 @@ class StartTest {
final Update update = final Update update =
gson.fromJson( gson.fromJson(
""" "{\n"
{ + "\"update_id\":10000,\n"
"update_id":10000, + "\"message\":{\n"
"message":{ + " \"date\":1441645532,\n"
"date":1441645532, + " \"chat\":{\n"
"chat":{ + " \"last_name\":\"Test Lastname\",\n"
"last_name":"Test Lastname", + " \"id\":1111111,\n"
"id":1111111, + " \"type\": \"private\",\n"
"type": "private", + " \"first_name\":\"Test Firstname\",\n"
"first_name":"Test Firstname", + " \"username\":\"Testusername\"\n"
"username":"Testusername" + " },\n"
}, + " \"message_id\":1365,\n"
"message_id":1365, + " \"from\":{\n"
"from":{ + " \"last_name\":\"Test Lastname\",\n"
"last_name":"Test Lastname", + " \"id\":1111111,\n"
"id":1111111, + " \"first_name\":\"Test Firstname\",\n"
"first_name":"Test Firstname", + " \"username\":\"Testusername\"\n"
"username":"Testusername" + " },\n"
}, + " \"text\":\"/start\"\n"
"text":"/start" + "}\n"
} + "}",
}""",
Update.class); Update.class);
final CompletableFuture<Optional<BaseRequest<?, ?>>> gotFuture = final CompletableFuture<Optional<BaseRequest<?, ?>>> gotFuture =
@ -94,7 +94,9 @@ class StartTest {
assertInstanceOf(SendMessage.class, gotMessage); assertInstanceOf(SendMessage.class, gotMessage);
final String message = (String) gotMessage.getParameters().get("text"); final String message = (String) gotMessage.getParameters().get("text");
assertEquals( assertEquals(
"**Hello Test Firstname! \uD83D\uDC4B**\n\nThis is _Mezzotre_, a simple bot focused on DnD content management! Please start by choosing a language down below. \uD83D\uDC47", "**Hello Test Firstname! \uD83D\uDC4B**\n\n"
+ "This is _Mezzotre_, a simple bot focused on DnD content management! Please start by"
+ " choosing a language down below. \uD83D\uDC47",
message); message);
assertEquals(1111111L, (Long) gotMessage.getParameters().get("chat_id")); assertEquals(1111111L, (Long) gotMessage.getParameters().get("chat_id"));
verify(fakeChat, times(1)).save(); verify(fakeChat, times(1)).save();