diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/bot/AbilityBot.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/bot/AbilityBot.java index c2024f46..d4d2c2ea 100644 --- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/bot/AbilityBot.java +++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/bot/AbilityBot.java @@ -14,6 +14,7 @@ import org.telegram.telegrambots.api.methods.groupadministration.GetChatAdminist import org.telegram.telegrambots.api.methods.send.SendDocument; import org.telegram.telegrambots.api.objects.Message; import org.telegram.telegrambots.api.objects.Update; +import org.telegram.telegrambots.api.objects.User; import org.telegram.telegrambots.bots.DefaultBotOptions; import org.telegram.telegrambots.bots.TelegramLongPollingBot; import org.telegram.telegrambots.exceptions.TelegramApiException; @@ -44,11 +45,11 @@ import static java.util.stream.Collectors.toMap; import static jersey.repackaged.com.google.common.base.Throwables.propagate; import static org.telegram.abilitybots.api.db.MapDBContext.onlineInstance; import static org.telegram.abilitybots.api.objects.Ability.builder; -import static org.telegram.abilitybots.api.objects.EndUser.fromUser; import static org.telegram.abilitybots.api.objects.Flag.*; import static org.telegram.abilitybots.api.objects.Locality.*; import static org.telegram.abilitybots.api.objects.MessageContext.newContext; import static org.telegram.abilitybots.api.objects.Privacy.*; +import static org.telegram.abilitybots.api.util.AbilityMessageCodes.*; import static org.telegram.abilitybots.api.util.AbilityUtils.*; /** @@ -102,10 +103,6 @@ public abstract class AbilityBot extends TelegramLongPollingBot { protected static final String RECOVER = "recover"; protected static final String COMMANDS = "commands"; - // Messages - protected static final String RECOVERY_MESSAGE = "I am ready to receive the backup file. Please reply to this message with the backup file attached."; - protected static final String RECOVER_SUCCESS = "I have successfully recovered."; - // DB and sender protected final DBContext db; protected MessageSender sender; @@ -148,9 +145,9 @@ public abstract class AbilityBot extends TelegramLongPollingBot { } /** - * @return the map of ID -> EndUser + * @return the map of ID -> User */ - protected Map users() { + protected Map users() { return db.getMap(USERS); } @@ -235,7 +232,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot { * @param username the username of the required user * @return the user */ - protected EndUser getUser(String username) { + protected User getUser(String username) { Integer id = userIds().get(username.toLowerCase()); if (id == null) { throw new IllegalStateException(format("Could not find ID corresponding to username [%s]", username)); @@ -250,26 +247,27 @@ public abstract class AbilityBot extends TelegramLongPollingBot { * @param id the id of the required user * @return the user */ - protected EndUser getUser(int id) { - EndUser endUser = users().get(id); - if (endUser == null) { + protected User getUser(int id) { + User user = users().get(id); + if (user == null) { throw new IllegalStateException(format("Could not find user corresponding to id [%d]", id)); } - return endUser; + return user; } /** * Gets the user with the specified username. If user was not found, the bot will send a message on Telegram. * * @param username the username of the required user + * @param ctx the message context with the originating user * @return the id of the user */ - protected int getUserIdSendError(String username, long chatId) { + protected int getUserIdSendError(String username, MessageContext ctx) { try { - return getUser(username).id(); + return getUser(username).getId(); } catch (IllegalStateException ex) { - silent.send(format("Sorry, I could not find the user [%s].", username), chatId); + silent.send(getLocalizedMessage(USER_NOT_FOUND, ctx.user().getLanguageCode(), username), ctx.chatId()); throw propagate(ex); } } @@ -306,7 +304,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot { }) .sorted() .reduce((a, b) -> format("%s%n%s", a, b)) - .orElse("No public commands found."); + .orElse(getLocalizedMessage(ABILITY_COMMANDS_NOT_FOUND, ctx.user().getLanguageCode())); silent.send(commands, ctx.chatId()); }) @@ -361,23 +359,27 @@ public abstract class AbilityBot extends TelegramLongPollingBot { .locality(USER) .privacy(CREATOR) .input(0) - .action(ctx -> silent.forceReply(RECOVERY_MESSAGE, ctx.chatId())) + .action(ctx -> silent.forceReply( + getLocalizedMessage(ABILITY_RECOVER_MESSAGE, ctx.user().getLanguageCode()), ctx.chatId())) .reply(update -> { - Long chatId = update.getMessage().getChatId(); - String fileId = update.getMessage().getDocument().getFileId(); + String replyToMsg = update.getMessage().getReplyToMessage().getText(); + String recoverMessage = getLocalizedMessage(ABILITY_RECOVER_MESSAGE, AbilityUtils.getUser(update).getLanguageCode()); + if (!replyToMsg.equals(recoverMessage)) + return; + String fileId = update.getMessage().getDocument().getFileId(); try (FileReader reader = new FileReader(downloadFileWithId(fileId))) { String backupData = IOUtils.toString(reader); if (db.recover(backupData)) { - silent.send(RECOVER_SUCCESS, chatId); + send(ABILITY_RECOVER_SUCCESS, update); } else { - silent.send("Oops, something went wrong during recovery.", chatId); + send(ABILITY_RECOVER_FAIL, update); } } catch (Exception e) { BotLogger.error("Could not recover DB from backup", TAG, e); - silent.send("I have failed to recover.", chatId); + send(ABILITY_RECOVER_ERROR, update); } - }, MESSAGE, DOCUMENT, REPLY, isReplyTo(RECOVERY_MESSAGE)) + }, MESSAGE, DOCUMENT, REPLY) .build(); } @@ -398,23 +400,23 @@ public abstract class AbilityBot extends TelegramLongPollingBot { .input(1) .action(ctx -> { String username = stripTag(ctx.firstArg()); - int userId = getUserIdSendError(username, ctx.chatId()); + int userId = getUserIdSendError(username, ctx); String bannedUser; // Protection from abuse if (userId == creatorId()) { - userId = ctx.user().id(); - bannedUser = isNullOrEmpty(ctx.user().username()) ? addTag(ctx.user().username()) : ctx.user().shortName(); + userId = ctx.user().getId(); + bannedUser = isNullOrEmpty(ctx.user().getUserName()) ? addTag(ctx.user().getUserName()) : shortName(ctx.user()); } else { bannedUser = addTag(username); } Set blacklist = blacklist(); if (blacklist.contains(userId)) - silent.sendMd(format("%s is already *banned*.", escape(bannedUser)), ctx.chatId()); + sendMd(ABILITY_BAN_FAIL, ctx, escape(bannedUser)); else { blacklist.add(userId); - silent.sendMd(format("%s is now *banned*.", escape(bannedUser)), ctx.chatId()); + sendMd(ABILITY_BAN_SUCCESS, ctx, escape(bannedUser)); } }) .post(commitTo(db)) @@ -434,14 +436,14 @@ public abstract class AbilityBot extends TelegramLongPollingBot { .input(1) .action(ctx -> { String username = stripTag(ctx.firstArg()); - Integer userId = getUserIdSendError(username, ctx.chatId()); + Integer userId = getUserIdSendError(username, ctx); Set blacklist = blacklist(); if (!blacklist.remove(userId)) - silent.sendMd(format("@%s is *not* on the *blacklist*.", escape(username)), ctx.chatId()); + silent.sendMd(getLocalizedMessage(ABILITY_UNBAN_FAIL, ctx.user().getLanguageCode(), escape(username)), ctx.chatId()); else { - silent.sendMd(format("@%s, your ban has been *lifted*.", escape(username)), ctx.chatId()); + silent.sendMd(getLocalizedMessage(ABILITY_UNBAN_SUCCESS, ctx.user().getLanguageCode(), escape(username)), ctx.chatId()); } }) .post(commitTo(db)) @@ -459,14 +461,14 @@ public abstract class AbilityBot extends TelegramLongPollingBot { .input(1) .action(ctx -> { String username = stripTag(ctx.firstArg()); - Integer userId = getUserIdSendError(username, ctx.chatId()); + Integer userId = getUserIdSendError(username, ctx); Set admins = admins(); if (admins.contains(userId)) - silent.sendMd(format("@%s is already an *admin*.", escape(username)), ctx.chatId()); + sendMd(ABILITY_PROMOTE_FAIL, ctx, escape(username)); else { admins.add(userId); - silent.sendMd(format("@%s has been *promoted*.", escape(username)), ctx.chatId()); + sendMd(ABILITY_PROMOTE_SUCCESS, ctx, escape(username)); } }).post(commitTo(db)) .build(); @@ -483,13 +485,13 @@ public abstract class AbilityBot extends TelegramLongPollingBot { .input(1) .action(ctx -> { String username = stripTag(ctx.firstArg()); - Integer userId = getUserIdSendError(username, ctx.chatId()); + Integer userId = getUserIdSendError(username, ctx); Set admins = admins(); if (admins.remove(userId)) { - silent.sendMd(format("@%s has been *demoted*.", escape(username)), ctx.chatId()); + sendMd(ABILITY_DEMOTE_SUCCESS, ctx, escape(username)); } else { - silent.sendMd(format("@%s is *not* an *admin*.", escape(username)), ctx.chatId()); + sendMd(ABILITY_DEMOTE_FAIL, ctx, escape(username)); } }) .post(commitTo(db)) @@ -508,26 +510,38 @@ public abstract class AbilityBot extends TelegramLongPollingBot { .privacy(PUBLIC) .input(0) .action(ctx -> { - if (ctx.user().id() == creatorId()) { + if (ctx.user().getId() == creatorId()) { Set admins = admins(); int id = creatorId(); - long chatId = ctx.chatId(); if (admins.contains(id)) - silent.send("You're already my master.", chatId); + send(ABILITY_CLAIM_FAIL, ctx); else { admins.add(id); - silent.send("You're now my master.", chatId); + send(ABILITY_CLAIM_SUCCESS, ctx); } } else { // This is not a joke - abilities.get(BAN).action().accept(newContext(ctx.update(), ctx.user(), ctx.chatId(), ctx.user().username())); + abilities.get(BAN).action().accept(newContext(ctx.update(), ctx.user(), ctx.chatId(), ctx.user().getUserName())); } }) .post(commitTo(db)) .build(); } + private Optional send(String message, MessageContext ctx, String... args) { + return silent.send(getLocalizedMessage(message, ctx.user().getLanguageCode(), args), ctx.chatId()); + } + + private Optional sendMd(String message, MessageContext ctx, String... args) { + return silent.sendMd(getLocalizedMessage(message, ctx.user().getLanguageCode(), args), ctx.chatId()); + } + + private Optional send(String message, Update upd) { + Long chatId = upd.getMessage().getChatId(); + return silent.send(getLocalizedMessage(message, AbilityUtils.getUser(upd).getLanguageCode()), chatId); + } + /** * Registers the declared abilities using method reflection. Also, replies are accumulated using the built abilities and standalone methods that return a Reply. *

@@ -597,7 +611,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot { Pair getContext(Trio trio) { Update update = trio.a(); - EndUser user = fromUser(AbilityUtils.getUser(update)); + User user = AbilityUtils.getUser(update); return Pair.of(newContext(update, user, getChatId(update), trio.c()), trio.b()); } @@ -615,7 +629,12 @@ public abstract class AbilityBot extends TelegramLongPollingBot { boolean isOk = abilityTokens == 0 || (tokens.length > 0 && tokens.length == abilityTokens); if (!isOk) - silent.send(format("Sorry, this feature requires %d additional %s.", abilityTokens, abilityTokens == 1 ? "input" : "inputs"), getChatId(trio.a())); + silent.send( + getLocalizedMessage( + CHECK_INPUT_FAIL, + AbilityUtils.getUser(trio.a()).getLanguageCode(), + abilityTokens, abilityTokens == 1 ? "input" : "inputs"), + getChatId(trio.a())); return isOk; } @@ -627,23 +646,31 @@ public abstract class AbilityBot extends TelegramLongPollingBot { boolean isOk = abilityLocality == ALL || locality == abilityLocality; if (!isOk) - silent.send(format("Sorry, %s-only feature.", abilityLocality.toString().toLowerCase()), getChatId(trio.a())); + silent.send( + getLocalizedMessage( + CHECK_LOCALITY_FAIL, + AbilityUtils.getUser(trio.a()).getLanguageCode(), + abilityLocality.toString().toLowerCase()), + getChatId(trio.a())); return isOk; } boolean checkPrivacy(Trio trio) { Update update = trio.a(); - EndUser user = fromUser(AbilityUtils.getUser(update)); + User user = AbilityUtils.getUser(update); Privacy privacy; - int id = user.id(); + int id = user.getId(); - privacy = isCreator(id) ? CREATOR : isAdmin(id) ? ADMIN : (isGroupUpdate(update) || isSuperGroupUpdate(update)) && isGroupAdmin(update, id)? GROUP_ADMIN : PUBLIC; + privacy = isCreator(id) ? CREATOR : isAdmin(id) ? ADMIN : (isGroupUpdate(update) || isSuperGroupUpdate(update)) && isGroupAdmin(update, id) ? GROUP_ADMIN : PUBLIC; boolean isOk = privacy.compareTo(trio.b().privacy()) >= 0; if (!isOk) - silent.send("Sorry, you don't have the required access level to do that.", getChatId(trio.a())); - + silent.send( + getLocalizedMessage( + CHECK_PRIVACY_FAIL, + AbilityUtils.getUser(trio.a()).getLanguageCode()), + getChatId(trio.a())); return isOk; } @@ -694,9 +721,9 @@ public abstract class AbilityBot extends TelegramLongPollingBot { } Update addUser(Update update) { - EndUser endUser = fromUser(AbilityUtils.getUser(update)); + User endUser = AbilityUtils.getUser(update); - users().compute(endUser.id(), (id, user) -> { + users().compute(endUser.getId(), (id, user) -> { if (user == null) { updateUserId(user, endUser); return endUser; @@ -714,15 +741,15 @@ public abstract class AbilityBot extends TelegramLongPollingBot { return update; } - private void updateUserId(EndUser oldUser, EndUser newUser) { - if (oldUser != null && oldUser.username() != null) { + private void updateUserId(User oldUser, User newUser) { + if (oldUser != null && oldUser.getUserName() != null) { // Remove old username -> ID - userIds().remove(oldUser.username()); + userIds().remove(oldUser.getUserName()); } - if (newUser.username() != null) { + if (newUser.getUserName() != null) { // Add new mapping with the new username - userIds().put(newUser.username().toLowerCase(), newUser.id()); + userIds().put(newUser.getUserName().toLowerCase(), newUser.getId()); } } @@ -750,6 +777,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot { return sender.downloadFile(sender.execute(new GetFile().setFileId(fileId))); } + private String escape(String username) { return username.replace("_", "\\_"); } diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/EndUser.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/EndUser.java deleted file mode 100644 index 7cc08145..00000000 --- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/EndUser.java +++ /dev/null @@ -1,138 +0,0 @@ -package org.telegram.abilitybots.api.objects; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.base.MoreObjects; -import org.telegram.telegrambots.api.objects.User; - -import java.io.Serializable; -import java.util.Objects; -import java.util.StringJoiner; - -import static org.apache.commons.lang3.StringUtils.isEmpty; - -/** - * This class serves the purpose of separating the basic Telegram {@link User} and the augmented {@link EndUser}. - *

- * It adds proper hashCode, equals, toString as well as useful utility methods such as {@link EndUser#shortName} and {@link EndUser#fullName}. - * - * @author Abbas Abou Daya - */ -public final class EndUser implements Serializable { - @JsonProperty("id") - private final Integer id; - @JsonProperty("firstName") - private final String firstName; - @JsonProperty("lastName") - private final String lastName; - @JsonProperty("username") - private final String username; - - private EndUser(Integer id, String firstName, String lastName, String username) { - this.id = id; - this.firstName = firstName; - this.lastName = lastName; - this.username = username; - } - - @JsonCreator - public static EndUser endUser(@JsonProperty("id") Integer id, - @JsonProperty("firstName") String firstName, - @JsonProperty("lastName") String lastName, - @JsonProperty("username") String username) { - return new EndUser(id, firstName, lastName, username); - } - - /** - * Constructs an {@link EndUser} from a {@link User}. - * - * @param user the Telegram user - * @return an augmented end-user - */ - public static EndUser fromUser(User user) { - return new EndUser(user.getId(), user.getFirstName(), user.getLastName(), user.getUserName()); - } - - public int id() { - return id; - } - - public String firstName() { - return firstName; - } - - public String lastName() { - return lastName; - } - - public String username() { - return username; - } - - /** - * The full name is identified as the concatenation of the first and last name, separated by a space. - * This method can return an empty name if both first and last name are empty. - * - * @return the full name of the user - */ - public String fullName() { - StringJoiner name = new StringJoiner(" "); - - if (!isEmpty(firstName)) - name.add(firstName); - if (!isEmpty(lastName)) - name.add(lastName); - - return name.toString(); - } - - /** - * The short name is one of the following: - *

    - *
  1. First name
  2. - *
  3. Last name
  4. - *
  5. Username
  6. - *
- * The method will try to return the first valid name in the specified order. - * - * @return the short name of the user - */ - public String shortName() { - if (!isEmpty(firstName)) - return firstName; - - if (!isEmpty(lastName)) - return lastName; - - return username; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - EndUser endUser = (EndUser) o; - return Objects.equals(id, endUser.id) && - Objects.equals(firstName, endUser.firstName) && - Objects.equals(lastName, endUser.lastName) && - Objects.equals(username, endUser.username); - } - - @Override - public int hashCode() { - return Objects.hash(id, firstName, lastName, username); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("id", id) - .add("firstName", firstName) - .add("lastName", lastName) - .add("username", username) - .toString(); - } -} diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/MessageContext.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/MessageContext.java index c3335af9..ca689cd1 100644 --- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/MessageContext.java +++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/MessageContext.java @@ -3,6 +3,7 @@ package org.telegram.abilitybots.api.objects; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; import org.telegram.telegrambots.api.objects.Update; +import org.telegram.telegrambots.api.objects.User; import java.util.Arrays; @@ -14,26 +15,26 @@ import java.util.Arrays; * @author Abbas Abou Daya */ public class MessageContext { - private final EndUser user; + private final User user; private final Long chatId; private final String[] arguments; private final Update update; - private MessageContext(Update update, EndUser user, Long chatId, String[] arguments) { + private MessageContext(Update update, User user, Long chatId, String[] arguments) { this.user = user; this.chatId = chatId; this.update = update; this.arguments = arguments; } - public static MessageContext newContext(Update update, EndUser user, Long chatId, String... arguments) { + public static MessageContext newContext(Update update, User user, Long chatId, String... arguments) { return new MessageContext(update, user, chatId, arguments); } /** * @return the originating Telegram user of this update */ - public EndUser user() { + public User user() { return user; } diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Reply.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Reply.java index 113d26b8..d88a99e3 100644 --- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Reply.java +++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/objects/Reply.java @@ -14,7 +14,7 @@ import static java.util.Arrays.asList; /** * A reply consists of update conditionals and an action to be applied on the update. *

- * If an update satisfies the {@link Reply#conditions}set by the reply, then it's safe to {@link Reply#actOn(Update)}. + * If an update satisfies the {@link Reply#conditions} set by the reply, then it's safe to {@link Reply#actOn(Update)}. * * @author Abbas Abou Daya */ diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityMessageCodes.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityMessageCodes.java new file mode 100644 index 00000000..4f21f937 --- /dev/null +++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityMessageCodes.java @@ -0,0 +1,31 @@ +package org.telegram.abilitybots.api.util; + +public final class AbilityMessageCodes { + public static String USER_NOT_FOUND = "userNotFound"; + public static String CHECK_INPUT_FAIL = "checkInput.fail"; + public static String CHECK_LOCALITY_FAIL = "checkLocality.fail"; + public static String CHECK_PRIVACY_FAIL = "checkPrivacy.fail"; + + public static String ABILITY_COMMANDS_NOT_FOUND = "ability.commands.notFound"; + + public static String ABILITY_RECOVER_SUCCESS = "ability.recover.success"; + public static String ABILITY_RECOVER_FAIL = "ability.recover.fail"; + public static String ABILITY_RECOVER_MESSAGE = "ability.recover.message"; + public static String ABILITY_RECOVER_ERROR = "ability.recover.error"; + + public static String ABILITY_BAN_SUCCESS = "ability.ban.success"; + public static String ABILITY_BAN_FAIL = "ability.ban.fail"; + + public static String ABILITY_UNBAN_SUCCESS = "ability.unban.success"; + public static String ABILITY_UNBAN_FAIL = "ability.unban.fail"; + + public static String ABILITY_PROMOTE_SUCCESS = "ability.promote.success"; + public static String ABILITY_PROMOTE_FAIL = "ability.promote.fail"; + + public static String ABILITY_DEMOTE_SUCCESS = "ability.demote.success"; + public static String ABILITY_DEMOTE_FAIL = "ability.demote.fail"; + + public static String ABILITY_CLAIM_SUCCESS = "ability.claim.success"; + public static String ABILITY_CLAIM_FAIL = "ability.claim.fail"; + +} diff --git a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityUtils.java b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityUtils.java index 6e313df4..a1aea560 100644 --- a/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityUtils.java +++ b/telegrambots-abilities/src/main/java/org/telegram/abilitybots/api/util/AbilityUtils.java @@ -1,13 +1,23 @@ package org.telegram.abilitybots.api.util; +import com.google.common.base.Strings; import org.telegram.abilitybots.api.db.DBContext; import org.telegram.abilitybots.api.objects.MessageContext; import org.telegram.telegrambots.api.objects.Update; import org.telegram.telegrambots.api.objects.User; +import java.text.MessageFormat; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.StringJoiner; import java.util.function.Consumer; import java.util.function.Predicate; +import static java.util.ResourceBundle.Control.FORMAT_PROPERTIES; +import static java.util.ResourceBundle.Control.getNoFallbackControl; +import static java.util.ResourceBundle.getBundle; +import static org.apache.commons.lang3.StringUtils.isEmpty; import static org.telegram.abilitybots.api.objects.Flag.*; /** @@ -172,4 +182,66 @@ public final class AbilityUtils { public static Predicate isReplyTo(String msg) { return update -> update.getMessage().getReplyToMessage().getText().equals(msg); } -} + + public static String getLocalizedMessage(String messageCode, Locale locale, Object...arguments) { + ResourceBundle bundle; + if (locale == null) { + bundle = getBundle("messages", Locale.ROOT); + } else { + try { + bundle = getBundle( + "messages", + locale, + getNoFallbackControl(FORMAT_PROPERTIES)); + } catch (MissingResourceException e) { + bundle = getBundle("messages", Locale.ROOT); + } + } + String message = bundle.getString(messageCode); + return MessageFormat.format(message, arguments); + } + + public static String getLocalizedMessage(String messageCode, String languageCode, Object...arguments){ + Locale locale = Strings.isNullOrEmpty(languageCode) ? null : Locale.forLanguageTag(languageCode); + return getLocalizedMessage(messageCode, locale, arguments); + } + + /** + * The short name is one of the following: + *

    + *
  1. First name
  2. + *
  3. Last name
  4. + *
  5. Username
  6. + *
+ * The method will try to return the first valid name in the specified order. + * + * @return the short name of the user + */ + public static String shortName(User user) { + if (!isEmpty(user.getFirstName())) + return user.getFirstName(); + + if (!isEmpty(user.getLastName())) + return user.getLastName(); + + return user.getUserName(); + } + + /** + * The full name is identified as the concatenation of the first and last name, separated by a space. + * This method can return an empty name if both first and last name are empty. + * + * @return the full name of the user + * @param user + */ + public static String fullName(User user) { + StringJoiner name = new StringJoiner(" "); + + if (!isEmpty(user.getFirstName())) + name.add(user.getFirstName()); + if (!isEmpty(user.getLastName())) + name.add(user.getLastName()); + + return name.toString(); + } +} \ No newline at end of file diff --git a/telegrambots-abilities/src/main/resources/messages.properties b/telegrambots-abilities/src/main/resources/messages.properties new file mode 100644 index 00000000..a8495e84 --- /dev/null +++ b/telegrambots-abilities/src/main/resources/messages.properties @@ -0,0 +1,27 @@ +ability.commands.notFound=No public commands found. + +ability.recover.success=I have successfully recovered. +ability.recover.fail=Oops, something went wrong during recovery. +ability.recover.message=I am ready to receive the backup file. Please reply to this message with the backup file attached. +ability.recover.error=I have failed to recover. + +ability.ban.success={0} is now *banned*. +ability.ban.fail={0} is already *banned*. + +ability.unban.success=@{0}, your ban has been *lifted*. +ability.unban.fail=@{0} is *not* on the *blacklist*. + +ability.promote.success=@{0} has been *promoted*. +ability.promote.fail=@{0} is already an *admin*. + +ability.demote.success=@{0} has been *demoted*. +ability.demote.fail=@{0} is *not* an *admin*. + +ability.claim.success=You''re now my master. +ability.claim.fail=You''re already my master. + +checkInput.fail=Sorry, this feature requires {0,number,integer} additional {1}. +checkLocality.fail=Sorry, {0}-only feature. +checkPrivacy.fail=Sorry, you don''t have the required access level to do that. + +userNotFound=Sorry, I could not find the user [{0}]. \ No newline at end of file diff --git a/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotI18nTest.java b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotI18nTest.java new file mode 100644 index 00000000..808b4eda --- /dev/null +++ b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotI18nTest.java @@ -0,0 +1,81 @@ +package org.telegram.abilitybots.api.bot; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.telegram.abilitybots.api.db.DBContext; +import org.telegram.abilitybots.api.objects.MessageContext; +import org.telegram.abilitybots.api.sender.MessageSender; +import org.telegram.abilitybots.api.sender.SilentSender; +import org.telegram.telegrambots.api.objects.User; + +import java.io.IOException; + +import static org.apache.commons.lang3.StringUtils.EMPTY; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.internal.verification.VerificationModeFactory.times; +import static org.telegram.abilitybots.api.bot.AbilityBotTest.mockContext; +import static org.telegram.abilitybots.api.db.MapDBContext.offlineInstance; + +public class AbilityBotI18nTest { + private static final User NO_LANGUAGE_USER = new User(1, "first", false, "last", "username", null); + private static final User ITALIAN_USER = new User(2, "first", false, "last", "username", "it-IT"); + + private DBContext db; + private NoPublicCommandsBot bot; + + private MessageSender sender; + private SilentSender silent; + + @Before + public void setUp() { + db = offlineInstance("db"); + bot = new NoPublicCommandsBot(EMPTY, EMPTY, db); + + sender = mock(MessageSender.class); + silent = mock(SilentSender.class); + + bot.sender = sender; + bot.silent = silent; + + } + + @Test + public void missingPublicCommandsLocalizedCorrectly1() { + MessageContext context = mockContext(NO_LANGUAGE_USER); + + bot.reportCommands().action().accept(context); + + verify(silent, times(1)) + .send("No public commands found.", NO_LANGUAGE_USER.getId()); + } + + @Test + public void missingPublicCommandsLocalizedCorrectly2() { + MessageContext context = mockContext(ITALIAN_USER); + + bot.reportCommands().action().accept(context); + + verify(silent, times(1)) + .send("Non sono presenti comandi pubblici.", ITALIAN_USER.getId()); + } + + @After + public void tearDown() throws IOException { + db.clear(); + db.close(); + } + + public static class NoPublicCommandsBot extends AbilityBot { + + protected NoPublicCommandsBot(String botToken, String botUsername, DBContext db) { + super(botToken, botUsername, db); + } + + @Override + public int creatorId() { + return 1; + } + } +} diff --git a/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotTest.java b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotTest.java index 29b26e01..c2fa81b7 100644 --- a/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotTest.java +++ b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/bot/AbilityBotTest.java @@ -36,11 +36,8 @@ import static org.junit.Assert.*; import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; import static org.mockito.internal.verification.VerificationModeFactory.times; -import static org.telegram.abilitybots.api.bot.AbilityBot.RECOVERY_MESSAGE; -import static org.telegram.abilitybots.api.bot.AbilityBot.RECOVER_SUCCESS; import static org.telegram.abilitybots.api.bot.DefaultBot.getDefaultBuilder; import static org.telegram.abilitybots.api.db.MapDBContext.offlineInstance; -import static org.telegram.abilitybots.api.objects.EndUser.endUser; import static org.telegram.abilitybots.api.objects.Flag.DOCUMENT; import static org.telegram.abilitybots.api.objects.Flag.MESSAGE; import static org.telegram.abilitybots.api.objects.Locality.ALL; @@ -49,12 +46,16 @@ import static org.telegram.abilitybots.api.objects.MessageContext.newContext; import static org.telegram.abilitybots.api.objects.Privacy.*; public class AbilityBotTest { + // Messages + private static final String RECOVERY_MESSAGE = "I am ready to receive the backup file. Please reply to this message with the backup file attached."; + private static final String RECOVER_SUCCESS = "I have successfully recovered."; + private static final String[] EMPTY_ARRAY = {}; private static final long GROUP_ID = 10L; private static final String TEST = "test"; private static final String[] TEXT = {TEST}; - public static final EndUser MUSER = endUser(1, "first", "last", "username"); - public static final EndUser CREATOR = endUser(1337, "creatorFirst", "creatorLast", "creatorUsername"); + public static final User USER = new User(1, "first", false, "last", "username", null); + public static final User CREATOR = new User(1337, "creatorFirst", false, "creatorLast", "creatorUsername", null); private DefaultBot bot; private DBContext db; @@ -75,39 +76,39 @@ public class AbilityBotTest { @Test public void sendsPrivacyViolation() { - Update update = mockFullUpdate(MUSER, "/admin"); + Update update = mockFullUpdate(USER, "/admin"); bot.onUpdateReceived(update); - verify(silent, times(1)).send("Sorry, you don't have the required access level to do that.", MUSER.id()); + verify(silent, times(1)).send("Sorry, you don't have the required access level to do that.", USER.getId()); } @Test public void sendsLocalityViolation() { - Update update = mockFullUpdate(MUSER, "/group"); + Update update = mockFullUpdate(USER, "/group"); bot.onUpdateReceived(update); - verify(silent, times(1)).send(format("Sorry, %s-only feature.", "group"), MUSER.id()); + verify(silent, times(1)).send(format("Sorry, %s-only feature.", "group"), USER.getId()); } @Test public void sendsInputArgsViolation() { - Update update = mockFullUpdate(MUSER, "/count 1 2 3"); + Update update = mockFullUpdate(USER, "/count 1 2 3"); bot.onUpdateReceived(update); - verify(silent, times(1)).send(format("Sorry, this feature requires %d additional inputs.", 4), MUSER.id()); + verify(silent, times(1)).send(format("Sorry, this feature requires %d additional inputs.", 4), USER.getId()); } @Test public void canProcessRepliesIfSatisfyRequirements() { - Update update = mockFullUpdate(MUSER, "must reply"); + Update update = mockFullUpdate(USER, "must reply"); // False means the update was not pushed down the stream since it has been consumed by the reply assertFalse(bot.filterReply(update)); - verify(silent, times(1)).send("reply", MUSER.id()); + verify(silent, times(1)).send("reply", USER.getId()); } @Test @@ -144,8 +145,8 @@ public class AbilityBotTest { @Test public void canDemote() { - addUsers(MUSER); - bot.admins().add(MUSER.id()); + addUsers(USER); + bot.admins().add(USER.getId()); MessageContext context = defaultContext(); @@ -158,33 +159,33 @@ public class AbilityBotTest { @Test public void canPromote() { - addUsers(MUSER); + addUsers(USER); MessageContext context = defaultContext(); bot.promoteAdmin().action().accept(context); Set actual = bot.admins(); - Set expected = newHashSet(MUSER.id()); + Set expected = newHashSet(USER.getId()); assertEquals("Could not sudo user", expected, actual); } @Test public void canBanUser() { - addUsers(MUSER); + addUsers(USER); MessageContext context = defaultContext(); bot.banUser().action().accept(context); Set actual = bot.blacklist(); - Set expected = newHashSet(MUSER.id()); + Set expected = newHashSet(USER.getId()); assertEquals("The ban was not emplaced", expected, actual); } @Test public void canUnbanUser() { - addUsers(MUSER); - bot.blacklist().add(MUSER.id()); + addUsers(USER); + bot.blacklist().add(USER.getId()); MessageContext context = defaultContext(); @@ -197,55 +198,49 @@ public class AbilityBotTest { @NotNull private MessageContext defaultContext() { - MessageContext context = mock(MessageContext.class); - when(context.user()).thenReturn(CREATOR); - when(context.firstArg()).thenReturn(MUSER.username()); + MessageContext context = mockContext(CREATOR, GROUP_ID, USER.getUserName()); return context; } @Test public void cannotBanCreator() { - addUsers(MUSER, CREATOR); - MessageContext context = mock(MessageContext.class); - when(context.user()).thenReturn(MUSER); - when(context.firstArg()).thenReturn(CREATOR.username()); + addUsers(USER, CREATOR); + MessageContext context = mockContext(USER, GROUP_ID, CREATOR.getUserName()); bot.banUser().action().accept(context); Set actual = bot.blacklist(); - Set expected = newHashSet(MUSER.id()); + Set expected = newHashSet(USER.getId()); assertEquals("Impostor was not added to the blacklist", expected, actual); } - private void addUsers(EndUser... users) { + private void addUsers(User... users) { Arrays.stream(users).forEach(user -> { - bot.users().put(user.id(), user); - bot.userIds().put(user.username().toLowerCase(), user.id()); + bot.users().put(user.getId(), user); + bot.userIds().put(user.getUserName().toLowerCase(), user.getId()); }); } @Test public void creatorCanClaimBot() { - MessageContext context = mock(MessageContext.class); - when(context.user()).thenReturn(CREATOR); + MessageContext context = mockContext(CREATOR, GROUP_ID); bot.claimCreator().action().accept(context); Set actual = bot.admins(); - Set expected = newHashSet(CREATOR.id()); + Set expected = newHashSet(CREATOR.getId()); assertEquals("Creator was not properly added to the super admins set", expected, actual); } @Test public void userGetsBannedIfClaimsBot() { - addUsers(MUSER); - MessageContext context = mock(MessageContext.class); - when(context.user()).thenReturn(MUSER); + addUsers(USER); + MessageContext context = mockContext(USER, GROUP_ID); bot.claimCreator().action().accept(context); Set actual = bot.blacklist(); - Set expected = newHashSet(MUSER.id()); + Set expected = newHashSet(USER.getId()); assertEquals("Could not find user on the blacklist", expected, actual); actual = bot.admins(); @@ -255,7 +250,7 @@ public class AbilityBotTest { @Test public void bannedCreatorPassesBlacklistCheck() { - bot.blacklist().add(CREATOR.id()); + bot.blacklist().add(CREATOR.getId()); Update update = mock(Update.class); Message message = mock(Message.class); User user = mock(User.class); @@ -272,35 +267,35 @@ public class AbilityBotTest { Message message = mock(Message.class); User user = mock(User.class); - mockAlternateUser(update, message, user, MUSER); + mockAlternateUser(update, message, USER); bot.addUser(update); - Map expectedUserIds = ImmutableMap.of(MUSER.username(), MUSER.id()); - Map expectedUsers = ImmutableMap.of(MUSER.id(), MUSER); + Map expectedUserIds = ImmutableMap.of(USER.getUserName(), USER.getId()); + Map expectedUsers = ImmutableMap.of(USER.getId(), USER); assertEquals("User was not added", expectedUserIds, bot.userIds()); assertEquals("User was not added", expectedUsers, bot.users()); } @Test public void canEditUser() { - addUsers(MUSER); + addUsers(USER); Update update = mock(Update.class); Message message = mock(Message.class); User user = mock(User.class); - String newUsername = MUSER.username() + "-test"; - String newFirstName = MUSER.firstName() + "-test"; - String newLastName = MUSER.lastName() + "-test"; - int sameId = MUSER.id(); - EndUser changedUser = endUser(sameId, newFirstName, newLastName, newUsername); + String newUsername = USER.getUserName() + "-test"; + String newFirstName = USER.getFirstName() + "-test"; + String newLastName = USER.getLastName() + "-test"; + int sameId = USER.getId(); + User changedUser = new User(sameId, newFirstName, false, newLastName, newUsername, null); - mockAlternateUser(update, message, user, changedUser); + mockAlternateUser(update, message, changedUser); bot.addUser(update); - Map expectedUserIds = ImmutableMap.of(changedUser.username(), changedUser.id()); - Map expectedUsers = ImmutableMap.of(changedUser.id(), changedUser); + Map expectedUserIds = ImmutableMap.of(changedUser.getUserName(), changedUser.getId()); + Map expectedUsers = ImmutableMap.of(changedUser.getId(), changedUser); assertEquals("User was not properly edited", bot.userIds(), expectedUserIds); assertEquals("User was not properly edited", expectedUsers, expectedUsers); } @@ -317,7 +312,7 @@ public class AbilityBotTest { @Test public void canCheckInput() { - Update update = mockFullUpdate(MUSER, "/something"); + Update update = mockFullUpdate(USER, "/something"); Ability abilityWithOneInput = getDefaultBuilder() .build(); Ability abilityWithZeroInput = getDefaultBuilder() @@ -408,7 +403,7 @@ public class AbilityBotTest { Trio creatorTrio = Trio.of(update, creatorAbility, TEXT); - bot.admins().add(MUSER.id()); + bot.admins().add(USER.getId()); mockUser(update, message, user); assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(creatorTrio)); @@ -439,15 +434,14 @@ public class AbilityBotTest { public void canRetrieveContext() { Update update = mock(Update.class); Message message = mock(Message.class); - User user = mock(User.class); Ability ability = getDefaultBuilder().build(); Trio trio = Trio.of(update, ability, TEXT); when(message.getChatId()).thenReturn(GROUP_ID); - mockUser(update, message, user); + mockUser(update, message, USER); Pair actualPair = bot.getContext(trio); - Pair expectedPair = Pair.of(newContext(update, MUSER, GROUP_ID, TEXT), ability); + Pair expectedPair = Pair.of(newContext(update, USER, GROUP_ID, TEXT), ability); assertEquals("Unexpected result when fetching for context", expectedPair, actualPair); } @@ -548,18 +542,30 @@ public class AbilityBotTest { @Test public void canReportCommands() { + MessageContext context = mockContext(USER, GROUP_ID); + + bot.reportCommands().action().accept(context); + + verify(silent, times(1)).send("default - dis iz default command", GROUP_ID); + } + + @NotNull + public static MessageContext mockContext(User user) { + return mockContext(user, user.getId()); + } + + @NotNull + public static MessageContext mockContext(User user, long groupId, String... args) { Update update = mock(Update.class); Message message = mock(Message.class); when(update.hasMessage()).thenReturn(true); when(update.getMessage()).thenReturn(message); + + when(message.getFrom()).thenReturn(user); when(message.hasText()).thenReturn(true); - MessageContext context = mock(MessageContext.class); - when(context.chatId()).thenReturn(GROUP_ID); - bot.reportCommands().action().accept(context); - - verify(silent, times(1)).send("default - dis iz default command", GROUP_ID); + return newContext(update, user, groupId, args); } @After @@ -568,26 +574,14 @@ public class AbilityBotTest { db.close(); } - private User mockUser(EndUser fromUser) { - User user = mock(User.class); - when(user.getId()).thenReturn(fromUser.id()); - when(user.getUserName()).thenReturn(fromUser.username()); - when(user.getFirstName()).thenReturn(fromUser.firstName()); - when(user.getLastName()).thenReturn(fromUser.lastName()); - - return user; - } - @NotNull - private Update mockFullUpdate(EndUser fromUser, String args) { - bot.users().put(MUSER.id(), MUSER); - bot.users().put(CREATOR.id(), CREATOR); - bot.userIds().put(CREATOR.username(), CREATOR.id()); - bot.userIds().put(MUSER.username(), MUSER.id()); + private Update mockFullUpdate(User user, String args) { + bot.users().put(USER.getId(), USER); + bot.users().put(CREATOR.getId(), CREATOR); + bot.userIds().put(CREATOR.getUserName(), CREATOR.getId()); + bot.userIds().put(USER.getUserName(), USER.getId()); - bot.admins().add(CREATOR.id()); - - User user = mockUser(fromUser); + bot.admins().add(CREATOR.getId()); Update update = mock(Update.class); when(update.hasMessage()).thenReturn(true); @@ -596,7 +590,7 @@ public class AbilityBotTest { when(message.getText()).thenReturn(args); when(message.hasText()).thenReturn(true); when(message.isUserMessage()).thenReturn(true); - when(message.getChatId()).thenReturn((long) fromUser.id()); + when(message.getChatId()).thenReturn((long) user.getId()); when(update.getMessage()).thenReturn(message); return update; } @@ -605,17 +599,9 @@ public class AbilityBotTest { when(update.hasMessage()).thenReturn(true); when(update.getMessage()).thenReturn(message); when(message.getFrom()).thenReturn(user); - when(user.getFirstName()).thenReturn(MUSER.firstName()); - when(user.getLastName()).thenReturn(MUSER.lastName()); - when(user.getId()).thenReturn(MUSER.id()); - when(user.getUserName()).thenReturn(MUSER.username()); } - private void mockAlternateUser(Update update, Message message, User user, EndUser changedUser) { - when(user.getId()).thenReturn(changedUser.id()); - when(user.getFirstName()).thenReturn(changedUser.firstName()); - when(user.getLastName()).thenReturn(changedUser.lastName()); - when(user.getUserName()).thenReturn(changedUser.username()); + private void mockAlternateUser(Update update, Message message, User user) { when(message.getFrom()).thenReturn(user); when(update.hasMessage()).thenReturn(true); when(update.getMessage()).thenReturn(message); @@ -627,10 +613,12 @@ public class AbilityBotTest { Message botMessage = mock(Message.class); Document document = mock(Document.class); + when(message.getFrom()).thenReturn(CREATOR); when(update.getMessage()).thenReturn(message); when(message.getDocument()).thenReturn(document); when(botMessage.getText()).thenReturn(RECOVERY_MESSAGE); when(message.isReply()).thenReturn(true); + when(update.hasMessage()).thenReturn(true); when(message.hasDocument()).thenReturn(true); when(message.getReplyToMessage()).thenReturn(botMessage); when(message.getChatId()).thenReturn(GROUP_ID); @@ -652,4 +640,17 @@ public class AbilityBotTest { writer.close(); return backupFile; } + + public static User newUser(Integer id, String firstname, String lastname, String username, String languageCode) { + User user = mock(User.class); + + when(user.getBot()).thenReturn(false); + when(user.getFirstName()).thenReturn(firstname); + when(user.getId()).thenReturn(id); + when(user.getLastName()).thenReturn(lastname); + when(user.getUserName()).thenReturn(username); + when(user.getLanguageCode()).thenReturn(languageCode); + + return user; + } } diff --git a/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/db/MapDBContextTest.java b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/db/MapDBContextTest.java index 7e53584b..502f70a1 100644 --- a/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/db/MapDBContextTest.java +++ b/telegrambots-abilities/src/test/java/org/telegram/abilitybots/api/db/MapDBContextTest.java @@ -3,7 +3,7 @@ package org.telegram.abilitybots.api.db; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.telegram.abilitybots.api.objects.EndUser; +import org.telegram.telegrambots.api.objects.User; import java.io.IOException; import java.util.Map; @@ -12,12 +12,11 @@ import java.util.Set; import static com.google.common.collect.Maps.newHashMap; import static com.google.common.collect.Sets.newHashSet; import static java.lang.String.format; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import static org.telegram.abilitybots.api.bot.AbilityBot.USERS; import static org.telegram.abilitybots.api.bot.AbilityBot.USER_ID; import static org.telegram.abilitybots.api.bot.AbilityBotTest.CREATOR; -import static org.telegram.abilitybots.api.bot.AbilityBotTest.MUSER; +import static org.telegram.abilitybots.api.bot.AbilityBotTest.USER; import static org.telegram.abilitybots.api.db.MapDBContext.offlineInstance; public class MapDBContextTest { @@ -32,22 +31,22 @@ public class MapDBContextTest { @Test public void canRecoverDB() { - Map users = db.getMap(USERS); + Map users = db.getMap(USERS); Map userIds = db.getMap(USER_ID); - users.put(CREATOR.id(), CREATOR); - users.put(MUSER.id(), MUSER); - userIds.put(CREATOR.username(), CREATOR.id()); - userIds.put(MUSER.username(), MUSER.id()); + users.put(CREATOR.getId(), CREATOR); + users.put(USER.getId(), USER); + userIds.put(CREATOR.getUserName(), CREATOR.getId()); + userIds.put(USER.getUserName(), USER.getId()); db.getSet("AYRE").add(123123); - Map originalUsers = newHashMap(users); + Map originalUsers = newHashMap(users); String beforeBackupInfo = db.info(USERS); Object jsonBackup = db.backup(); db.clear(); boolean recovered = db.recover(jsonBackup); - Map recoveredUsers = db.getMap(USERS); + Map recoveredUsers = db.getMap(USERS); String afterRecoveryInfo = db.info(USERS); assertTrue("Could not recover database successfully", recovered); @@ -56,24 +55,24 @@ public class MapDBContextTest { } @Test - public void canFallbackDBIfRecoveryFails() throws IOException { - Set users = db.getSet(USERS); + public void canFallbackDBIfRecoveryFails() { + Set users = db.getSet(USERS); users.add(CREATOR); - users.add(MUSER); + users.add(USER); - Set originalSet = newHashSet(users); + Set originalSet = newHashSet(users); Object jsonBackup = db.backup(); String corruptBackup = "!@#$" + String.valueOf(jsonBackup); boolean recovered = db.recover(corruptBackup); - Set recoveredSet = db.getSet(USERS); + Set recoveredSet = db.getSet(USERS); - assertEquals("Recovery was successful from a CORRUPT backup", false, recovered); + assertFalse("Recovery was successful from a CORRUPT backup", recovered); assertEquals("Set before and after corrupt recovery are not equal", originalSet, recoveredSet); } @Test - public void canGetSummary() throws IOException { + public void canGetSummary() { String anotherTest = TEST + 1; db.getSet(TEST).add(TEST); db.getSet(anotherTest).add(anotherTest); @@ -86,7 +85,7 @@ public class MapDBContextTest { } @Test - public void canGetInfo() throws IOException { + public void canGetInfo() { db.getSet(TEST).add(TEST); String actualInfo = db.info(TEST); @@ -97,7 +96,7 @@ public class MapDBContextTest { } @Test(expected = IllegalStateException.class) - public void cantGetInfoFromNonexistentDBStructureName() throws IOException { + public void cantGetInfoFromNonexistentDBStructureName() { db.info(TEST); } diff --git a/telegrambots-abilities/src/test/resources/messages_it_IT.properties b/telegrambots-abilities/src/test/resources/messages_it_IT.properties new file mode 100644 index 00000000..c5656cc1 --- /dev/null +++ b/telegrambots-abilities/src/test/resources/messages_it_IT.properties @@ -0,0 +1 @@ +ability.commands.notFound=Non sono presenti comandi pubblici. \ No newline at end of file