feat: complete show help button event
continuous-integration/drone/push Build is passing Details

* Code refactor so that help command and event use the same logic
* Fix invasive string rename (ty intellij)
* Fix Processor not returning right locale key name
* Add tests and add todos for the one remaining
pull/3/head
Davide Polonio 2023-04-08 17:57:43 +02:00
parent 53cdd4aa22
commit 3e094ec72a
18 changed files with 311 additions and 127 deletions

View File

@ -2,6 +2,7 @@ package com.github.polpetta.mezzotre.telegram.callbackquery;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.inject.Named; import javax.inject.Named;
@ -9,6 +10,16 @@ import javax.inject.Singleton;
public class CallbackQueryDI extends AbstractModule { public class CallbackQueryDI extends AbstractModule {
@Override
protected void configure() {
super.configure();
install(
new FactoryModuleBuilder()
.implement(Processor.class, NotFound.class)
.build(NotFoundFactory.class));
}
@Provides @Provides
@Singleton @Singleton
@Named("eventProcessors") @Named("eventProcessors")

View File

@ -3,8 +3,8 @@ package com.github.polpetta.mezzotre.telegram.callbackquery;
import com.github.polpetta.mezzotre.orm.model.CallbackQueryContext; import com.github.polpetta.mezzotre.orm.model.CallbackQueryContext;
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 java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import javax.inject.Inject; import javax.inject.Inject;
@ -22,15 +22,18 @@ import javax.inject.Singleton;
@Singleton @Singleton
public class Dispatcher { public class Dispatcher {
private final Set<Processor> tgEventProcessors; private final Map<String, Processor> tgEventProcessors;
private final Executor threadPool; private final Executor threadPool;
private final NotFoundFactory notFoundFactory;
@Inject @Inject
public Dispatcher( public Dispatcher(
@Named("eventProcessors") Set<Processor> tgEventProcessors, @Named("eventProcessors") Map<String, Processor> tgEventProcessors,
@Named("eventThreadPool") Executor threadPool) { @Named("eventThreadPool") Executor threadPool,
NotFoundFactory notFoundFactory) {
this.tgEventProcessors = tgEventProcessors; this.tgEventProcessors = tgEventProcessors;
this.threadPool = threadPool; this.threadPool = threadPool;
this.notFoundFactory = notFoundFactory;
} }
/** /**
@ -50,14 +53,11 @@ public class Dispatcher {
.thenComposeAsync( .thenComposeAsync(
ignored -> ignored ->
Optional.of(callbackQueryContext.getFields().getEvent()) Optional.of(callbackQueryContext.getFields().getEvent())
.flatMap( .map(
eventName -> eventName ->
tgEventProcessors.stream() tgEventProcessors
// FIXME this is fucking stupid, why iterate over, just use a map! .getOrDefault(eventName, notFoundFactory.create(eventName))
// Make mapping at startup then we're gucci for the rest of the run .process(callbackQueryContext, update))
.filter(processor -> processor.getEventName().equals(eventName))
.findAny())
.map(processor -> processor.process(callbackQueryContext, update))
.orElse(CompletableFuture.failedFuture(new EventProcessorNotFoundException())), .orElse(CompletableFuture.failedFuture(new EventProcessorNotFoundException())),
threadPool); threadPool);
} }

View File

@ -0,0 +1,38 @@
package com.github.polpetta.mezzotre.telegram.callbackquery;
import com.github.polpetta.mezzotre.orm.model.CallbackQueryContext;
import com.google.inject.assistedinject.Assisted;
import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.request.BaseRequest;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import javax.inject.Inject;
import org.slf4j.Logger;
public class NotFound implements Processor {
private final Logger log;
private final String eventName;
@Inject
public NotFound(Logger logger, @Assisted String eventName) {
this.log = logger;
this.eventName = eventName;
}
@Override
public String getEventName() {
return "eventNotFound";
}
@Override
public CompletableFuture<Optional<BaseRequest<?, ?>>> process(
CallbackQueryContext callbackQueryContext, Update update) {
log.warn(
"A stray event was detected for callback "
+ callbackQueryContext.getId()
+ " event name "
+ eventName);
return CompletableFuture.completedFuture(Optional.empty());
}
}

View File

@ -0,0 +1,5 @@
package com.github.polpetta.mezzotre.telegram.callbackquery;
public interface NotFoundFactory {
NotFound create(String eventName);
}

View File

@ -3,10 +3,8 @@ package com.github.polpetta.mezzotre.telegram.callbackquery;
import com.github.polpetta.mezzotre.i18n.TemplateContentGenerator; import com.github.polpetta.mezzotre.i18n.TemplateContentGenerator;
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.QCallbackQueryContext;
import com.github.polpetta.mezzotre.orm.model.query.QTgChat;
import com.github.polpetta.mezzotre.util.UUIDGenerator; import com.github.polpetta.mezzotre.util.UUIDGenerator;
import com.github.polpetta.types.json.CallbackQueryMetadata; import com.github.polpetta.types.json.CallbackQueryMetadata;
import com.pengrad.telegrambot.model.Message;
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.InlineKeyboardButton;
import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup; import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup;
@ -61,16 +59,7 @@ public class SelectLanguageTutorial implements Processor {
CallbackQueryContext callbackQueryContext, Update update) { CallbackQueryContext callbackQueryContext, Update update) {
return CompletableFuture.supplyAsync( return CompletableFuture.supplyAsync(
() -> () ->
Optional.of(callbackQueryContext.getFields().getTelegramChatId()) Util.extractChat(callbackQueryContext, update)
.map(Double::longValue)
// If we're desperate, search in the message for the chat id
.or(
() ->
Optional.ofNullable(update.callbackQuery().message())
.map(Message::messageId)
.map(Long::valueOf))
.filter(chatId -> chatId != 0L && chatId != Long.MIN_VALUE)
.flatMap(chatId -> new QTgChat().id.eq(chatId).findOneOrEmpty())
.map( .map(
tgChat -> { tgChat -> {
tgChat.setLocale( tgChat.setLocale(
@ -119,8 +108,7 @@ public class SelectLanguageTutorial implements Processor {
+ " entries regarding callback group " + " entries regarding callback group "
+ callBackGroupToDelete); + callBackGroupToDelete);
final Optional<Integer> messageId = final Optional<Integer> messageId = Util.extractMessageId(update);
Optional.ofNullable(update.callbackQuery().message()).map(Message::messageId);
BaseRequest<?, ?> baseRequest; BaseRequest<?, ?> baseRequest;
Optional<InlineKeyboardMarkup> helpButton = Optional.empty(); Optional<InlineKeyboardMarkup> helpButton = Optional.empty();
if (!tgChat.getHasHelpBeenShown()) { if (!tgChat.getHasHelpBeenShown()) {

View File

@ -1,15 +1,45 @@
package com.github.polpetta.mezzotre.telegram.callbackquery; package com.github.polpetta.mezzotre.telegram.callbackquery;
import com.github.polpetta.mezzotre.orm.model.CallbackQueryContext; import com.github.polpetta.mezzotre.orm.model.CallbackQueryContext;
import com.github.polpetta.mezzotre.telegram.model.Help;
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.request.BaseRequest; import com.pengrad.telegrambot.request.BaseRequest;
import com.pengrad.telegrambot.request.EditMessageText;
import com.pengrad.telegrambot.request.SendMessage; import com.pengrad.telegrambot.request.SendMessage;
import java.util.Map;
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.Named;
class ShowHelp implements Processor { class ShowHelp implements Processor {
public static String EVENT_NAME = "showHelp"; public static String EVENT_NAME = "showHelp";
private final Executor threadPool;
private final Help modelHelp;
private final Map<String, com.github.polpetta.mezzotre.telegram.command.Processor>
tgCommandProcessors;
private final Map<String, Processor> eventProcessor;
// FIXME tests
@Inject
public ShowHelp(
@Named("eventThreadPool") Executor threadPool,
com.github.polpetta.mezzotre.telegram.model.Help modelHelp,
@Named("commandProcessor")
Map<String, com.github.polpetta.mezzotre.telegram.command.Processor> tgCommandProcessors,
@Named("eventProcessors")
Map<String, com.github.polpetta.mezzotre.telegram.callbackquery.Processor>
eventProcessor) {
this.threadPool = threadPool;
this.modelHelp = modelHelp;
this.tgCommandProcessors = tgCommandProcessors;
this.eventProcessor = eventProcessor;
}
@Override @Override
public String getEventName() { public String getEventName() {
@ -19,8 +49,30 @@ class ShowHelp implements Processor {
@Override @Override
public CompletableFuture<Optional<BaseRequest<?, ?>>> process( public CompletableFuture<Optional<BaseRequest<?, ?>>> process(
CallbackQueryContext callbackQueryContext, Update update) { CallbackQueryContext callbackQueryContext, Update update) {
// TODO implement this method and put `hasHelpBeenShown` in tgChat to false return CompletableFuture.supplyAsync(
return CompletableFuture.completedFuture( () ->
Optional.of(new SendMessage(callbackQueryContext.getFields().getTelegramChatId(), "TODO"))); Util.extractChat(callbackQueryContext, update)
.map(
chat -> {
final String message = modelHelp.getMessage(chat, tgCommandProcessors);
final Optional<Integer> messageId = Util.extractMessageId(update);
final InlineKeyboardButton[] buttons =
modelHelp.generateInlineKeyBoardButton(chat, eventProcessor);
BaseRequest<?, ?> request;
if (messageId.isPresent()) {
final EditMessageText editMessageText =
new EditMessageText(chat.getId(), messageId.get(), message);
editMessageText.replyMarkup(new InlineKeyboardMarkup(buttons));
request = editMessageText;
} else {
final SendMessage sendMessage =
new SendMessage(chat.getId(), message).parseMode(ParseMode.Markdown);
sendMessage.replyMarkup(new InlineKeyboardMarkup(buttons));
request = sendMessage;
}
return request;
}),
threadPool);
} }
} }

View File

@ -0,0 +1,29 @@
package com.github.polpetta.mezzotre.telegram.callbackquery;
import com.github.polpetta.mezzotre.orm.model.CallbackQueryContext;
import com.github.polpetta.mezzotre.orm.model.TgChat;
import com.github.polpetta.mezzotre.orm.model.query.QTgChat;
import com.pengrad.telegrambot.model.Message;
import com.pengrad.telegrambot.model.Update;
import java.util.Optional;
public class Util {
public static Optional<TgChat> extractChat(
CallbackQueryContext callbackQueryContext, Update update) {
return Optional.of(callbackQueryContext.getFields().getTelegramChatId())
.map(Double::longValue)
// If we're desperate, search in the message for the chat id
.or(
() ->
Optional.ofNullable(update.callbackQuery().message())
.map(Message::messageId)
.map(Long::valueOf))
.filter(chatId -> chatId != 0L && chatId != Long.MIN_VALUE)
.flatMap(chatId -> new QTgChat().id.eq(chatId).findOneOrEmpty());
}
public static Optional<Integer> extractMessageId(Update update) {
return Optional.ofNullable(update.callbackQuery().message()).map(Message::messageId);
}
}

View File

@ -1,13 +1,6 @@
package com.github.polpetta.mezzotre.telegram.command; package com.github.polpetta.mezzotre.telegram.command;
import com.github.polpetta.mezzotre.i18n.TemplateContentGenerator;
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.Field;
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.pengrad.telegrambot.model.Update; import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.model.request.InlineKeyboardButton; import com.pengrad.telegrambot.model.request.InlineKeyboardButton;
import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup; import com.pengrad.telegrambot.model.request.InlineKeyboardMarkup;
@ -19,38 +12,30 @@ 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.Executor; import java.util.concurrent.Executor;
import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import org.apache.commons.lang3.tuple.Pair;
public class Help implements Processor { public class Help implements Processor {
private static final String TRIGGERING_STAGING_NAME = "/help"; private static final String TRIGGERING_STAGING_NAME = "/help";
private final TemplateContentGenerator templateContentGenerator;
private final Executor threadPool; private final Executor threadPool;
private final Clock clock;
private final Map<String, Processor> tgCommandProcessors; private final Map<String, Processor> tgCommandProcessors;
private final Map<String, com.github.polpetta.mezzotre.telegram.callbackquery.Processor> private final Map<String, com.github.polpetta.mezzotre.telegram.callbackquery.Processor>
eventProcessor; eventProcessor;
private final UUIDGenerator uuidGenerator; private final com.github.polpetta.mezzotre.telegram.model.Help modelHelp;
@Inject @Inject
public Help( public Help(
TemplateContentGenerator templateContentGenerator,
@Named("eventThreadPool") Executor threadPool, @Named("eventThreadPool") Executor threadPool,
Clock clock,
@Named("commandProcessor") Map<String, Processor> tgCommandProcessors, @Named("commandProcessor") Map<String, Processor> tgCommandProcessors,
@Named("eventProcessors") @Named("eventProcessors")
Map<String, com.github.polpetta.mezzotre.telegram.callbackquery.Processor> eventProcessor, Map<String, com.github.polpetta.mezzotre.telegram.callbackquery.Processor> eventProcessor,
UUIDGenerator uuidGenerator) { com.github.polpetta.mezzotre.telegram.model.Help modelHelp) {
this.templateContentGenerator = templateContentGenerator;
this.threadPool = threadPool; this.threadPool = threadPool;
this.clock = clock;
this.tgCommandProcessors = tgCommandProcessors; this.tgCommandProcessors = tgCommandProcessors;
this.eventProcessor = eventProcessor; this.eventProcessor = eventProcessor;
this.uuidGenerator = uuidGenerator; this.modelHelp = modelHelp;
} }
@Override @Override
@ -62,66 +47,17 @@ public class Help implements Processor {
public CompletableFuture<Optional<BaseRequest<?, ?>>> process(TgChat chat, Update update) { public CompletableFuture<Optional<BaseRequest<?, ?>>> process(TgChat chat, Update update) {
return CompletableFuture.supplyAsync( return CompletableFuture.supplyAsync(
() -> { () -> {
final String message = final String message = modelHelp.getMessage(chat, tgCommandProcessors);
templateContentGenerator.mergeTemplate(
velocityContext -> {
velocityContext.put(
"commands",
tgCommandProcessors.values().stream()
.distinct()
.map(
p ->
Pair.of(
p.getTriggerKeywords().stream()
.sorted()
.collect(Collectors.toList()),
p.getLocaleDescriptionKeyword()))
.collect(Collectors.toList()));
},
chat.getLocale(),
"template/telegram/help.vm");
final ChatContext chatContext = chat.getChatContext();
chatContext.setStage(TRIGGERING_STAGING_NAME);
chatContext.setStep(0);
chatContext.setPreviousMessageUnixTimestampInSeconds(clock.now());
chat.setChatContext(chatContext);
chat.setHasHelpBeenShown(true);
chat.save();
final SendMessage sendMessage = final SendMessage sendMessage =
new SendMessage(chat.getId(), message).parseMode(ParseMode.Markdown); new SendMessage(chat.getId(), message).parseMode(ParseMode.Markdown);
final String callBackGroupId = uuidGenerator.generateAsString(); final InlineKeyboardButton[] buttons =
final InlineKeyboardButton[] collect = modelHelp.generateInlineKeyBoardButton(chat, eventProcessor);
eventProcessor.values().stream()
.filter(
com.github.polpetta.mezzotre.telegram.callbackquery.Processor
::canBeDirectlyInvokedByTheUser)
.filter(e -> e.getPrettyPrintLocaleKeyName().isPresent())
.map(
eventProcessor -> {
final CallbackQueryContext callbackQueryContext =
new CallbackQueryContext(
uuidGenerator.generateAsString(),
callBackGroupId,
new CallbackQueryMetadata.CallbackQueryMetadataBuilder()
.withEvent(eventProcessor.getEventName())
.withTelegramChatId(chat.getId())
.withAdditionalProperty(
Field.ShowHelp.InvokedFromHelpMessage.getName(), true)
.build());
callbackQueryContext.save();
return new InlineKeyboardButton( if (buttons.length > 0) {
templateContentGenerator.getString( sendMessage.replyMarkup(new InlineKeyboardMarkup(buttons));
chat.getLocale(), }
eventProcessor.getPrettyPrintLocaleKeyName().get()))
.callbackData(callbackQueryContext.getId());
})
.toArray(InlineKeyboardButton[]::new);
sendMessage.replyMarkup(new InlineKeyboardMarkup(collect));
return Optional.of(sendMessage); return Optional.of(sendMessage);
}, },

View File

@ -43,6 +43,6 @@ public interface Processor {
* description * description
*/ */
default String getLocaleDescriptionKeyword() { default String getLocaleDescriptionKeyword() {
return this.getClass().getName().toLowerCase() + ".cmdDescription"; return this.getClass().getSimpleName().toLowerCase() + ".cmdDescription";
} }
} }

View File

@ -1,18 +1,97 @@
package com.github.polpetta.mezzotre.telegram.model; package com.github.polpetta.mezzotre.telegram.model;
import com.github.polpetta.mezzotre.i18n.LocalizedMessageFactory; import com.github.polpetta.mezzotre.i18n.TemplateContentGenerator;
import com.github.polpetta.mezzotre.orm.model.CallbackQueryContext;
import com.github.polpetta.mezzotre.orm.model.TgChat;
import com.github.polpetta.mezzotre.telegram.callbackquery.Field;
import com.github.polpetta.mezzotre.telegram.command.Processor;
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.pengrad.telegrambot.model.request.InlineKeyboardButton;
import java.util.Map;
import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.commons.lang3.tuple.Pair;
// FIXME tests!
public class Help { public class Help {
private final LocalizedMessageFactory localizedMessageFactory; private static final String TRIGGERING_STAGING_NAME = "/help";
private final TemplateContentGenerator templateContentGenerator;
private final Clock clock;
private final UUIDGenerator uuidGenerator;
@Inject @Inject
public Help(LocalizedMessageFactory localizedMessageFactory) { public Help(
this.localizedMessageFactory = localizedMessageFactory; TemplateContentGenerator templateContentGenerator, Clock clock, UUIDGenerator uuidGenerator) {
this.templateContentGenerator = templateContentGenerator;
this.clock = clock;
this.uuidGenerator = uuidGenerator;
} }
public String generateErrorMessage() { public String getMessage(TgChat chat, Map<String, Processor> tgCommandProcessors) {
return ""; final String message =
templateContentGenerator.mergeTemplate(
velocityContext -> {
velocityContext.put(
"commands",
tgCommandProcessors.values().stream()
.distinct()
.map(
p ->
Pair.of(
p.getTriggerKeywords().stream()
.sorted()
.collect(Collectors.toList()),
p.getLocaleDescriptionKeyword()))
.collect(Collectors.toList()));
},
chat.getLocale(),
"template/telegram/help.vm");
// FIXME this shouldn't stay here. We need to move it into another method
final ChatContext chatContext = chat.getChatContext();
chatContext.setStage(TRIGGERING_STAGING_NAME);
chatContext.setStep(0);
chatContext.setPreviousMessageUnixTimestampInSeconds(clock.now());
chat.setChatContext(chatContext);
chat.setHasHelpBeenShown(true);
chat.save();
return message;
}
public InlineKeyboardButton[] generateInlineKeyBoardButton(
TgChat chat,
Map<String, com.github.polpetta.mezzotre.telegram.callbackquery.Processor> eventProcessors) {
final String callBackGroupId = uuidGenerator.generateAsString();
return eventProcessors.values().stream()
.filter(
com.github.polpetta.mezzotre.telegram.callbackquery.Processor
::canBeDirectlyInvokedByTheUser)
.filter(e -> e.getPrettyPrintLocaleKeyName().isPresent())
.map(
eventProcessor -> {
final CallbackQueryContext callbackQueryContext =
new CallbackQueryContext(
uuidGenerator.generateAsString(),
callBackGroupId,
new CallbackQueryMetadata.CallbackQueryMetadataBuilder()
.withEvent(eventProcessor.getEventName())
.withTelegramChatId(chat.getId())
.withAdditionalProperty(
Field.ShowHelp.InvokedFromHelpMessage.getName(), true)
.build());
callbackQueryContext.save();
return new InlineKeyboardButton(
templateContentGenerator.getString(
chat.getLocale(), eventProcessor.getPrettyPrintLocaleKeyName().get()))
.callbackData(callbackQueryContext.getId());
})
.toArray(InlineKeyboardButton[]::new);
} }
} }

View File

@ -1,11 +1,11 @@
start.helloFirstName=Hello {0}! \ud83d\udc4b start.helloFirstName=Hello {0}! \ud83d\udc4b
start.description=This is {0}, a simple bot focused on DnD content management! Please start by choosing a selectLanguageTutorial down below \ud83d\udc47 start.description=This is {0}, a simple bot focused on DnD content management! Please start by choosing a language down below \ud83d\udc47
start.cmdDescription=Trigger this very bot start.cmdDescription=Trigger this very bot
start.inlineKeyboardButtonName=Let''s begin! start.inlineKeyboardButtonName=Let''s begin!
selectLanguageTutorial.inlineKeyboardButtonName=Select language selectLanguageTutorial.inlineKeyboardButtonName=Select language
selectLanguageTutorial.drinkAction=*Proceeds to drink a potion with a strange, multicolor liquid* selectLanguageTutorial.drinkAction=*Proceeds to drink a potion with a strange, multicolor liquid*
selectLanguageTutorial.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 selectLanguageTutorial that you prefer! selectLanguageTutorial.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 that you prefer!
selectLanguageTutorial.instructions=You can always change your selectLanguageTutorial settings by typing /selectLanguageTutorial in the chat. selectLanguageTutorial.instructions=You can always change your language settings by typing /changeLanguage in the chat.
changeLanguage.english=English changeLanguage.english=English
changeLanguage.italian=Italian changeLanguage.italian=Italian
changeLanguage.cmdDescription=Select the new language I will use to speak to you changeLanguage.cmdDescription=Select the new language I will use to speak to you

View File

@ -1,11 +1,19 @@
start.helloFirstName=Hello {0}! \ud83d\udc4b start.helloFirstName=Hello {0}! \ud83d\udc4b
start.description=This is {0}, a simple bot focused on DnD content management! Please start by choosing a selectLanguageTutorial down below \ud83d\udc47 start.description=This is {0}, a simple bot focused on DnD content management! Please start by choosing a language down below \ud83d\udc47
start.cmdDescription=Trigger this very bot
start.inlineKeyboardButtonName=Let''s begin!
selectLanguageTutorial.inlineKeyboardButtonName=Select language
selectLanguageTutorial.drinkAction=*Proceeds to drink a potion with a strange, multicolor liquid* selectLanguageTutorial.drinkAction=*Proceeds to drink a potion with a strange, multicolor liquid*
selectLanguageTutorial.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 selectLanguageTutorial that you prefer! selectLanguageTutorial.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 that you prefer!
selectLanguageTutorial.instructions=You can always change your selectLanguageTutorial settings by typing /selectLanguageTutorial in the chat. selectLanguageTutorial.instructions=You can always change your language settings by typing /changeLanguage in the chat.
selectLanguageTutorial.english=English changeLanguage.english=English
selectLanguageTutorial.italian=Italian changeLanguage.italian=Italian
changeLanguage.cmdDescription=Select the new language I will use to speak to you
changeLanguage.inlineKeyboardButtonName=Change language
spell.speakWithAnimals=Speak with animals spell.speakWithAnimals=Speak with animals
selectLanguageTutorial.showMeTutorialInlineKeyboardButtonName=Show me what you can do! selectLanguageTutorial.showMeTutorialInlineKeyboardButtonName=Show me what you can do!
help.notShownYet=It seems you haven''t checked out what I can do yet! To have a complete list of my abilities, type /help in chat at any time! help.notShownYet=It seems you haven''t checked out what I can do yet! To have a complete list of my abilities, type /help in chat at any time!
help.buttonBelow=Alternatively, you can click the button down below. help.buttonBelow=Alternatively, you can click the button down below.
help.description=Here is a list of what I can do
help.buttonsToo=You can do the same operations you''d do with the commands aforementioned by selecting the corresponding button below \ud83d\udc47
help.cmdDescription=Print the help message

View File

@ -2,7 +2,7 @@ start.helloFirstName=Ciao {0}! \ud83d\udc4b
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=Questo è {0}, un semplice bot che ci concenta sulla gestione di contenuto per DnD! Per favore comincia selezionando la lingua qui sotto \ud83d\udc47
selectLanguageTutorial.drinkAction=*Procede a bere una pozione al cui suo interno si trova uno strano liquido multicolore* selectLanguageTutorial.drinkAction=*Procede a bere una pozione al cui suo interno si trova uno strano liquido multicolore*
selectLanguageTutorial.setLanguage=Grazie! Ora che ho bevuto questa posizione modificata di {0} che ho trovato ieri al negozio di pozioni magiche la "Cristalleria Fermentatrice" posso parlare con te nel linguaggio che preferisci! selectLanguageTutorial.setLanguage=Grazie! Ora che ho bevuto questa posizione modificata di {0} che ho trovato ieri al negozio di pozioni magiche la "Cristalleria Fermentatrice" posso parlare con te nel linguaggio che preferisci!
selectLanguageTutorial.instructions=Puoi sempre cambiare le preferenze della tua lingua scrivendo /selectLanguageTutorial nella chat. selectLanguageTutorial.instructions=Puoi sempre cambiare le preferenze della tua lingua scrivendo /changeLanguage nella chat.
selectLanguageTutorial.english=Inglese selectLanguageTutorial.english=Inglese
selectLanguageTutorial.italian=Italiano selectLanguageTutorial.italian=Italiano
spell.speakWithAnimals=Parlare con animali spell.speakWithAnimals=Parlare con animali

View File

@ -2,7 +2,7 @@ start.helloFirstName=Ciao {0}! \ud83d\udc4b
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=Questo è {0}, un semplice bot che ci concenta sulla gestione di contenuto per DnD! Per favore comincia selezionando la lingua qui sotto \ud83d\udc47
selectLanguageTutorial.drinkAction=*Procede a bere una pozione al cui suo interno si trova uno strano liquido multicolore* selectLanguageTutorial.drinkAction=*Procede a bere una pozione al cui suo interno si trova uno strano liquido multicolore*
selectLanguageTutorial.setLanguage=Grazie! Ora che ho bevuto questa posizione modificata di {0} che ho trovato ieri al negozio di pozioni magiche la "Cristalleria Fermentatrice" posso parlare con te nel linguaggio che preferisci! selectLanguageTutorial.setLanguage=Grazie! Ora che ho bevuto questa posizione modificata di {0} che ho trovato ieri al negozio di pozioni magiche la "Cristalleria Fermentatrice" posso parlare con te nel linguaggio che preferisci!
selectLanguageTutorial.instructions=Puoi sempre cambiare le preferenze della tua lingua scrivendo /selectLanguageTutorial nella chat. selectLanguageTutorial.instructions=Puoi sempre cambiare le preferenze della tua lingua scrivendo /changeLanguage nella chat.
selectLanguageTutorial.english=Inglese selectLanguageTutorial.english=Inglese
selectLanguageTutorial.italian=Italiano selectLanguageTutorial.italian=Italiano
spell.speakWithAnimals=Parlare con animali spell.speakWithAnimals=Parlare con animali

View File

@ -1,6 +1,7 @@
${i18n.help.description}: ${i18n.help.description}:
#foreach(${command} in ${commands}) #foreach(${command} in ${commands})
## FIXME this is not displayed correctly in telegram!
*#foreach(${key} in ${command.left}) ${key}#end: ${i18n.get(${command.right})} *#foreach(${key} in ${command.left}) ${key}#end: ${i18n.get(${command.right})}
#end #end

View File

@ -86,7 +86,7 @@ class SelectLanguageTutorialIntegrationTest {
+ " posso parlare con te nel linguaggio che preferisci!\n" + " posso parlare con te nel linguaggio che preferisci!\n"
+ "\n" + "\n"
+ "Puoi sempre cambiare le preferenze della tua lingua scrivendo" + "Puoi sempre cambiare le preferenze della tua lingua scrivendo"
+ " /selectLanguageTutorial nella chat.\n" + " /changeLanguage nella chat.\n"
+ "\n" + "\n"
+ "Sembra tu non abbia ancora visto cosa posso fare! Per avere una lista completa" + "Sembra tu non abbia ancora visto cosa posso fare! Per avere una lista completa"
+ " delle mie abilità, scrivi /help nella chat in qualsiasi momento!" + " delle mie abilità, scrivi /help nella chat in qualsiasi momento!"
@ -102,7 +102,7 @@ class SelectLanguageTutorialIntegrationTest {
+ " found at the \"Crystal Fermentary\" magic potion shop yesterday I can speak" + " found at the \"Crystal Fermentary\" magic potion shop yesterday I can speak"
+ " with you in the language that you prefer!\n" + " with you in the language that you prefer!\n"
+ "\n" + "\n"
+ "You can always change your language settings by typing /selectLanguageTutorial" + "You can always change your language settings by typing /changeLanguage"
+ " in the chat.\n" + " in the chat.\n"
+ "\n" + "\n"
+ "It seems you haven't checked out what I can do yet! To have a complete list of" + "It seems you haven't checked out what I can do yet! To have a complete list of"
@ -121,7 +121,7 @@ class SelectLanguageTutorialIntegrationTest {
+ " posso parlare con te nel linguaggio che preferisci!\n" + " posso parlare con te nel linguaggio che preferisci!\n"
+ "\n" + "\n"
+ "Puoi sempre cambiare le preferenze della tua lingua scrivendo" + "Puoi sempre cambiare le preferenze della tua lingua scrivendo"
+ " /selectLanguageTutorial nella chat.\n\n", + " /changeLanguage nella chat.\n\n",
"en-US", "en-US",
"Mostrami cosa puoi fare!", "Mostrami cosa puoi fare!",
true), true),
@ -133,7 +133,7 @@ class SelectLanguageTutorialIntegrationTest {
+ " found at the \"Crystal Fermentary\" magic potion shop yesterday I can speak" + " found at the \"Crystal Fermentary\" magic potion shop yesterday I can speak"
+ " with you in the language that you prefer!\n" + " with you in the language that you prefer!\n"
+ "\n" + "\n"
+ "You can always change your language settings by typing /selectLanguageTutorial" + "You can always change your language settings by typing /changeLanguage"
+ " in the chat.\n\n", + " in the chat.\n\n",
"it-IT", "it-IT",
"Show me what you can do!", "Show me what you can do!",

View File

@ -169,15 +169,14 @@ class HelpIntegrationTest {
events.put(dummyEvent1.getEventName(), dummyEvent1); events.put(dummyEvent1.getEventName(), dummyEvent1);
events.put(dummyEvent2.getEventName(), dummyEvent2); events.put(dummyEvent2.getEventName(), dummyEvent2);
help = final com.github.polpetta.mezzotre.telegram.model.Help modelHelp =
new Help( new com.github.polpetta.mezzotre.telegram.model.Help(
new TemplateContentGenerator(new LocalizedMessageFactory(velocityEngine)), new TemplateContentGenerator(new LocalizedMessageFactory(velocityEngine)),
Executors.newSingleThreadExecutor(),
fakeClock, fakeClock,
commands,
events,
new UUIDGenerator()); new UUIDGenerator());
help = new Help(Executors.newSingleThreadExecutor(), commands, events, modelHelp);
final Update update = final Update update =
gson.fromJson( gson.fromJson(
"{\n" "{\n"

View File

@ -0,0 +1,38 @@
package com.github.polpetta.mezzotre.telegram.command;
import static org.junit.jupiter.api.Assertions.*;
import com.github.polpetta.mezzotre.orm.model.TgChat;
import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.request.BaseRequest;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
@Execution(ExecutionMode.CONCURRENT)
class ProcessorTest {
@Test
void shouldGetSimpleNameClassIfNotDefined() {
class Test implements Processor {
@Override
public Set<String> getTriggerKeywords() {
return null;
}
@Override
public CompletableFuture<Optional<BaseRequest<?, ?>>> process(TgChat chat, Update update) {
return null;
}
}
final Test test = new Test();
assertEquals("test.cmdDescription", test.getLocaleDescriptionKeyword());
}
}