feat: add first changeLanguage event implementation
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
421909d5ae
commit
3705840989
8
pom.xml
8
pom.xml
|
@ -40,6 +40,7 @@
|
||||||
<org.testcontainers.junit-jupiter.version>1.16.3</org.testcontainers.junit-jupiter.version>
|
<org.testcontainers.junit-jupiter.version>1.16.3</org.testcontainers.junit-jupiter.version>
|
||||||
<jsonschema2pojo.version>1.1.1</jsonschema2pojo.version>
|
<jsonschema2pojo.version>1.1.1</jsonschema2pojo.version>
|
||||||
<jackson-databind.version>2.13.3</jackson-databind.version>
|
<jackson-databind.version>2.13.3</jackson-databind.version>
|
||||||
|
<junit-jupiter-params.version>5.9.1</junit-jupiter-params.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -68,6 +69,13 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-params</artifactId>
|
||||||
|
<version>${junit-jupiter-params.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.jooby</groupId>
|
<groupId>io.jooby</groupId>
|
||||||
<artifactId>jooby-test</artifactId>
|
<artifactId>jooby-test</artifactId>
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
"default": {},
|
"default": {},
|
||||||
"required": [
|
"required": [
|
||||||
"event",
|
"event",
|
||||||
"messageId",
|
|
||||||
"telegramChatId"
|
"telegramChatId"
|
||||||
],
|
],
|
||||||
"additionalProperties": true,
|
"additionalProperties": true,
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.github.polpetta.mezzotre;
|
||||||
import com.github.polpetta.mezzotre.orm.di.Db;
|
import com.github.polpetta.mezzotre.orm.di.Db;
|
||||||
import com.github.polpetta.mezzotre.route.Telegram;
|
import com.github.polpetta.mezzotre.route.Telegram;
|
||||||
import com.github.polpetta.mezzotre.route.di.Route;
|
import com.github.polpetta.mezzotre.route.di.Route;
|
||||||
|
import com.github.polpetta.mezzotre.telegram.callbackquery.di.CallbackQuery;
|
||||||
import com.github.polpetta.mezzotre.telegram.command.di.Command;
|
import com.github.polpetta.mezzotre.telegram.command.di.Command;
|
||||||
import com.github.polpetta.mezzotre.util.di.ThreadPool;
|
import com.github.polpetta.mezzotre.util.di.ThreadPool;
|
||||||
import com.google.inject.*;
|
import com.google.inject.*;
|
||||||
|
@ -26,6 +27,7 @@ public class App extends Jooby {
|
||||||
modules.add(new ThreadPool());
|
modules.add(new ThreadPool());
|
||||||
modules.add(new Route());
|
modules.add(new Route());
|
||||||
modules.add(new Command());
|
modules.add(new Command());
|
||||||
|
modules.add(new CallbackQuery());
|
||||||
return modules;
|
return modules;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ public class LocalizedMessageFactory {
|
||||||
|
|
||||||
public ToolManager create(Locale locale) {
|
public ToolManager create(Locale locale) {
|
||||||
|
|
||||||
// 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);
|
||||||
final FactoryConfiguration factoryConfiguration = new FactoryConfiguration();
|
final FactoryConfiguration factoryConfiguration = new FactoryConfiguration();
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.github.polpetta.mezzotre.orm.model;
|
||||||
|
|
||||||
import com.github.polpetta.types.json.CallbackQueryMetadata;
|
import com.github.polpetta.types.json.CallbackQueryMetadata;
|
||||||
import io.ebean.annotation.DbJson;
|
import io.ebean.annotation.DbJson;
|
||||||
|
import io.ebean.annotation.Length;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
@ -22,12 +23,19 @@ import javax.validation.constraints.NotNull;
|
||||||
@Table(name = "callback_query_context")
|
@Table(name = "callback_query_context")
|
||||||
public class CallbackQueryContext extends Base {
|
public class CallbackQueryContext extends Base {
|
||||||
|
|
||||||
@Id private final String id;
|
@Id
|
||||||
|
@Length(36)
|
||||||
|
private final String id;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Length(36)
|
||||||
|
private final String entryGroup;
|
||||||
|
|
||||||
@DbJson @NotNull private final CallbackQueryMetadata fields;
|
@DbJson @NotNull private final CallbackQueryMetadata fields;
|
||||||
|
|
||||||
public CallbackQueryContext(String id, CallbackQueryMetadata fields) {
|
public CallbackQueryContext(String id, String entryGroup, CallbackQueryMetadata fields) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
this.entryGroup = entryGroup;
|
||||||
this.fields = fields;
|
this.fields = fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +43,10 @@ public class CallbackQueryContext extends Base {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getEntryGroup() {
|
||||||
|
return entryGroup;
|
||||||
|
}
|
||||||
|
|
||||||
public CallbackQueryMetadata getFields() {
|
public CallbackQueryMetadata getFields() {
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,157 @@
|
||||||
package com.github.polpetta.mezzotre.telegram.callbackquery;
|
package com.github.polpetta.mezzotre.telegram.callbackquery;
|
||||||
|
|
||||||
|
import com.github.polpetta.mezzotre.i18n.LocalizedMessageFactory;
|
||||||
import com.github.polpetta.mezzotre.orm.model.CallbackQueryContext;
|
import com.github.polpetta.mezzotre.orm.model.CallbackQueryContext;
|
||||||
|
import com.github.polpetta.mezzotre.orm.model.query.QCallbackQueryContext;
|
||||||
|
import com.github.polpetta.mezzotre.orm.model.query.QTgChat;
|
||||||
import com.pengrad.telegrambot.model.Update;
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.model.request.ParseMode;
|
||||||
import com.pengrad.telegrambot.request.BaseRequest;
|
import com.pengrad.telegrambot.request.BaseRequest;
|
||||||
|
import com.pengrad.telegrambot.request.SendMessage;
|
||||||
|
import io.vavr.control.Try;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import org.apache.velocity.VelocityContext;
|
||||||
|
import org.apache.velocity.tools.ToolManager;
|
||||||
|
import org.apache.velocity.util.StringBuilderWriter;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ChangeLanguage implements Processor {
|
public class ChangeLanguage implements Processor {
|
||||||
|
|
||||||
|
public static final String EVENT_NAME = "changeLanguage";
|
||||||
|
private final Executor threadPool;
|
||||||
|
private final LocalizedMessageFactory localizedMessageFactory;
|
||||||
|
private final Logger log;
|
||||||
|
|
||||||
|
public enum Field {
|
||||||
|
NewLanguage("newLanguage");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
Field(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Language {
|
||||||
|
English("en-US"),
|
||||||
|
Italian("it-IT");
|
||||||
|
|
||||||
|
private final String locale;
|
||||||
|
|
||||||
|
Language(String locale) {
|
||||||
|
this.locale = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocale() {
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ChangeLanguage() {}
|
public ChangeLanguage(
|
||||||
|
@Named("eventThreadPool") Executor threadPool,
|
||||||
|
LocalizedMessageFactory localizedMessageFactory,
|
||||||
|
Logger log) {
|
||||||
|
this.threadPool = threadPool;
|
||||||
|
this.localizedMessageFactory = localizedMessageFactory;
|
||||||
|
this.log = log;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getEventName() {
|
public String getEventName() {
|
||||||
return "changeLanguage";
|
return EVENT_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Optional<BaseRequest<?, ?>>> process(
|
public CompletableFuture<Optional<BaseRequest<?, ?>>> process(
|
||||||
CallbackQueryContext callbackQueryContext, Update update) {
|
CallbackQueryContext callbackQueryContext, Update update) {
|
||||||
return null;
|
return CompletableFuture.supplyAsync(
|
||||||
|
() ->
|
||||||
|
Optional.of(callbackQueryContext.getFields().getTelegramChatId())
|
||||||
|
.filter(
|
||||||
|
chatId ->
|
||||||
|
chatId.longValue() != 0L
|
||||||
|
&& !chatId.isNaN()
|
||||||
|
&& !chatId.isInfinite()
|
||||||
|
&& chatId != Double.MIN_VALUE)
|
||||||
|
.flatMap(chatId -> new QTgChat().id.eq(chatId.longValue()).findOneOrEmpty())
|
||||||
|
.map(
|
||||||
|
tgChat -> {
|
||||||
|
tgChat.setLocale(
|
||||||
|
(String)
|
||||||
|
callbackQueryContext
|
||||||
|
.getFields()
|
||||||
|
.getAdditionalProperties()
|
||||||
|
.getOrDefault(
|
||||||
|
Field.NewLanguage.getName(),
|
||||||
|
Language.English.getLocale()));
|
||||||
|
tgChat.save();
|
||||||
|
return tgChat;
|
||||||
|
})
|
||||||
|
.orElseThrow(
|
||||||
|
() ->
|
||||||
|
new NoSuchElementException(
|
||||||
|
"Unable to find telegram chat "
|
||||||
|
+ Double.valueOf(
|
||||||
|
callbackQueryContext.getFields().getTelegramChatId())
|
||||||
|
.longValue()
|
||||||
|
+ " in the database")),
|
||||||
|
threadPool)
|
||||||
|
.thenApplyAsync(
|
||||||
|
// If we are here then we're sure there is at least a chat associated with this callback
|
||||||
|
tgChat -> {
|
||||||
|
final String message =
|
||||||
|
Try.of(
|
||||||
|
() -> {
|
||||||
|
final Locale locale = Locale.forLanguageTag(tgChat.getLocale());
|
||||||
|
final ToolManager toolManager = localizedMessageFactory.create(locale);
|
||||||
|
final VelocityContext velocityContext =
|
||||||
|
new VelocityContext(toolManager.createContext());
|
||||||
|
|
||||||
|
final StringBuilder content = new StringBuilder();
|
||||||
|
final StringBuilderWriter stringBuilderWriter =
|
||||||
|
new StringBuilderWriter(content);
|
||||||
|
|
||||||
|
toolManager
|
||||||
|
.getVelocityEngine()
|
||||||
|
.mergeTemplate(
|
||||||
|
"/template/callbackQuery/changeLanguage.vm",
|
||||||
|
StandardCharsets.UTF_8.name(),
|
||||||
|
velocityContext,
|
||||||
|
stringBuilderWriter);
|
||||||
|
|
||||||
|
stringBuilderWriter.close();
|
||||||
|
return content.toString();
|
||||||
|
})
|
||||||
|
.get();
|
||||||
|
|
||||||
|
log.trace("ChangeLanguage event - message to send back: " + message);
|
||||||
|
|
||||||
|
final String callBackGroupToDelete = callbackQueryContext.getEntryGroup();
|
||||||
|
final int delete =
|
||||||
|
new QCallbackQueryContext().entryGroup.eq(callBackGroupToDelete).delete();
|
||||||
|
log.trace(
|
||||||
|
"Deleted "
|
||||||
|
+ delete
|
||||||
|
+ " entries regarding callback group "
|
||||||
|
+ callBackGroupToDelete);
|
||||||
|
|
||||||
|
return Optional.of(
|
||||||
|
new SendMessage(tgChat.getId(), message).parseMode(ParseMode.Markdown));
|
||||||
|
},
|
||||||
|
threadPool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
package com.github.polpetta.mezzotre.telegram.command;
|
package com.github.polpetta.mezzotre.telegram.command;
|
||||||
|
|
||||||
import com.github.polpetta.mezzotre.i18n.LocalizedMessageFactory;
|
import com.github.polpetta.mezzotre.i18n.LocalizedMessageFactory;
|
||||||
|
import com.github.polpetta.mezzotre.orm.model.CallbackQueryContext;
|
||||||
import com.github.polpetta.mezzotre.orm.model.TgChat;
|
import com.github.polpetta.mezzotre.orm.model.TgChat;
|
||||||
|
import com.github.polpetta.mezzotre.telegram.callbackquery.ChangeLanguage;
|
||||||
|
import com.github.polpetta.mezzotre.util.Clock;
|
||||||
|
import com.github.polpetta.mezzotre.util.UUIDGenerator;
|
||||||
|
import com.github.polpetta.types.json.CallbackQueryMetadata;
|
||||||
import com.github.polpetta.types.json.ChatContext;
|
import com.github.polpetta.types.json.ChatContext;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.pengrad.telegrambot.model.Update;
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.model.request.InlineKeyboardButton;
|
||||||
|
import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup;
|
||||||
import com.pengrad.telegrambot.model.request.ParseMode;
|
import com.pengrad.telegrambot.model.request.ParseMode;
|
||||||
import com.pengrad.telegrambot.request.BaseRequest;
|
import com.pengrad.telegrambot.request.BaseRequest;
|
||||||
import com.pengrad.telegrambot.request.SendMessage;
|
import com.pengrad.telegrambot.request.SendMessage;
|
||||||
|
@ -13,6 +20,7 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import org.apache.velocity.VelocityContext;
|
import org.apache.velocity.VelocityContext;
|
||||||
|
@ -29,18 +37,24 @@ import org.slf4j.Logger;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class Start implements Processor {
|
public class Start implements Processor {
|
||||||
|
|
||||||
private final java.util.concurrent.Executor threadPool;
|
private final Executor threadPool;
|
||||||
private final Logger log;
|
private final Logger log;
|
||||||
|
private final UUIDGenerator uuidGenerator;
|
||||||
|
private final Clock clock;
|
||||||
private final LocalizedMessageFactory localizedMessageFactory;
|
private final LocalizedMessageFactory localizedMessageFactory;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public Start(
|
public Start(
|
||||||
LocalizedMessageFactory localizedMessageFactory,
|
LocalizedMessageFactory localizedMessageFactory,
|
||||||
@Named("eventThreadPool") java.util.concurrent.Executor threadPool,
|
@Named("eventThreadPool") Executor threadPool,
|
||||||
Logger log) {
|
Logger log,
|
||||||
|
UUIDGenerator uuidGenerator,
|
||||||
|
Clock clock) {
|
||||||
this.localizedMessageFactory = localizedMessageFactory;
|
this.localizedMessageFactory = localizedMessageFactory;
|
||||||
this.threadPool = threadPool;
|
this.threadPool = threadPool;
|
||||||
this.log = log;
|
this.log = log;
|
||||||
|
this.uuidGenerator = uuidGenerator;
|
||||||
|
this.clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,17 +76,17 @@ public class Start implements Processor {
|
||||||
Try.of(
|
Try.of(
|
||||||
() -> {
|
() -> {
|
||||||
final Locale locale = Locale.forLanguageTag(chat.getLocale());
|
final Locale locale = Locale.forLanguageTag(chat.getLocale());
|
||||||
final ToolManager toolContext = localizedMessageFactory.create(locale);
|
final ToolManager toolManager = localizedMessageFactory.create(locale);
|
||||||
final VelocityContext context =
|
final VelocityContext context =
|
||||||
new VelocityContext(toolContext.createContext());
|
new VelocityContext(toolManager.createContext());
|
||||||
context.put("firstName", update.message().chat().firstName());
|
context.put("firstName", update.message().chat().firstName());
|
||||||
context.put("programName", "Mezzotre");
|
context.put("programName", "_Mezzotre_");
|
||||||
|
|
||||||
final StringBuilder content = new StringBuilder();
|
final StringBuilder content = new StringBuilder();
|
||||||
final StringBuilderWriter stringBuilderWriter =
|
final StringBuilderWriter stringBuilderWriter =
|
||||||
new StringBuilderWriter(content);
|
new StringBuilderWriter(content);
|
||||||
|
|
||||||
toolContext
|
toolManager
|
||||||
.getVelocityEngine()
|
.getVelocityEngine()
|
||||||
.mergeTemplate(
|
.mergeTemplate(
|
||||||
"template/command/start.0.vm",
|
"template/command/start.0.vm",
|
||||||
|
@ -87,14 +101,51 @@ public class Start implements Processor {
|
||||||
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.setStage(getTriggerKeyword());
|
chatContext.setStage(getTriggerKeyword());
|
||||||
chatContext.setStep(0);
|
chatContext.setStep(0);
|
||||||
chatContext.setPreviousMessageUnixTimestampInSeconds(update.message().date());
|
chatContext.setPreviousMessageUnixTimestampInSeconds(clock.now());
|
||||||
chat.setChatContext(chatContext);
|
chat.setChatContext(chatContext);
|
||||||
chat.save();
|
chat.save();
|
||||||
|
|
||||||
return Optional.of(new SendMessage(chat.getId(), message).parseMode(ParseMode.Markdown));
|
// To get the messageId we should send the message first, then save it in the database!
|
||||||
|
final String groupId = uuidGenerator.generateAsString();
|
||||||
|
final CallbackQueryContext switchToEnglish =
|
||||||
|
new CallbackQueryContext(
|
||||||
|
uuidGenerator.generateAsString(),
|
||||||
|
groupId,
|
||||||
|
new CallbackQueryMetadata.CallbackQueryMetadataBuilder()
|
||||||
|
.withEvent(ChangeLanguage.EVENT_NAME)
|
||||||
|
.withTelegramChatId(update.message().chat().id())
|
||||||
|
.withAdditionalProperty(
|
||||||
|
ChangeLanguage.Field.NewLanguage.getName(),
|
||||||
|
ChangeLanguage.Language.English)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
final CallbackQueryContext switchToItalian =
|
||||||
|
new CallbackQueryContext(
|
||||||
|
uuidGenerator.generateAsString(),
|
||||||
|
groupId,
|
||||||
|
new CallbackQueryMetadata.CallbackQueryMetadataBuilder()
|
||||||
|
.withEvent(ChangeLanguage.EVENT_NAME)
|
||||||
|
.withTelegramChatId(update.message().chat().id())
|
||||||
|
.withAdditionalProperty(
|
||||||
|
ChangeLanguage.Field.NewLanguage.getName(),
|
||||||
|
ChangeLanguage.Language.Italian)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
final SendMessage messageToSend =
|
||||||
|
new SendMessage(chat.getId(), message)
|
||||||
|
.parseMode(ParseMode.Markdown)
|
||||||
|
.replyMarkup(
|
||||||
|
new InlineKeyboardMarkup(
|
||||||
|
new InlineKeyboardButton("English").callbackData(switchToEnglish.getId()),
|
||||||
|
new InlineKeyboardButton("Italian")
|
||||||
|
.callbackData(switchToItalian.getId())));
|
||||||
|
|
||||||
|
switchToEnglish.save();
|
||||||
|
switchToItalian.save();
|
||||||
|
|
||||||
|
return Optional.of(messageToSend);
|
||||||
},
|
},
|
||||||
threadPool);
|
threadPool);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
start.hello=Hello
|
start.helloFirstName=Hello {0}! \ud83d\udc4b
|
||||||
start.thisIs=This is
|
start.description=This is {0}, a simple bot focused on DnD content management! Please start by choosing a language down below \ud83d\udc47
|
||||||
start.description=a simple bot focused on DnD content management! Please start by choosing a language down below.
|
changeLanguage.drinkAction=*Proceeds to drink a potion with a strange, multicolor liquid*
|
||||||
|
changeLanguage.setLanguage=Thanks! Now that I drank this modified potion of {0} that I''ve found at the "Crystal Fermentary" magic potion shop yesterday I can speak with you in the language you prefer!
|
||||||
|
changeLanguage.instructions=You can always change your language settings by typing /changeLanguage in the chat.
|
||||||
|
spell.speakWithAnimals=Speak with animals
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
start.hello=Hello
|
start.helloFirstName=Hello {0}! \ud83d\udc4b
|
||||||
start.thisIs=This is
|
start.description=This is {0}, a simple bot focused on DnD content management! Please start by choosing a language down below \ud83d\udc47
|
||||||
start.description=a simple bot focused on DnD content management! Please start by choosing a language down below.
|
changeLanguage.drinkAction=*Proceeds to drink a potion with a strange, multicolor liquid*
|
||||||
|
changeLanguage.setLanguage=Thanks! Now that I drank this modified potion of {0} that I''ve found at the "Crystal Fermentary" magic potion shop yesterday I can speak with you in the language you prefer!
|
||||||
|
changeLanguage.instructions=You can always change your language settings by typing /changeLanguage in the chat.
|
||||||
|
spell.speakWithAnimals=Speak with animals
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
start.hello=Ciao
|
start.helloFirstName=Ciao {0}! \ud83d\udc4b
|
||||||
start.thisIs=Questo è
|
start.description=Questo è {0}, un semplice bot che ci concenta sulla gestione di contenuto per DnD! Per favore comincia selezionando la lingua qui sotto \ud83d\udc47
|
||||||
start.description=un semplice bot che ci concenta sulla gestione di contenuto per DnD! Per favore comincia selezionando la lingua qui sotto
|
changeLanguage.drinkAction=*Procede a bere una pozione al cui suo interno si trova uno strano liquido multicolore*
|
||||||
|
changeLanguage.setLanguage=Grazie! Ora che ho bevuto quest posizione modificata di {0} che ho trovato ieri al negozio di pozioni magiche la "Cristalleria Fermentatrice" posso parlare con te nel linguaggio che preferisci!
|
||||||
|
changeLanguage.instructions=Puoi sempre cambiare le preferenze della tua lingua scrivendo /changeLanguage nella chat.
|
||||||
|
spell.speakWithAnimals=Parlare con animali
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
start.hello=Ciao
|
start.helloFirstName=Ciao {0}! \ud83d\udc4b
|
||||||
start.thisIs=Questo è
|
start.description=Questo è {0}, un semplice bot che ci concenta sulla gestione di contenuto per DnD! Per favore comincia selezionando la lingua qui sotto \ud83d\udc47
|
||||||
start.description=un semplice bot che ci concenta sulla gestione di contenuto per DnD! Per favore comincia selezionando la lingua qui sotto
|
changeLanguage.drinkAction=*Procede a bere una pozione al cui suo interno si trova uno strano liquido multicolore*
|
||||||
|
changeLanguage.setLanguage=Grazie! Ora che ho bevuto quest posizione modificata di {0} che ho trovato ieri al negozio di pozioni magiche la "Cristalleria Fermentatrice" posso parlare con te nel linguaggio che preferisci!
|
||||||
|
changeLanguage.instructions=Puoi sempre cambiare le preferenze della tua lingua scrivendo /changeLanguage nella chat.
|
||||||
|
spell.speakWithAnimals=Parlare con animali
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
_${i18n.changeLanguage.drinkAction}_
|
||||||
|
|
||||||
|
${i18n.changeLanguage.setLanguage.insert(${i18n.spell.speakWithAnimals})}
|
||||||
|
|
||||||
|
${i18n.changeLanguage.instructions}
|
|
@ -1,4 +1,3 @@
|
||||||
## https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ResourceTool.html
|
**${i18n.start.helloFirstName.insert(${firstName})}**
|
||||||
**$i18n.start.hello $firstName! 👋**
|
|
||||||
|
|
||||||
$i18n.start.thisIs _${programName}_, $i18n.start.description 👇
|
${i18n.start.description.insert(${programName})}
|
|
@ -11,6 +11,9 @@ import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.apache.velocity.app.VelocityEngine;
|
||||||
|
import org.apache.velocity.runtime.RuntimeConstants;
|
||||||
|
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
|
||||||
import org.testcontainers.containers.PostgreSQLContainer;
|
import org.testcontainers.containers.PostgreSQLContainer;
|
||||||
|
|
||||||
public class Loader {
|
public class Loader {
|
||||||
|
@ -49,4 +52,13 @@ public class Loader {
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static VelocityEngine defaultVelocityEngine() {
|
||||||
|
final VelocityEngine velocityEngine = new VelocityEngine();
|
||||||
|
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADERS, "classpath");
|
||||||
|
velocityEngine.setProperty(
|
||||||
|
"resource.loader.classpath.class", ClasspathResourceLoader.class.getName());
|
||||||
|
velocityEngine.init();
|
||||||
|
return velocityEngine;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,7 @@ class TelegramIntegrationTest {
|
||||||
final CallbackQueryContext callbackQueryContext =
|
final CallbackQueryContext callbackQueryContext =
|
||||||
new CallbackQueryContext(
|
new CallbackQueryContext(
|
||||||
"41427473-0d81-40a8-af60-9517163615a4",
|
"41427473-0d81-40a8-af60-9517163615a4",
|
||||||
|
"2ee7f5c6-93f0-4859-b902-af9476cf74ad",
|
||||||
new CallbackQueryMetadata.CallbackQueryMetadataBuilder()
|
new CallbackQueryMetadata.CallbackQueryMetadataBuilder()
|
||||||
.withTelegramChatId(666L)
|
.withTelegramChatId(666L)
|
||||||
.withMessageId(42L)
|
.withMessageId(42L)
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
package com.github.polpetta.mezzotre.telegram.callbackquery;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import com.github.polpetta.mezzotre.helper.Loader;
|
||||||
|
import com.github.polpetta.mezzotre.helper.TestConfig;
|
||||||
|
import com.github.polpetta.mezzotre.i18n.LocalizedMessageFactory;
|
||||||
|
import com.github.polpetta.mezzotre.orm.model.CallbackQueryContext;
|
||||||
|
import com.github.polpetta.mezzotre.orm.model.TgChat;
|
||||||
|
import com.github.polpetta.mezzotre.orm.model.query.QCallbackQueryContext;
|
||||||
|
import com.github.polpetta.mezzotre.orm.model.query.QTgChat;
|
||||||
|
import com.github.polpetta.types.json.CallbackQueryMetadata;
|
||||||
|
import com.github.polpetta.types.json.ChatContext;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.request.BaseRequest;
|
||||||
|
import com.pengrad.telegrambot.request.SendMessage;
|
||||||
|
import io.ebean.Database;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.junit.jupiter.api.*;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.testcontainers.containers.PostgreSQLContainer;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
|
||||||
|
@Tag("slow")
|
||||||
|
@Tag("database")
|
||||||
|
@Tag("velocity")
|
||||||
|
@Testcontainers
|
||||||
|
class ChangeLanguageIntegrationTest {
|
||||||
|
|
||||||
|
private static Gson gson;
|
||||||
|
|
||||||
|
@Container
|
||||||
|
private final PostgreSQLContainer<?> postgresServer =
|
||||||
|
new PostgreSQLContainer<>(TestConfig.POSTGRES_DOCKER_IMAGE);
|
||||||
|
|
||||||
|
private Database database;
|
||||||
|
private ChangeLanguage changeLanguage;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void beforeAll() {
|
||||||
|
gson = new Gson();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() throws Exception {
|
||||||
|
database =
|
||||||
|
Loader.connectToDatabase(Loader.loadDefaultEbeanConfigWithPostgresSettings(postgresServer));
|
||||||
|
|
||||||
|
changeLanguage =
|
||||||
|
new ChangeLanguage(
|
||||||
|
Executors.newSingleThreadExecutor(),
|
||||||
|
new LocalizedMessageFactory(Loader.defaultVelocityEngine()),
|
||||||
|
LoggerFactory.getLogger(ChangeLanguage.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> getTestLocales() {
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(
|
||||||
|
ChangeLanguage.Language.Italian,
|
||||||
|
"_*Procede a bere una pozione al cui suo interno si trova uno strano liquido"
|
||||||
|
+ " multicolore*_\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "Grazie! Ora che ho bevuto quest posizione modificata di Parlare con animali che"
|
||||||
|
+ " ho trovato ieri al negozio di pozioni magiche la \"Cristalleria Fermentatrice\""
|
||||||
|
+ " posso parlare con te nel linguaggio che preferisci!\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "Puoi sempre cambiare le preferenze della tua lingua scrivendo /changeLanguage"
|
||||||
|
+ " nella chat.",
|
||||||
|
"en-US"),
|
||||||
|
Arguments.of(
|
||||||
|
ChangeLanguage.Language.English,
|
||||||
|
"_*Proceeds to drink a potion with a strange, multicolor liquid*_\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "Thanks! Now that I drank this modified potion of Speak with animals that I've"
|
||||||
|
+ " found at the \"Crystal Fermentary\" magic potion shop yesterday I can speak"
|
||||||
|
+ " with you in the language you prefer!\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "You can always change your language settings by typing /changeLanguage in the"
|
||||||
|
+ " chat.",
|
||||||
|
"it-IT"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||||
|
@MethodSource("getTestLocales")
|
||||||
|
void shouldProcessChangeLanguageToDesiredOne(
|
||||||
|
ChangeLanguage.Language language, String expectedResult, String startingLocale)
|
||||||
|
throws Exception {
|
||||||
|
|
||||||
|
final Update update =
|
||||||
|
gson.fromJson(
|
||||||
|
"{\n"
|
||||||
|
+ "\"update_id\":10000,\n"
|
||||||
|
+ "\"callback_query\":{\n"
|
||||||
|
+ " \"id\": \"4382bfdwdsb323b2d9\",\n"
|
||||||
|
+ " \"from\":{\n"
|
||||||
|
+ " \"last_name\":\"Test Lastname\",\n"
|
||||||
|
+ " \"type\": \"private\",\n"
|
||||||
|
+ " \"id\":1111111,\n"
|
||||||
|
+ " \"first_name\":\"Test Firstname\",\n"
|
||||||
|
+ " \"username\":\"Testusername\"\n"
|
||||||
|
+ " },\n"
|
||||||
|
+ " \"data\": \"Data from button callback\",\n"
|
||||||
|
+ " \"inline_message_id\": \"1234csdbsk4839\"\n"
|
||||||
|
+ "}\n"
|
||||||
|
+ "}",
|
||||||
|
Update.class);
|
||||||
|
|
||||||
|
final long tgChatId = 1111111L;
|
||||||
|
final ChatContext chatContext = new ChatContext();
|
||||||
|
final TgChat tgChat = new TgChat(tgChatId, chatContext, startingLocale);
|
||||||
|
tgChat.save();
|
||||||
|
|
||||||
|
final CallbackQueryMetadata callbackQueryMetadata =
|
||||||
|
new CallbackQueryMetadata.CallbackQueryMetadataBuilder()
|
||||||
|
.withEvent("changeLanguage")
|
||||||
|
.withTelegramChatId(tgChatId)
|
||||||
|
.withAdditionalProperty(
|
||||||
|
ChangeLanguage.Field.NewLanguage.getName(), language.getLocale())
|
||||||
|
.build();
|
||||||
|
final String entryGroupId = "2e67774a-e4e4-4369-a414-a7f8bfe74b80";
|
||||||
|
final CallbackQueryContext changeLanguageCallbackQueryContext =
|
||||||
|
new CallbackQueryContext(
|
||||||
|
"c018108f-6612-4848-8fca-cf301460d4eb", entryGroupId, callbackQueryMetadata);
|
||||||
|
changeLanguageCallbackQueryContext.save();
|
||||||
|
|
||||||
|
final CompletableFuture<Optional<BaseRequest<?, ?>>> processFuture =
|
||||||
|
changeLanguage.process(changeLanguageCallbackQueryContext, update);
|
||||||
|
final Optional<BaseRequest<?, ?>> gotResponseOpt = processFuture.get();
|
||||||
|
final SendMessage gotMessage = (SendMessage) gotResponseOpt.get();
|
||||||
|
assertEquals(expectedResult, gotMessage.getParameters().get("text"));
|
||||||
|
|
||||||
|
final TgChat retrievedTgChat = new QTgChat().id.eq(tgChatId).findOne();
|
||||||
|
assertNotNull(retrievedTgChat);
|
||||||
|
assertEquals(language.getLocale(), retrievedTgChat.getLocale());
|
||||||
|
|
||||||
|
assertEquals(0, new QCallbackQueryContext().entryGroup.eq(entryGroupId).findCount());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,15 @@
|
||||||
package com.github.polpetta.mezzotre.telegram.command;
|
package com.github.polpetta.mezzotre.telegram.command;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
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;
|
||||||
import com.github.polpetta.mezzotre.orm.model.TgChat;
|
import com.github.polpetta.mezzotre.orm.model.TgChat;
|
||||||
import com.github.polpetta.mezzotre.orm.model.query.QTgChat;
|
import com.github.polpetta.mezzotre.orm.model.query.QTgChat;
|
||||||
|
import com.github.polpetta.mezzotre.util.Clock;
|
||||||
|
import com.github.polpetta.mezzotre.util.UUIDGenerator;
|
||||||
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;
|
||||||
|
@ -15,6 +18,7 @@ import com.pengrad.telegrambot.request.SendMessage;
|
||||||
import io.ebean.Database;
|
import io.ebean.Database;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Executors;
|
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;
|
||||||
|
@ -45,6 +49,8 @@ class StartIntegrationTest {
|
||||||
private LocalizedMessageFactory localizedMessageFactory;
|
private LocalizedMessageFactory localizedMessageFactory;
|
||||||
private Start start;
|
private Start start;
|
||||||
private Database database;
|
private Database database;
|
||||||
|
private Clock fakeClock;
|
||||||
|
private UUIDGenerator fakeUUIDGenerator;
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
static void beforeAll() {
|
static void beforeAll() {
|
||||||
|
@ -64,11 +70,25 @@ class StartIntegrationTest {
|
||||||
|
|
||||||
final Logger log = LoggerFactory.getLogger(Start.class);
|
final Logger log = LoggerFactory.getLogger(Start.class);
|
||||||
|
|
||||||
start = new Start(localizedMessageFactory, Executors.newSingleThreadExecutor(), log);
|
fakeClock = mock(Clock.class);
|
||||||
|
fakeUUIDGenerator = mock(UUIDGenerator.class);
|
||||||
|
|
||||||
|
start =
|
||||||
|
new Start(
|
||||||
|
localizedMessageFactory,
|
||||||
|
Executors.newSingleThreadExecutor(),
|
||||||
|
log,
|
||||||
|
fakeUUIDGenerator,
|
||||||
|
fakeClock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldUpdateContextInTheDatabase() throws Exception {
|
void shouldUpdateContextInTheDatabase() throws Exception {
|
||||||
|
when(fakeClock.now()).thenReturn(42L);
|
||||||
|
when(fakeUUIDGenerator.generateAsString())
|
||||||
|
.thenReturn("e86e6fa1-fdd4-4120-b85d-a5482db2e8b5")
|
||||||
|
.thenReturn("16507fbd-9f28-48a8-9de1-3ea1c943af67")
|
||||||
|
.thenReturn("0b0ac18e-f621-484e-aa8d-9b176be5b930");
|
||||||
final TgChat tgChat = new TgChat(1111111L, new ChatContext());
|
final TgChat tgChat = new TgChat(1111111L, new ChatContext());
|
||||||
tgChat.setLocale("en-US");
|
tgChat.setLocale("en-US");
|
||||||
tgChat.save();
|
tgChat.save();
|
||||||
|
@ -108,16 +128,104 @@ class StartIntegrationTest {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"**Hello Test Firstname! \uD83D\uDC4B**\n\n"
|
"**Hello Test Firstname! \uD83D\uDC4B**\n\n"
|
||||||
+ "This is _Mezzotre_, a simple bot focused on DnD content management! Please start by"
|
+ "This is _Mezzotre_, a simple bot focused on DnD content management! Please start by"
|
||||||
+ " choosing a language down below. \uD83D\uDC47",
|
+ " 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"));
|
||||||
|
|
||||||
final TgChat retrievedTgChat = new QTgChat().id.eq(1111111L).findOne();
|
final TgChat retrievedTgChat = new QTgChat().id.eq(1111111L).findOne();
|
||||||
assertNotNull(retrievedTgChat);
|
assertNotNull(retrievedTgChat);
|
||||||
final ChatContext gotChatContext = retrievedTgChat.getChatContext();
|
final ChatContext gotChatContext = retrievedTgChat.getChatContext();
|
||||||
assertEquals(1441645532, gotChatContext.getPreviousMessageUnixTimestampInSeconds());
|
assertEquals(42, gotChatContext.getPreviousMessageUnixTimestampInSeconds());
|
||||||
assertEquals(1365, gotChatContext.getLastMessageSentId());
|
assertEquals(0, gotChatContext.getLastMessageSentId());
|
||||||
assertEquals("/start", gotChatContext.getStage());
|
assertEquals("/start", gotChatContext.getStage());
|
||||||
assertEquals(0, gotChatContext.getStep());
|
assertEquals(0, gotChatContext.getStep());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldReceiveHelloIntroduction() throws Exception {
|
||||||
|
when(fakeClock.now()).thenReturn(42L);
|
||||||
|
when(fakeUUIDGenerator.generateAsString())
|
||||||
|
.thenReturn("e86e6fa1-fdd4-4120-b85d-a5482db2e8b5")
|
||||||
|
.thenReturn("16507fbd-9f28-48a8-9de1-3ea1c943af67")
|
||||||
|
.thenReturn("0b0ac18e-f621-484e-aa8d-9b176be5b930");
|
||||||
|
|
||||||
|
final TgChat tgChat = new TgChat(1111111L, new ChatContext(), "en-US");
|
||||||
|
|
||||||
|
final Update update =
|
||||||
|
gson.fromJson(
|
||||||
|
"{\n"
|
||||||
|
+ "\"update_id\":10000,\n"
|
||||||
|
+ "\"message\":{\n"
|
||||||
|
+ " \"date\":1441645532,\n"
|
||||||
|
+ " \"chat\":{\n"
|
||||||
|
+ " \"last_name\":\"Test Lastname\",\n"
|
||||||
|
+ " \"id\":1111111,\n"
|
||||||
|
+ " \"type\": \"private\",\n"
|
||||||
|
+ " \"first_name\":\"Test Firstname\",\n"
|
||||||
|
+ " \"username\":\"Testusername\"\n"
|
||||||
|
+ " },\n"
|
||||||
|
+ " \"message_id\":1365,\n"
|
||||||
|
+ " \"from\":{\n"
|
||||||
|
+ " \"last_name\":\"Test Lastname\",\n"
|
||||||
|
+ " \"id\":1111111,\n"
|
||||||
|
+ " \"first_name\":\"Test Firstname\",\n"
|
||||||
|
+ " \"username\":\"Testusername\"\n"
|
||||||
|
+ " },\n"
|
||||||
|
+ " \"text\":\"/start\"\n"
|
||||||
|
+ "}\n"
|
||||||
|
+ "}",
|
||||||
|
Update.class);
|
||||||
|
|
||||||
|
final CompletableFuture<Optional<BaseRequest<?, ?>>> gotFuture = start.process(tgChat, update);
|
||||||
|
assertDoesNotThrow(() -> gotFuture.get());
|
||||||
|
final Optional<BaseRequest<?, ?>> gotMessageOptional = gotFuture.get();
|
||||||
|
assertDoesNotThrow(gotMessageOptional::get);
|
||||||
|
final BaseRequest<?, ?> gotMessage = gotMessageOptional.get();
|
||||||
|
assertInstanceOf(SendMessage.class, gotMessage);
|
||||||
|
final String message = (String) gotMessage.getParameters().get("text");
|
||||||
|
assertEquals(
|
||||||
|
"**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);
|
||||||
|
assertEquals(1111111L, (Long) gotMessage.getParameters().get("chat_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldThrowErrorIfLocaleNonExists() {
|
||||||
|
when(fakeClock.now()).thenReturn(42L);
|
||||||
|
when(fakeUUIDGenerator.generateAsString())
|
||||||
|
.thenReturn("e86e6fa1-fdd4-4120-b85d-a5482db2e8b5")
|
||||||
|
.thenReturn("16507fbd-9f28-48a8-9de1-3ea1c943af67")
|
||||||
|
.thenReturn("0b0ac18e-f621-484e-aa8d-9b176be5b930");
|
||||||
|
final TgChat tgChat = new TgChat(1111111L, null);
|
||||||
|
|
||||||
|
final Update update =
|
||||||
|
gson.fromJson(
|
||||||
|
"{\n"
|
||||||
|
+ "\"update_id\":10000,\n"
|
||||||
|
+ "\"message\":{\n"
|
||||||
|
+ " \"date\":1441645532,\n"
|
||||||
|
+ " \"chat\":{\n"
|
||||||
|
+ " \"last_name\":\"Test Lastname\",\n"
|
||||||
|
+ " \"id\":1111111,\n"
|
||||||
|
+ " \"type\": \"private\",\n"
|
||||||
|
+ " \"first_name\":\"Test Firstname\",\n"
|
||||||
|
+ " \"username\":\"Testusername\"\n"
|
||||||
|
+ " },\n"
|
||||||
|
+ " \"message_id\":1365,\n"
|
||||||
|
+ " \"from\":{\n"
|
||||||
|
+ " \"last_name\":\"Test Lastname\",\n"
|
||||||
|
+ " \"id\":1111111,\n"
|
||||||
|
+ " \"first_name\":\"Test Firstname\",\n"
|
||||||
|
+ " \"username\":\"Testusername\"\n"
|
||||||
|
+ " },\n"
|
||||||
|
+ " \"text\":\"/start\"\n"
|
||||||
|
+ "}\n"
|
||||||
|
+ "}",
|
||||||
|
Update.class);
|
||||||
|
|
||||||
|
final CompletableFuture<Optional<BaseRequest<?, ?>>> gotFuture = start.process(tgChat, update);
|
||||||
|
assertThrows(ExecutionException.class, gotFuture::get);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,140 +0,0 @@
|
||||||
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.orm.model.TgChat;
|
|
||||||
import com.github.polpetta.types.json.ChatContext;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.pengrad.telegrambot.model.Update;
|
|
||||||
import com.pengrad.telegrambot.request.BaseRequest;
|
|
||||||
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.runtime.RuntimeConstants;
|
|
||||||
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Tag;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.parallel.Execution;
|
|
||||||
import org.junit.jupiter.api.parallel.ExecutionMode;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
@Tag("velocity")
|
|
||||||
@Execution(ExecutionMode.CONCURRENT)
|
|
||||||
class StartTest {
|
|
||||||
|
|
||||||
private VelocityEngine velocityEngine;
|
|
||||||
private LocalizedMessageFactory localizedMessageFactory;
|
|
||||||
private Start start;
|
|
||||||
private static Gson gson;
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
static void beforeAll() {
|
|
||||||
gson = new Gson();
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setUp() {
|
|
||||||
velocityEngine = new VelocityEngine();
|
|
||||||
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADERS, "classpath");
|
|
||||||
velocityEngine.setProperty(
|
|
||||||
"resource.loader.classpath.class", ClasspathResourceLoader.class.getName());
|
|
||||||
velocityEngine.init();
|
|
||||||
localizedMessageFactory = new LocalizedMessageFactory(velocityEngine);
|
|
||||||
|
|
||||||
final Logger fakeLog = mock(Logger.class);
|
|
||||||
|
|
||||||
start = new Start(localizedMessageFactory, Executors.newSingleThreadExecutor(), fakeLog);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldReceiveHelloIntroduction() throws Exception {
|
|
||||||
final TgChat fakeChat = mock(TgChat.class);
|
|
||||||
when(fakeChat.getLocale()).thenReturn("en-US");
|
|
||||||
when(fakeChat.getChatContext()).thenReturn(new ChatContext());
|
|
||||||
when(fakeChat.getId()).thenReturn(1111111L);
|
|
||||||
|
|
||||||
final Update update =
|
|
||||||
gson.fromJson(
|
|
||||||
"{\n"
|
|
||||||
+ "\"update_id\":10000,\n"
|
|
||||||
+ "\"message\":{\n"
|
|
||||||
+ " \"date\":1441645532,\n"
|
|
||||||
+ " \"chat\":{\n"
|
|
||||||
+ " \"last_name\":\"Test Lastname\",\n"
|
|
||||||
+ " \"id\":1111111,\n"
|
|
||||||
+ " \"type\": \"private\",\n"
|
|
||||||
+ " \"first_name\":\"Test Firstname\",\n"
|
|
||||||
+ " \"username\":\"Testusername\"\n"
|
|
||||||
+ " },\n"
|
|
||||||
+ " \"message_id\":1365,\n"
|
|
||||||
+ " \"from\":{\n"
|
|
||||||
+ " \"last_name\":\"Test Lastname\",\n"
|
|
||||||
+ " \"id\":1111111,\n"
|
|
||||||
+ " \"first_name\":\"Test Firstname\",\n"
|
|
||||||
+ " \"username\":\"Testusername\"\n"
|
|
||||||
+ " },\n"
|
|
||||||
+ " \"text\":\"/start\"\n"
|
|
||||||
+ "}\n"
|
|
||||||
+ "}",
|
|
||||||
Update.class);
|
|
||||||
|
|
||||||
final CompletableFuture<Optional<BaseRequest<?, ?>>> gotFuture =
|
|
||||||
start.process(fakeChat, update);
|
|
||||||
assertDoesNotThrow(() -> gotFuture.get());
|
|
||||||
final Optional<BaseRequest<?, ?>> gotMessageOptional = gotFuture.get();
|
|
||||||
assertDoesNotThrow(gotMessageOptional::get);
|
|
||||||
final BaseRequest<?, ?> gotMessage = gotMessageOptional.get();
|
|
||||||
assertInstanceOf(SendMessage.class, gotMessage);
|
|
||||||
final String message = (String) gotMessage.getParameters().get("text");
|
|
||||||
assertEquals(
|
|
||||||
"**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);
|
|
||||||
assertEquals(1111111L, (Long) gotMessage.getParameters().get("chat_id"));
|
|
||||||
verify(fakeChat, times(1)).save();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldThrowErrorIfLocaleNonExists() {
|
|
||||||
final TgChat fakeChat = mock(TgChat.class);
|
|
||||||
// Do not set Locale on purpose
|
|
||||||
when(fakeChat.getId()).thenReturn(1111111L);
|
|
||||||
|
|
||||||
final Update update =
|
|
||||||
gson.fromJson(
|
|
||||||
"{\n"
|
|
||||||
+ "\"update_id\":10000,\n"
|
|
||||||
+ "\"message\":{\n"
|
|
||||||
+ " \"date\":1441645532,\n"
|
|
||||||
+ " \"chat\":{\n"
|
|
||||||
+ " \"last_name\":\"Test Lastname\",\n"
|
|
||||||
+ " \"id\":1111111,\n"
|
|
||||||
+ " \"type\": \"private\",\n"
|
|
||||||
+ " \"first_name\":\"Test Firstname\",\n"
|
|
||||||
+ " \"username\":\"Testusername\"\n"
|
|
||||||
+ " },\n"
|
|
||||||
+ " \"message_id\":1365,\n"
|
|
||||||
+ " \"from\":{\n"
|
|
||||||
+ " \"last_name\":\"Test Lastname\",\n"
|
|
||||||
+ " \"id\":1111111,\n"
|
|
||||||
+ " \"first_name\":\"Test Firstname\",\n"
|
|
||||||
+ " \"username\":\"Testusername\"\n"
|
|
||||||
+ " },\n"
|
|
||||||
+ " \"text\":\"/start\"\n"
|
|
||||||
+ "}\n"
|
|
||||||
+ "}",
|
|
||||||
Update.class);
|
|
||||||
|
|
||||||
final CompletableFuture<Optional<BaseRequest<?, ?>>> gotFuture =
|
|
||||||
start.process(fakeChat, update);
|
|
||||||
assertThrows(ExecutionException.class, gotFuture::get);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue