Merge pull request #640 from rubenlagus/dev

Dev
This commit is contained in:
Ruben Bermudez 2019-07-30 02:14:10 +01:00 committed by GitHub
commit f85409f852
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 2870 additions and 2423 deletions

View File

@ -1,11 +1,18 @@
language: java
jdk:
- oraclejdk8
install: mvn install -Dgpg.skip
script: mvn clean compile test
- oraclejdk11
- oraclejdk-ea
- openjdk11
- openjdk-ea
install: mvn -q install -Dgpg.skip
script: mvn -q clean compile test
after_success:
- bash <(curl -s https://codecov.io/bash)
notifications:
webhooks:
secure: "jC7dK/x67ONWQoeLZg4HfW0mHhcjDerJjsLLkrbcpltiqAbw2p7XfY8Pk4zHoD72a+5o6WKu5WvYvZ4OdldnjP8Y6ZUbliQ5RG3olg3gFDoe0+sc3geeb4HRYVcdI20O0z4Bup/qO0ZihxPBc0D5IpHmFxlaqlZG0WeST4CicU8PNnBh6aX9/VMrwXhkMb2vfzmjmIhMbx/uK5+93bnk/vR5Uwu00/Yd2cTAAWMaqK1MRdtR0WLbxlUNsprEfCjYiH3n9XZnlKXs6cLC8EOU436Wx7aepiAszW0wWFMe/7nVqOqztrQiKNvL0qXYwlQf0BLechJdt458EopL9QCu687TNDFYvg1yERAmCRiaayYZcX3PbUSMr6H5Q+Odntjs3XKyzfgSqqlkgf/SAND5jny1/1uteVoplZmFXuZFIiK4H8Rl2ezy1/8pnbp+JD3YEfiA2NuRjlou1BZXyMhiqqVXbrJqk/tXF6yZSkDlYJfNsWzRCGfra4B6JjEvUP927chIFm1ii3dgNstXDo1evV46+OQQO4HKvMPdtU2FPvWpPlkTxnmpZRZjB+bjmybluJdWT3E+e1C3wm7YbRe3vporhpfNPlnod6M0G10y9CKzl9Fbcku6X1FtM+IoPO/aqZ8S4/CBZoYEuR/Nk6bcvsYouxtyIl6PSuF9E8YjpJE="
email: false
matrix:
allow_failures:
- jdk: openjdk-ea
- jdk: oraclejdk-ea

803
Bots.ipr

File diff suppressed because it is too large Load Diff

View File

@ -27,16 +27,16 @@ Just import add the library to your project with one of these options:
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>4.3.1</version>
<version>4.4.0</version>
</dependency>
```
```gradle
compile "org.telegram:telegrambots:4.3.1"
compile "org.telegram:telegrambots:4.4.0"
```
2. Using Jitpack from [here](https://jitpack.io/#rubenlagus/TelegramBots/4.3.1)
3. Download the jar(including all dependencies) from [here](https://mvnrepository.com/artifact/org.telegram/telegrambots/4.3.1)
2. Using Jitpack from [here](https://jitpack.io/#rubenlagus/TelegramBots/4.4.0)
3. Download the jar(including all dependencies) from [here](https://mvnrepository.com/artifact/org.telegram/telegrambots/4.4.0)
In order to use Long Polling mode, just create your own bot extending `org.telegram.telegrambots.bots.TelegramLongPollingBot`.

View File

@ -1,3 +1,11 @@
### <a id="4.4.0"></a>4.4.0 ###
1. Update Api version [4.4](https://core.telegram.org/bots/api-changelog#july-29-2019)
2. Removed BotLogger, replaced with [log4j2](https://logging.apache.org/log4j/2.x/)
3. Library is now built using [Java11](https://www.oracle.com/technetwork/java/javase/overview/index.html)
4. Updated dependencies to use last versions
5. Files can be downloaded into a stream. Allowing it to be processed immediately.
6. A java.io.File can be passed into the methods. The downloaded file is copied into that file instead of a temp file then (does not work with the async methods)
### <a id="4.3.1"></a>4.3.1 ###
1. Fix bug #625
2. Moved ApiResponse to different package, deprecated old one (will be removed in next mayor version)

View File

@ -11,13 +11,13 @@ First you need ot get the library and add it to your project. There are few poss
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>4.3.1</version>
<version>4.4.0</version>
</dependency>
```
* With **Gradle**:
```groovy
compile group: 'org.telegram', name: 'telegrambots', version: '4.3.1'
compile group: 'org.telegram', name: 'telegrambots', version: '4.4.0'
```
2. Don't like **Maven Central Repository**? It can also be taken from [Jitpack](https://jitpack.io/#rubenlagus/TelegramBots).

View File

@ -9,12 +9,12 @@ As with any Java project, you will need to set your dependencies.
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots-abilities</artifactId>
<version>4.3.1</version>
<version>4.4.0</version>
</dependency>
```
* **Gradle**
```groovy
compile group: 'org.telegram', name: 'telegrambots-abilities', version: '4.3.1'
compile group: 'org.telegram', name: 'telegrambots-abilities', version: 'permissions'
```
* [JitPack](https://jitpack.io/#rubenlagus/TelegramBots)

86
pom.xml
View File

@ -7,7 +7,7 @@
<groupId>org.telegram</groupId>
<artifactId>Bots</artifactId>
<packaging>pom</packaging>
<version>4.3.1</version>
<version>4.4.0</version>
<modules>
<module>telegrambots</module>
@ -27,6 +27,90 @@
</licenses>
<properties>
<java.version>11</java.version>
<maven.compiler.release>8</maven.compiler.release>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.deploy.skip>true</maven.deploy.skip>
<junit.version>5.5.1</junit.version>
<mockito.version>3.0.0</mockito.version>
<mockitojupiter.version>3.0.0</mockitojupiter.version>
<jacksonbase.version>2.9.9</jacksonbase.version>
<jackson.version>2.9.9.1</jackson.version>
<log4j.version>2.12.0</log4j.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jacksonbase.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>${jacksonbase.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockitojupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -18,19 +18,19 @@ Usage
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots-abilities</artifactId>
<version>4.3.1</version>
<version>4.4.0</version>
</dependency>
```
**Gradle**
```gradle
compile "org.telegram:telegrambots-abilities:4.3.1"
compile "org.telegram:telegrambots-abilities:4.4.0"
```
**JitPack** - [JitPack](https://jitpack.io/#rubenlagus/TelegramBots/v4.3.1)
**JitPack** - [JitPack](https://jitpack.io/#rubenlagus/TelegramBots/v4.4.0)
**Plain imports** - [Here](https://github.com/rubenlagus/TelegramBots/releases/tag/v4.3.1)
**Plain imports** - [Here](https://github.com/rubenlagus/TelegramBots/releases/tag/v4.4.0)
Motivation
----------

View File

@ -3,9 +3,14 @@
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.telegram</groupId>
<parent>
<groupId>org.telegram</groupId>
<artifactId>Bots</artifactId>
<version>4.4.0</version>
</parent>
<artifactId>telegrambots-abilities</artifactId>
<version>4.3.1</version>
<packaging>jar</packaging>
<name>Telegram Ability Bot</name>
@ -63,17 +68,23 @@
</distributionManagement>
<properties>
<java.version>11</java.version>
<maven.compiler.release>8</maven.compiler.release>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<commonslang.version>3.5</commonslang.version>
<mapdb.version>3.0.4</mapdb.version>
<commonslang.version>3.9</commonslang.version>
<mapdb.version>3.0.7</mapdb.version>
</properties>
<dependencies>
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>4.3.1</version>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
@ -91,18 +102,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -112,10 +111,15 @@
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
@ -129,7 +133,7 @@
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
@ -139,7 +143,7 @@
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<id>clean-project</id>
@ -152,7 +156,7 @@
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<version>3.1.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
@ -171,7 +175,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
@ -183,14 +187,14 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
<doclint>none</doclint>
</configuration>
</execution>
</executions>
@ -198,7 +202,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<version>0.8.4</version>
<executions>
<execution>
<goals>
@ -217,7 +221,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<version>3.0.0-M2</version>
<executions>
<execution>
<id>enforce-versions</id>
@ -235,7 +239,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<version>3.1.1</version>
<executions>
<execution>
<id>copy</id>
@ -249,9 +253,10 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>

View File

@ -11,7 +11,7 @@ import java.util.Set;
/**
* This interface represents the high-level methods exposed to the user when handling an {@link Update}.
* Example usage:
* <p><code>Ability.builder().action(ctx -> {db.getSet(USERS); doSomething();})* </code></p>
* <p><code>Ability.builder().action(ctx -> {db.getSet(USERS); doSomething();})</code></p>
* {@link BaseAbilityBot} contains a handle on the <code>db</code> that the user can use inside his declared abilities.
*
* @author Abbas Abou Daya

View File

@ -3,25 +3,29 @@ package org.telegram.abilitybots.api.db;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.mapdb.Atomic;
import org.mapdb.DB;
import org.mapdb.DBMaker;
import org.mapdb.Serializer;
import org.telegram.abilitybots.api.util.Pair;
import org.telegram.telegrambots.meta.logging.BotLogger;
import java.io.IOException;
import java.util.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.newHashSet;
import static java.lang.String.format;
import static java.util.Objects.isNull;
import static java.util.stream.Collectors.toMap;
import static java.util.stream.StreamSupport.stream;
import static org.mapdb.Serializer.JAVA;
import static org.telegram.abilitybots.api.bot.BaseAbilityBot.USERS;
/**
* An implementation of {@link DBContext} that relies on a {@link DB}.
@ -31,7 +35,7 @@ import static org.telegram.abilitybots.api.bot.BaseAbilityBot.USERS;
*/
@SuppressWarnings({"unchecked", "WeakerAccess"})
public class MapDBContext implements DBContext {
private static final String TAG = DBContext.class.getSimpleName();
private static final Logger log = LogManager.getLogger(MapDBContext.class);
private final DB db;
private final ObjectMapper objectMapper;
@ -71,7 +75,6 @@ public class MapDBContext implements DBContext {
.fileDB(name)
.fileMmapEnableIfSupported()
.closeOnJvmShutdown()
.cleanerHackEnable()
.transactionEnable()
.fileDeleteAfterClose()
.make();
@ -123,7 +126,7 @@ public class MapDBContext implements DBContext {
doRecover(backupData);
return true;
} catch (IOException e) {
BotLogger.error(format("Could not recover DB data from file with String representation %s", backup), TAG, e);
log.error(format("Could not recover DB data from file with String representation %s", backup), e);
// Attempt to fallback to data snapshot before recovery
doRecover(snapshot);
return false;
@ -204,7 +207,7 @@ public class MapDBContext implements DBContext {
List entryList = (List) value;
getList(name).addAll(entryList);
} else {
BotLogger.error(TAG, format("Unable to identify object type during DB recovery, entry name: %s", name));
log.error(format("Unable to identify object type during DB recovery, entry name: %s", name));
}
});
commit();
@ -214,7 +217,7 @@ public class MapDBContext implements DBContext {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
BotLogger.info(format("Failed to read the JSON representation of object: %s", obj), TAG, e);
log.info(format("Failed to read the JSON representation of object: %s", obj), e);
return "Error reading required data...";
}
}

View File

@ -2,8 +2,9 @@ package org.telegram.abilitybots.api.objects;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.logging.BotLogger;
import java.util.Arrays;
import java.util.List;
@ -34,7 +35,7 @@ import static org.apache.commons.lang3.StringUtils.*;
* @author Abbas Abou Daya
*/
public final class Ability {
private static final String TAG = Ability.class.getSimpleName();
private static final Logger log = LogManager.getLogger(Ability.class);
private final String name;
private final String info;
@ -63,7 +64,7 @@ public final class Ability {
this.action = checkNotNull(action, "Method action can't be empty. Please assign a function by using .action() method");
if (postAction == null)
BotLogger.info(TAG, format("No post action was detected for method with name [%s]", name));
log.info(format("No post action was detected for method with name [%s]", name));
this.flags = ofNullable(flags).map(Arrays::asList).orElse(newArrayList());

View File

@ -1,11 +1,12 @@
package org.telegram.abilitybots.api.sender;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.telegram.telegrambots.meta.api.methods.BotApiMethod;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.ForceReplyKeyboard;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.logging.BotLogger;
import java.io.Serializable;
import java.util.Optional;
@ -17,7 +18,7 @@ import java.util.Optional;
* @author Abbas Abou Daya
*/
public class SilentSender {
private static final String TAG = SilentSender.class.getSimpleName();
private static final Logger log = LogManager.getLogger(SilentSender.class);
private final MessageSender sender;
@ -46,7 +47,7 @@ public class SilentSender {
try {
return Optional.ofNullable(sender.execute(method));
} catch (TelegramApiException e) {
BotLogger.error("Could not execute bot API method", TAG, e);
log.error("Could not execute bot API method", e);
return Optional.empty();
}
}
@ -55,7 +56,7 @@ public class SilentSender {
try {
return Optional.ofNullable(sender.execute(method));
} catch (TelegramApiException e) {
BotLogger.error("Could not execute bot API method", TAG, e);
log.error("Could not execute bot API method", e);
return Optional.empty();
}
}

View File

@ -1,8 +1,8 @@
package org.telegram.abilitybots.api.bot;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.telegram.abilitybots.api.db.DBContext;
import org.telegram.abilitybots.api.objects.MessageContext;
import org.telegram.abilitybots.api.sender.MessageSender;
@ -18,7 +18,7 @@ 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 {
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");
@ -28,8 +28,8 @@ public class AbilityBotI18nTest {
private MessageSender sender;
private SilentSender silent;
@Before
public void setUp() {
@BeforeEach
void setUp() {
db = offlineInstance("db");
bot = new NoPublicCommandsBot(EMPTY, EMPTY, db);
@ -38,11 +38,16 @@ public class AbilityBotI18nTest {
bot.sender = sender;
bot.silent = silent;
}
@AfterEach
void tearDown() throws IOException {
db.clear();
db.close();
}
@Test
public void missingPublicCommandsLocalizedInEnglishByDefault() {
void missingPublicCommandsLocalizedInEnglishByDefault() {
MessageContext context = mockContext(NO_LANGUAGE_USER);
bot.reportCommands().action().accept(context);
@ -52,7 +57,7 @@ public class AbilityBotI18nTest {
}
@Test
public void missingPublicCommandsLocalizedInItalian() {
void missingPublicCommandsLocalizedInItalian() {
MessageContext context = mockContext(ITALIAN_USER);
bot.reportCommands().action().accept(context);
@ -61,15 +66,9 @@ public class AbilityBotI18nTest {
.send("Non sono presenti comandi disponibile.", 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) {
NoPublicCommandsBot(String botToken, String botUsername, DBContext db) {
super(botToken, botUsername, db);
}

View File

@ -3,9 +3,11 @@ 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.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatchers;
import org.telegram.abilitybots.api.db.DBContext;
import org.telegram.abilitybots.api.objects.*;
import org.telegram.abilitybots.api.sender.MessageSender;
@ -13,7 +15,12 @@ import org.telegram.abilitybots.api.sender.SilentSender;
import org.telegram.abilitybots.api.util.Pair;
import org.telegram.abilitybots.api.util.Trio;
import org.telegram.telegrambots.meta.api.methods.groupadministration.GetChatAdministrators;
import org.telegram.telegrambots.meta.api.objects.*;
import org.telegram.telegrambots.meta.api.objects.ChatMember;
import org.telegram.telegrambots.meta.api.objects.Document;
import org.telegram.telegrambots.meta.api.objects.File;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.api.objects.User;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import java.io.BufferedWriter;
@ -32,9 +39,13 @@ import static java.util.Optional.empty;
import static org.apache.commons.io.FileUtils.deleteQuietly;
import static org.apache.commons.lang3.ArrayUtils.addAll;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import static org.telegram.abilitybots.api.bot.DefaultBot.getDefaultBuilder;
import static org.telegram.abilitybots.api.db.MapDBContext.offlineInstance;
@ -62,8 +73,8 @@ public class AbilityBotTest {
private MessageSender sender;
private SilentSender silent;
@Before
public void setUp() {
@BeforeEach
void setUp() {
db = offlineInstance("db");
bot = new DefaultBot(EMPTY, EMPTY, db);
@ -74,8 +85,14 @@ public class AbilityBotTest {
bot.silent = silent;
}
@AfterEach
void tearDown() throws IOException {
db.clear();
db.close();
}
@Test
public void sendsPrivacyViolation() {
void sendsPrivacyViolation() {
Update update = mockFullUpdate(USER, "/admin");
bot.onUpdateReceived(update);
@ -84,7 +101,7 @@ public class AbilityBotTest {
}
@Test
public void sendsLocalityViolation() {
void sendsLocalityViolation() {
Update update = mockFullUpdate(USER, "/group");
bot.onUpdateReceived(update);
@ -94,7 +111,7 @@ public class AbilityBotTest {
}
@Test
public void sendsInputArgsViolation() {
void sendsInputArgsViolation() {
Update update = mockFullUpdate(USER, "/count 1 2 3");
bot.onUpdateReceived(update);
@ -103,7 +120,7 @@ public class AbilityBotTest {
}
@Test
public void canProcessRepliesIfSatisfyRequirements() {
void canProcessRepliesIfSatisfyRequirements() {
Update update = mockFullUpdate(USER, "must reply");
// False means the update was not pushed down the stream since it has been consumed by the reply
@ -112,7 +129,7 @@ public class AbilityBotTest {
}
@Test
public void canBackupDB() throws TelegramApiException {
void canBackupDB() throws TelegramApiException {
MessageContext context = defaultContext();
bot.backupDB().action().accept(context);
@ -122,21 +139,23 @@ public class AbilityBotTest {
}
@Test
public void canRecoverDB() throws TelegramApiException, IOException {
void canRecoverDB() throws TelegramApiException, IOException {
Update update = mockBackupUpdate();
Object backup = getDbBackup();
java.io.File backupFile = createBackupFile(backup);
when(sender.downloadFile(any(File.class))).thenReturn(backupFile);
// Support for null parameter matching since due to mocking API changes
when(sender.downloadFile(ArgumentMatchers.<File>isNull())).thenReturn(backupFile);
bot.recoverDB().replies().get(0).actOn(update);
verify(silent, times(1)).send(RECOVER_SUCCESS, GROUP_ID);
assertEquals("Bot recovered but the DB is still not in sync", db.getSet(TEST), newHashSet(TEST));
assertTrue("Could not delete backup file", backupFile.delete());
assertEquals(db.getSet(TEST), newHashSet(TEST), "Bot recovered but the DB is still not in sync");
assertTrue(backupFile.delete(), "Could not delete backup file");
}
@Test
public void canFilterOutReplies() {
void canFilterOutReplies() {
Update update = mock(Update.class);
when(update.hasMessage()).thenReturn(false);
@ -144,7 +163,7 @@ public class AbilityBotTest {
}
@Test
public void canDemote() {
void canDemote() {
addUsers(USER);
bot.admins().add(USER.getId());
@ -154,11 +173,11 @@ public class AbilityBotTest {
Set<Integer> actual = bot.admins();
Set<Integer> expected = emptySet();
assertEquals("Could not sudont super-admin", expected, actual);
assertEquals(expected, actual, "Could not sudont super-admin");
}
@Test
public void canPromote() {
void canPromote() {
addUsers(USER);
MessageContext context = defaultContext();
@ -167,11 +186,11 @@ public class AbilityBotTest {
Set<Integer> actual = bot.admins();
Set<Integer> expected = newHashSet(USER.getId());
assertEquals("Could not sudo user", expected, actual);
assertEquals(expected, actual, "Could not sudo user");
}
@Test
public void canBanUser() {
void canBanUser() {
addUsers(USER);
MessageContext context = defaultContext();
@ -179,11 +198,11 @@ public class AbilityBotTest {
Set<Integer> actual = bot.blacklist();
Set<Integer> expected = newHashSet(USER.getId());
assertEquals("The ban was not emplaced", expected, actual);
assertEquals(expected, actual, "The ban was not emplaced");
}
@Test
public void canUnbanUser() {
void canUnbanUser() {
addUsers(USER);
bot.blacklist().add(USER.getId());
@ -193,7 +212,7 @@ public class AbilityBotTest {
Set<Integer> actual = bot.blacklist();
Set<Integer> expected = newHashSet();
assertEquals("The ban was not lifted", expected, actual);
assertEquals(expected, actual, "The ban was not lifted");
}
@NotNull
@ -202,7 +221,7 @@ public class AbilityBotTest {
}
@Test
public void cannotBanCreator() {
void cannotBanCreator() {
addUsers(USER, CREATOR);
MessageContext context = mockContext(USER, GROUP_ID, CREATOR.getUserName());
@ -210,7 +229,7 @@ public class AbilityBotTest {
Set<Integer> actual = bot.blacklist();
Set<Integer> expected = newHashSet(USER.getId());
assertEquals("Impostor was not added to the blacklist", expected, actual);
assertEquals(expected, actual, "Impostor was not added to the blacklist");
}
private void addUsers(User... users) {
@ -221,18 +240,18 @@ public class AbilityBotTest {
}
@Test
public void creatorCanClaimBot() {
void creatorCanClaimBot() {
MessageContext context = mockContext(CREATOR, GROUP_ID);
bot.claimCreator().action().accept(context);
Set<Integer> actual = bot.admins();
Set<Integer> expected = newHashSet(CREATOR.getId());
assertEquals("Creator was not properly added to the super admins set", expected, actual);
assertEquals(expected, actual, "Creator was not properly added to the super admins set");
}
@Test
public void bannedCreatorPassesBlacklistCheck() {
void bannedCreatorPassesBlacklistCheck() {
bot.blacklist().add(CREATOR.getId());
Update update = mock(Update.class);
Message message = mock(Message.class);
@ -241,11 +260,11 @@ public class AbilityBotTest {
mockUser(update, message, user);
boolean notBanned = bot.checkBlacklist(update);
assertTrue("Creator is banned", notBanned);
assertTrue(notBanned, "Creator is banned");
}
@Test
public void canAddUser() {
void canAddUser() {
Update update = mock(Update.class);
Message message = mock(Message.class);
@ -255,12 +274,12 @@ public class AbilityBotTest {
Map<String, Integer> expectedUserIds = ImmutableMap.of(USER.getUserName(), USER.getId());
Map<Integer, User> expectedUsers = ImmutableMap.of(USER.getId(), USER);
assertEquals("User was not added", expectedUserIds, bot.userIds());
assertEquals("User was not added", expectedUsers, bot.users());
assertEquals(expectedUserIds, bot.userIds(), "User was not added");
assertEquals(expectedUsers, bot.users(), "User was not added");
}
@Test
public void canEditUser() {
void canEditUser() {
addUsers(USER);
Update update = mock(Update.class);
Message message = mock(Message.class);
@ -277,22 +296,22 @@ public class AbilityBotTest {
Map<String, Integer> expectedUserIds = ImmutableMap.of(changedUser.getUserName(), changedUser.getId());
Map<Integer, User> expectedUsers = ImmutableMap.of(changedUser.getId(), changedUser);
assertEquals("User was not properly edited", bot.userIds(), expectedUserIds);
assertEquals("User was not properly edited", expectedUsers, expectedUsers);
assertEquals(bot.userIds(), expectedUserIds, "User was not properly edited");
assertEquals(expectedUsers, expectedUsers, "User was not properly edited");
}
@Test
public void canValidateAbility() {
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);
assertFalse("Bot can't validate ability properly", bot.validateAbility(invalidPair));
assertTrue("Bot can't validate ability properly", bot.validateAbility(validPair));
assertFalse(bot.validateAbility(invalidPair), "Bot can't validate ability properly");
assertTrue(bot.validateAbility(validPair), "Bot can't validate ability properly");
}
@Test
public void canCheckInput() {
void canCheckInput() {
Update update = mockFullUpdate(USER, "/something");
Ability abilityWithOneInput = getDefaultBuilder()
.build();
@ -303,19 +322,19 @@ public class AbilityBotTest {
Trio<Update, Ability, String[]> trioOneArg = Trio.of(update, abilityWithOneInput, TEXT);
Trio<Update, Ability, String[]> trioZeroArg = Trio.of(update, abilityWithZeroInput, TEXT);
assertTrue("Unexpected result when applying token filter", bot.checkInput(trioOneArg));
assertTrue(bot.checkInput(trioOneArg), "Unexpected result when applying token filter");
trioOneArg = Trio.of(update, abilityWithOneInput, addAll(TEXT, TEXT));
assertFalse("Unexpected result when applying token filter", bot.checkInput(trioOneArg));
assertFalse(bot.checkInput(trioOneArg), "Unexpected result when applying token filter");
assertTrue("Unexpected result when applying token filter", bot.checkInput(trioZeroArg));
assertTrue(bot.checkInput(trioZeroArg), "Unexpected result when applying token filter");
trioZeroArg = Trio.of(update, abilityWithZeroInput, EMPTY_ARRAY);
assertTrue("Unexpected result when applying token filter", bot.checkInput(trioZeroArg));
assertTrue(bot.checkInput(trioZeroArg), "Unexpected result when applying token filter");
}
@Test
public void canCheckPrivacy() {
void canCheckPrivacy() {
Update update = mock(Update.class);
Message message = mock(Message.class);
User user = mock(User.class);
@ -331,14 +350,14 @@ public class AbilityBotTest {
mockUser(update, message, user);
assertTrue("Unexpected result when checking for privacy", bot.checkPrivacy(publicTrio));
assertFalse("Unexpected result when checking for privacy", bot.checkPrivacy(groupAdminTrio));
assertFalse("Unexpected result when checking for privacy", bot.checkPrivacy(adminTrio));
assertFalse("Unexpected result when checking for privacy", bot.checkPrivacy(creatorTrio));
assertTrue(bot.checkPrivacy(publicTrio), "Unexpected result when checking for privacy");
assertFalse(bot.checkPrivacy(groupAdminTrio), "Unexpected result when checking for privacy");
assertFalse(bot.checkPrivacy(adminTrio), "Unexpected result when checking for privacy");
assertFalse(bot.checkPrivacy(creatorTrio), "Unexpected result when checking for privacy");
}
@Test
public void canValidateGroupAdminPrivacy() {
void canValidateGroupAdminPrivacy() {
Update update = mock(Update.class);
Message message = mock(Message.class);
User user = mock(User.class);
@ -355,11 +374,11 @@ public class AbilityBotTest {
when(silent.execute(any(GetChatAdministrators.class))).thenReturn(Optional.of(newArrayList(member)));
assertTrue("Unexpected result when checking for privacy", bot.checkPrivacy(groupAdminTrio));
assertTrue(bot.checkPrivacy(groupAdminTrio), "Unexpected result when checking for privacy");
}
@Test
public void canRestrictNormalUsersFromGroupAdminAbilities() {
void canRestrictNormalUsersFromGroupAdminAbilities() {
Update update = mock(Update.class);
Message message = mock(Message.class);
User user = mock(User.class);
@ -372,11 +391,11 @@ public class AbilityBotTest {
when(silent.execute(any(GetChatAdministrators.class))).thenReturn(empty());
assertFalse("Unexpected result when checking for privacy", bot.checkPrivacy(groupAdminTrio));
assertFalse(bot.checkPrivacy(groupAdminTrio), "Unexpected result when checking for privacy");
}
@Test
public void canBlockAdminsFromCreatorAbilities() {
void canBlockAdminsFromCreatorAbilities() {
Update update = mock(Update.class);
Message message = mock(Message.class);
User user = mock(User.class);
@ -387,11 +406,11 @@ public class AbilityBotTest {
bot.admins().add(USER.getId());
mockUser(update, message, user);
assertFalse("Unexpected result when checking for privacy", bot.checkPrivacy(creatorTrio));
assertFalse(bot.checkPrivacy(creatorTrio), "Unexpected result when checking for privacy");
}
@Test
public void canCheckLocality() {
void canCheckLocality() {
Update update = mock(Update.class);
Message message = mock(Message.class);
User user = mock(User.class);
@ -406,13 +425,13 @@ public class AbilityBotTest {
mockUser(update, message, user);
when(message.isUserMessage()).thenReturn(true);
assertTrue("Unexpected result when checking for locality", bot.checkLocality(publicTrio));
assertTrue("Unexpected result when checking for locality", bot.checkLocality(userTrio));
assertFalse("Unexpected result when checking for locality", bot.checkLocality(groupTrio));
assertTrue(bot.checkLocality(publicTrio), "Unexpected result when checking for locality");
assertTrue(bot.checkLocality(userTrio), "Unexpected result when checking for locality");
assertFalse(bot.checkLocality(groupTrio), "Unexpected result when checking for locality");
}
@Test
public void canRetrieveContext() {
void canRetrieveContext() {
Update update = mock(Update.class);
Message message = mock(Message.class);
Ability ability = getDefaultBuilder().build();
@ -424,17 +443,17 @@ public class AbilityBotTest {
Pair<MessageContext, Ability> actualPair = bot.getContext(trio);
Pair<MessageContext, Ability> expectedPair = Pair.of(newContext(update, USER, GROUP_ID, TEXT), ability);
assertEquals("Unexpected result when fetching for context", expectedPair, actualPair);
assertEquals(expectedPair, actualPair, "Unexpected result when fetching for context");
}
@Test
public void defaultGlobalFlagIsTrue() {
void defaultGlobalFlagIsTrue() {
Update update = mock(Update.class);
assertTrue("Unexpected result when checking for the default global flags", bot.checkGlobalFlags(update));
assertTrue(bot.checkGlobalFlags(update), "Unexpected result when checking for the default global flags");
}
@Test(expected = ArithmeticException.class)
public void canConsumeUpdate() {
@Test
void canConsumeUpdate() {
Ability ability = getDefaultBuilder()
.action((context) -> {
int x = 1 / 0;
@ -443,11 +462,11 @@ public class AbilityBotTest {
Pair<MessageContext, Ability> pair = Pair.of(context, ability);
bot.consumeUpdate(pair);
Assertions.assertThrows(ArithmeticException.class, () -> bot.consumeUpdate(pair));
}
@Test
public void canFetchAbility() {
void canFetchAbility() {
Update update = mock(Update.class);
Message message = mock(Message.class);
@ -462,11 +481,11 @@ public class AbilityBotTest {
Ability expected = bot.testAbility();
Ability actual = trio.b();
assertEquals("Wrong ability was fetched", expected, actual);
assertEquals(expected, actual, "Wrong ability was fetched");
}
@Test
public void canFetchAbilityCaseInsensitive() {
void canFetchAbilityCaseInsensitive() {
Update update = mock(Update.class);
Message message = mock(Message.class);
@ -481,11 +500,11 @@ public class AbilityBotTest {
Ability expected = bot.testAbility();
Ability actual = trio.b();
assertEquals("Wrong ability was fetched", expected, actual);
assertEquals(expected, actual, "Wrong ability was fetched");
}
@Test
public void canFetchDefaultAbility() {
void canFetchDefaultAbility() {
Update update = mock(Update.class);
Message message = mock(Message.class);
@ -498,11 +517,11 @@ public class AbilityBotTest {
Ability expected = bot.defaultAbility();
Ability actual = trio.b();
assertEquals("Wrong ability was fetched", expected, actual);
assertEquals(expected, actual, "Wrong ability was fetched");
}
@Test
public void canCheckAbilityFlags() {
void canCheckAbilityFlags() {
Update update = mock(Update.class);
Message message = mock(Message.class);
@ -517,12 +536,12 @@ public class AbilityBotTest {
Trio<Update, Ability, String[]> docTrio = Trio.of(update, documentAbility, TEXT);
Trio<Update, Ability, String[]> textTrio = Trio.of(update, textAbility, TEXT);
assertFalse("Unexpected result when checking for message flags", bot.checkMessageFlags(docTrio));
assertTrue("Unexpected result when checking for message flags", bot.checkMessageFlags(textTrio));
assertFalse(bot.checkMessageFlags(docTrio), "Unexpected result when checking for message flags");
assertTrue(bot.checkMessageFlags(textTrio), "Unexpected result when checking for message flags");
}
@Test
public void canReportCommands() {
void canReportCommands() {
MessageContext context = mockContext(USER, GROUP_ID);
bot.reportCommands().action().accept(context);
@ -531,12 +550,12 @@ public class AbilityBotTest {
}
@NotNull
public static MessageContext mockContext(User user) {
static MessageContext mockContext(User user) {
return mockContext(user, user.getId());
}
@NotNull
public static MessageContext mockContext(User user, long groupId, String... args) {
static MessageContext mockContext(User user, long groupId, String... args) {
Update update = mock(Update.class);
Message message = mock(Message.class);
@ -550,7 +569,7 @@ public class AbilityBotTest {
}
@Test
public void canPrintCommandsBasedOnPrivacy() {
void canPrintCommandsBasedOnPrivacy() {
Update update = mock(Update.class);
Message message = mock(Message.class);
@ -566,7 +585,7 @@ public class AbilityBotTest {
}
@Test
public void printsOnlyPublicCommandsForNormalUser() {
void printsOnlyPublicCommandsForNormalUser() {
Update update = mock(Update.class);
Message message = mock(Message.class);
@ -582,12 +601,6 @@ public class AbilityBotTest {
verify(silent, times(1)).send(expected, GROUP_ID);
}
@After
public void tearDown() throws IOException {
db.clear();
db.close();
}
@NotNull
private Update mockFullUpdate(User user, String args) {
bot.users().put(USER.getId(), USER);

View File

@ -1,45 +1,45 @@
package org.telegram.abilitybots.api.bot;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.telegram.abilitybots.api.objects.Ability;
import org.telegram.abilitybots.api.util.AbilityExtension;
import java.io.IOException;
import static junit.framework.TestCase.assertTrue;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.telegram.abilitybots.api.db.MapDBContext.offlineInstance;
import static org.telegram.abilitybots.api.objects.Locality.ALL;
import static org.telegram.abilitybots.api.objects.Privacy.PUBLIC;
public class ExtensionTest {
class ExtensionTest {
private ExtensionUsingBot bot;
@Before
public void setUp() {
@BeforeEach
void setUp() {
bot = new ExtensionUsingBot();
}
@Test
public void methodReturningAbilities() {
assertTrue("Failed to find Ability in directly declared in root extension/bot", hasAbilityNamed("direct"));
assertTrue("Failed to find Ability in directly declared in extension returned by method returning the AbilityExtension class", hasAbilityNamed("returningSuperClass0abc"));
assertTrue("Failed to find Ability in directly declared in extension returned by method returning the AbilityExtension subclass", hasAbilityNamed("returningSubClass0abc"));
}
@After
public void tearDown() throws IOException {
@AfterEach
void tearDown() throws IOException {
bot.db.clear();
bot.db.close();
}
@Test
void methodReturningAbilities() {
assertTrue(hasAbilityNamed("direct"), "Failed to find Ability in directly declared in root extension/bot");
assertTrue(hasAbilityNamed("returningSuperClass0abc"), "Failed to find Ability in directly declared in extension returned by method returning the AbilityExtension class");
assertTrue(hasAbilityNamed("returningSubClass0abc"), "Failed to find Ability in directly declared in extension returned by method returning the AbilityExtension subclass");
}
private boolean hasAbilityNamed(String name) {
return bot.abilities().values().stream().map(Ability::name).anyMatch(name::equals);
}
public static class ExtensionUsingBot extends AbilityBot {
public ExtensionUsingBot() {
ExtensionUsingBot() {
super("", "", offlineInstance("testing"));
}
@ -71,7 +71,7 @@ public class ExtensionTest {
public static class AbilityBotExtension implements AbilityExtension {
private String name;
public AbilityBotExtension(String name) {
AbilityBotExtension(String name) {
this.name = name;
}

View File

@ -1,8 +1,9 @@
package org.telegram.abilitybots.api.db;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.telegram.telegrambots.meta.api.objects.User;
import java.io.IOException;
@ -12,25 +13,33 @@ 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.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.telegram.abilitybots.api.bot.AbilityBotTest.CREATOR;
import static org.telegram.abilitybots.api.bot.AbilityBotTest.USER;
import static org.telegram.abilitybots.api.db.MapDBContext.offlineInstance;
public class MapDBContextTest {
class MapDBContextTest {
private static final String USERS = "USERS";
private static final String USER_ID = "USER_ID";
private static final String TEST = "TEST";
private DBContext db;
@Before
public void setUp() {
@BeforeEach
void setUp() {
db = offlineInstance("db");
}
@AfterEach
void tearDown() throws IOException {
db.clear();
db.close();
}
@Test
public void canRecoverDB() {
void canRecoverDB() {
Map<Integer, User> users = db.getMap(USERS);
Map<String, Integer> userIds = db.getMap(USER_ID);
users.put(CREATOR.getId(), CREATOR);
@ -49,30 +58,30 @@ public class MapDBContextTest {
Map<Integer, User> recoveredUsers = db.getMap(USERS);
String afterRecoveryInfo = db.info(USERS);
assertTrue("Could not recover database successfully", recovered);
assertEquals("Map info before and after recovery is different", beforeBackupInfo, afterRecoveryInfo);
assertEquals("Map before and after recovery are not equal", originalUsers, recoveredUsers);
assertTrue(recovered, "Could not recover database successfully");
assertEquals(beforeBackupInfo, afterRecoveryInfo, "Map info before and after recovery is different");
assertEquals(originalUsers, recoveredUsers, "Map before and after recovery are not equal");
}
@Test
public void canFallbackDBIfRecoveryFails() {
void canFallbackDBIfRecoveryFails() {
Set<User> users = db.getSet(USERS);
users.add(CREATOR);
users.add(USER);
Set<User> originalSet = newHashSet(users);
Object jsonBackup = db.backup();
String corruptBackup = "!@#$" + String.valueOf(jsonBackup);
String corruptBackup = "!@#$" + jsonBackup;
boolean recovered = db.recover(corruptBackup);
Set<User> recoveredSet = db.getSet(USERS);
assertFalse("Recovery was successful from a CORRUPT backup", recovered);
assertEquals("Set before and after corrupt recovery are not equal", originalSet, recoveredSet);
assertFalse(recovered, "Recovery was successful from a CORRUPT backup");
assertEquals(originalSet, recoveredSet, "Set before and after corrupt recovery are not equal");
}
@Test
public void canGetSummary() {
void canGetSummary() {
String anotherTest = TEST + 1;
db.getSet(TEST).add(TEST);
db.getSet(anotherTest).add(anotherTest);
@ -81,27 +90,27 @@ public class MapDBContextTest {
// Name - Type - Number of "rows"
String expectedSummary = format("%s - Set - 1\n%s - Set - 1", TEST, anotherTest);
assertEquals("Actual DB summary does not match that of the expected", expectedSummary, actualSummary);
assertEquals(expectedSummary, actualSummary, "Actual DB summary does not match that of the expected");
}
@Test
public void canGetInfo() {
void canGetInfo() {
db.getSet(TEST).add(TEST);
String actualInfo = db.info(TEST);
// JSON
String expectedInfo = "TEST - Set - 1";
assertEquals("Actual DB structure info does not match that of the expected", expectedInfo, actualInfo);
}
@Test(expected = IllegalStateException.class)
public void cantGetInfoFromNonexistentDBStructureName() {
db.info(TEST);
assertEquals(expectedInfo, actualInfo, "Actual DB structure info does not match that of the expected");
}
@Test
public void canGetAndSetVariables() {
void cantGetInfoFromNonexistentDBStructureName() {
Assertions.assertThrows(IllegalStateException.class, () -> db.info(TEST));
}
@Test
void canGetAndSetVariables() {
String varName = "somevar";
Var<User> var = db.getVar(varName);
var.set(CREATOR);
@ -116,10 +125,4 @@ public class MapDBContextTest {
Var<User> changedVar = db.getVar(varName);
assertEquals(changedVar.get(), USER);
}
@After
public void tearDown() throws IOException {
db.clear();
db.close();
}
}

View File

@ -1,58 +1,59 @@
package org.telegram.abilitybots.api.objects;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.telegram.abilitybots.api.bot.DefaultBot.getDefaultBuilder;
public class AbilityTest {
@Test(expected = IllegalArgumentException.class)
public void argumentsCannotBeNegative() {
getDefaultBuilder().input(-4).build();
}
@Test(expected = IllegalArgumentException.class)
public void nameCannotBeEmpty() {
getDefaultBuilder().name("").build();
}
@Test(expected = IllegalArgumentException.class)
public void nameCannotBeNull() {
getDefaultBuilder().name(null).build();
}
@Test(expected = NullPointerException.class)
public void consumerCannotBeNull() {
getDefaultBuilder().action(null).build();
}
@Test(expected = NullPointerException.class)
public void localityCannotBeNull() {
getDefaultBuilder().locality(null).build();
}
@Test(expected = NullPointerException.class)
public void privacyCannotBeNull() {
getDefaultBuilder().privacy(null).build();
}
@Test(expected = IllegalArgumentException.class)
public void nameCannotContainSpaces() {
getDefaultBuilder().name("test test").build();
class AbilityTest {
@Test
void argumentsCannotBeNegative() {
Assertions.assertThrows(IllegalArgumentException.class, () -> getDefaultBuilder().input(-4).build());
}
@Test
public void abilityEqualsMethod() {
void nameCannotBeEmpty() {
Assertions.assertThrows(IllegalArgumentException.class, () -> getDefaultBuilder().name("").build());
}
@Test
void nameCannotBeNull() {
Assertions.assertThrows(IllegalArgumentException.class, () -> getDefaultBuilder().name(null).build());
}
@Test
void consumerCannotBeNull() {
Assertions.assertThrows(NullPointerException.class, () -> getDefaultBuilder().action(null).build());
}
@Test
void localityCannotBeNull() {
Assertions.assertThrows(NullPointerException.class, () -> getDefaultBuilder().locality(null).build());
}
@Test
void privacyCannotBeNull() {
Assertions.assertThrows(NullPointerException.class, () -> getDefaultBuilder().privacy(null).build());
}
@Test
void nameCannotContainSpaces() {
Assertions.assertThrows(IllegalArgumentException.class, () -> getDefaultBuilder().name("test test").build());
}
@Test
void abilityEqualsMethod() {
Ability ability1 = getDefaultBuilder().build();
Ability ability2 = getDefaultBuilder().build();
Ability ability3 = getDefaultBuilder().name("anotherconsumer").build();
Ability ability4 = getDefaultBuilder().action((context) -> {
}).build();
assertEquals("Abilities should not be equal", ability1, ability2);
assertEquals("Abilities should not be equal", ability1, ability4);
assertNotEquals("Abilities should be equal", ability1, ability3);
assertEquals(ability1, ability2, "Abilities should not be equal");
assertEquals(ability1, ability4, "Abilities should not be equal");
assertNotEquals(ability1, ability3, "Abilities should be equal");
}
}

View File

@ -1,43 +1,43 @@
package org.telegram.abilitybots.api.sender;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import java.util.Optional;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static org.mockito.Matchers.any;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class SilentSenderTest {
class SilentSenderTest {
private SilentSender silent;
private MessageSender sender;
@Before
public void setUp() {
@BeforeEach
void setUp() {
sender = mock(MessageSender.class);
silent = new SilentSender(sender);
}
@Test
public void returnsEmptyOnError() throws TelegramApiException {
void returnsEmptyOnError() throws TelegramApiException {
when(sender.execute(any())).thenThrow(TelegramApiException.class);
Optional execute = silent.execute(null);
assertFalse("Execution of a bot API method with execption results in a nonempty optional", execute.isPresent());
assertFalse(execute.isPresent(), "Execution of a bot API method with execption results in a nonempty optional");
}
@Test
public void returnOptionalOnSuccess() throws TelegramApiException {
void returnOptionalOnSuccess() throws TelegramApiException {
String data = "data";
when(sender.execute(any())).thenReturn(data);
Optional execute = silent.execute(null);
assertEquals("Silent execution resulted in a different object", data, execute.get());
assertEquals(data, execute.get(), "Silent execution resulted in a different object");
}
}

View File

@ -15,7 +15,7 @@ Usage
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots-chat-session-bot</artifactId>
<version>4.3.1</version>
<version>4.4.0</version>
</dependency>
```

View File

@ -3,9 +3,14 @@
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.telegram</groupId>
<parent>
<groupId>org.telegram</groupId>
<artifactId>Bots</artifactId>
<version>4.4.0</version>
</parent>
<artifactId>telegrambots-chat-session-bot</artifactId>
<version>4.3.1</version>
<packaging>jar</packaging>
<name>Telegram Bots Chat Session Bot</name>
@ -63,9 +68,15 @@
</distributionManagement>
<properties>
<java.version>11</java.version>
<maven.compiler.release>8</maven.compiler.release>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<shiro.version>1.4.0</shiro.version>
<shiro.version>1.4.1</shiro.version>
</properties>
<dependencies>
@ -73,7 +84,7 @@
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>4.3.1</version>
<version>4.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
@ -82,19 +93,6 @@
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -104,10 +102,15 @@
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
@ -121,7 +124,7 @@
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
@ -131,7 +134,7 @@
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<id>clean-project</id>
@ -144,7 +147,7 @@
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<version>3.1.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
@ -163,7 +166,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
@ -175,14 +178,14 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
<doclint>none</doclint>
</configuration>
</execution>
</executions>
@ -190,7 +193,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<version>0.8.4</version>
<executions>
<execution>
<goals>
@ -209,7 +212,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<version>3.0.0-M2</version>
<executions>
<execution>
<id>enforce-versions</id>
@ -227,7 +230,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<version>3.1.1</version>
<executions>
<execution>
<id>copy</id>
@ -241,9 +244,10 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>

View File

@ -16,12 +16,12 @@ Just import add the library to your project with one of these options:
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambotsextensions</artifactId>
<version>4.3.1</version>
<version>4.4.0</version>
</dependency>
```
2. Using Gradle:
```gradle
compile "org.telegram:telegrambotsextensions:4.3.1"
compile "org.telegram:telegrambotsextensions:4.4.0"
```

View File

@ -3,9 +3,14 @@
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.telegram</groupId>
<parent>
<groupId>org.telegram</groupId>
<artifactId>Bots</artifactId>
<version>4.4.0</version>
</parent>
<artifactId>telegrambotsextensions</artifactId>
<version>4.3.1</version>
<packaging>jar</packaging>
<name>Telegram Bots Extensions</name>
@ -57,6 +62,11 @@
</distributionManagement>
<properties>
<java.version>11</java.version>
<maven.compiler.release>8</maven.compiler.release>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
@ -65,7 +75,7 @@
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>4.3.1</version>
<version>4.4.0</version>
</dependency>
</dependencies>
@ -76,10 +86,15 @@
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
@ -93,7 +108,7 @@
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
@ -103,7 +118,7 @@
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<id>clean-project</id>
@ -116,7 +131,7 @@
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<version>3.1.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
@ -135,7 +150,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
@ -147,14 +162,14 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
<doclint>none</doclint>
</configuration>
</execution>
</executions>
@ -162,7 +177,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<version>0.8.4</version>
<executions>
<execution>
<goals>
@ -181,7 +196,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<version>3.0.0-M2</version>
<executions>
<execution>
<id>enforce-versions</id>
@ -199,7 +214,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<version>3.1.1</version>
<executions>
<execution>
<id>copy</id>
@ -213,9 +228,10 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>

View File

@ -11,9 +11,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
* Created by Daniil Nikanov aka JetCoder
*/
@SuppressWarnings("unused")
public abstract class TimedSendLongPollingBot extends TelegramLongPollingBot
{
private static final long MANY_CHATS_SEND_INTERVAL = 33;
private static final long ONE_CHAT_SEND_INTERVAL = 1000;
private static final long CHAT_INACTIVE_INTERVAL = 1000 * 60 * 10;
private final Timer mSendTimer = new Timer(true);
@ -21,88 +21,29 @@ public abstract class TimedSendLongPollingBot extends TelegramLongPollingBot
private final ArrayList<MessageQueue> mSendQueues = new ArrayList<>();
private final AtomicBoolean mSendRequested = new AtomicBoolean(false);
private final class MessageSenderTask extends TimerTask
{
@Override
public void run()
{
//mSendRequested used for optimisation to not traverse all mMessagesMap 30 times per second all the time
if (!mSendRequested.getAndSet(false))
return;
long currentTime = System.currentTimeMillis();
mSendQueues.clear();
boolean processNext = false;
//First step - find all chats in which already allowed to send message (passed more than 1000 ms from previuos send)
Iterator<Map.Entry<Long,MessageQueue>> it = mMessagesMap.entrySet().iterator();
while (it.hasNext())
{
MessageQueue queue = it.next().getValue();
int state = queue.getCurrentState(currentTime); //Actual check here
if (state == MessageQueue.GET_MESSAGE)
{
mSendQueues.add(queue);
processNext = true;
}
else if (state == MessageQueue.WAIT)
{
processNext = true;
}
else if (state == MessageQueue.DELETE)
{
it.remove();
}
}
//If any of chats are in state WAIT or GET_MESSAGE, request another iteration
if (processNext)
mSendRequested.set(true);
//Second step - find oldest waiting queue and peek it's message
MessageQueue sendQueue = null;
long oldestPutTime = Long.MAX_VALUE;
for (int i = 0; i < mSendQueues.size(); i++)
{
MessageQueue queue = mSendQueues.get(i);
long putTime = queue.getPutTime();
if (putTime < oldestPutTime)
{
oldestPutTime = putTime;
sendQueue = queue;
}
}
if (sendQueue == null) //Possible if on first step wasn't found any chats in state GET_MESSAGE
return;
//Invoke the send callback. ChatId is passed for possible additional processing
sendMessageCallback(sendQueue.getChatId(), sendQueue.getMessage(currentTime));
}
}
private static class MessageQueue
{
public static final int EMPTY = 0; //Queue is empty
public static final int WAIT = 1; //Queue has message(s) but not yet allowed to send
public static final int DELETE = 2; //No one message of given queue was sent longer than CHAT_INACTIVE_INTERVAL, delete for optimisation
public static final int GET_MESSAGE = 3; //Queue has message(s) and ready to send
static final int EMPTY = 0; //Queue is empty
static final int WAIT = 1; //Queue has message(s) but not yet allowed to send
static final int DELETE = 2; //No one message of given queue was sent longer than CHAT_INACTIVE_INTERVAL, delete for optimisation
static final int GET_MESSAGE = 3; //Queue has message(s) and ready to send
private final ConcurrentLinkedQueue<Object> mQueue = new ConcurrentLinkedQueue<>();
private final Long mChatId;
private long mLastSendTime; //Time of last peek from queue
private volatile long mLastPutTime; //Time of last put into queue
public MessageQueue(Long chatId)
MessageQueue(Long chatId)
{
mChatId = chatId;
}
public synchronized void putMessage(Object msg)
synchronized void putMessage(Object msg)
{
mQueue.add(msg);
mLastPutTime = System.currentTimeMillis();
}
public synchronized int getCurrentState(long currentTime)
synchronized int getCurrentState(long currentTime)
{
//currentTime is passed as parameter for optimisation to do not recall currentTimeMillis() many times
long interval = currentTime - mLastSendTime;
@ -117,29 +58,23 @@ public abstract class TimedSendLongPollingBot extends TelegramLongPollingBot
return WAIT;
}
public synchronized Object getMessage(long currentTime)
synchronized Object getMessage(long currentTime)
{
mLastSendTime = currentTime;
return mQueue.poll();
}
public long getPutTime()
long getPutTime()
{
return mLastPutTime;
}
public Long getChatId()
Long getChatId()
{
return mChatId;
}
}
//Constructor
protected TimedSendLongPollingBot()
{
mSendTimer.schedule(new MessageSenderTask(), MANY_CHATS_SEND_INTERVAL, MANY_CHATS_SEND_INTERVAL);
}
//Something like destructor
public void finish()
{
@ -214,5 +149,5 @@ public abstract class TimedSendLongPollingBot extends TelegramLongPollingBot
}
}
*/
public abstract void sendMessageCallback(Long chatId, Object messageRequest);
abstract void sendMessageCallback(Long chatId, Object messageRequest);
}

View File

@ -3,9 +3,14 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.telegram</groupId>
<parent>
<groupId>org.telegram</groupId>
<artifactId>Bots</artifactId>
<version>4.4.0</version>
</parent>
<artifactId>telegrambots-meta</artifactId>
<version>4.3.1</version>
<packaging>jar</packaging>
<name>Telegram Bots Meta</name>
@ -57,14 +62,18 @@
</distributionManagement>
<properties>
<java.version>11</java.version>
<maven.compiler.release>8</maven.compiler.release>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<guice.version>4.2.2</guice.version>
<jackson.version>2.9.9</jackson.version>
<jacksonanotation.version>2.9.0</jacksonanotation.version>
<jacksonanotation.version>2.9.9</jacksonanotation.version>
<json.version>20180813</json.version>
<junit.version>4.12</junit.version>
<guava.version>25.1-jre</guava.version>
<guava.version>28.0-jre</guava.version>
</properties>
<dependencies>
@ -105,12 +114,6 @@
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -123,7 +126,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
@ -137,7 +140,7 @@
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
@ -147,7 +150,7 @@
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<id>clean-project</id>
@ -160,7 +163,7 @@
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<version>3.1.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
@ -179,7 +182,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
@ -191,14 +194,14 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
<doclint>none</doclint>
</configuration>
</execution>
</executions>
@ -206,7 +209,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<version>0.8.4</version>
<executions>
<execution>
<goals>
@ -225,7 +228,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<version>3.0.0-M2</version>
<executions>
<execution>
<id>enforce</id>
@ -243,7 +246,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<version>3.1.1</version>
<executions>
<execution>
<id>copy</id>
@ -251,15 +254,21 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>

View File

@ -4,8 +4,8 @@ import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import org.telegram.telegrambots.meta.logging.BotLogger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.text.MessageFormat;
import java.util.HashMap;
@ -16,6 +16,8 @@ import java.util.Map;
* @version 1.0
*/
public class ApiContext {
private static final Logger log = LogManager.getLogger(ApiContext.class);
private static final Object lock = new Object();
private static Injector INJECTOR;
private static Map<Class, Class> bindings = new HashMap<>();
@ -27,14 +29,14 @@ public class ApiContext {
public static <T, S extends T> void register(Class<T> type, Class<S> implementation) {
if (bindings.containsKey(type)) {
BotLogger.debug("ApiContext", MessageFormat.format("Class {0} already registered", type.getName()));
log.debug(MessageFormat.format("Class {0} already registered", type.getName()));
}
bindings.put(type, implementation);
}
public static <T, S extends T> void registerSingleton(Class<T> type, Class<S> implementation) {
if (singletonBindings.containsKey(type)) {
BotLogger.debug("ApiContext", MessageFormat.format("Class {0} already registered", type.getName()));
log.debug(MessageFormat.format("Class {0} already registered", type.getName()));
}
singletonBindings.put(type, implementation);
}

View File

@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import org.telegram.telegrambots.meta.api.methods.BotApiMethod;
import org.telegram.telegrambots.meta.api.objects.ApiResponse;
import org.telegram.telegrambots.meta.api.objects.ChatPermissions;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
@ -24,6 +25,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
* Pass True for all boolean parameters to lift restrictions from a user. Returns True on success.
*
*/
@SuppressWarnings("WeakerAccess")
public class RestrictChatMember extends BotApiMethod<Boolean> {
public static final String PATH = "restrictchatmember";
@ -34,6 +36,7 @@ public class RestrictChatMember extends BotApiMethod<Boolean> {
private static final String CANSENDMEDIAMESSAGES_FIELD = "can_send_media_messages";
private static final String CANSENDOTHERMESSAGES_FIELD = "can_send_other_messages";
private static final String CANADDWEBPAGEPREVIEWS_FIELD = "can_add_web_page_previews";
private static final String PERMISSIONS_FIELD = "permissions";
@JsonProperty(CHATID_FIELD)
private String chatId; ///< Required. Unique identifier for the chat to send the message to (Or username for channels)
@ -49,7 +52,14 @@ public class RestrictChatMember extends BotApiMethod<Boolean> {
private Boolean canSendOtherMessages; ///< Pass True, if the user can send animations, games, stickers and use inline bots, implies can_send_media_messages
@JsonProperty(CANADDWEBPAGEPREVIEWS_FIELD)
private Boolean canAddWebPagePreviews; ///< Pass True, if the user may add web page previews to their messages, implies can_send_messages
/**
* Optional
* Date when restrictions will be lifted for the user, unix time.
* If user is restricted for more than 366 days or less than 30 seconds
* from the current time, they are considered to be restricted forever
*/
@JsonProperty(PERMISSIONS_FIELD)
private ChatPermissions permissions;
public RestrictChatMember() {
super();
@ -108,46 +118,87 @@ public class RestrictChatMember extends BotApiMethod<Boolean> {
return setUntilDate(date.toInstant());
}
@JsonIgnore
public RestrictChatMember forTimePeriod(Duration duration) {
return setUntilDate(Instant.now().plusMillis(duration.toMillis()));
}
/**
* @deprecated Use {@link #getPermissions()} instead
*/
@Deprecated
public Boolean getCanSendMessages() {
return canSendMessages;
}
/**
* @deprecated Use {@link #setPermissions(ChatPermissions)} instead
*/
@Deprecated
public RestrictChatMember setCanSendMessages(Boolean canSendMessages) {
this.canSendMessages = canSendMessages;
return this;
}
/**
* @deprecated Use {@link #getPermissions()} instead
*/
@Deprecated
public Boolean getCanSendMediaMessages() {
return canSendMediaMessages;
}
/**
* @deprecated Use {@link #setPermissions(ChatPermissions)} instead
*/
@Deprecated
public RestrictChatMember setCanSendMediaMessages(Boolean canSendMediaMessages) {
this.canSendMediaMessages = canSendMediaMessages;
return this;
}
/**
* @deprecated Use {@link #getPermissions()} instead
*/
@Deprecated
public Boolean getCanSendOtherMessages() {
return canSendOtherMessages;
}
/**
* @deprecated Use {@link #setPermissions(ChatPermissions)} instead
*/
@Deprecated
public RestrictChatMember setCanSendOtherMessages(Boolean canSendOtherMessages) {
this.canSendOtherMessages = canSendOtherMessages;
return this;
}
/**
* @deprecated Use {@link #getPermissions()} instead
*/
@Deprecated
public Boolean getCanAddWebPagePreviews() {
return canAddWebPagePreviews;
}
/**
* @deprecated Use {@link #setPermissions(ChatPermissions)} instead
*/
@Deprecated
public RestrictChatMember setCanAddWebPagePreviews(Boolean canAddWebPagePreviews) {
this.canAddWebPagePreviews = canAddWebPagePreviews;
return this;
}
public ChatPermissions getPermissions() {
return permissions;
}
public void setPermissions(ChatPermissions permissions) {
this.permissions = permissions;
}
@Override
public String getMethod() {
return PATH;
@ -176,6 +227,9 @@ public class RestrictChatMember extends BotApiMethod<Boolean> {
if (userId == null) {
throw new TelegramApiValidationException("UserId can't be empty", this);
}
if (permissions == null) {
throw new TelegramApiValidationException("Permissions can't be empty", this);
}
}
@Override
@ -188,6 +242,7 @@ public class RestrictChatMember extends BotApiMethod<Boolean> {
", canSendMediaMessages=" + canSendMediaMessages +
", canSendOtherMessages=" + canSendOtherMessages +
", canAddWebPagePreviews=" + canAddWebPagePreviews +
", permissions=" + permissions +
'}';
}
}

View File

@ -0,0 +1,112 @@
package org.telegram.telegrambots.meta.api.methods.groupadministration;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import org.telegram.telegrambots.meta.api.methods.BotApiMethod;
import org.telegram.telegrambots.meta.api.objects.ApiResponse;
import org.telegram.telegrambots.meta.api.objects.ChatPermissions;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
import java.io.IOException;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* @author Ruben Bermudez
* @version 4.4
* Use this method to set default chat permissions for all members.
* The bot must be an administrator in the group or a supergroup
* for this to work and must have the can_restrict_members admin rights.
*/
public class SetChatPermissions extends BotApiMethod<Boolean> {
public static final String PATH = "setChatPermissions";
private static final String CHAT_ID_FIELD = "chat_id";
private static final String PERMISSIONS_FIELD = "permissions";
@JsonProperty(CHAT_ID_FIELD)
private String chatId; ///< Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)
@JsonProperty(PERMISSIONS_FIELD)
private ChatPermissions permissions; ///< New default chat permissions
public SetChatPermissions() {
super();
}
public SetChatPermissions(String chatId, ChatPermissions permissions) {
super();
this.chatId = checkNotNull(chatId);
this.permissions = checkNotNull(permissions);
}
public SetChatPermissions(Long chatId, ChatPermissions permissions) {
super();
this.chatId = checkNotNull(chatId).toString();
this.permissions = checkNotNull(permissions);
}
public String getChatId() {
return chatId;
}
public SetChatPermissions setChatId(String chatId) {
this.chatId = chatId;
return this;
}
public SetChatPermissions setChatId(Long chatId) {
Objects.requireNonNull(chatId);
this.chatId = chatId.toString();
return this;
}
public ChatPermissions getPermissions() {
return permissions;
}
public SetChatPermissions setPermissions(ChatPermissions permissions) {
Objects.requireNonNull(permissions);
this.permissions = permissions;
return this;
}
@Override
public String getMethod() {
return PATH;
}
@Override
public Boolean deserializeResponse(String answer) throws TelegramApiRequestException {
try {
ApiResponse<Boolean> result = OBJECT_MAPPER.readValue(answer,
new TypeReference<ApiResponse<Boolean>>(){});
if (result.getOk()) {
return result.getResult();
} else {
throw new TelegramApiRequestException("Error setting chat description", result);
}
} catch (IOException e) {
throw new TelegramApiRequestException("Unable to deserialize response", e);
}
}
@Override
public void validate() throws TelegramApiValidationException {
if (chatId == null || chatId.isEmpty()) {
throw new TelegramApiValidationException("ChatId can't be empty", this);
}
if (permissions == null) {
throw new TelegramApiValidationException("Permissions can't be null", this);
}
}
@Override
public String toString() {
return "SetChatPermissions{" +
"chatId='" + chatId + '\'' +
", permissions=" + permissions +
'}';
}
}

View File

@ -25,6 +25,7 @@ public class Chat implements BotApiObject {
private static final String PINNEDMESSAGE_FIELD = "pinned_message";
private static final String STICKERSETNAME_FIELD = "sticker_set_name";
private static final String CANSETSTICKERSET_FIELD = "can_set_sticker_set";
private static final String PERMISSIONS_FIELD = "permissions";
private static final String USERCHATTYPE = "private";
private static final String GROUPCHATTYPE = "group";
@ -57,15 +58,23 @@ public class Chat implements BotApiObject {
@JsonProperty(PHOTO_FIELD)
private ChatPhoto photo; ///< Optional. Chat photo. Returned only in getChat.
@JsonProperty(DESCRIPTION_FIELD)
private String description; ///< Optional. Description, for supergroups and channel chats. Returned only in getChat.
private String description; ///< Optional. Description, for groups, supergroups and channel chats. Returned only in getChat.
/**
* Optional. Chat invite link, for groups, supergroups and channel chats.
* Each administrator in a chat generates their own invite links, so the bot must first generate the link using
* exportChatInviteLink.
* Each Returned only in getChat.
*/
@JsonProperty(INVITELINK_FIELD)
private String inviteLink; ///< Optional. Chat invite link, for supergroups and channel chats. Returned only in getChat.
private String inviteLink;
@JsonProperty(PINNEDMESSAGE_FIELD)
private Message pinnedMessage; ///< Optional. Pinned message, for groups, supergroups and channels. Returned only in getChat.
@JsonProperty(STICKERSETNAME_FIELD)
private String stickerSetName; ///< Optional. For supergroups, name of Group sticker set. Returned only in getChat.
@JsonProperty(CANSETSTICKERSET_FIELD)
private Boolean canSetStickerSet; ///< Optional. True, if the bot can change group the sticker set. Returned only in getChat.
@JsonProperty(PERMISSIONS_FIELD)
private ChatPermissions permissions; ///< Optional. Default chat member permissions, for groups and supergroups. Returned only in getChat.
public Chat() {
super();
@ -107,6 +116,14 @@ public class Chat implements BotApiObject {
return userName;
}
public ChatPermissions getPermissions() {
return permissions;
}
/**
* @deprecated Use {@link #getPermissions()} instead
*/
@Deprecated
public Boolean getAllMembersAreAdministrators() {
return allMembersAreAdministrators;
}
@ -151,6 +168,7 @@ public class Chat implements BotApiObject {
", pinnedMessage=" + pinnedMessage +
", stickerSetName='" + stickerSetName + '\'' +
", canSetStickerSet=" + canSetStickerSet +
", permissions=" + permissions +
'}';
}
}

View File

@ -9,8 +9,7 @@ import java.time.Instant;
/**
* @author Ruben Bermudez
* @version 1.0
* @brief This object contains information about one member of the chat.
* @date 20 of May of 2016
* This object contains information about one member of the chat.
*/
public class ChatMember implements BotApiObject {
private static final String USER_FIELD = "user";
@ -29,18 +28,19 @@ public class ChatMember implements BotApiObject {
private static final String CANSENDMEDIAMESSAGES_FIELD = "can_send_media_messages";
private static final String CANSENDOTHERMESSAGES_FIELD = "can_send_other_messages";
private static final String CANADDWEBPAGEPREVIEWS_FIELD = "can_add_web_page_previews";
private static final String CAN_SEND_POLLS_FIELD = "can_send_polls";
private static final String ISMEMBER_FIELD = "is_member";
@JsonProperty(USER_FIELD)
private User user; ///< Information about the user
@JsonProperty(STATUS_FIELD)
private String status; ///< The member's status in the chat. Can be creator, administrator, member, restricted, left or kicked
private String status; ///< The member's status in the chat. Can be creator, administrator, member, restricted, left or kicked
@JsonProperty(UNTILDATE_FIELD)
private Integer untilDate; ///< Optional. Restricted and kicked only. Date when restrictions will be lifted for this user, unix time
@JsonProperty(CANBEEDITED_FIELD)
private Boolean canBeEdited; ///< Optional. Administrators only. True, if the bot is allowed to edit administrator privileges of that user
@JsonProperty(CANCHANGEINFORMATION_FIELD)
private Boolean canChangeInformation; ///< Optional. Administrators only. True, if the administrator can change the chat title, photo and other settings
private Boolean canChangeInformation; ///< Optional. Administrators and restricted only. True, if the administrator can change the chat title, photo and other settings
@JsonProperty(CANPOSTMESSAGES_FIELD)
private Boolean canPostMessages; ///< Optional. Administrators only. True, if the administrator can post in the channel, channels only
@JsonProperty(CANEDITMESSAGES_FIELD)
@ -48,21 +48,23 @@ public class ChatMember implements BotApiObject {
@JsonProperty(CANDELETEMESSAGES_FIELD)
private Boolean canDeleteMessages; ///< Optional. Administrators only. True, if the administrator can delete messages of other users
@JsonProperty(CANINVITEUSERS_FIELD)
private Boolean canInviteUsers; ///< Optional. Administrators only. True, if the administrator can invite new users to the chat
private Boolean canInviteUsers; ///< Optional. Administrators and restricted only. True, if the administrator can invite new users to the chat
@JsonProperty(CANRESTRICTUSERS_FIELD)
private Boolean canRestrictUsers; ///< Optional. Administrators only. True, if the administrator can restrict, ban or unban chat members
@JsonProperty(CANPINMESSAGES_FIELD)
private Boolean canPinMessages; ///< Optional. Administrators only. True, if the administrator can pin messages, groups and supergroups only
private Boolean canPinMessages; ///< Optional. Administrators and restricted only. True, if the administrator can pin messages, groups and supergroups only
@JsonProperty(CANPROMOTEMEMBERS_FIELD)
private Boolean canPromoteMembers; ///< Optional. Administrators only. True, if the administrator can add new administrators with a subset of his own privileges or demote administrators that it has promoted, directly or indirectly (promoted by administrators that were appointed by the bot)
@JsonProperty(CANSENDMESSAGES_FIELD)
private Boolean canSendMessages; ///< Optional. Restricted only. True, if the user can send text messages, contacts, locations and venues
private Boolean canSendMessages; ///< Optional. Restricted only. True, if the user is allowed to send text messages, contacts, locations and venues
@JsonProperty(CANSENDMEDIAMESSAGES_FIELD)
private Boolean canSendMediaMessages; ///< Optional. Restricted only. True, if the user can send audios, documents, photos, videos, video notes and voice notes, implies can_send_messages
private Boolean canSendMediaMessages; ///< Optional. Restricted only. True, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes, implies can_send_messages
@JsonProperty(CANSENDOTHERMESSAGES_FIELD)
private Boolean canSendOtherMessages; ///< Optional. Restricted only. True, if the user can send animations, games, stickers and use inline bots, implies can_send_media_messages
private Boolean canSendOtherMessages; ///< Optional. Restricted only. True, if the user is allowed to send animations, games, stickers and use inline bots, implies can_send_media_messages
@JsonProperty(CANADDWEBPAGEPREVIEWS_FIELD)
private Boolean canAddWebPagePreviews; ///< Optional. Restricted only. True, if user may add web page previews Э to his messages, implies can_send_messages
private Boolean canAddWebPagePreviews; ///< Optional. Restricted only. True, if the user is allowed to add web page previews to his messages
@JsonProperty(CAN_SEND_POLLS_FIELD)
private Boolean canSendPolls; ///< Optional. Restricted only. True, if the user is allowed to send polls.
@JsonProperty(ISMEMBER_FIELD)
private Boolean isMemberField; ///< True, if the user is a member of the chat at the moment of the request. For example, it can be false for the chat creator or for a restricted user.
@ -141,6 +143,14 @@ public class ChatMember implements BotApiObject {
return canAddWebPagePreviews;
}
public Boolean getCanSendPolls() {
return canSendPolls;
}
public Boolean getMemberField() {
return isMemberField;
}
@Override
public String toString() {
return "ChatMember{" +
@ -160,6 +170,8 @@ public class ChatMember implements BotApiObject {
", canSendMediaMessages=" + canSendMediaMessages +
", canSendOtherMessages=" + canSendOtherMessages +
", canAddWebPagePreviews=" + canAddWebPagePreviews +
", canSendPolls=" + canSendPolls +
", isMemberField=" + isMemberField +
'}';
}
}

View File

@ -0,0 +1,89 @@
package org.telegram.telegrambots.meta.api.objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.telegram.telegrambots.meta.api.interfaces.BotApiObject;
/**
* @author Ruben Bermudez
* @version 4.4
* Use this method to change the description of a group, supergroup or channel.
* The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
* Returns True on success.
*/
public class ChatPermissions implements BotApiObject {
private static final String CAN_SEND_MESSAGES_FIELD = "can_send_messages";
private static final String CAN_SEND_MEDIA_MESSAGES_FIELD = "can_send_media_messages";
private static final String CAN_SEND_POLLS_FIELD = "can_send_polls";
private static final String CAN_SEND_OTHER_MESSAGES_FIELD = "can_send_other_messages";
private static final String CAN_ADD_WEB_PAGE_PREVIEWS_FIELD = "can_add_web_page_previews";
private static final String CAN_CHANGE_INFO_FIELD = "can_change_info";
private static final String CAN_INVITE_USERS_FIELD = "can_invite_users";
private static final String CAN_PIN_MESSAGES_FIELD = "can_pin_messages";
@JsonProperty(CAN_SEND_MESSAGES_FIELD)
private Boolean canSendMessages; ///< Optional. True, if the user is allowed to send text messages, contacts, locations and venues
@JsonProperty(CAN_SEND_MEDIA_MESSAGES_FIELD)
private Boolean getCanSendMediaMessages; ///< Optional. True, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes, implies can_send_messages
@JsonProperty(CAN_SEND_POLLS_FIELD)
private Boolean canSendPolls; ///< Optional. True, if the user is allowed to send polls, implies can_send_messages
@JsonProperty(CAN_SEND_OTHER_MESSAGES_FIELD)
private Boolean canSendOtherMessages; ///< Optional. True, if the user is allowed to send animations, games, stickers and use inline bots, implies can_send_media_messages
@JsonProperty(CAN_ADD_WEB_PAGE_PREVIEWS_FIELD)
private Boolean canAddWebPagePreviews; ///< Optional. True, if the user is allowed to add web page previews to their messages, implies can_send_media_messages
@JsonProperty(CAN_CHANGE_INFO_FIELD)
private Boolean canChangeInfo; ///< Optional. True, if the user is allowed to change the chat title, photo and other settings. Ignored in public supergroups
@JsonProperty(CAN_INVITE_USERS_FIELD)
private Boolean canInviteUsers; ///< Optional. True, if the user is allowed to invite new users to the chat
@JsonProperty(CAN_PIN_MESSAGES_FIELD)
private Boolean canPinMessages; ///< Optional. True, if the user is allowed to pin messages. Ignored in public supergroups
public ChatPermissions() {
super();
}
public Boolean getCanSendMessages() {
return canSendMessages;
}
public Boolean getGetCanSendMediaMessages() {
return getCanSendMediaMessages;
}
public Boolean getCanSendPolls() {
return canSendPolls;
}
public Boolean getCanSendOtherMessages() {
return canSendOtherMessages;
}
public Boolean getCanAddWebPagePreviews() {
return canAddWebPagePreviews;
}
public Boolean getCanChangeInfo() {
return canChangeInfo;
}
public Boolean getCanInviteUsers() {
return canInviteUsers;
}
public Boolean getCanPinMessages() {
return canPinMessages;
}
@Override
public String toString() {
return "ChatPermissions{" +
"canSendMessages=" + canSendMessages +
", getCanSendMediaMessages=" + getCanSendMediaMessages +
", canSendPolls=" + canSendPolls +
", canSendOtherMessages=" + canSendOtherMessages +
", canAddWebPagePreviews=" + canAddWebPagePreviews +
", canChangeInfo=" + canChangeInfo +
", canInviteUsers=" + canInviteUsers +
", canPinMessages=" + canPinMessages +
'}';
}
}

View File

@ -6,16 +6,24 @@ import org.telegram.telegrambots.meta.api.interfaces.BotApiObject;
/**
* @author Ruben Bermudez
* @version 1.0
* This object represents a chat photo.
* This object represents a chat photo (profile picture of a user, group or channel)
*/
public class ChatPhoto implements BotApiObject {
private static final String SMALLFILEID_FIELD = "small_file_id";
private static final String BIGFILEID_FIELD = "big_file_id";
/**
* Unique file identifier of a small chat photo (160x160).
* This file_id can be used only for photo download and only for as long as the photo is not changed.
*/
@JsonProperty(SMALLFILEID_FIELD)
private String smallFileId; ///< Unique file identifier of small (160x160) chat photo. This file_id can be used only for photo download.
private String smallFileId;
/**
* Unique file identifier of a big chat photo (640x640).
* This file_id can be used only for photo download and only for as long as the photo is not changed.
*/
@JsonProperty(BIGFILEID_FIELD)
private String bigFileId; ///< Unique file identifier of big (640x640) chat photo. This file_id can be used only for photo download.
private String bigFileId;
public ChatPhoto() {
super();

View File

@ -1,4 +0,0 @@
/**
* @deprecated Replaced by {@link org.telegram.telegrambots.meta.api.objects.inlinequery.result.cached}
*/
package org.telegram.telegrambots.meta.api.objects.inlinequery.result.chached;

View File

@ -8,7 +8,7 @@ import org.telegram.telegrambots.meta.api.objects.PhotoSize;
/**
* @author Ruben Bermudez
* @version 1.0
* @brief This object represents a sticker.
* This object represents a sticker.
*/
public class Sticker implements BotApiObject {
@ -20,6 +20,7 @@ public class Sticker implements BotApiObject {
private static final String EMOJI_FIELD = "emoji";
private static final String SETNAME_FIELD = "set_name";
private static final String MASKPOSITON_FIELD = "mask_position";
private static final String ISANIMATED_FIELD = "is_animated";
@JsonProperty(FILEID_FIELD)
private String fileId; ///< Unique identifier for this file
@ -37,6 +38,8 @@ public class Sticker implements BotApiObject {
private String setName; ///< Optional. Name of the sticker set to which the sticker belongs
@JsonProperty(MASKPOSITON_FIELD)
private MaskPosition maskPosition; ///< Optional. For mask stickers, the position where the mask should be placed
@JsonProperty(ISANIMATED_FIELD)
private Boolean isAnimated; ///< True, if the sticker is animated
public Sticker() {
super();
@ -74,6 +77,10 @@ public class Sticker implements BotApiObject {
return maskPosition;
}
public Boolean getAnimated() {
return isAnimated;
}
@Override
public String toString() {
return "Sticker{" +
@ -85,6 +92,7 @@ public class Sticker implements BotApiObject {
", emoji='" + emoji + '\'' +
", setName='" + setName + '\'' +
", maskPosition=" + maskPosition +
", isAnimated=" + isAnimated +
'}';
}
}

View File

@ -15,6 +15,7 @@ public class StickerSet implements BotApiObject {
private static final String TITLE_FIELD = "title";
private static final String CONTAINSMASKS_FIELD = "contains_masks";
private static final String STICKERS_FIELD = "stickers";
private static final String ISANIMATED_FIELD = "is_animated";
@JsonProperty(NAME_FIELD)
private String name;
@ -24,6 +25,8 @@ public class StickerSet implements BotApiObject {
private Boolean containsMasks;
@JsonProperty(STICKERS_FIELD)
private List<Sticker> stickers;
@JsonProperty(ISANIMATED_FIELD)
private Boolean isAnimated;
public StickerSet() {
super();
@ -45,6 +48,10 @@ public class StickerSet implements BotApiObject {
return stickers;
}
public Boolean getAnimated() {
return isAnimated;
}
@Override
public String toString() {
return "StickerSet{" +
@ -52,6 +59,7 @@ public class StickerSet implements BotApiObject {
", title='" + title + '\'' +
", containsMasks=" + containsMasks +
", stickers=" + stickers +
", isAnimated=" + isAnimated +
'}';
}
}

View File

@ -18,11 +18,11 @@
package org.telegram.telegrambots.meta.exceptions;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONObject;
import org.telegram.telegrambots.meta.api.objects.ResponseParameters;
import org.telegram.telegrambots.meta.api.objects.ApiResponse;
import org.telegram.telegrambots.meta.logging.BotLogger;
import org.telegram.telegrambots.meta.api.objects.ResponseParameters;
import java.io.IOException;
@ -33,6 +33,8 @@ import java.io.IOException;
* Exception thrown when something goes wrong in the api
*/
public class TelegramApiRequestException extends TelegramApiException {
private static final Logger log = LogManager.getLogger(TelegramApiRequestException.class);
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private static final String ERRORDESCRIPTIONFIELD = "description";
private static final String ERRORCODEFIELD = "error_code";
@ -54,7 +56,7 @@ public class TelegramApiRequestException extends TelegramApiException {
try {
parameters = OBJECT_MAPPER.readValue(object.getJSONObject(PARAMETERSFIELD).toString(), ResponseParameters.class);
} catch (IOException e) {
BotLogger.severe("APIEXCEPTION", e);
log.fatal(e.getLocalizedMessage(), e);
}
}
}

View File

@ -1,171 +0,0 @@
package org.telegram.telegrambots.meta.logging;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author Ruben Bermudez
* @version 2.0
* @brief Logger to file
* @date 21/01/15
*/
public class BotLogger {
private static final Logger logger = Logger.getLogger("Telegram Bots Api");
public static void setLevel(Level level) {
logger.setLevel(level);
}
public static Level getLevel() {
return logger.getLevel();
}
public static void registerLogger(Handler handler) {
logger.addHandler(handler);
}
public static void log(Level level, String tag, String msg) {
logger.log(level, String.format("%s - %s", tag, msg));
}
public static void severe(String tag, String msg) {
logger.severe(String.format("%s - %s", tag, msg));
}
public static void warn(String tag, String msg) {
warning(tag, msg);
}
public static void debug(String tag, String msg) {
fine(tag, msg);
}
public static void error(String tag, String msg) {
severe(tag, msg);
}
public static void trace(String tag, String msg) {
finer(tag, msg);
}
public static void warning(String tag, String msg) {
logger.warning(String.format("%s - %s", tag, msg));
}
public static void info(String tag, String msg) {
logger.info(String.format("%s - %s", tag, msg));
}
public static void config(String tag, String msg) {
logger.config(String.format("%s - %s", tag, msg));
}
public static void fine(String tag, String msg) {
logger.fine(String.format("%s - %s", tag, msg));
}
public static void finer(String tag, String msg) {
logger.finer(String.format("%s - %s", tag, msg));
}
public static void finest(String tag, String msg) {
logger.finest(String.format("%s - %s", tag, msg));
}
public static void log(Level level, String tag, Throwable throwable) {
logger.log(level, tag, throwable);
}
public static void log(Level level, String tag, String msg, Throwable thrown) {
logger.log(level, String.format("%s - %s", tag, msg), thrown);
}
public static void severe(String tag, Throwable throwable) {
logger.log(Level.SEVERE, tag, throwable);
}
public static void warning(String tag, Throwable throwable) {
logger.log(Level.WARNING, tag, throwable);
}
public static void info(String tag, Throwable throwable) {
logger.log(Level.INFO, tag, throwable);
}
public static void config(String tag, Throwable throwable) {
logger.log(Level.CONFIG, tag, throwable);
}
public static void fine(String tag, Throwable throwable) {
logger.log(Level.FINE, tag, throwable);
}
public static void finer(String tag, Throwable throwable) {
logger.log(Level.FINER, tag, throwable);
}
public static void finest(String tag, Throwable throwable) {
logger.log(Level.FINEST, tag, throwable);
}
public static void warn(String tag, Throwable throwable) {
warning(tag, throwable);
}
public static void debug(String tag, Throwable throwable) {
fine(tag, throwable);
}
public static void error(String tag, Throwable throwable) {
severe(tag, throwable);
}
public static void trace(String tag, Throwable throwable) {
finer(tag, throwable);
}
public static void severe(String msg, String tag, Throwable throwable) {
log(Level.SEVERE, tag, msg, throwable);
}
public static void warning(String msg, String tag, Throwable throwable) {
log(Level.WARNING, tag, msg, throwable);
}
public static void info(String msg, String tag, Throwable throwable) {
log(Level.INFO, tag, msg, throwable);
}
public static void config(String msg, String tag, Throwable throwable) {
log(Level.CONFIG, tag, msg, throwable);
}
public static void fine(String msg, String tag, Throwable throwable) {
log(Level.FINE, tag, msg, throwable);
}
public static void finer(String msg, String tag, Throwable throwable) {
log(Level.FINER, tag, msg, throwable);
}
public static void finest(String msg, String tag, Throwable throwable) {
log(Level.FINEST, tag, msg, throwable);
}
public static void warn(String msg, String tag, Throwable throwable) {
log(Level.WARNING, tag, msg, throwable);
}
public static void debug(String msg, String tag, Throwable throwable) {
log(Level.FINE, tag, msg, throwable);
}
public static void error(String msg, String tag, Throwable throwable) {
log(Level.SEVERE, tag, msg, throwable);
}
public static void trace(String msg, String tag, Throwable throwable) {
log(Level.FINER, tag, msg, throwable);
}
}

View File

@ -1,45 +0,0 @@
package org.telegram.telegrambots.meta.logging;
import java.io.IOException;
import java.util.logging.FileHandler;
/**
* @author Ruben Bermudez
* @version 1.0
* @brief Handler to use a file as logs destination with {@link BotLogger}
* @date 19 of May of 2016
*/
public class BotsFileHandler extends FileHandler {
private static final String filePattern = "./TelegramBots%g.%u.log";
public BotsFileHandler() throws IOException, SecurityException {
super(filePattern, 1024 * 1024 * 10, 50, true);
setFormatter(new FileFormatter());
}
public BotsFileHandler(int limit, int count) throws IOException, SecurityException {
super(filePattern, limit, count);
setFormatter(new FileFormatter());
}
public BotsFileHandler(String pattern) throws IOException, SecurityException {
super(pattern);
setFormatter(new FileFormatter());
}
public BotsFileHandler(String pattern, boolean append) throws IOException, SecurityException {
super(pattern, append);
setFormatter(new FileFormatter());
}
public BotsFileHandler(String pattern, int limit, int count) throws IOException, SecurityException {
super(pattern, limit, count);
setFormatter(new FileFormatter());
}
public BotsFileHandler(String pattern, int limit, int count, boolean append) throws IOException, SecurityException {
super(pattern, limit, count, append);
setFormatter(new FileFormatter());
}
}

View File

@ -1,52 +0,0 @@
package org.telegram.telegrambots.meta.logging;
import java.time.LocalDateTime;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
/**
* @author Ruben Bermudez
* @version 1.0
* @brief Formatter for {@link BotsFileHandler}
* @date 19 of May of 2016
*/
class FileFormatter extends Formatter {
@Override
public String format(LogRecord record) {
final LocalDateTime currentDate = LocalDateTime.now();
final String dateForLog = dateFormatterForLogs(currentDate);
String result;
if (record.getThrown() == null) {
result = logMsgToFile(record.getLevel(), record.getMessage(), dateForLog);
} else {
result = logThrowableToFile(record.getLevel(), record.getMessage(), record.getThrown(), dateForLog);
}
return result;
}
private static String dateFormatterForLogs(LocalDateTime dateTime) {
String dateString = "[";
dateString += dateTime.getDayOfMonth() + "_";
dateString += dateTime.getMonthValue() + "_";
dateString += dateTime.getYear() + "_";
dateString += dateTime.getHour() + ":";
dateString += dateTime.getMinute() + ":";
dateString += dateTime.getSecond();
dateString += "] ";
return dateString;
}
private static String logMsgToFile(Level level, String msg, String dateForLog) {
return String.format("%s{%s} %s\n", dateForLog, level.toString(), msg);
}
private static String logThrowableToFile(Level level, String message, Throwable throwable, String dateForLog) {
String throwableLog = String.format("%s{%s} %s - %s\n", dateForLog, level.toString(), message, throwable.toString());
for (StackTraceElement element : throwable.getStackTrace()) {
throwableLog += "\tat " + element + "\n";
}
return throwableLog;
}
}

View File

@ -1,25 +1,26 @@
package org.telegram.telegrambots.meta.api.methods.send;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
public class SendMessageTest {
class SendMessageTest {
@Test
public void comparison() throws Exception {
void comparison() {
SendMessage sm1 = new SendMessage().setChatId(1L).setText("Hello World");
SendMessage sm2 = new SendMessage().setChatId(1L).setText("Hello World");
SendMessage noMessage = new SendMessage().setChatId(1L);
SendMessage disabledNotification = new SendMessage().setChatId(1L).setText("Hello World").disableNotification();
assertTrue(sm1.equals(sm2));
assertFalse(sm1.equals(noMessage));
assertFalse(sm1.equals(disabledNotification));
assertEquals(sm1, sm2);
assertNotEquals(sm1, noMessage);
assertNotEquals(sm1, disabledNotification);
assertTrue(sm1.hashCode() == sm2.hashCode());
assertFalse(sm1.hashCode() == noMessage.hashCode());
assertFalse(sm1.hashCode() == disabledNotification.hashCode());
assertEquals(sm1.hashCode(), sm2.hashCode());
assertNotEquals(sm1.hashCode(), noMessage.hashCode());
assertNotEquals(sm1.hashCode(), disabledNotification.hashCode());
}
}

View File

@ -1,31 +1,30 @@
package org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static java.util.Arrays.asList;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class KeyboardRowTest {
class KeyboardRowTest {
private static final List<String> BUTTON_NAMES = asList("Carlotta Valdes", "Jimmy Stewart");
@Test
public void shouldAddAllButtons() {
void shouldAddAllButtons() {
final KeyboardRow keyboardRow = new KeyboardRow();
keyboardRow.addAll(BUTTON_NAMES);
assertThat(keyboardRow.size(), is(2));
assertThat(keyboardRow.get(0).getText(), is("Carlotta Valdes"));
assertThat(keyboardRow.get(1).getText(), is("Jimmy Stewart"));
assertEquals(2, keyboardRow.size());
assertEquals("Carlotta Valdes", keyboardRow.get(0).getText());
assertEquals("Jimmy Stewart", keyboardRow.get(1).getText());
}
@Test
public void shouldAddNoButtons() {
void shouldAddNoButtons() {
final KeyboardRow keyboardRow = new KeyboardRow();
keyboardRow.addAll(new ArrayList<String>());
assertTrue(keyboardRow.isEmpty());

View File

@ -3,9 +3,9 @@ package org.telegram.telegrambots.meta.test;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.telegram.telegrambots.meta.api.objects.ApiResponse;
import org.telegram.telegrambots.meta.api.objects.Audio;
import org.telegram.telegrambots.meta.api.objects.CallbackQuery;
import org.telegram.telegrambots.meta.api.objects.Chat;
@ -18,63 +18,67 @@ import org.telegram.telegrambots.meta.api.objects.User;
import org.telegram.telegrambots.meta.api.objects.Voice;
import org.telegram.telegrambots.meta.api.objects.inlinequery.ChosenInlineQuery;
import org.telegram.telegrambots.meta.api.objects.inlinequery.InlineQuery;
import org.telegram.telegrambots.meta.api.objects.ApiResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Ruben Bermudez
* @version 1.0
*/
public class TestDeserialization {
class TestDeserialization {
private ObjectMapper mapper;
@Before
public void setUp() {
@BeforeEach
void setUp() {
mapper = new ObjectMapper();
}
@Test
public void TestUpdateDeserialization() throws Exception {
void TestUpdateDeserialization() throws Exception {
Update update = mapper.readValue(TelegramBotsHelper.GetUpdate(), Update.class);
assertUpdate(update);
}
@Test
public void TestUpdateDeserializationWithInlineKeyboard() throws Exception {
void TestUpdateDeserializationWithInlineKeyboard() throws Exception {
Update update = mapper.readValue(TelegramBotsHelper.GetUpdateWithMessageInCallbackQuery(), Update.class);
Assert.assertNotNull(update);
Assert.assertNotNull(update.getCallbackQuery());
Assert.assertNotNull(update.getCallbackQuery().getMessage());
Assert.assertNotNull(update.getCallbackQuery().getMessage().getReplyMarkup());
assertNotNull(update);
assertNotNull(update.getCallbackQuery());
assertNotNull(update.getCallbackQuery().getMessage());
assertNotNull(update.getCallbackQuery().getMessage().getReplyMarkup());
}
@Test
public void TestResponseWithoutErrorDeserialization() throws IOException {
void TestResponseWithoutErrorDeserialization() throws IOException {
ApiResponse<ArrayList<Update>> result = mapper.readValue(TelegramBotsHelper.GetResponseWithoutError(), new TypeReference<ApiResponse<ArrayList<Update>>>(){});
Assert.assertNotNull(result);
Assert.assertTrue(result.getOk());
Assert.assertEquals(1, result.getResult().size());
assertNotNull(result);
assertTrue(result.getOk());
assertEquals(1, result.getResult().size());
assertUpdate(result.getResult().get(0));
}
@Test
public void TestResponseWithErrorDeserialization() throws IOException {
void TestResponseWithErrorDeserialization() throws IOException {
ApiResponse<ArrayList<Update>> result = mapper.readValue(TelegramBotsHelper.GetResponseWithError(), new TypeReference<ApiResponse<ArrayList<Update>>>(){});
Assert.assertNotNull(result);
Assert.assertFalse(result.getOk());
Assert.assertEquals(Integer.valueOf(400), result.getErrorCode());
Assert.assertEquals("Error descriptions", result.getErrorDescription());
Assert.assertNotNull(result.getParameters());
Assert.assertEquals(Long.valueOf(12345), result.getParameters().getMigrateToChatId());
Assert.assertEquals(Integer.valueOf(12), result.getParameters().getRetryAfter());
assertNotNull(result);
assertFalse(result.getOk());
assertEquals(Integer.valueOf(400), result.getErrorCode());
assertEquals("Error descriptions", result.getErrorDescription());
assertNotNull(result.getParameters());
assertEquals(Long.valueOf(12345), result.getParameters().getMigrateToChatId());
assertEquals(Integer.valueOf(12), result.getParameters().getRetryAfter());
}
private void assertUpdate(Update update) {
Assert.assertNotNull(update);
Assert.assertEquals((Integer) 10000, update.getUpdateId());
assertNotNull(update);
assertEquals((Integer) 10000, update.getUpdateId());
assertEditedMessage(update.getEditedMessage());
assertCallbackQuery(update.getCallbackQuery());
assertInlineQuery(update.getInlineQuery());
@ -83,11 +87,11 @@ public class TestDeserialization {
}
private void assertMessage(Message message) {
Assert.assertNotNull(message);
Assert.assertEquals(Integer.valueOf(1441645532), message.getDate());
Assert.assertEquals(Integer.valueOf(1365), message.getMessageId());
Assert.assertEquals(Integer.valueOf(1441645550), message.getForwardDate());
Assert.assertEquals("Bold and italics", message.getText());
assertNotNull(message);
assertEquals(Integer.valueOf(1441645532), message.getDate());
assertEquals(Integer.valueOf(1365), message.getMessageId());
assertEquals(Integer.valueOf(1441645550), message.getForwardDate());
assertEquals("Bold and italics", message.getText());
assertPrivateChat(message.getChat());
assertFromUser(message.getFrom());
assertForwardFrom(message.getForwardFrom());
@ -99,119 +103,119 @@ public class TestDeserialization {
}
private void assertDocument(Document document) {
Assert.assertNotNull(document);
Assert.assertEquals("AwADBAADbXXXXXXXXXXXGBdhD2l6_XX", document.getFileId());
Assert.assertEquals("Testfile.pdf", document.getFileName());
Assert.assertEquals("application/pdf", document.getMimeType());
Assert.assertEquals(Integer.valueOf(536392), document.getFileSize());
assertNotNull(document);
assertEquals("AwADBAADbXXXXXXXXXXXGBdhD2l6_XX", document.getFileId());
assertEquals("Testfile.pdf", document.getFileName());
assertEquals("application/pdf", document.getMimeType());
assertEquals(Integer.valueOf(536392), document.getFileSize());
}
private void assertVoice(Voice voice) {
Assert.assertNotNull(voice);
Assert.assertEquals("AwADBAADbXXXXXXXXXXXGBdhD2l6_XX", voice.getFileId());
Assert.assertEquals(Integer.valueOf(5), voice.getDuration());
Assert.assertEquals("audio/ogg", voice.getMimeType());
Assert.assertEquals(Integer.valueOf(23000), voice.getFileSize());
assertNotNull(voice);
assertEquals("AwADBAADbXXXXXXXXXXXGBdhD2l6_XX", voice.getFileId());
assertEquals(Integer.valueOf(5), voice.getDuration());
assertEquals("audio/ogg", voice.getMimeType());
assertEquals(Integer.valueOf(23000), voice.getFileSize());
}
private void assertAudio(Audio audio) {
Assert.assertNotNull(audio);
Assert.assertEquals("AwADBAADbXXXXXXXXXXXGBdhD2l6_XX", audio.getFileId());
Assert.assertEquals(Integer.valueOf(243), audio.getDuration());
Assert.assertEquals("audio/mpeg", audio.getMimeType());
Assert.assertEquals(Integer.valueOf(3897500), audio.getFileSize());
Assert.assertEquals("Testmusicfile", audio.getTitle());
assertNotNull(audio);
assertEquals("AwADBAADbXXXXXXXXXXXGBdhD2l6_XX", audio.getFileId());
assertEquals(Integer.valueOf(243), audio.getDuration());
assertEquals("audio/mpeg", audio.getMimeType());
assertEquals(Integer.valueOf(3897500), audio.getFileSize());
assertEquals("Testmusicfile", audio.getTitle());
}
private void assertEntities(List<MessageEntity> entities) {
Assert.assertNotNull(entities);
Assert.assertEquals(2, entities.size());
Assert.assertEquals(EntityType.ITALIC, entities.get(0).getType());
Assert.assertEquals(Integer.valueOf(9), entities.get(0).getOffset());
Assert.assertEquals(Integer.valueOf(7), entities.get(0).getLength());
Assert.assertEquals("italics", entities.get(0).getText());
Assert.assertEquals(EntityType.BOLD, entities.get(1).getType());
Assert.assertEquals(Integer.valueOf(0), entities.get(1).getOffset());
Assert.assertEquals(Integer.valueOf(4), entities.get(1).getLength());
Assert.assertEquals("Bold", entities.get(1).getText());
assertNotNull(entities);
assertEquals(2, entities.size());
assertEquals(EntityType.ITALIC, entities.get(0).getType());
assertEquals(Integer.valueOf(9), entities.get(0).getOffset());
assertEquals(Integer.valueOf(7), entities.get(0).getLength());
assertEquals("italics", entities.get(0).getText());
assertEquals(EntityType.BOLD, entities.get(1).getType());
assertEquals(Integer.valueOf(0), entities.get(1).getOffset());
assertEquals(Integer.valueOf(4), entities.get(1).getLength());
assertEquals("Bold", entities.get(1).getText());
}
private void assertReplyToMessage(Message replyToMessage) {
Assert.assertNotNull(replyToMessage);
Assert.assertEquals(Integer.valueOf(1441645000), replyToMessage.getDate());
Assert.assertEquals(Integer.valueOf(1334), replyToMessage.getMessageId());
Assert.assertEquals("Original", replyToMessage.getText());
Assert.assertNotNull(replyToMessage.getChat());
Assert.assertEquals("ReplyLastname", replyToMessage.getChat().getLastName());
Assert.assertEquals("ReplyFirstname", replyToMessage.getChat().getFirstName());
Assert.assertEquals("Testusername", replyToMessage.getChat().getUserName());
Assert.assertEquals(Long.valueOf(1111112), replyToMessage.getChat().getId());
assertNotNull(replyToMessage);
assertEquals(Integer.valueOf(1441645000), replyToMessage.getDate());
assertEquals(Integer.valueOf(1334), replyToMessage.getMessageId());
assertEquals("Original", replyToMessage.getText());
assertNotNull(replyToMessage.getChat());
assertEquals("ReplyLastname", replyToMessage.getChat().getLastName());
assertEquals("ReplyFirstname", replyToMessage.getChat().getFirstName());
assertEquals("Testusername", replyToMessage.getChat().getUserName());
assertEquals(Long.valueOf(1111112), replyToMessage.getChat().getId());
}
private void assertForwardFrom(User forwardFrom) {
Assert.assertNotNull(forwardFrom);
Assert.assertEquals("ForwardLastname", forwardFrom.getLastName());
Assert.assertEquals("ForwardFirstname", forwardFrom.getFirstName());
Assert.assertEquals(Integer.valueOf(222222), forwardFrom.getId());
assertNotNull(forwardFrom);
assertEquals("ForwardLastname", forwardFrom.getLastName());
assertEquals("ForwardFirstname", forwardFrom.getFirstName());
assertEquals(Integer.valueOf(222222), forwardFrom.getId());
}
private void assertPrivateChat(Chat chat) {
Assert.assertNotNull(chat);
Assert.assertEquals(Long.valueOf(1111111), chat.getId());
Assert.assertTrue(chat.isUserChat());
Assert.assertEquals("Test Lastname", chat.getLastName());
Assert.assertEquals("Test Firstname", chat.getFirstName());
Assert.assertEquals("Testusername", chat.getUserName());
assertNotNull(chat);
assertEquals(Long.valueOf(1111111), chat.getId());
assertTrue(chat.isUserChat());
assertEquals("Test Lastname", chat.getLastName());
assertEquals("Test Firstname", chat.getFirstName());
assertEquals("Testusername", chat.getUserName());
}
private void assertChosenInlineQuery(ChosenInlineQuery chosenInlineQuery) {
Assert.assertNotNull(chosenInlineQuery);
Assert.assertEquals("12", chosenInlineQuery.getResultId());
Assert.assertEquals("inline query", chosenInlineQuery.getQuery());
Assert.assertEquals("1234csdbsk4839", chosenInlineQuery.getInlineMessageId());
assertNotNull(chosenInlineQuery);
assertEquals("12", chosenInlineQuery.getResultId());
assertEquals("inline query", chosenInlineQuery.getQuery());
assertEquals("1234csdbsk4839", chosenInlineQuery.getInlineMessageId());
assertFromUser(chosenInlineQuery.getFrom());
}
private void assertInlineQuery(InlineQuery inlineQuery) {
Assert.assertNotNull(inlineQuery);
Assert.assertEquals("134567890097", inlineQuery.getId());
Assert.assertEquals("inline query", inlineQuery.getQuery());
Assert.assertEquals("offset", inlineQuery.getOffset());
assertNotNull(inlineQuery);
assertEquals("134567890097", inlineQuery.getId());
assertEquals("inline query", inlineQuery.getQuery());
assertEquals("offset", inlineQuery.getOffset());
assertFromUser(inlineQuery.getFrom());
Assert.assertNotNull(inlineQuery.getLocation());
Assert.assertEquals(Float.valueOf("0.234242534"), inlineQuery.getLocation().getLatitude());
Assert.assertEquals(Float.valueOf("0.234242534"), inlineQuery.getLocation().getLongitude());
assertNotNull(inlineQuery.getLocation());
assertEquals(Float.valueOf("0.234242534"), inlineQuery.getLocation().getLatitude());
assertEquals(Float.valueOf("0.234242534"), inlineQuery.getLocation().getLongitude());
}
private void assertCallbackQuery(CallbackQuery callbackQuery) {
Assert.assertNotNull(callbackQuery);
Assert.assertEquals("4382bfdwdsb323b2d9", callbackQuery.getId());
Assert.assertEquals("Data from button callback", callbackQuery.getData());
Assert.assertEquals("1234csdbsk4839", callbackQuery.getInlineMessageId());
assertNotNull(callbackQuery);
assertEquals("4382bfdwdsb323b2d9", callbackQuery.getId());
assertEquals("Data from button callback", callbackQuery.getData());
assertEquals("1234csdbsk4839", callbackQuery.getInlineMessageId());
assertFromUser(callbackQuery.getFrom());
}
private void assertEditedMessage(Message message) {
Assert.assertEquals((Integer) 1441645532, message.getDate());
Assert.assertEquals((Integer) 1441646600, message.getEditDate());
Assert.assertEquals((Integer) 1365, message.getMessageId());
Assert.assertEquals("Edited text", message.getText());
assertEquals((Integer) 1441645532, message.getDate());
assertEquals((Integer) 1441646600, message.getEditDate());
assertEquals((Integer) 1365, message.getMessageId());
assertEquals("Edited text", message.getText());
assertChannelChat(message.getChat());
assertFromUser(message.getFrom());
}
private void assertFromUser(User from) {
Assert.assertNotNull(from);
Assert.assertEquals((Integer) 1111111, from.getId());
Assert.assertEquals("Test Lastname", from.getLastName());
Assert.assertEquals("Test Firstname", from.getFirstName());
Assert.assertEquals("Testusername", from.getUserName());
assertNotNull(from);
assertEquals((Integer) 1111111, from.getId());
assertEquals("Test Lastname", from.getLastName());
assertEquals("Test Firstname", from.getFirstName());
assertEquals("Testusername", from.getUserName());
}
private void assertChannelChat(Chat chat) {
Assert.assertNotNull(chat);
Assert.assertEquals(Long.valueOf(-10000000000L), chat.getId());
Assert.assertTrue(chat.isChannelChat());
Assert.assertEquals("Test channel", chat.getTitle());
assertNotNull(chat);
assertEquals(Long.valueOf(-10000000000L), chat.getId());
assertTrue(chat.isChannelChat());
assertEquals("Test channel", chat.getTitle());
}
}
}

View File

@ -1,46 +1,47 @@
package org.telegram.telegrambots.meta.test;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.test.base.TestBase;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.test.base.TestBase;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Ruben Bermudez
* @version 1.0
*/
public class TestTelegramApi extends TestBase {
class TestTelegramApi extends TestBase {
@Test
public void TestTelegramApiMustBeInitializableForLongPolling() {
void TestTelegramApiMustBeInitializableForLongPolling() {
new TelegramBotsApi();
}
@Test
public void TestTelegramApiMustBeInitializableForWebhookWithoutSecureSupport() {
void TestTelegramApiMustBeInitializableForWebhookWithoutSecureSupport() {
try {
new TelegramBotsApi("externalUrl", "internalUrl");
} catch (TelegramApiRequestException e) {
Assert.fail();
fail();
}
}
@Test
public void TestTelegramApiMustBeInitializableForWebhook() {
void TestTelegramApiMustBeInitializableForWebhook() {
try {
new TelegramBotsApi("keyStore", "keyStorePassword", "externalUrl", "internalUrl");
} catch (TelegramApiRequestException e) {
Assert.fail();
fail();
}
}
@Test
public void TestTelegramApiMustBeInitializableForWebhookWithSelfSignedCertificate() {
void TestTelegramApiMustBeInitializableForWebhookWithSelfSignedCertificate() {
try {
new TelegramBotsApi("keyStore", "keyStorePassword", "externalUrl", "internalUrl", "selfSignedPath");
} catch (TelegramApiRequestException e) {
Assert.fail();
fail();
}
}
}

View File

@ -1,56 +1,57 @@
package org.telegram.telegrambots.meta.test.apimethods;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.telegram.telegrambots.meta.api.methods.AnswerInlineQuery;
import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Ruben Bermudez
* @version 1.0
*/
public class TestAnswerInlineQuery {
class TestAnswerInlineQuery {
private AnswerInlineQuery answerInlineQuery;
@Before
public void setUp() throws Exception {
@BeforeEach
void setUp() {
answerInlineQuery = new AnswerInlineQuery();
}
@Test
public void TestInlineQueryIdMustBePresent() throws Exception {
void TestInlineQueryIdMustBePresent() {
try {
answerInlineQuery.validate();
} catch (TelegramApiValidationException e) {
Assert.assertEquals("InlineQueryId can't be empty", e.getMessage());
assertEquals("InlineQueryId can't be empty", e.getMessage());
}
}
@Test
public void TestInlineQueryIdCanNotBeEmpty() throws Exception {
void TestInlineQueryIdCanNotBeEmpty() {
answerInlineQuery.setInlineQueryId("");
try {
answerInlineQuery.validate();
} catch (TelegramApiValidationException e) {
Assert.assertEquals("InlineQueryId can't be empty", e.getMessage());
assertEquals("InlineQueryId can't be empty", e.getMessage());
}
}
@Test
public void TestResultsMustBePresent() throws Exception {
void TestResultsMustBePresent() {
answerInlineQuery.setInlineQueryId("RANDOMEID");
try {
answerInlineQuery.validate();
} catch (TelegramApiValidationException e) {
Assert.assertEquals("Results array can't be null", e.getMessage());
assertEquals("Results array can't be null", e.getMessage());
}
}
@Test
public void TestSwitchPmTextCanNotBeEmpty() throws Exception {
void TestSwitchPmTextCanNotBeEmpty() {
answerInlineQuery.setInlineQueryId("RANDOMEID");
answerInlineQuery.setResults(new ArrayList<>());
answerInlineQuery.setSwitchPmText("");
@ -58,12 +59,12 @@ public class TestAnswerInlineQuery {
try {
answerInlineQuery.validate();
} catch (TelegramApiValidationException e) {
Assert.assertEquals("SwitchPmText can't be empty", e.getMessage());
assertEquals("SwitchPmText can't be empty", e.getMessage());
}
}
@Test
public void TestSwitchPmParameterIsMandatoryIfSwitchPmTextIsPresent() throws Exception {
void TestSwitchPmParameterIsMandatoryIfSwitchPmTextIsPresent() {
answerInlineQuery.setInlineQueryId("RANDOMEID");
answerInlineQuery.setResults(new ArrayList<>());
answerInlineQuery.setSwitchPmText("Test Text");
@ -71,12 +72,12 @@ public class TestAnswerInlineQuery {
try {
answerInlineQuery.validate();
} catch (TelegramApiValidationException e) {
Assert.assertEquals("SwitchPmParameter can't be empty if switchPmText is present", e.getMessage());
assertEquals("SwitchPmParameter can't be empty if switchPmText is present", e.getMessage());
}
}
@Test
public void TestSwitchPmParameterCanNotBeEmptyIfSwitchPmTextIsPresent() throws Exception {
void TestSwitchPmParameterCanNotBeEmptyIfSwitchPmTextIsPresent() {
answerInlineQuery.setInlineQueryId("RANDOMEID");
answerInlineQuery.setResults(new ArrayList<>());
answerInlineQuery.setSwitchPmText("Test Text");
@ -85,12 +86,12 @@ public class TestAnswerInlineQuery {
try {
answerInlineQuery.validate();
} catch (TelegramApiValidationException e) {
Assert.assertEquals("SwitchPmParameter can't be empty if switchPmText is present", e.getMessage());
assertEquals("SwitchPmParameter can't be empty if switchPmText is present", e.getMessage());
}
}
@Test
public void TestSwitchPmParameterContainsUpTo64Chars() throws Exception {
void TestSwitchPmParameterContainsUpTo64Chars() {
answerInlineQuery.setInlineQueryId("RANDOMEID");
answerInlineQuery.setResults(new ArrayList<>());
answerInlineQuery.setSwitchPmText("Test Text");
@ -99,12 +100,12 @@ public class TestAnswerInlineQuery {
try {
answerInlineQuery.validate();
} catch (TelegramApiValidationException e) {
Assert.assertEquals("SwitchPmParameter can't be longer than 64 chars", e.getMessage());
assertEquals("SwitchPmParameter can't be longer than 64 chars", e.getMessage());
}
}
@Test
public void TestSwitchPmParameterOnlyContainsAcceptedCharacters() throws Exception {
void TestSwitchPmParameterOnlyContainsAcceptedCharacters() {
answerInlineQuery.setInlineQueryId("RANDOMEID");
answerInlineQuery.setResults(new ArrayList<>());
answerInlineQuery.setSwitchPmText("Test Text");
@ -113,7 +114,7 @@ public class TestAnswerInlineQuery {
try {
answerInlineQuery.validate();
} catch (TelegramApiValidationException e) {
Assert.assertEquals("SwitchPmParameter only allows A-Z, a-z, 0-9, _ and - characters", e.getMessage());
assertEquals("SwitchPmParameter only allows A-Z, a-z, 0-9, _ and - characters", e.getMessage());
}
}
}

View File

@ -2,27 +2,29 @@ package org.telegram.telegrambots.meta.test.apimethods;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.telegram.telegrambots.meta.test.TelegramBotsHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.telegram.telegrambots.meta.api.methods.updates.GetUpdates;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.test.TelegramBotsHelper;
import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* @author Ruben Bermudez
* @version 1.0
*/
public class TestGetUpdates {
class TestGetUpdates {
private GetUpdates getUpdates;
private ObjectMapper mapper = new ObjectMapper();
@Before
public void setUp() throws Exception {
@BeforeEach
void setUp() {
getUpdates = new GetUpdates();
getUpdates.setOffset(15);
getUpdates.setTimeout(50);
@ -30,28 +32,28 @@ public class TestGetUpdates {
}
@Test
public void TestGetUpdatesMustBeSerializable() throws Exception {
void TestGetUpdatesMustBeSerializable() throws Exception {
String json = mapper.writeValueAsString(getUpdates);
Assert.assertNotNull(json);
Assert.assertEquals("{\"offset\":15,\"limit\":100,\"timeout\":50,\"method\":\"getupdates\"}", json);
assertNotNull(json);
assertEquals("{\"offset\":15,\"limit\":100,\"timeout\":50,\"method\":\"getupdates\"}", json);
}
@Test
public void TestGetUpdatesMustDeserializeCorrectResponse() throws Exception {
void TestGetUpdatesMustDeserializeCorrectResponse() throws Exception {
ArrayList<Update> result =
getUpdates.deserializeResponse(TelegramBotsHelper.GetResponseWithoutError());
Assert.assertNotNull(result);
Assert.assertEquals(1, result.size());
assertNotNull(result);
assertEquals(1, result.size());
}
@Test
public void TestGetUpdatesMustThrowAnExceptionForInCorrectResponse() {
void TestGetUpdatesMustThrowAnExceptionForInCorrectResponse() {
try {
getUpdates.deserializeResponse(TelegramBotsHelper.GetResponseWithError());
} catch (TelegramApiRequestException e) {
Assert.assertNotNull(e.getParameters());
Assert.assertEquals(Integer.valueOf(400), e.getErrorCode());
Assert.assertEquals("Error descriptions", e.getApiResponse());
assertNotNull(e.getParameters());
assertEquals(Integer.valueOf(400), e.getErrorCode());
assertEquals("Error descriptions", e.getApiResponse());
}
}
}

View File

@ -2,26 +2,29 @@ package org.telegram.telegrambots.meta.test.apimethods;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.telegram.telegrambots.meta.test.TelegramBotsHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.telegram.telegrambots.meta.api.methods.games.SetGameScore;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.test.TelegramBotsHelper;
import java.io.Serializable;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Ruben Bermudez
* @version 1.0
*/
public class TestSetGameScore {
class TestSetGameScore {
private SetGameScore setGameScore;
private ObjectMapper mapper = new ObjectMapper();
@Before
public void setUp() throws Exception {
@BeforeEach
void setUp() {
setGameScore = new SetGameScore();
setGameScore.setChatId("12345");
setGameScore.setDisableEditMessage(true);
@ -31,25 +34,25 @@ public class TestSetGameScore {
}
@Test
public void TestGetUpdatesMustBeSerializable() throws Exception {
void TestGetUpdatesMustBeSerializable() throws Exception {
String json = mapper.writeValueAsString(setGameScore);
Assert.assertNotNull(json);
Assert.assertEquals("{\"chat_id\":\"12345\",\"message_id\":54321,\"disable_edit_message\":true,\"user_id\":98765,\"score\":12,\"method\":\"setGameScore\"}", json);
assertNotNull(json);
assertEquals("{\"chat_id\":\"12345\",\"message_id\":54321,\"disable_edit_message\":true,\"user_id\":98765,\"score\":12,\"method\":\"setGameScore\"}", json);
}
@Test
public void TestGetUpdatesMustDeserializeCorrectResponse() throws Exception {
void TestGetUpdatesMustDeserializeCorrectResponse() throws Exception {
Serializable result =
setGameScore.deserializeResponse(TelegramBotsHelper.GetSetGameScoreBooleanResponse());
Assert.assertNotNull(result);
Assert.assertTrue(result instanceof Boolean);
Assert.assertTrue((Boolean) result);
assertNotNull(result);
assertTrue(result instanceof Boolean);
assertTrue((Boolean) result);
}
@Test
public void TestGetUpdatesMustThrowAnExceptionForInCorrectResponse() throws Exception {
void TestGetUpdatesMustThrowAnExceptionForInCorrectResponse() throws Exception {
Serializable result = setGameScore.deserializeResponse(TelegramBotsHelper.GetSetGameScoreMessageResponse());
Assert.assertNotNull(result);
Assert.assertTrue(result instanceof Message);
assertNotNull(result);
assertTrue(result instanceof Message);
}
}

View File

@ -1,11 +1,11 @@
package org.telegram.telegrambots.meta.test.base;
import org.junit.BeforeClass;
import org.junit.jupiter.api.BeforeAll;
import org.telegram.telegrambots.meta.ApiContext;
import org.telegram.telegrambots.meta.test.fakes.FakeBotSession;
import org.telegram.telegrambots.meta.test.fakes.FakeWebhook;
import org.telegram.telegrambots.meta.generics.BotSession;
import org.telegram.telegrambots.meta.generics.Webhook;
import org.telegram.telegrambots.meta.test.fakes.FakeBotSession;
import org.telegram.telegrambots.meta.test.fakes.FakeWebhook;
/**
* @author Ruben Bermudez
@ -13,7 +13,7 @@ import org.telegram.telegrambots.meta.generics.Webhook;
*/
public abstract class TestBase {
@BeforeClass
@BeforeAll
public static void beforeClass() {
ApiContext.register(BotSession.class, FakeBotSession.class);
ApiContext.register(Webhook.class, FakeWebhook.class);

View File

@ -3,9 +3,14 @@
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.telegram</groupId>
<parent>
<groupId>org.telegram</groupId>
<artifactId>Bots</artifactId>
<version>4.4.0</version>
</parent>
<artifactId>telegrambots-spring-boot-starter</artifactId>
<version>4.3.1</version>
<packaging>jar</packaging>
<name>Telegram Bots Spring Boot Starter</name>
@ -57,9 +62,15 @@
</distributionManagement>
<properties>
<java.version>11</java.version>
<maven.compiler.release>8</maven.compiler.release>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.0.2.RELEASE</spring-boot.version>
<spring-boot.version>2.1.6.RELEASE</spring-boot.version>
</properties>
<dependencies>
@ -67,7 +78,7 @@
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>4.3.1</version>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -92,23 +103,8 @@
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
<version>3.9.1</version>
<version>3.13.1</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -121,7 +117,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
@ -135,7 +131,7 @@
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
@ -145,7 +141,7 @@
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<id>clean-project</id>
@ -158,7 +154,7 @@
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<version>3.1.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
@ -177,7 +173,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
@ -189,14 +185,14 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
<doclint>none</doclint>
</configuration>
</execution>
</executions>
@ -204,7 +200,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<version>0.8.4</version>
<executions>
<execution>
<goals>
@ -223,7 +219,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<version>3.0.0-M2</version>
<executions>
<execution>
<id>enforce-versions</id>
@ -241,7 +237,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<version>3.1.1</version>
<executions>
<execution>
<id>copy</id>
@ -249,15 +245,21 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>

View File

@ -1,12 +1,13 @@
package org.telegram.telegrambots.starter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.generics.BotSession;
import org.telegram.telegrambots.meta.generics.LongPollingBot;
import org.telegram.telegrambots.meta.generics.WebhookBot;
import org.telegram.telegrambots.meta.logging.BotLogger;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@ -20,6 +21,7 @@ import static java.lang.String.format;
* Receives all beand which are #LongPollingBot and #WebhookBot and register them in #TelegramBotsApi.
*/
public class TelegramBotInitializer implements InitializingBean {
private static final Logger log = LogManager.getLogger(TelegramBotInitializer.class);
private final TelegramBotsApi telegramBotsApi;
private final List<LongPollingBot> longPollingBots;
@ -37,7 +39,7 @@ public class TelegramBotInitializer implements InitializingBean {
}
@Override
public void afterPropertiesSet() throws Exception {
public void afterPropertiesSet() {
try {
for (LongPollingBot bot : longPollingBots) {
BotSession session = telegramBotsApi.registerBot(bot);
@ -54,12 +56,8 @@ public class TelegramBotInitializer implements InitializingBean {
private void handleAnnotatedMethod(Object bot, Method method, BotSession session) {
try {
if (method.getParameterCount() > 1) {
BotLogger.warn(this.getClass().getSimpleName(),
format("Method %s of Type %s has too many parameters",
method.getName(),
method.getDeclaringClass().getCanonicalName()
)
);
log.warn(format("Method %s of Type %s has too many parameters",
method.getName(), method.getDeclaringClass().getCanonicalName()));
return;
}
if (method.getParameterCount() == 0) {
@ -70,18 +68,11 @@ public class TelegramBotInitializer implements InitializingBean {
method.invoke(bot, session);
return;
}
BotLogger.warn(this.getClass().getSimpleName(),
format("Method %s of Type %s has invalid parameter type",
method.getName(),
method.getDeclaringClass().getCanonicalName()
)
);
log.warn(format("Method %s of Type %s has invalid parameter type",
method.getName(), method.getDeclaringClass().getCanonicalName()));
} catch (InvocationTargetException | IllegalAccessException e) {
BotLogger.error(this.getClass().getSimpleName(),
format("Couldn't invoke Method %s of Type %s",
method.getName(), method.getDeclaringClass().getCanonicalName()
)
);
log.error(format("Couldn't invoke Method %s of Type %s",
method.getName(), method.getDeclaringClass().getCanonicalName()));
}
}

View File

@ -1,10 +1,6 @@
package org.telegram.telegrambots.starter;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
@ -13,13 +9,19 @@ import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.generics.LongPollingBot;
import org.telegram.telegrambots.meta.generics.WebhookBot;
public class TestTelegramBotStarterConfiguration {
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
class TestTelegramBotStarterConfiguration {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MockTelegramBotsApi.class, TelegramBotStarterConfiguration.class));
@Test
public void createMockTelegramBotsApiWithDefaultSettings() {
void createMockTelegramBotsApiWithDefaultSettings() {
this.contextRunner.run((context) -> {
assertThat(context).hasSingleBean(TelegramBotsApi.class);
assertThat(context).hasSingleBean(TelegramBotInitializer.class);
@ -30,7 +32,7 @@ public class TestTelegramBotStarterConfiguration {
}
@Test
public void createOnlyLongPollingBot() {
void createOnlyLongPollingBot() {
this.contextRunner.withUserConfiguration(LongPollingBotConfig.class)
.run((context) -> {
assertThat(context).hasSingleBean(LongPollingBot.class);
@ -44,7 +46,7 @@ public class TestTelegramBotStarterConfiguration {
}
@Test
public void createOnlyWebhookBot() {
void createOnlyWebhookBot() {
this.contextRunner.withUserConfiguration(WebhookBotConfig.class)
.run((context) -> {
assertThat(context).hasSingleBean(WebhookBot.class);
@ -58,7 +60,7 @@ public class TestTelegramBotStarterConfiguration {
}
@Test
public void createLongPoolingBotAndWebhookBot() {
void createLongPoolingBotAndWebhookBot() {
this.contextRunner.withUserConfiguration(LongPollingBotConfig.class, WebhookBotConfig.class)
.run((context) -> {
assertThat(context).hasSingleBean(LongPollingBot.class);

View File

@ -1,7 +1,6 @@
package org.telegram.telegrambots.starter;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
@ -15,9 +14,14 @@ import org.telegram.telegrambots.meta.generics.LongPollingBot;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
public class TestTelegramBotStarterRegistrationHooks {
class TestTelegramBotStarterRegistrationHooks {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MockTelegramBotsApi.class, TelegramBotStarterConfiguration.class));
@ -30,7 +34,7 @@ public class TestTelegramBotStarterRegistrationHooks {
private static final TelegramBotsApi mockTelegramBotsApi = mock(TelegramBotsApi.class);
@Test
public void longPollingBotWithAnnotatedMethodshouldBeCalled() throws TelegramApiRequestException {
void longPollingBotWithAnnotatedMethodshouldBeCalled() throws TelegramApiRequestException {
when(mockTelegramBotsApi.registerBot(any(LongPollingBot.class))).thenReturn(someBotSession);

View File

@ -3,9 +3,14 @@
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.telegram</groupId>
<parent>
<groupId>org.telegram</groupId>
<artifactId>Bots</artifactId>
<version>4.4.0</version>
</parent>
<artifactId>telegrambots</artifactId>
<version>4.3.1</version>
<packaging>jar</packaging>
<name>Telegram Bots</name>
@ -57,15 +62,21 @@
</distributionManagement>
<properties>
<java.version>11</java.version>
<maven.compiler.release>8</maven.compiler.release>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<glassfish.version>2.25.1</glassfish.version>
<glassfish.version>2.29</glassfish.version>
<jerseybundle.version>1.19.3</jerseybundle.version>
<httpcompontents.version>4.5.3</httpcompontents.version>
<httpcompontents.version>4.5.9</httpcompontents.version>
<json.version>20180813</json.version>
<jackson.version>2.9.9</jackson.version>
<jacksonanotation.version>2.9.0</jacksonanotation.version>
<commonio.version>2.5</commonio.version>
<jacksonanotation.version>2.9.9</jacksonanotation.version>
<commonio.version>2.6</commonio.version>
</properties>
<dependencyManagement>
@ -84,7 +95,7 @@
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots-meta</artifactId>
<version>4.3.1</version>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
@ -96,26 +107,26 @@
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${glassfish.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${glassfish.version}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
@ -169,12 +180,6 @@
<version>${glassfish.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -184,10 +189,15 @@
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
@ -201,7 +211,7 @@
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
@ -211,7 +221,7 @@
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<id>clean-project</id>
@ -224,7 +234,7 @@
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<version>3.1.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
@ -243,7 +253,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
@ -255,14 +265,14 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<version>3.1.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
<doclint>none</doclint>
</configuration>
</execution>
</executions>
@ -270,7 +280,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<version>0.8.4</version>
<executions>
<execution>
<goals>
@ -289,7 +299,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<version>3.0.0-M2</version>
<executions>
<execution>
<id>enforce-versions</id>
@ -307,7 +317,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<version>3.1.1</version>
<executions>
<execution>
<id>copy</id>
@ -321,9 +331,10 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>

View File

@ -2,7 +2,6 @@ package org.telegram.telegrambots.bots;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
@ -14,6 +13,7 @@ import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.telegram.telegrambots.facilities.TelegramHttpClientBuilder;
import org.telegram.telegrambots.facilities.filedownloader.TelegramFileDownloader;
import org.telegram.telegrambots.meta.api.methods.BotApiMethod;
import org.telegram.telegrambots.meta.api.methods.groupadministration.SetChatPhoto;
import org.telegram.telegrambots.meta.api.methods.send.*;
@ -36,10 +36,9 @@ import org.telegram.telegrambots.meta.updateshandlers.DownloadFileCallback;
import org.telegram.telegrambots.meta.updateshandlers.SentCallback;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.ExecutorService;
@ -52,7 +51,7 @@ import static org.telegram.telegrambots.Constants.SOCKET_TIMEOUT;
* @version 1.0
* Implementation of all the methods needed to interact with Telegram Servers
*/
@SuppressWarnings({"unused", "WeakerAccess"})
@SuppressWarnings({"unused"})
public abstract class DefaultAbsSender extends AbsSender {
private static final ContentType TEXT_PLAIN_CONTENT_TYPE = ContentType.create("text/plain", StandardCharsets.UTF_8);
@ -61,6 +60,7 @@ public abstract class DefaultAbsSender extends AbsSender {
private final DefaultBotOptions options;
private volatile CloseableHttpClient httpClient;
private volatile RequestConfig requestConfig;
private final TelegramFileDownloader telegramFileDownloader = new TelegramFileDownloader(this::getBotToken);
protected DefaultAbsSender(DefaultBotOptions options) {
super();
@ -109,37 +109,35 @@ public abstract class DefaultAbsSender extends AbsSender {
// Send Requests
public final java.io.File downloadFile(String filePath) throws TelegramApiException {
if(filePath == null || filePath.isEmpty()){
throw new TelegramApiException("Parameter file can not be null");
}
String url = File.getFileUrl(getBotToken(), filePath);
String tempFileName = Long.toString(System.currentTimeMillis());
return downloadToTemporaryFileWrappingExceptions(url, tempFileName);
return telegramFileDownloader.downloadFile(filePath);
}
public final java.io.File downloadFile(File file) throws TelegramApiException {
assertParamNotNull(file, "file");
String url = file.getFileUrl(getBotToken());
String tempFileName = file.getFileId();
return downloadToTemporaryFileWrappingExceptions(url, tempFileName);
return telegramFileDownloader.downloadFile(file);
}
public final java.io.File downloadFile(File file, java.io.File outputFile) throws TelegramApiException {
return telegramFileDownloader.downloadFile(file, outputFile);
}
public final java.io.File downloadFile(String filePath, java.io.File outputFile) throws TelegramApiException {
return telegramFileDownloader.downloadFile(filePath, outputFile);
}
public final void downloadFileAsync(String filePath, DownloadFileCallback<String> callback) throws TelegramApiException {
if(filePath == null || filePath.isEmpty()){
throw new TelegramApiException("Parameter filePath can not be null");
}
assertParamNotNull(callback, "callback");
String url = File.getFileUrl(getBotToken(), filePath);
String tempFileName = Long.toString(System.currentTimeMillis());
exe.submit(getDownloadFileAsyncJob(filePath, callback, url, tempFileName));
telegramFileDownloader.downloadFileAsync(filePath, callback);
}
public final void downloadFileAsync(File file, DownloadFileCallback<File> callback) throws TelegramApiException {
assertParamNotNull(file, "file");
assertParamNotNull(callback, "callback");
String url = file.getFileUrl(getBotToken());
String tempFileName = file.getFileId();
exe.submit(getDownloadFileAsyncJob(file, callback, url, tempFileName));
telegramFileDownloader.downloadFileAsync(file, callback);
}
public final InputStream downloadFileAsStream(String filePath) throws TelegramApiException {
return telegramFileDownloader.downloadFileAsStream(filePath);
}
public final InputStream downloadFileAsStream(File file) throws TelegramApiException {
return telegramFileDownloader.downloadFileAsStream(file);
}
// Specific Send Requests
@ -720,38 +718,6 @@ public abstract class DefaultAbsSender extends AbsSender {
}
}
private <T> Runnable getDownloadFileAsyncJob(T fileIdentifier, DownloadFileCallback<T> callback, String url, String tempFileName) {
//noinspection Convert2Lambda
return new Runnable() {
@Override
public void run() {
try {
callback.onResult(fileIdentifier, downloadToTemporaryFile(url, tempFileName));
} catch (MalformedURLException e) {
callback.onException(fileIdentifier, new TelegramApiException("Wrong url for file: " + url));
} catch (IOException e) {
callback.onException(fileIdentifier, new TelegramApiRequestException("Error downloading the file", e));
}
}
};
}
private java.io.File downloadToTemporaryFileWrappingExceptions(String url, String tempFileName) throws TelegramApiException {
try {
return downloadToTemporaryFile(url, tempFileName);
} catch (MalformedURLException e) {
throw new TelegramApiException("Wrong url for file: " + url);
} catch (IOException e) {
throw new TelegramApiRequestException("Error downloading the file", e);
}
}
private java.io.File downloadToTemporaryFile(String url, String tempFileName) throws IOException {
java.io.File output = java.io.File.createTempFile(tempFileName, ".tmp");
FileUtils.copyURLToFile(new URL(url), output);
return output;
}
private <T extends Serializable, Method extends BotApiMethod<T>> String sendMethodRequest(Method method) throws TelegramApiValidationException, IOException {
method.validate();
String url = getBaseUrl() + method.getMethod();

View File

@ -0,0 +1,11 @@
package org.telegram.telegrambots.facilities.filedownloader;
/**
* Runtime Exception to wrap Exceptions thrown during file download
*/
@SuppressWarnings("WeakerAccess")
public class DownloadFileException extends RuntimeException {
public DownloadFileException(final String message, final Throwable e) {
super(message, e);
}
}

View File

@ -0,0 +1,172 @@
package org.telegram.telegrambots.facilities.filedownloader;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.telegram.telegrambots.meta.api.objects.File;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.updateshandlers.DownloadFileCallback;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.function.Supplier;
import static org.apache.commons.io.FileUtils.copyInputStreamToFile;
import static org.apache.http.HttpStatus.SC_OK;
/**
* Wraps the file downloading code into one class.
* @author Chase22
* @version 1.0
*/
public class TelegramFileDownloader {
private final HttpClient httpClient;
private final Supplier<String> botTokenSupplier;
public TelegramFileDownloader(final Supplier<String> botTokenSupplier) {
this.botTokenSupplier = botTokenSupplier;
httpClient = HttpClients.createDefault();
}
public TelegramFileDownloader(final HttpClient httpClient, final Supplier<String> botTokenSupplier) {
this.httpClient = httpClient;
this.botTokenSupplier = botTokenSupplier;
}
public final java.io.File downloadFile(String filePath) throws TelegramApiException {
String tempFileName = Long.toString(System.currentTimeMillis());
return downloadFile(filePath, getTempFile(tempFileName));
}
public final java.io.File downloadFile(File file) throws TelegramApiException {
return downloadFile(file, getTempFile(file.getFileId()));
}
public final java.io.File downloadFile(File file, java.io.File outputFile) throws TelegramApiException {
if (file == null) {
throw new TelegramApiException("Parameter file can not be null");
}
String url = file.getFileUrl(botTokenSupplier.get());
return downloadToFile(url, outputFile);
}
public final java.io.File downloadFile(String filePath, java.io.File outputFile) throws TelegramApiException {
if (filePath == null || filePath.isEmpty()) {
throw new TelegramApiException("Parameter file can not be null");
}
String url = File.getFileUrl(botTokenSupplier.get(), filePath);
return downloadToFile(url, outputFile);
}
public final InputStream downloadFileAsStream(String filePath) throws TelegramApiException {
try {
return getFileDownloadStreamFuture(File.getFileUrl(botTokenSupplier.get(), filePath)).get();
} catch (InterruptedException e) {
throw new TelegramApiException("Error downloading file", e);
} catch (ExecutionException e) {
throw new TelegramApiException("Error downloading file", e.getCause());
}
}
public final InputStream downloadFileAsStream(File file) throws TelegramApiException {
try {
return getFileDownloadStreamFuture(file.getFileUrl(botTokenSupplier.get())).get();
} catch (InterruptedException e) {
throw new TelegramApiException("Error downloading file", e);
} catch (ExecutionException e) {
throw new TelegramApiException("Error downloading file", e.getCause());
}
}
public final void downloadFileAsync(String filePath, DownloadFileCallback<String> callback) throws TelegramApiException {
if (filePath == null || filePath.isEmpty()) {
throw new TelegramApiException("Parameter filePath can not be null");
}
if (callback == null) {
throw new TelegramApiException("Parameter callback can not be null");
}
String url = File.getFileUrl(botTokenSupplier.get(), filePath);
String tempFileName = Long.toString(System.currentTimeMillis());
getFileDownloadFuture(url, getTempFile(tempFileName))
.thenAccept(output -> callback.onResult(filePath, output))
.exceptionally(throwable -> {
// Unwrap java.util.concurrent.CompletionException
if (throwable instanceof CompletionException) {
callback.onException(filePath, new TelegramApiException("Error downloading file", throwable.getCause()));
} else {
callback.onException(filePath, new TelegramApiException("Error downloading file", throwable));
}
return null;
});
}
public final void downloadFileAsync(File file, DownloadFileCallback<File> callback) throws TelegramApiException {
if (file == null) {
throw new TelegramApiException("Parameter file can not be null");
}
if (callback == null) {
throw new TelegramApiException("Parameter callback can not be null");
}
String url = file.getFileUrl(botTokenSupplier.get());
String tempFileName = file.getFileId();
getFileDownloadFuture(url, getTempFile(tempFileName))
.thenAccept(output -> callback.onResult(file, output))
.exceptionally(throwable -> {
callback.onException(file, new TelegramApiException("Error downloading file", throwable));
return null;
});
}
private java.io.File getTempFile(String tempFileName) throws TelegramApiException {
try {
return java.io.File.createTempFile(tempFileName, ".tmp");
} catch (IOException e) {
throw new TelegramApiException("Error downloading file", e);
}
}
private java.io.File downloadToFile(String url, java.io.File output) throws TelegramApiException {
try {
return getFileDownloadFuture(url, output).get();
} catch (InterruptedException e) {
throw new TelegramApiException("File Download got interrupted", e);
} catch (ExecutionException e) {
throw new TelegramApiException("Error downloading file", e.getCause());
}
}
private CompletableFuture<java.io.File> getFileDownloadFuture(String url, java.io.File output) {
return getFileDownloadStreamFuture(url).thenApply(stream -> {
try {
copyInputStreamToFile(stream, output);
return output;
} catch (IOException e) {
throw new DownloadFileException("Error writing downloaded file", e);
}
});
}
private CompletableFuture<InputStream> getFileDownloadStreamFuture(final String url) {
return CompletableFuture.supplyAsync(() -> {
try {
HttpResponse response = httpClient.execute(new HttpGet(url));
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == SC_OK) {
return response.getEntity().getContent();
} else {
throw new TelegramApiException("Unexpected Status code while downloading file. Expected 200 got " + statusCode);
}
} catch (IOException | TelegramApiException e) {
throw new DownloadFileException("Error downloading file", e);
}
});
}
}

View File

@ -4,7 +4,6 @@ package org.telegram.telegrambots.facilities.proxysocketfactorys;
import org.apache.http.HttpHost;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.protocol.HttpContext;
import sun.net.SocksProxy;
import java.io.IOException;
import java.net.InetSocketAddress;
@ -14,10 +13,9 @@ import java.net.Socket;
public class SocksConnectionSocketFactory extends PlainConnectionSocketFactory {
@Override
public Socket createSocket(final HttpContext context) throws IOException {
public Socket createSocket(final HttpContext context) {
InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socketAddress");
int socksVersion = (Integer) context.getAttribute("socksVersion");
Proxy proxy = SocksProxy.create(socksaddr, socksVersion);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr);
return new Socket(proxy);
}

View File

@ -4,14 +4,14 @@ import org.apache.http.HttpHost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.protocol.HttpContext;
import sun.net.SocksProxy;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import javax.net.ssl.SSLContext;
public class SocksSSLConnectionSocketFactory extends SSLConnectionSocketFactory {
@ -20,10 +20,9 @@ public class SocksSSLConnectionSocketFactory extends SSLConnectionSocketFactory
}
@Override
public Socket createSocket(final HttpContext context) throws IOException {
public Socket createSocket(final HttpContext context) {
InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socketAddress");
int socksVersion = (Integer) context.getAttribute("socksVersion");
Proxy proxy = SocksProxy.create(socksaddr, socksVersion);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr);
return new Socket(proxy);
}

View File

@ -11,6 +11,8 @@ import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONException;
import org.telegram.telegrambots.meta.ApiConstants;
import org.telegram.telegrambots.meta.api.methods.updates.GetUpdates;
@ -19,7 +21,6 @@ import org.telegram.telegrambots.bots.DefaultBotOptions;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.facilities.TelegramHttpClientBuilder;
import org.telegram.telegrambots.meta.generics.*;
import org.telegram.telegrambots.meta.logging.BotLogger;
import java.io.IOException;
import java.io.InvalidObjectException;
@ -39,7 +40,7 @@ import static org.telegram.telegrambots.Constants.SOCKET_TIMEOUT;
* Thread to request updates with active wait
*/
public class DefaultBotSession implements BotSession {
private static final String LOGTAG = "BOTSESSION";
private static final Logger log = LogManager.getLogger(DefaultBotSession.class);
private AtomicBoolean running = new AtomicBoolean(false);
@ -170,7 +171,7 @@ public class DefaultBotSession implements BotSession {
try {
httpclient.close();
} catch (IOException e) {
BotLogger.warn(LOGTAG, e);
log.warn(e.getLocalizedMessage(), e);
}
}
super.interrupt();
@ -203,10 +204,10 @@ public class DefaultBotSession implements BotSession {
if (!running.get()) {
receivedUpdates.clear();
}
BotLogger.debug(LOGTAG, e);
log.debug(e.getLocalizedMessage(), e);
interrupt();
} catch (Exception global) {
BotLogger.severe(LOGTAG, global);
log.fatal(global.getLocalizedMessage(), global);
try {
synchronized (lock) {
lock.wait(exponentialBackOff.nextBackOffMillis());
@ -215,14 +216,14 @@ public class DefaultBotSession implements BotSession {
if (!running.get()) {
receivedUpdates.clear();
}
BotLogger.debug(LOGTAG, e);
log.debug(e.getLocalizedMessage(), e);
interrupt();
}
}
}
}
}
BotLogger.debug(LOGTAG, "Reader thread has being closed");
log.debug("Reader thread has being closed");
}
private List<Update> getUpdatesFromServer() throws IOException {
@ -248,7 +249,7 @@ public class DefaultBotSession implements BotSession {
String responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
if (response.getStatusLine().getStatusCode() >= 500) {
BotLogger.warn(LOGTAG, responseContent);
log.warn(responseContent);
synchronized (lock) {
lock.wait(500);
}
@ -258,15 +259,15 @@ public class DefaultBotSession implements BotSession {
exponentialBackOff.reset();
return updates;
} catch (JSONException e) {
BotLogger.severe(responseContent, LOGTAG, e);
log.error("Error deserializing update: " + responseContent, e);
}
}
} catch (SocketException | InvalidObjectException | TelegramApiRequestException e) {
BotLogger.severe(LOGTAG, e);
log.fatal(e.getLocalizedMessage(), e);
} catch (SocketTimeoutException e) {
BotLogger.fine(LOGTAG, e);
log.info(e.getLocalizedMessage(), e);
} catch (InterruptedException e) {
BotLogger.fine(LOGTAG, e);
log.info(e.getLocalizedMessage(), e);
interrupt();
}
return Collections.emptyList();
@ -305,13 +306,13 @@ public class DefaultBotSession implements BotSession {
}
callback.onUpdatesReceived(updates);
} catch (InterruptedException e) {
BotLogger.debug(LOGTAG, e);
log.debug(e.getLocalizedMessage(), e);
interrupt();
} catch (Exception e) {
BotLogger.severe(LOGTAG, e);
log.fatal(e.getLocalizedMessage(), e);
}
}
BotLogger.debug(LOGTAG, "Handler thread has being closed");
log.debug("Handler thread has being closed");
}
}
}

View File

@ -70,22 +70,22 @@ import com.google.common.base.Preconditions;
*/
public class ExponentialBackOff {
/** The default initial interval value in milliseconds (0.5 seconds). */
public static final int DEFAULT_INITIAL_INTERVAL_MILLIS = 500;
private static final int DEFAULT_INITIAL_INTERVAL_MILLIS = 500;
/**
* The default randomization factor (0.5 which results in a random period ranging between 50%
* below and 50% above the retry interval).
*/
public static final double DEFAULT_RANDOMIZATION_FACTOR = 0.5;
private static final double DEFAULT_RANDOMIZATION_FACTOR = 0.5;
/** The default multiplier value (1.5 which is 50% increase per back off). */
public static final double DEFAULT_MULTIPLIER = 1.5;
private static final double DEFAULT_MULTIPLIER = 1.5;
/** The default maximum back off time in milliseconds (15 minutes). */
public static final int DEFAULT_MAX_INTERVAL_MILLIS = 30000;
private static final int DEFAULT_MAX_INTERVAL_MILLIS = 30000;
/** The default maximum elapsed time in milliseconds (60 minutes). */
public static final int DEFAULT_MAX_ELAPSED_TIME_MILLIS = 3600000;
private static final int DEFAULT_MAX_ELAPSED_TIME_MILLIS = 3600000;
/** The current retry interval in milliseconds. */
private int currentIntervalMillis;
@ -116,7 +116,7 @@ public class ExponentialBackOff {
* The system time in nanoseconds. It is calculated when an ExponentialBackOffPolicy instance is
* created and is reset when {@link #reset()} is called.
*/
long startTimeNanos;
private long startTimeNanos;
/**
* The maximum elapsed time after instantiating {@link ExponentialBackOff} or calling
@ -139,14 +139,14 @@ public class ExponentialBackOff {
* <li>{@code maxElapsedTimeMillis} defaults in {@link #DEFAULT_MAX_ELAPSED_TIME_MILLIS}</li>
* </ul>
*/
public ExponentialBackOff() {
ExponentialBackOff() {
this(new Builder());
}
/**
* @param builder builder
*/
protected ExponentialBackOff(Builder builder) {
private ExponentialBackOff(Builder builder) {
initialIntervalMillis = builder.initialIntervalMillis;
randomizationFactor = builder.randomizationFactor;
multiplier = builder.multiplier;
@ -161,7 +161,7 @@ public class ExponentialBackOff {
}
/** Sets the interval back to the initial retry interval and restarts the timer. */
public final void reset() {
final void reset() {
currentIntervalMillis = initialIntervalMillis;
startTimeNanos = nanoTime();
}
@ -178,7 +178,7 @@ public class ExponentialBackOff {
* Subclasses may override if a different algorithm is required.
* </p>
*/
public long nextBackOffMillis() {
long nextBackOffMillis() {
// Make sure we have not gone over the maximum elapsed time.
if (getElapsedTimeMillis() > maxElapsedTimeMillis) {
return maxElapsedTimeMillis;
@ -193,7 +193,7 @@ public class ExponentialBackOff {
* Returns a random value from the interval [randomizationFactor * currentInterval,
* randomizationFactor * currentInterval].
*/
static int getRandomValueFromInterval(
private static int getRandomValueFromInterval(
double randomizationFactor, double random, int currentIntervalMillis) {
double delta = randomizationFactor * currentIntervalMillis;
double minInterval = currentIntervalMillis - delta;
@ -201,60 +201,7 @@ public class ExponentialBackOff {
// Get a random value from the range [minInterval, maxInterval].
// The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then
// we want a 33% chance for selecting either 1, 2 or 3.
int randomValue = (int) (minInterval + (random * (maxInterval - minInterval + 1)));
return randomValue;
}
/** Returns the initial retry interval in milliseconds. */
public final int getInitialIntervalMillis() {
return initialIntervalMillis;
}
/**
* Returns the randomization factor to use for creating a range around the retry interval.
*
* <p>
* A randomization factor of 0.5 results in a random period ranging between 50% below and 50%
* above the retry interval.
* </p>
*/
public final double getRandomizationFactor() {
return randomizationFactor;
}
/**
* Returns the current retry interval in milliseconds.
*/
public final int getCurrentIntervalMillis() {
return currentIntervalMillis;
}
/**
* Returns the value to multiply the current interval with for each retry attempt.
*/
public final double getMultiplier() {
return multiplier;
}
/**
* Returns the maximum value of the back off period in milliseconds. Once the current interval
* reaches this value it stops increasing.
*/
public final int getMaxIntervalMillis() {
return maxIntervalMillis;
}
/**
* Returns the maximum elapsed time in milliseconds.
*
* <p>
* If the time elapsed since an {@link ExponentialBackOff} instance is created goes past the
* max_elapsed_time then the method {@link #nextBackOffMillis()} starts returning
* this value. The elapsed time can be reset by calling {@link #reset()}.
* </p>
*/
public final int getMaxElapsedTimeMillis() {
return maxElapsedTimeMillis;
return (int) (minInterval + (random * (maxInterval - minInterval + 1)));
}
/**
@ -265,7 +212,7 @@ public class ExponentialBackOff {
* The elapsed time is computed using {@link System#nanoTime()}.
* </p>
*/
public final long getElapsedTimeMillis() {
private long getElapsedTimeMillis() {
return (nanoTime() - startTimeNanos) / 1000000;
}
@ -327,152 +274,12 @@ public class ExponentialBackOff {
*/
int maxElapsedTimeMillis = DEFAULT_MAX_ELAPSED_TIME_MILLIS;
public Builder() {
Builder() {
}
/** Builds a new instance of {@link ExponentialBackOff}. */
public ExponentialBackOff build() {
return new ExponentialBackOff(this);
}
/**
* Returns the initial retry interval in milliseconds. The default value is
* {@link #DEFAULT_INITIAL_INTERVAL_MILLIS}.
*/
public final int getInitialIntervalMillis() {
return initialIntervalMillis;
}
/**
* Sets the initial retry interval in milliseconds. The default value is
* {@link #DEFAULT_INITIAL_INTERVAL_MILLIS}. Must be {@code > 0}.
*
* <p>
* Overriding is only supported for the purpose of calling the super implementation and changing
* the return type, but nothing else.
* </p>
*/
public Builder setInitialIntervalMillis(int initialIntervalMillis) {
this.initialIntervalMillis = initialIntervalMillis;
return this;
}
/**
* Returns the randomization factor to use for creating a range around the retry interval. The
* default value is {@link #DEFAULT_RANDOMIZATION_FACTOR}.
*
* <p>
* A randomization factor of 0.5 results in a random period ranging between 50% below and 50%
* above the retry interval.
* </p>
*
* <p>
* Overriding is only supported for the purpose of calling the super implementation and changing
* the return type, but nothing else.
* </p>
*/
public final double getRandomizationFactor() {
return randomizationFactor;
}
/**
* Sets the randomization factor to use for creating a range around the retry interval. The
* default value is {@link #DEFAULT_RANDOMIZATION_FACTOR}. Must fall in the range
* {@code 0 <= randomizationFactor < 1}.
*
* <p>
* A randomization factor of 0.5 results in a random period ranging between 50% below and 50%
* above the retry interval.
* </p>
*
* <p>
* Overriding is only supported for the purpose of calling the super implementation and changing
* the return type, but nothing else.
* </p>
*/
public Builder setRandomizationFactor(double randomizationFactor) {
this.randomizationFactor = randomizationFactor;
return this;
}
/**
* Returns the value to multiply the current interval with for each retry attempt. The default
* value is {@link #DEFAULT_MULTIPLIER}.
*/
public final double getMultiplier() {
return multiplier;
}
/**
* Sets the value to multiply the current interval with for each retry attempt. The default
* value is {@link #DEFAULT_MULTIPLIER}. Must be {@code >= 1}.
*
* <p>
* Overriding is only supported for the purpose of calling the super implementation and changing
* the return type, but nothing else.
* </p>
*/
public Builder setMultiplier(double multiplier) {
this.multiplier = multiplier;
return this;
}
/**
* Returns the maximum value of the back off period in milliseconds. Once the current interval
* reaches this value it stops increasing. The default value is
* {@link #DEFAULT_MAX_INTERVAL_MILLIS}. Must be {@code >= initialInterval}.
*/
public final int getMaxIntervalMillis() {
return maxIntervalMillis;
}
/**
* Sets the maximum value of the back off period in milliseconds. Once the current interval
* reaches this value it stops increasing. The default value is
* {@link #DEFAULT_MAX_INTERVAL_MILLIS}.
*
* <p>
* Overriding is only supported for the purpose of calling the super implementation and changing
* the return type, but nothing else.
* </p>
*/
public Builder setMaxIntervalMillis(int maxIntervalMillis) {
this.maxIntervalMillis = maxIntervalMillis;
return this;
}
/**
* Returns the maximum elapsed time in milliseconds. The default value is
* {@link #DEFAULT_MAX_ELAPSED_TIME_MILLIS}.
*
* <p>
* If the time elapsed since an {@link ExponentialBackOff} instance is created goes past the
* max_elapsed_time then the method {@link #nextBackOffMillis()} starts returning
* this value. The elapsed time can be reset by calling {@link #reset()}.
* </p>
*/
public final int getMaxElapsedTimeMillis() {
return maxElapsedTimeMillis;
}
/**
* Sets the maximum elapsed time in milliseconds. The default value is
* {@link #DEFAULT_MAX_ELAPSED_TIME_MILLIS}. Must be {@code > 0}.
*
* <p>
* If the time elapsed since an {@link ExponentialBackOff} instance is created goes past the
* max_elapsed_time then the method {@link #nextBackOffMillis()} starts returning
* this value. The elapsed time can be reset by calling {@link #reset()}.
* </p>
*
* <p>
* Overriding is only supported for the purpose of calling the super implementation and changing
* the return type, but nothing else.
* </p>
*/
public Builder setMaxElapsedTimeMillis(int maxElapsedTimeMillis) {
this.maxElapsedTimeMillis = maxElapsedTimeMillis;
return this;
}
}
}

View File

@ -1,12 +1,11 @@
package org.telegram.telegrambots.updatesreceivers;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.telegram.telegrambots.meta.api.methods.BotApiMethod;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
import org.telegram.telegrambots.meta.generics.WebhookBot;
import org.telegram.telegrambots.meta.logging.BotLogger;
import java.util.concurrent.ConcurrentHashMap;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@ -16,15 +15,16 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Ruben Bermudez
* @version 1.0
* @brief Rest api to for webhook callback function
* @date 20 of June of 2015
* Rest api to for webhook callback function
*/
@Path("callback")
public class RestApi {
private static final Logger log = LogManager.getLogger(RestApi.class);
private final ConcurrentHashMap<String, WebhookBot> callbacks = new ConcurrentHashMap<>();
@ -50,7 +50,7 @@ public class RestApi {
}
return Response.ok(response).build();
} catch (TelegramApiValidationException e) {
BotLogger.severe("RESTAPI", e);
log.error(e.getLocalizedMessage(), e);
return Response.serverError().build();
}
}

View File

@ -43,7 +43,7 @@ public final class WebhookUtils {
builder.addTextBody(SetWebhook.MAXCONNECTIONS_FIELD, botOptions.getMaxWebhookConnections().toString());
}
if (botOptions.getAllowedUpdates() != null) {
builder.addTextBody(SetWebhook.ALLOWEDUPDATES_FIELD, new JSONArray(botOptions.getMaxWebhookConnections()).toString());
builder.addTextBody(SetWebhook.ALLOWEDUPDATES_FIELD, new JSONArray(botOptions.getAllowedUpdates()).toString());
}
if (publicCertificatePath != null) {
File certificate = new File(publicCertificatePath);

View File

@ -0,0 +1,115 @@
package org.telegram.telegrambots.test;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.message.BasicStatusLine;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.telegram.telegrambots.facilities.filedownloader.TelegramFileDownloader;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.updateshandlers.DownloadFileCallback;
import java.io.File;
import java.io.IOException;
import java.util.function.Supplier;
import static java.nio.charset.Charset.defaultCharset;
import static org.apache.commons.io.FileUtils.readFileToString;
import static org.apache.commons.io.IOUtils.toInputStream;
import static org.apache.http.HttpVersion.HTTP_1_1;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class TelegramFileDownloaderTest {
private TelegramFileDownloader telegramFileDownloader;
@Mock
private DownloadFileCallback<String> downloadFileCallbackMock;
@Mock
private HttpClient httpClientMock;
@Mock
private HttpResponse httpResponseMock;
@Mock
private HttpEntity httpEntityMock;
private Supplier<String> tokenSupplierMock = () -> "someToken";
@BeforeEach
void setup() throws IOException {
when(httpResponseMock.getStatusLine()).thenReturn(new BasicStatusLine(HTTP_1_1, 200, "emptyString"));
when(httpResponseMock.getEntity()).thenReturn(httpEntityMock);
when(httpEntityMock.getContent()).thenReturn(toInputStream("Some File Content", defaultCharset()));
when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock);
telegramFileDownloader = new TelegramFileDownloader(httpClientMock, tokenSupplierMock);
}
@Test
void testFileDownload() throws TelegramApiException, IOException {
File returnFile = telegramFileDownloader.downloadFile("someFilePath");
String content = readFileToString(returnFile, defaultCharset());
assertEquals("Some File Content", content);
}
@Test
void testDownloadException() {
when(httpResponseMock.getStatusLine()).thenReturn(new BasicStatusLine(HTTP_1_1, 500, "emptyString"));
Assertions.assertThrows(TelegramApiException.class,
() -> telegramFileDownloader.downloadFile("someFilePath"));
}
@Test
void testAsyncDownload() throws TelegramApiException, IOException {
final ArgumentCaptor<File> fileArgumentCaptor = ArgumentCaptor.forClass(File.class);
telegramFileDownloader.downloadFileAsync("someFilePath", downloadFileCallbackMock);
verify(downloadFileCallbackMock, timeout(100)
.times(1))
.onResult(any(), fileArgumentCaptor.capture());
String content = readFileToString(fileArgumentCaptor.getValue(), defaultCharset());
assertEquals("Some File Content", content);
}
@Test
void testAsyncException() throws TelegramApiException {
final ArgumentCaptor<Exception> exceptionArgumentCaptor = ArgumentCaptor.forClass(Exception.class);
when(httpResponseMock.getStatusLine()).thenReturn(new BasicStatusLine(HTTP_1_1, 500, "emptyString"));
telegramFileDownloader.downloadFileAsync("someFilePath", downloadFileCallbackMock);
verify(downloadFileCallbackMock, timeout(100)
.times(1))
.onException(any(), exceptionArgumentCaptor.capture());
Exception e = exceptionArgumentCaptor.getValue();
assertThat(e, instanceOf(TelegramApiException.class));
assertEquals(e.getCause().getCause().getMessage(), "Unexpected Status code while downloading file. Expected 200 got 500");
}
}

View File

@ -2,23 +2,23 @@ package org.telegram.telegrambots.test;
import org.junit.Test;
import org.mockito.Mockito;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.bots.DefaultBotOptions;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
public class TelegramLongPollingBotTest {
@Test
public void testOnUpdateReceived() throws Exception {
public void testOnUpdateReceived() {
TelegramLongPollingBot bot = Mockito.mock(TelegramLongPollingBot.class);
Mockito.doCallRealMethod().when(bot).onUpdatesReceived(any());
Update update1 = new Update();

View File

@ -11,10 +11,9 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.bots.DefaultBotOptions;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.generics.LongPollingBot;
import org.telegram.telegrambots.test.Fakes.FakeLongPollingBot;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
@ -22,17 +21,18 @@ import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
import static org.mockito.ArgumentMatchers.any;
/**
* @author Ruben Bermudez
* @version 1.0
* @brief Test for DefaultBotSession
* Test for DefaultBotSession
*/
public class TestDefaultBotSession {
DefaultBotSession session;
private DefaultBotSession session;
@Before
public void setUp() throws Exception {
@ -40,14 +40,14 @@ public class TestDefaultBotSession {
}
@After
public void tearDown() throws Exception {
public void tearDown() {
if (session != null && session.isRunning()) {
session.stop();
}
}
@Test
public void TestDefaultBotSessionIsNotRunningWhenCreated() throws Exception {
public void TestDefaultBotSessionIsNotRunningWhenCreated() {
Assert.assertFalse(session.isRunning());
}
@ -96,7 +96,7 @@ public class TestDefaultBotSession {
session.setUpdatesSupplier(createFakeUpdatesSupplier(flag, updates));
session.start();
Thread.sleep(1000);
Mockito.verify(bot, Mockito.never()).onUpdateReceived(Matchers.any());
Mockito.verify(bot, Mockito.never()).onUpdateReceived(any());
flag.compareAndSet(0, 1);
Thread.sleep(1000);
Mockito.verify(bot).onUpdateReceived(updates[0]);
@ -124,7 +124,7 @@ public class TestDefaultBotSession {
session.setUpdatesSupplier(createFakeUpdatesSupplier(flag, updates));
session.start();
Thread.sleep(1000);
Mockito.verify(bot, Mockito.never()).onUpdateReceived(Matchers.any());
Mockito.verify(bot, Mockito.never()).onUpdateReceived(any());
flag.compareAndSet(0, 1);
Thread.sleep(1000);
Mockito.verify(bot).onUpdatesReceived(Arrays.asList(updates[0], updates[1]));
@ -146,18 +146,15 @@ public class TestDefaultBotSession {
}
private DefaultBotSession.UpdatesSupplier createFakeUpdatesSupplier(AtomicInteger flag, Update[] updates) {
return new DefaultBotSession.UpdatesSupplier() {
@Override
public List<Update> getUpdates() throws InterruptedException, Exception {
if (flag.compareAndSet(1, 2)) {
return Arrays.asList(updates[0], updates[1]);
} else if (flag.compareAndSet(3, 4)) {
return Arrays.asList(updates[2], updates[3], updates[4]);
} else if (flag.compareAndSet(5, 6)) {
return Arrays.asList(updates[5], updates[6], updates[7], updates[8]);
}
return Collections.emptyList();
return () -> {
if (flag.compareAndSet(1, 2)) {
return Arrays.asList(updates[0], updates[1]);
} else if (flag.compareAndSet(3, 4)) {
return Arrays.asList(updates[2], updates[3], updates[4]);
} else if (flag.compareAndSet(5, 6)) {
return Arrays.asList(updates[5], updates[6], updates[7], updates[8]);
}
return Collections.emptyList();
};
}
@ -172,7 +169,7 @@ public class TestDefaultBotSession {
response.setEntity(new StringEntity("{}"));
HttpClient mockHttpClient = Mockito.mock(HttpClient.class);
Mockito.when(mockHttpClient.execute(Mockito.any(HttpPost.class)))
Mockito.when(mockHttpClient.execute(any(HttpPost.class)))
.thenReturn(response);
DefaultBotSession session = new DefaultBotSession();
session.setCallback(bot);