doc: add JavaDoc and remaining tests
parent
9ff5748964
commit
3baa041745
|
@ -17,6 +17,19 @@ import javax.inject.Named;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class works as a "batch" persistence entries remover - basically, it removes all the entries
|
||||||
|
* that are in the database in an async way. This allows better performance on other pieces of
|
||||||
|
* codebase, where we don't really care about checking that the removal has been successful, and
|
||||||
|
* instead we just want to issue a deletion and instantly continue with our codebase flow.
|
||||||
|
*
|
||||||
|
* <p>This service provides the ability to listen to the operation in two ways: via old-fashioned
|
||||||
|
* listeners and via {@link CompletableFuture}. If the caller wants to be sure that the removal has
|
||||||
|
* effectively happened, it can sync with the given {@link CompletableFuture}.
|
||||||
|
*
|
||||||
|
* @author Davide Polonio
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
public class BatchBeanCleanerService extends AbstractExecutionThreadService {
|
public class BatchBeanCleanerService extends AbstractExecutionThreadService {
|
||||||
|
|
||||||
private final LinkedBlockingDeque<
|
private final LinkedBlockingDeque<
|
||||||
|
@ -24,6 +37,10 @@ public class BatchBeanCleanerService extends AbstractExecutionThreadService {
|
||||||
entriesToRemove;
|
entriesToRemove;
|
||||||
private final Logger log;
|
private final Logger log;
|
||||||
private final Pair<Integer, TimeUnit> serviceRunningCheckTime;
|
private final Pair<Integer, TimeUnit> serviceRunningCheckTime;
|
||||||
|
|
||||||
|
// Accessing adding listeners while we iterate on the list inside the service thread _can_ be
|
||||||
|
// considered a race condition - but given the frequency of adding and removing listeners, the
|
||||||
|
// computational cost of putting Locks in place and check for them everytime is way greater
|
||||||
private final LinkedList<
|
private final LinkedList<
|
||||||
Consumer<Tuple3<String, PString<? extends TQRootBean<?, ?>>, CompletableFuture<Integer>>>>
|
Consumer<Tuple3<String, PString<? extends TQRootBean<?, ?>>, CompletableFuture<Integer>>>>
|
||||||
deletionListener;
|
deletionListener;
|
||||||
|
@ -40,6 +57,7 @@ public class BatchBeanCleanerService extends AbstractExecutionThreadService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void run() throws Exception {
|
protected void run() throws Exception {
|
||||||
|
log.trace("BatchBeanCleanerService run() method invoked");
|
||||||
while (isRunning()) {
|
while (isRunning()) {
|
||||||
// This statement is blocking for 1 sec if the queue is empty, and then it goes on - this way
|
// This statement is blocking for 1 sec if the queue is empty, and then it goes on - this way
|
||||||
// we check if the service is still supposed to be up or what
|
// we check if the service is still supposed to be up or what
|
||||||
|
@ -78,19 +96,39 @@ public class BatchBeanCleanerService extends AbstractExecutionThreadService {
|
||||||
entriesToRemove.clear();
|
entriesToRemove.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an entry to be removed
|
||||||
|
*
|
||||||
|
* @param id the id of the entry to remove
|
||||||
|
* @param column the column that will be used to perform the delete statement
|
||||||
|
* @return a {@link CompletableFuture} containing an {@link Integer} indicating the number of rows
|
||||||
|
* affected by the operation
|
||||||
|
*/
|
||||||
public CompletableFuture<Integer> removeAsync(
|
public CompletableFuture<Integer> removeAsync(
|
||||||
String id, PString<? extends TQRootBean<?, ?>> row) {
|
String id, PString<? extends TQRootBean<?, ?>> column) {
|
||||||
final CompletableFuture<Integer> jobExecution = new CompletableFuture<>();
|
final CompletableFuture<Integer> jobExecution = new CompletableFuture<>();
|
||||||
entriesToRemove.offer(Tuple.of(id, row, jobExecution));
|
entriesToRemove.offer(Tuple.of(id, column, jobExecution));
|
||||||
return jobExecution;
|
return jobExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a listener that will be invoked once the entry has been removed. This listener is invoked
|
||||||
|
* after the {@link CompletableFuture} completion. Note that all the listeners are called in a
|
||||||
|
* parallel fashion, so call order can change any time.
|
||||||
|
*
|
||||||
|
* @param listener the listener to add.
|
||||||
|
*/
|
||||||
public void addListener(
|
public void addListener(
|
||||||
Consumer<Tuple3<String, PString<? extends TQRootBean<?, ?>>, CompletableFuture<Integer>>>
|
Consumer<Tuple3<String, PString<? extends TQRootBean<?, ?>>, CompletableFuture<Integer>>>
|
||||||
listener) {
|
listener) {
|
||||||
deletionListener.add(listener);
|
deletionListener.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a listener
|
||||||
|
*
|
||||||
|
* @param listener the listener to be removed
|
||||||
|
*/
|
||||||
public void removeListener(
|
public void removeListener(
|
||||||
Consumer<Tuple3<String, PString<? extends TQRootBean<?, ?>>, CompletableFuture<Integer>>>
|
Consumer<Tuple3<String, PString<? extends TQRootBean<?, ?>>, CompletableFuture<Integer>>>
|
||||||
listener) {
|
listener) {
|
||||||
|
|
|
@ -73,7 +73,7 @@ class ShowHelp implements Processor {
|
||||||
return CompletableFuture.supplyAsync(
|
return CompletableFuture.supplyAsync(
|
||||||
() ->
|
() ->
|
||||||
chatUtil
|
chatUtil
|
||||||
.extractChat(callbackQueryContext, update) // FIXME callbackquerycontext removal?
|
.extractChat(callbackQueryContext, update)
|
||||||
.map(
|
.map(
|
||||||
chat -> {
|
chat -> {
|
||||||
final String message = modelHelp.getMessage(chat, tgCommandProcessors);
|
final String message = modelHelp.getMessage(chat, tgCommandProcessors);
|
||||||
|
|
|
@ -4,9 +4,21 @@ import com.pengrad.telegrambot.model.Message;
|
||||||
import com.pengrad.telegrambot.model.Update;
|
import com.pengrad.telegrambot.model.Update;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class with misc utilities
|
||||||
|
*
|
||||||
|
* @author Davide Polonio
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
public class Util {
|
public class Util {
|
||||||
|
|
||||||
// FIXME tests, doc
|
/**
|
||||||
|
* Extract the message id of the given {@link Update}
|
||||||
|
*
|
||||||
|
* @param update the {@link Update} to check and search the message id for
|
||||||
|
* @return an {@link Optional} containing a {@link Integer} with the message id if it is present,
|
||||||
|
* otherwise a {@link Optional#empty()} if it is not found.
|
||||||
|
*/
|
||||||
public static Optional<Integer> extractMessageId(Update update) {
|
public static Optional<Integer> extractMessageId(Update update) {
|
||||||
return Optional.ofNullable(update.callbackQuery().message()).map(Message::messageId);
|
return Optional.ofNullable(update.callbackQuery().message()).map(Message::messageId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,6 @@ class Start implements Processor {
|
||||||
"template/telegram/start.vm");
|
"template/telegram/start.vm");
|
||||||
log.trace("Start command - message to send back: " + message);
|
log.trace("Start command - message to send back: " + message);
|
||||||
|
|
||||||
// FIXME bug!! Show help button set to true but its fake news
|
|
||||||
chatUtil.updateChatContext(chat, TRIGGERING_STAGING_NAME, 0, Collections.emptyMap());
|
chatUtil.updateChatContext(chat, TRIGGERING_STAGING_NAME, 0, Collections.emptyMap());
|
||||||
|
|
||||||
// To get the messageId we should send the message first, then save it in the database!
|
// To get the messageId we should send the message first, then save it in the database!
|
||||||
|
|
|
@ -13,11 +13,17 @@ import java.util.stream.Collectors;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
// FIXME tests!
|
/**
|
||||||
|
* This class provides the model for the Help message output. It is the business logic behind the
|
||||||
|
* message, and a way to keep the codebase DRY.
|
||||||
|
*
|
||||||
|
* @author Davide Polonio
|
||||||
|
* @since 1.0
|
||||||
|
* @see com.github.polpetta.mezzotre.telegram.command.Help for the command help
|
||||||
|
* @see com.github.polpetta.mezzotre.telegram.callbackquery.ShowHelp for the event help
|
||||||
|
*/
|
||||||
public class Help {
|
public class Help {
|
||||||
|
|
||||||
private static final String TRIGGERING_STAGING_NAME = "/help";
|
|
||||||
|
|
||||||
private final TemplateContentGenerator templateContentGenerator;
|
private final TemplateContentGenerator templateContentGenerator;
|
||||||
private final UUIDGenerator uuidGenerator;
|
private final UUIDGenerator uuidGenerator;
|
||||||
|
|
||||||
|
@ -27,6 +33,15 @@ public class Help {
|
||||||
this.uuidGenerator = uuidGenerator;
|
this.uuidGenerator = uuidGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the message that will be sent back to the user. This takes the given {@link
|
||||||
|
* Processor} and formats them accordingly to the chat locale
|
||||||
|
*
|
||||||
|
* @param chat the {@link TgChat} conversation
|
||||||
|
* @param tgCommandProcessors a {@link Map} of all the {@link Processor} that will be printed in
|
||||||
|
* the help message
|
||||||
|
* @return a {@link String} localized ready to be sent to the user
|
||||||
|
*/
|
||||||
public String getMessage(TgChat chat, Map<String, Processor> tgCommandProcessors) {
|
public String getMessage(TgChat chat, Map<String, Processor> tgCommandProcessors) {
|
||||||
return templateContentGenerator.mergeTemplate(
|
return templateContentGenerator.mergeTemplate(
|
||||||
velocityContext -> {
|
velocityContext -> {
|
||||||
|
@ -45,6 +60,17 @@ public class Help {
|
||||||
"template/telegram/help.vm");
|
"template/telegram/help.vm");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates {@link InlineKeyboardButton} to be returned to the user to give them the possibility
|
||||||
|
* to interact with them via events rather than commands.
|
||||||
|
*
|
||||||
|
* @param chat the current {@link TgChat} conversation
|
||||||
|
* @param eventProcessors a {@link Map} of {@link
|
||||||
|
* com.github.polpetta.mezzotre.telegram.callbackquery.Processor} that are currently used to
|
||||||
|
* process all events. Note that only the one the user can interact with will be added as
|
||||||
|
* buttons
|
||||||
|
* @return an array of {@link InlineKeyboardButton}
|
||||||
|
*/
|
||||||
public InlineKeyboardButton[] generateInlineKeyBoardButton(
|
public InlineKeyboardButton[] generateInlineKeyBoardButton(
|
||||||
TgChat chat,
|
TgChat chat,
|
||||||
Map<String, com.github.polpetta.mezzotre.telegram.callbackquery.Processor> eventProcessors) {
|
Map<String, com.github.polpetta.mezzotre.telegram.callbackquery.Processor> eventProcessors) {
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package com.github.polpetta.mezzotre.telegram.callbackquery;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Execution(ExecutionMode.CONCURRENT)
|
||||||
|
class UtilTest {
|
||||||
|
|
||||||
|
private static Gson gson;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void beforeAll() {
|
||||||
|
gson = new Gson();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldProvideAMessageIdGivenTheUpdate() {
|
||||||
|
final Update update =
|
||||||
|
gson.fromJson(
|
||||||
|
"{\n"
|
||||||
|
+ " \"update_id\": 158712614,\n"
|
||||||
|
+ " \"callback_query\": {\n"
|
||||||
|
+ " \"id\": \"20496049451114620\",\n"
|
||||||
|
+ " \"from\": {\n"
|
||||||
|
+ " \"id\": 1111111,\n"
|
||||||
|
+ " \"is_bot\": false,\n"
|
||||||
|
+ " \"first_name\": \"Test Firstname\",\n"
|
||||||
|
+ " \"last_name\": \"Test Lastname\",\n"
|
||||||
|
+ " \"username\": \"Testusername\",\n"
|
||||||
|
+ " \"language_code\": \"en\"\n"
|
||||||
|
+ " },\n"
|
||||||
|
+ " \"message\": {\n"
|
||||||
|
+ " \"message_id\": 2723,\n"
|
||||||
|
+ " \"from\": {\n"
|
||||||
|
+ " \"id\": 244745330,\n"
|
||||||
|
+ " \"is_bot\": true,\n"
|
||||||
|
+ " \"first_name\": \"Dev - DavideBot\",\n"
|
||||||
|
+ " \"username\": \"devdavidebot\"\n"
|
||||||
|
+ " },\n"
|
||||||
|
+ " \"date\": 1681218838,\n"
|
||||||
|
+ " \"chat\": {\n"
|
||||||
|
+ " \"id\": 1111111,\n"
|
||||||
|
+ " \"type\": \"private\",\n"
|
||||||
|
+ " \"username\": \"Testusername\",\n"
|
||||||
|
+ " \"first_name\": \"Test Firstname\",\n"
|
||||||
|
+ " \"last_name\": \"Test Lastname\"\n"
|
||||||
|
+ " },\n"
|
||||||
|
+ " \"text\": \"a message\",\n"
|
||||||
|
+ " \"reply_markup\": {\n"
|
||||||
|
+ " \"inline_keyboard\": [\n"
|
||||||
|
+ " [\n"
|
||||||
|
+ " {\n"
|
||||||
|
+ " \"text\": \"English\",\n"
|
||||||
|
+ " \"callback_data\": \"9a64be11-d086-4bd9-859f-720c43dedcb5\"\n"
|
||||||
|
+ " },\n"
|
||||||
|
+ " {\n"
|
||||||
|
+ " \"text\": \"Italian\",\n"
|
||||||
|
+ " \"callback_data\": \"8768d660-f05f-4f4b-bda5-3451ab573d56\"\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ " ]\n"
|
||||||
|
+ " ]\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ "}",
|
||||||
|
Update.class);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
2723, Util.extractMessageId(update).get(), "A message id should be returned, 2723");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldGiveAnEmptyOptionalWithoutMessageId() {
|
||||||
|
final Update update =
|
||||||
|
gson.fromJson(
|
||||||
|
"{\n"
|
||||||
|
+ " \"update_id\": 158712614,\n"
|
||||||
|
+ " \"callback_query\": {\n"
|
||||||
|
+ " \"id\": \"20496049451114620\",\n"
|
||||||
|
+ " \"from\": {\n"
|
||||||
|
+ " \"id\": 1111111,\n"
|
||||||
|
+ " \"is_bot\": false,\n"
|
||||||
|
+ " \"first_name\": \"Test Firstname\",\n"
|
||||||
|
+ " \"last_name\": \"Test Lastname\",\n"
|
||||||
|
+ " \"username\": \"Testusername\",\n"
|
||||||
|
+ " \"language_code\": \"en\"\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ "}",
|
||||||
|
Update.class);
|
||||||
|
|
||||||
|
assertTrue(Util.extractMessageId(update).isEmpty(), "The shouldn't be any message id");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
package com.github.polpetta.mezzotre.telegram.model;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
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.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.query.QCallbackQueryContext;
|
||||||
|
import com.github.polpetta.mezzotre.telegram.callbackquery.Processor;
|
||||||
|
import com.github.polpetta.mezzotre.util.UUIDGenerator;
|
||||||
|
import com.github.polpetta.types.json.ChatContext;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.model.request.InlineKeyboardButton;
|
||||||
|
import com.pengrad.telegrambot.request.BaseRequest;
|
||||||
|
import io.ebean.Database;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
|
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("database")
|
||||||
|
@Tag("velocity")
|
||||||
|
@Testcontainers
|
||||||
|
class HelpIntegrationTest {
|
||||||
|
|
||||||
|
@Container
|
||||||
|
private final PostgreSQLContainer<?> postgresServer =
|
||||||
|
new PostgreSQLContainer<>(TestConfig.POSTGRES_DOCKER_IMAGE);
|
||||||
|
|
||||||
|
private TemplateContentGenerator templateContentGenerator;
|
||||||
|
private UUIDGenerator fakeUUIDGenerator;
|
||||||
|
private Help help;
|
||||||
|
private Database database;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() throws Exception {
|
||||||
|
database =
|
||||||
|
Loader.connectToDatabase(Loader.loadDefaultEbeanConfigWithPostgresSettings(postgresServer));
|
||||||
|
templateContentGenerator =
|
||||||
|
new TemplateContentGenerator(new LocalizedMessageFactory(Loader.defaultVelocityEngine()));
|
||||||
|
fakeUUIDGenerator = mock(UUIDGenerator.class);
|
||||||
|
|
||||||
|
help = new Help(templateContentGenerator, fakeUUIDGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldGenerateAGoodHelpMessage() {
|
||||||
|
final TgChat tgChat = new TgChat(11111L, new ChatContext());
|
||||||
|
tgChat.save();
|
||||||
|
|
||||||
|
final com.github.polpetta.mezzotre.telegram.command.Processor dummyCommand1 =
|
||||||
|
new com.github.polpetta.mezzotre.telegram.command.Processor() {
|
||||||
|
@Override
|
||||||
|
public Set<String> getTriggerKeywords() {
|
||||||
|
return Set.of("/example", "/another");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Optional<BaseRequest<?, ?>>> process(
|
||||||
|
TgChat chat, Update update) {
|
||||||
|
return CompletableFuture.completedFuture(Optional.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLocaleDescriptionKeyword() {
|
||||||
|
return "help.cmdDescription";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final String gotMessage =
|
||||||
|
help.getMessage(tgChat, Map.of("/example", dummyCommand1, "/another", dummyCommand1));
|
||||||
|
assertEquals(
|
||||||
|
"Here is a list of what I can do:\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "- /another /example: Print the help message\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "You can do the same operations you'd do with the commands aforementioned by"
|
||||||
|
+ " selecting the corresponding button below \uD83D\uDC47",
|
||||||
|
gotMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldGenerateButtonsCorrectly() {
|
||||||
|
final TgChat tgChat = new TgChat(111111L, new ChatContext());
|
||||||
|
tgChat.save();
|
||||||
|
when(fakeUUIDGenerator.generateAsString())
|
||||||
|
.thenReturn("53dc6dca-1042-4bc7-beb8-ce2a34df6a54")
|
||||||
|
.thenReturn("d5d3e016-7b60-4f1a-bd79-e1a6bff32f17");
|
||||||
|
|
||||||
|
final Processor visibleProcessor1 =
|
||||||
|
new Processor() {
|
||||||
|
@Override
|
||||||
|
public String getEventName() {
|
||||||
|
return "eventName";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBeDirectlyInvokedByTheUser() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getPrettyPrintLocaleKeyName() {
|
||||||
|
return Optional.of("changeLanguage.inlineKeyboardButtonName");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Optional<BaseRequest<?, ?>>> process(
|
||||||
|
CallbackQueryContext callbackQueryContext, Update update) {
|
||||||
|
return CompletableFuture.completedFuture(Optional.empty());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final Processor invisibleProcessor1 =
|
||||||
|
new Processor() {
|
||||||
|
@Override
|
||||||
|
public String getEventName() {
|
||||||
|
return "invisible";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Optional<BaseRequest<?, ?>>> process(
|
||||||
|
CallbackQueryContext callbackQueryContext, Update update) {
|
||||||
|
return CompletableFuture.completedFuture(Optional.empty());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final InlineKeyboardButton[] buttons =
|
||||||
|
help.generateInlineKeyBoardButton(
|
||||||
|
tgChat,
|
||||||
|
Map.of(
|
||||||
|
visibleProcessor1.getEventName(),
|
||||||
|
visibleProcessor1,
|
||||||
|
invisibleProcessor1.getEventName(),
|
||||||
|
invisibleProcessor1));
|
||||||
|
|
||||||
|
assertEquals(1, buttons.length);
|
||||||
|
assertEquals("Change language", buttons[0].text());
|
||||||
|
|
||||||
|
assertEquals(1, new QCallbackQueryContext().findCount());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.github.polpetta.mezzotre.telegram.model;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
import com.github.polpetta.mezzotre.i18n.TemplateContentGenerator;
|
||||||
|
import com.github.polpetta.mezzotre.orm.model.TgChat;
|
||||||
|
import com.github.polpetta.mezzotre.util.UUIDGenerator;
|
||||||
|
import java.util.Collections;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.parallel.Execution;
|
||||||
|
import org.junit.jupiter.api.parallel.ExecutionMode;
|
||||||
|
|
||||||
|
@Execution(ExecutionMode.CONCURRENT)
|
||||||
|
class HelpTest {
|
||||||
|
|
||||||
|
private TemplateContentGenerator fakeTemplateContentGenerator;
|
||||||
|
private UUIDGenerator fakeUUIDGenerator;
|
||||||
|
private Help help;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
|
||||||
|
fakeTemplateContentGenerator = mock(TemplateContentGenerator.class);
|
||||||
|
fakeUUIDGenerator = mock(UUIDGenerator.class);
|
||||||
|
|
||||||
|
help = new Help(fakeTemplateContentGenerator, fakeUUIDGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldCallTemplateContentGeneratorRight() {
|
||||||
|
|
||||||
|
final TgChat fakeChat = mock(TgChat.class);
|
||||||
|
when(fakeChat.getLocale()).thenReturn("en-US");
|
||||||
|
|
||||||
|
final String message = help.getMessage(fakeChat, Collections.emptyMap());
|
||||||
|
|
||||||
|
verify(fakeTemplateContentGenerator, times(1))
|
||||||
|
.mergeTemplate(any(), eq("en-US"), eq("template/telegram/help.vm"));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue