2017-06-30 18:29:10 +02:00
|
|
|
package org.telegram.abilitybots.api.bot;
|
|
|
|
|
|
|
|
import com.google.common.collect.ImmutableMap;
|
|
|
|
import com.google.common.io.Files;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
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.*;
|
|
|
|
import org.telegram.abilitybots.api.sender.MessageSender;
|
2017-10-29 03:15:53 +01:00
|
|
|
import org.telegram.abilitybots.api.sender.SilentSender;
|
2017-06-30 18:29:10 +02:00
|
|
|
import org.telegram.abilitybots.api.util.Pair;
|
|
|
|
import org.telegram.abilitybots.api.util.Trio;
|
2018-02-04 09:23:41 +01:00
|
|
|
import org.telegram.telegrambots.api.methods.groupadministration.GetChatAdministrators;
|
2017-06-30 18:29:10 +02:00
|
|
|
import org.telegram.telegrambots.api.objects.*;
|
|
|
|
import org.telegram.telegrambots.exceptions.TelegramApiException;
|
|
|
|
|
|
|
|
import java.io.BufferedWriter;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.nio.charset.Charset;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Map;
|
2018-02-04 09:23:41 +01:00
|
|
|
import java.util.Optional;
|
2017-06-30 18:29:10 +02:00
|
|
|
import java.util.Set;
|
|
|
|
|
2018-02-04 09:23:41 +01:00
|
|
|
import static com.google.common.collect.Lists.newArrayList;
|
2017-06-30 18:29:10 +02:00
|
|
|
import static com.google.common.collect.Sets.newHashSet;
|
|
|
|
import static java.lang.String.format;
|
|
|
|
import static java.util.Collections.emptySet;
|
2018-02-04 09:23:41 +01:00
|
|
|
import static java.util.Optional.empty;
|
2017-10-29 03:15:53 +01:00
|
|
|
import static org.apache.commons.io.FileUtils.deleteQuietly;
|
2017-06-30 18:29:10 +02:00
|
|
|
import static org.apache.commons.lang3.ArrayUtils.addAll;
|
|
|
|
import static org.apache.commons.lang3.StringUtils.EMPTY;
|
|
|
|
import static org.junit.Assert.*;
|
2017-10-29 03:15:53 +01:00
|
|
|
import static org.mockito.Matchers.any;
|
2017-06-30 18:29:10 +02:00
|
|
|
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;
|
|
|
|
import static org.telegram.abilitybots.api.objects.Locality.GROUP;
|
|
|
|
import static org.telegram.abilitybots.api.objects.MessageContext.newContext;
|
2018-02-04 09:23:41 +01:00
|
|
|
import static org.telegram.abilitybots.api.objects.Privacy.*;
|
2017-06-30 18:29:10 +02:00
|
|
|
|
|
|
|
public class AbilityBotTest {
|
2017-07-20 22:24:23 +02:00
|
|
|
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};
|
2017-06-30 18:29:10 +02:00
|
|
|
public static final EndUser MUSER = endUser(1, "first", "last", "username");
|
|
|
|
public static final EndUser CREATOR = endUser(1337, "creatorFirst", "creatorLast", "creatorUsername");
|
|
|
|
|
|
|
|
private DefaultBot bot;
|
|
|
|
private DBContext db;
|
|
|
|
private MessageSender sender;
|
2017-10-29 03:15:53 +01:00
|
|
|
private SilentSender silent;
|
2017-06-30 18:29:10 +02:00
|
|
|
|
|
|
|
@Before
|
|
|
|
public void setUp() {
|
|
|
|
db = offlineInstance("db");
|
|
|
|
bot = new DefaultBot(EMPTY, EMPTY, db);
|
2017-10-29 03:15:53 +01:00
|
|
|
|
2017-06-30 18:29:10 +02:00
|
|
|
sender = mock(MessageSender.class);
|
2017-10-29 03:15:53 +01:00
|
|
|
silent = mock(SilentSender.class);
|
|
|
|
|
|
|
|
bot.sender = sender;
|
|
|
|
bot.silent = silent;
|
2017-06-30 18:29:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void sendsPrivacyViolation() {
|
|
|
|
Update update = mockFullUpdate(MUSER, "/admin");
|
|
|
|
|
|
|
|
bot.onUpdateReceived(update);
|
|
|
|
|
2018-02-04 09:23:41 +01:00
|
|
|
verify(silent, times(1)).send("Sorry, you don't have the required access level to do that.", MUSER.id());
|
2017-06-30 18:29:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void sendsLocalityViolation() {
|
|
|
|
Update update = mockFullUpdate(MUSER, "/group");
|
|
|
|
|
|
|
|
bot.onUpdateReceived(update);
|
|
|
|
|
2017-10-29 03:15:53 +01:00
|
|
|
verify(silent, times(1)).send(format("Sorry, %s-only feature.", "group"), MUSER.id());
|
2017-06-30 18:29:10 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void sendsInputArgsViolation() {
|
|
|
|
Update update = mockFullUpdate(MUSER, "/count 1 2 3");
|
|
|
|
|
|
|
|
bot.onUpdateReceived(update);
|
|
|
|
|
2017-10-29 03:15:53 +01:00
|
|
|
verify(silent, times(1)).send(format("Sorry, this feature requires %d additional inputs.", 4), MUSER.id());
|
2017-06-30 18:29:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canProcessRepliesIfSatisfyRequirements() {
|
|
|
|
Update update = mockFullUpdate(MUSER, "must reply");
|
|
|
|
|
|
|
|
// False means the update was not pushed down the stream since it has been consumed by the reply
|
|
|
|
assertFalse(bot.filterReply(update));
|
2017-10-29 03:15:53 +01:00
|
|
|
verify(silent, times(1)).send("reply", MUSER.id());
|
2017-06-30 18:29:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canBackupDB() throws TelegramApiException {
|
|
|
|
MessageContext context = defaultContext();
|
|
|
|
|
|
|
|
bot.backupDB().action().accept(context);
|
2017-10-29 03:15:53 +01:00
|
|
|
deleteQuietly(new java.io.File("backup.json"));
|
2017-06-30 18:29:10 +02:00
|
|
|
|
|
|
|
verify(sender, times(1)).sendDocument(any());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canRecoverDB() throws TelegramApiException, IOException {
|
|
|
|
Update update = mockBackupUpdate();
|
|
|
|
Object backup = getDbBackup();
|
|
|
|
java.io.File backupFile = createBackupFile(backup);
|
|
|
|
|
2017-10-29 03:15:53 +01:00
|
|
|
when(sender.downloadFile(any(File.class))).thenReturn(backupFile);
|
2017-06-30 18:29:10 +02:00
|
|
|
bot.recoverDB().replies().get(0).actOn(update);
|
|
|
|
|
2017-10-29 03:15:53 +01:00
|
|
|
verify(silent, times(1)).send(RECOVER_SUCCESS, GROUP_ID);
|
2017-06-30 18:29:10 +02:00
|
|
|
assertEquals("Bot recovered but the DB is still not in sync", db.getSet(TEST), newHashSet(TEST));
|
|
|
|
assertTrue("Could not delete backup file", backupFile.delete());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canFilterOutReplies() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
when(update.hasMessage()).thenReturn(false);
|
|
|
|
|
|
|
|
assertTrue(bot.filterReply(update));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canDemote() {
|
|
|
|
addUsers(MUSER);
|
|
|
|
bot.admins().add(MUSER.id());
|
|
|
|
|
|
|
|
MessageContext context = defaultContext();
|
|
|
|
|
|
|
|
bot.demoteAdmin().action().accept(context);
|
|
|
|
|
|
|
|
Set<Integer> actual = bot.admins();
|
|
|
|
Set<Integer> expected = emptySet();
|
|
|
|
assertEquals("Could not sudont super-admin", expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canPromote() {
|
|
|
|
addUsers(MUSER);
|
|
|
|
|
|
|
|
MessageContext context = defaultContext();
|
|
|
|
|
|
|
|
bot.promoteAdmin().action().accept(context);
|
|
|
|
|
|
|
|
Set<Integer> actual = bot.admins();
|
|
|
|
Set<Integer> expected = newHashSet(MUSER.id());
|
|
|
|
assertEquals("Could not sudo user", expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canBanUser() {
|
|
|
|
addUsers(MUSER);
|
|
|
|
MessageContext context = defaultContext();
|
|
|
|
|
|
|
|
bot.banUser().action().accept(context);
|
|
|
|
|
|
|
|
Set<Integer> actual = bot.blacklist();
|
|
|
|
Set<Integer> expected = newHashSet(MUSER.id());
|
|
|
|
assertEquals("The ban was not emplaced", expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canUnbanUser() {
|
|
|
|
addUsers(MUSER);
|
|
|
|
bot.blacklist().add(MUSER.id());
|
|
|
|
|
|
|
|
MessageContext context = defaultContext();
|
|
|
|
|
|
|
|
bot.unbanUser().action().accept(context);
|
|
|
|
|
|
|
|
Set<Integer> actual = bot.blacklist();
|
|
|
|
Set<Integer> expected = newHashSet();
|
|
|
|
assertEquals("The ban was not lifted", expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
private MessageContext defaultContext() {
|
|
|
|
MessageContext context = mock(MessageContext.class);
|
|
|
|
when(context.user()).thenReturn(CREATOR);
|
|
|
|
when(context.firstArg()).thenReturn(MUSER.username());
|
|
|
|
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());
|
|
|
|
|
|
|
|
bot.banUser().action().accept(context);
|
|
|
|
|
|
|
|
Set<Integer> actual = bot.blacklist();
|
|
|
|
Set<Integer> expected = newHashSet(MUSER.id());
|
|
|
|
assertEquals("Impostor was not added to the blacklist", expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void addUsers(EndUser... users) {
|
|
|
|
Arrays.stream(users).forEach(user -> {
|
|
|
|
bot.users().put(user.id(), user);
|
|
|
|
bot.userIds().put(user.username().toLowerCase(), user.id());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void creatorCanClaimBot() {
|
|
|
|
MessageContext context = mock(MessageContext.class);
|
|
|
|
when(context.user()).thenReturn(CREATOR);
|
|
|
|
|
|
|
|
bot.claimCreator().action().accept(context);
|
|
|
|
|
|
|
|
Set<Integer> actual = bot.admins();
|
|
|
|
Set<Integer> expected = newHashSet(CREATOR.id());
|
|
|
|
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);
|
|
|
|
|
|
|
|
bot.claimCreator().action().accept(context);
|
|
|
|
|
|
|
|
Set<Integer> actual = bot.blacklist();
|
|
|
|
Set<Integer> expected = newHashSet(MUSER.id());
|
|
|
|
assertEquals("Could not find user on the blacklist", expected, actual);
|
|
|
|
|
|
|
|
actual = bot.admins();
|
|
|
|
expected = emptySet();
|
|
|
|
assertEquals("Admins set is not empty", expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void bannedCreatorPassesBlacklistCheck() {
|
|
|
|
bot.blacklist().add(CREATOR.id());
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
User user = mock(User.class);
|
|
|
|
|
|
|
|
mockUser(update, message, user);
|
|
|
|
|
|
|
|
boolean notBanned = bot.checkBlacklist(update);
|
|
|
|
assertTrue("Creator is banned", notBanned);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canAddUser() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
User user = mock(User.class);
|
|
|
|
|
|
|
|
mockAlternateUser(update, message, user, MUSER);
|
|
|
|
|
|
|
|
bot.addUser(update);
|
|
|
|
|
|
|
|
Map<String, Integer> expectedUserIds = ImmutableMap.of(MUSER.username(), MUSER.id());
|
|
|
|
Map<Integer, EndUser> expectedUsers = ImmutableMap.of(MUSER.id(), MUSER);
|
|
|
|
assertEquals("User was not added", expectedUserIds, bot.userIds());
|
|
|
|
assertEquals("User was not added", expectedUsers, bot.users());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canEditUser() {
|
|
|
|
addUsers(MUSER);
|
|
|
|
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);
|
|
|
|
|
|
|
|
mockAlternateUser(update, message, user, changedUser);
|
|
|
|
|
|
|
|
bot.addUser(update);
|
|
|
|
|
|
|
|
Map<String, Integer> expectedUserIds = ImmutableMap.of(changedUser.username(), changedUser.id());
|
|
|
|
Map<Integer, EndUser> expectedUsers = ImmutableMap.of(changedUser.id(), changedUser);
|
|
|
|
assertEquals("User was not properly edited", bot.userIds(), expectedUserIds);
|
|
|
|
assertEquals("User was not properly edited", expectedUsers, expectedUsers);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canValidateAbility() {
|
|
|
|
Trio<Update, Ability, String[]> invalidPair = Trio.of(null, null, null);
|
|
|
|
Ability validAbility = getDefaultBuilder().build();
|
|
|
|
Trio<Update, Ability, String[]> validPair = Trio.of(null, validAbility, null);
|
|
|
|
|
|
|
|
assertEquals("Bot can't validate ability properly", false, bot.validateAbility(invalidPair));
|
|
|
|
assertEquals("Bot can't validate ability properly", true, bot.validateAbility(validPair));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canCheckInput() {
|
|
|
|
Update update = mockFullUpdate(MUSER, "/something");
|
|
|
|
Ability abilityWithOneInput = getDefaultBuilder()
|
|
|
|
.build();
|
|
|
|
Ability abilityWithZeroInput = getDefaultBuilder()
|
|
|
|
.input(0)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
Trio<Update, Ability, String[]> trioOneArg = Trio.of(update, abilityWithOneInput, TEXT);
|
|
|
|
Trio<Update, Ability, String[]> trioZeroArg = Trio.of(update, abilityWithZeroInput, TEXT);
|
|
|
|
|
|
|
|
assertEquals("Unexpected result when applying token filter", true, bot.checkInput(trioOneArg));
|
|
|
|
|
|
|
|
trioOneArg = Trio.of(update, abilityWithOneInput, addAll(TEXT, TEXT));
|
|
|
|
assertEquals("Unexpected result when applying token filter", false, bot.checkInput(trioOneArg));
|
|
|
|
|
|
|
|
assertEquals("Unexpected result when applying token filter", true, bot.checkInput(trioZeroArg));
|
|
|
|
|
|
|
|
trioZeroArg = Trio.of(update, abilityWithZeroInput, EMPTY_ARRAY);
|
|
|
|
assertEquals("Unexpected result when applying token filter", true, bot.checkInput(trioZeroArg));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canCheckPrivacy() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
org.telegram.telegrambots.api.objects.User user = mock(User.class);
|
|
|
|
Ability publicAbility = getDefaultBuilder().privacy(PUBLIC).build();
|
2018-02-04 09:23:41 +01:00
|
|
|
Ability groupAdminAbility = getDefaultBuilder().privacy(GROUP_ADMIN).build();
|
2017-06-30 18:29:10 +02:00
|
|
|
Ability adminAbility = getDefaultBuilder().privacy(ADMIN).build();
|
|
|
|
Ability creatorAbility = getDefaultBuilder().privacy(Privacy.CREATOR).build();
|
|
|
|
|
|
|
|
Trio<Update, Ability, String[]> publicTrio = Trio.of(update, publicAbility, TEXT);
|
2018-02-04 09:23:41 +01:00
|
|
|
Trio<Update, Ability, String[]> groupAdminTrio = Trio.of(update, groupAdminAbility, TEXT);
|
2017-06-30 18:29:10 +02:00
|
|
|
Trio<Update, Ability, String[]> adminTrio = Trio.of(update, adminAbility, TEXT);
|
|
|
|
Trio<Update, Ability, String[]> creatorTrio = Trio.of(update, creatorAbility, TEXT);
|
|
|
|
|
|
|
|
mockUser(update, message, user);
|
|
|
|
|
|
|
|
assertEquals("Unexpected result when checking for privacy", true, bot.checkPrivacy(publicTrio));
|
2018-02-04 09:23:41 +01:00
|
|
|
assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(groupAdminTrio));
|
2017-06-30 18:29:10 +02:00
|
|
|
assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(adminTrio));
|
|
|
|
assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(creatorTrio));
|
|
|
|
}
|
|
|
|
|
2018-02-04 09:23:41 +01:00
|
|
|
@Test
|
2018-05-08 02:39:21 +02:00
|
|
|
public void canValidateGroupAdminPrivacy() {
|
2018-02-04 09:23:41 +01:00
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
org.telegram.telegrambots.api.objects.User user = mock(User.class);
|
|
|
|
Ability groupAdminAbility = getDefaultBuilder().privacy(GROUP_ADMIN).build();
|
|
|
|
|
|
|
|
Trio<Update, Ability, String[]> groupAdminTrio = Trio.of(update, groupAdminAbility, TEXT);
|
|
|
|
|
|
|
|
mockUser(update, message, user);
|
|
|
|
when(message.isGroupMessage()).thenReturn(true);
|
|
|
|
|
|
|
|
ChatMember member = mock(ChatMember.class);
|
|
|
|
when(member.getUser()).thenReturn(user);
|
|
|
|
when(member.getUser()).thenReturn(user);
|
|
|
|
|
|
|
|
when(silent.execute(any(GetChatAdministrators.class))).thenReturn(Optional.of(newArrayList(member)));
|
|
|
|
|
|
|
|
assertEquals("Unexpected result when checking for privacy", true, bot.checkPrivacy(groupAdminTrio));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2018-05-08 02:39:21 +02:00
|
|
|
public void canRestrictNormalUsersFromGroupAdminAbilities() {
|
2018-02-04 09:23:41 +01:00
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
org.telegram.telegrambots.api.objects.User user = mock(User.class);
|
|
|
|
Ability groupAdminAbility = getDefaultBuilder().privacy(GROUP_ADMIN).build();
|
|
|
|
|
|
|
|
Trio<Update, Ability, String[]> groupAdminTrio = Trio.of(update, groupAdminAbility, TEXT);
|
|
|
|
|
|
|
|
mockUser(update, message, user);
|
|
|
|
when(message.isGroupMessage()).thenReturn(true);
|
|
|
|
|
|
|
|
when(silent.execute(any(GetChatAdministrators.class))).thenReturn(empty());
|
|
|
|
|
|
|
|
assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(groupAdminTrio));
|
|
|
|
}
|
|
|
|
|
2017-06-30 18:29:10 +02:00
|
|
|
@Test
|
|
|
|
public void canBlockAdminsFromCreatorAbilities() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
org.telegram.telegrambots.api.objects.User user = mock(User.class);
|
|
|
|
Ability creatorAbility = getDefaultBuilder().privacy(Privacy.CREATOR).build();
|
|
|
|
|
|
|
|
Trio<Update, Ability, String[]> creatorTrio = Trio.of(update, creatorAbility, TEXT);
|
|
|
|
|
|
|
|
bot.admins().add(MUSER.id());
|
|
|
|
mockUser(update, message, user);
|
|
|
|
|
|
|
|
assertEquals("Unexpected result when checking for privacy", false, bot.checkPrivacy(creatorTrio));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canCheckLocality() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
User user = mock(User.class);
|
|
|
|
Ability allAbility = getDefaultBuilder().locality(ALL).build();
|
|
|
|
Ability userAbility = getDefaultBuilder().locality(Locality.USER).build();
|
|
|
|
Ability groupAbility = getDefaultBuilder().locality(GROUP).build();
|
|
|
|
|
|
|
|
Trio<Update, Ability, String[]> publicTrio = Trio.of(update, allAbility, TEXT);
|
|
|
|
Trio<Update, Ability, String[]> userTrio = Trio.of(update, userAbility, TEXT);
|
|
|
|
Trio<Update, Ability, String[]> groupTrio = Trio.of(update, groupAbility, TEXT);
|
|
|
|
|
|
|
|
mockUser(update, message, user);
|
|
|
|
when(message.isUserMessage()).thenReturn(true);
|
|
|
|
|
|
|
|
assertEquals("Unexpected result when checking for locality", true, bot.checkLocality(publicTrio));
|
|
|
|
assertEquals("Unexpected result when checking for locality", true, bot.checkLocality(userTrio));
|
|
|
|
assertEquals("Unexpected result when checking for locality", false, bot.checkLocality(groupTrio));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canRetrieveContext() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
User user = mock(User.class);
|
|
|
|
Ability ability = getDefaultBuilder().build();
|
|
|
|
Trio<Update, Ability, String[]> trio = Trio.of(update, ability, TEXT);
|
|
|
|
|
|
|
|
when(message.getChatId()).thenReturn(GROUP_ID);
|
|
|
|
mockUser(update, message, user);
|
|
|
|
|
|
|
|
Pair<MessageContext, Ability> actualPair = bot.getContext(trio);
|
|
|
|
Pair<MessageContext, Ability> expectedPair = Pair.of(newContext(update, MUSER, GROUP_ID, TEXT), ability);
|
|
|
|
|
|
|
|
assertEquals("Unexpected result when fetching for context", expectedPair, actualPair);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2017-11-01 04:06:03 +01:00
|
|
|
public void defaultGlobalFlagIsTrue() {
|
2017-06-30 18:29:10 +02:00
|
|
|
Update update = mock(Update.class);
|
2017-11-01 04:06:03 +01:00
|
|
|
assertEquals("Unexpected result when checking for the default global flags", true, bot.checkGlobalFlags(update));
|
2017-06-30 18:29:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test(expected = ArithmeticException.class)
|
|
|
|
public void canConsumeUpdate() {
|
|
|
|
Ability ability = getDefaultBuilder()
|
|
|
|
.action((context) -> {
|
|
|
|
int x = 1 / 0;
|
|
|
|
}).build();
|
|
|
|
MessageContext context = mock(MessageContext.class);
|
|
|
|
|
|
|
|
Pair<MessageContext, Ability> pair = Pair.of(context, ability);
|
|
|
|
|
|
|
|
bot.consumeUpdate(pair);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canFetchAbility() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
|
|
|
|
String text = "/test";
|
|
|
|
when(update.hasMessage()).thenReturn(true);
|
|
|
|
when(update.getMessage()).thenReturn(message);
|
|
|
|
when(update.getMessage().hasText()).thenReturn(true);
|
|
|
|
when(message.getText()).thenReturn(text);
|
|
|
|
|
|
|
|
Trio<Update, Ability, String[]> trio = bot.getAbility(update);
|
|
|
|
|
|
|
|
Ability expected = bot.testAbility();
|
|
|
|
Ability actual = trio.b();
|
|
|
|
|
|
|
|
assertEquals("Wrong ability was fetched", expected, actual);
|
|
|
|
}
|
|
|
|
|
2018-02-04 09:23:41 +01:00
|
|
|
@Test
|
|
|
|
public void canFetchAbilityCaseInsensitive() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
|
|
|
|
String text = "/tESt";
|
|
|
|
when(update.hasMessage()).thenReturn(true);
|
|
|
|
when(update.getMessage()).thenReturn(message);
|
|
|
|
when(update.getMessage().hasText()).thenReturn(true);
|
|
|
|
when(message.getText()).thenReturn(text);
|
|
|
|
|
|
|
|
Trio<Update, Ability, String[]> trio = bot.getAbility(update);
|
|
|
|
|
|
|
|
Ability expected = bot.testAbility();
|
|
|
|
Ability actual = trio.b();
|
|
|
|
|
|
|
|
assertEquals("Wrong ability was fetched", expected, actual);
|
|
|
|
}
|
|
|
|
|
2017-06-30 18:29:10 +02:00
|
|
|
@Test
|
|
|
|
public void canFetchDefaultAbility() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
|
|
|
|
String text = "test tags";
|
|
|
|
when(update.getMessage()).thenReturn(message);
|
|
|
|
when(message.getText()).thenReturn(text);
|
|
|
|
|
|
|
|
Trio<Update, Ability, String[]> trio = bot.getAbility(update);
|
|
|
|
|
|
|
|
Ability expected = bot.defaultAbility();
|
|
|
|
Ability actual = trio.b();
|
|
|
|
|
|
|
|
assertEquals("Wrong ability was fetched", expected, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canCheckAbilityFlags() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
|
|
|
|
when(update.hasMessage()).thenReturn(true);
|
|
|
|
when(update.getMessage()).thenReturn(message);
|
|
|
|
when(message.hasDocument()).thenReturn(false);
|
|
|
|
when(message.hasText()).thenReturn(true);
|
|
|
|
|
|
|
|
Ability documentAbility = getDefaultBuilder().flag(DOCUMENT, MESSAGE).build();
|
|
|
|
Ability textAbility = getDefaultBuilder().flag(Flag.TEXT, MESSAGE).build();
|
|
|
|
|
|
|
|
Trio<Update, Ability, String[]> docTrio = Trio.of(update, documentAbility, TEXT);
|
|
|
|
Trio<Update, Ability, String[]> textTrio = Trio.of(update, textAbility, TEXT);
|
|
|
|
|
|
|
|
assertEquals("Unexpected result when checking for message flags", false, bot.checkMessageFlags(docTrio));
|
|
|
|
assertEquals("Unexpected result when checking for message flags", true, bot.checkMessageFlags(textTrio));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void canReportCommands() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
|
|
|
|
when(update.hasMessage()).thenReturn(true);
|
|
|
|
when(update.getMessage()).thenReturn(message);
|
|
|
|
when(message.hasText()).thenReturn(true);
|
|
|
|
MessageContext context = mock(MessageContext.class);
|
|
|
|
when(context.chatId()).thenReturn(GROUP_ID);
|
2018-04-18 17:14:32 +02:00
|
|
|
when(context.user()).thenReturn(MUSER);
|
2017-06-30 18:29:10 +02:00
|
|
|
|
|
|
|
bot.reportCommands().action().accept(context);
|
|
|
|
|
2017-10-29 03:15:53 +01:00
|
|
|
verify(silent, times(1)).send("default - dis iz default command", GROUP_ID);
|
2017-06-30 18:29:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@After
|
|
|
|
public void tearDown() throws IOException {
|
|
|
|
db.clear();
|
|
|
|
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());
|
|
|
|
|
|
|
|
bot.admins().add(CREATOR.id());
|
|
|
|
|
|
|
|
User user = mockUser(fromUser);
|
|
|
|
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
when(update.hasMessage()).thenReturn(true);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
when(message.getFrom()).thenReturn(user);
|
|
|
|
when(message.getText()).thenReturn(args);
|
|
|
|
when(message.hasText()).thenReturn(true);
|
|
|
|
when(message.isUserMessage()).thenReturn(true);
|
|
|
|
when(message.getChatId()).thenReturn((long) fromUser.id());
|
|
|
|
when(update.getMessage()).thenReturn(message);
|
|
|
|
return update;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void mockUser(Update update, Message message, User user) {
|
|
|
|
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());
|
|
|
|
when(message.getFrom()).thenReturn(user);
|
|
|
|
when(update.hasMessage()).thenReturn(true);
|
|
|
|
when(update.getMessage()).thenReturn(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Update mockBackupUpdate() {
|
|
|
|
Update update = mock(Update.class);
|
|
|
|
Message message = mock(Message.class);
|
|
|
|
Message botMessage = mock(Message.class);
|
|
|
|
Document document = mock(Document.class);
|
|
|
|
|
|
|
|
when(update.getMessage()).thenReturn(message);
|
|
|
|
when(message.getDocument()).thenReturn(document);
|
|
|
|
when(botMessage.getText()).thenReturn(RECOVERY_MESSAGE);
|
|
|
|
when(message.isReply()).thenReturn(true);
|
|
|
|
when(message.hasDocument()).thenReturn(true);
|
|
|
|
when(message.getReplyToMessage()).thenReturn(botMessage);
|
|
|
|
when(message.getChatId()).thenReturn(GROUP_ID);
|
|
|
|
return update;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Object getDbBackup() {
|
|
|
|
db.getSet(TEST).add(TEST);
|
|
|
|
Object backup = db.backup();
|
|
|
|
db.clear();
|
|
|
|
return backup;
|
|
|
|
}
|
|
|
|
|
|
|
|
private java.io.File createBackupFile(Object backup) throws IOException {
|
|
|
|
java.io.File backupFile = new java.io.File(TEST);
|
|
|
|
BufferedWriter writer = Files.newWriter(backupFile, Charset.defaultCharset());
|
|
|
|
writer.write(backup.toString());
|
|
|
|
writer.flush();
|
|
|
|
writer.close();
|
|
|
|
return backupFile;
|
|
|
|
}
|
|
|
|
}
|