diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml deleted file mode 100644 index f7367e0..0000000 --- a/.github/workflows/maven.yml +++ /dev/null @@ -1,35 +0,0 @@ -# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven - -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -name: Java CI with Maven - -on: - push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up JDK 11 - uses: actions/setup-java@v3 - with: - java-version: '11' - distribution: 'temurin' - cache: maven - - name: Build with Maven - run: mvn -B package --file pom.xml - - # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive - - name: Update dependency graph - uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 diff --git a/.github/workflows/test_and_pub.yml b/.github/workflows/test_and_pub.yml new file mode 100644 index 0000000..8945c74 --- /dev/null +++ b/.github/workflows/test_and_pub.yml @@ -0,0 +1,56 @@ +name: Docker + +on: + push: + branches: ["master", "dev"] + +env: + REGISTRY: ghcr.io + # github.repository as / + IMAGE_NAME: ${{ github.repository }} + + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + # This is used to complete the identity challenge + # with sigstore/fulcio when running outside of PRs. + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf + + # Login against a Docker registry except on PR + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.gitignore b/.gitignore index 3611940..0f37f52 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,7 @@ build/ ### Custom ### .idea -*.class \ No newline at end of file +*.class + +### Secret ### +/src/main/resources/config.properties diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e64dfc4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM maven:3.8.5-openjdk-17-slim AS build + +COPY src /app/src +COPY pom.xml /app + +RUN mvn -B test -f /app/pom.xml clean package + +FROM eclipse-temurin:17.0.5_8-jre-ubi9-minimal + +COPY --from=build /app/target/MailgramBot-1.0-SNAPSHOT-jar-with-dependencies.jar /app/bot.jar +ENTRYPOINT ["java", "-jar", "/app/bot.jar"] +CMD ["/app/config.properties"] \ No newline at end of file diff --git a/README.md b/README.md index f7096ee..7fa24f8 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,16 @@ # MailgramBot - +snippet.png + +[![Telegram](https://badgen.net/badge/icon/telegram?icon=telegram&label=open)](https://t.me/CoolMailgramBot) +![Build status](https://github.com/WoodieDudy/MailgramBot/actions/workflows/test_and_pub.yml/badge.svg?branch=dev) ### MailgramBot is a email client for Telegram Tasks: 1. Implemented a conversation with the user in the console, configured the processing of incorrect commands and switching "states" (states) necessary to determine the currently available tools of the bot. +2. States replaced by command classes for each command. Added base mail functional. +3. Bot moved to Telegram (using Activity Bot) with buttons. Add Ci/CD. # About. Java-based Telegram bot that provides the functionality of receiving emails. @@ -13,15 +18,25 @@ If you want to know more about options you can use /help. ## Clone the repo ```sh -$ git clone https://github.com/WoodieDudy/MailgramBot +git clone https://github.com/WoodieDudy/MailgramBot +cd MailgramBot ``` ### Running test with maven ```sh -$ mvn clean test +mvn clean test ``` ### Running locally with maven ```sh -$ mvn clean compile exec:java +# Build +mvn -B clean package +# Run +java -jar target/mailgrambot-1.0-SNAPSHOT-jar-with-dependencies.jar src/main/resources/config.properties ``` + +### Running with docker +```sh +docker build -t mailgrambot . +docker run -it mailgrambot -v /path/to/config:/app/config.properties +``` \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8a29939..4c48cbf 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,11 @@ jsoup 1.15.3 + + org.telegram + telegrambots-abilities + 6.3.0 + @@ -75,6 +80,16 @@ maven-surefire-plugin 2.22.0 + + maven-jar-plugin + 3.0.2 + + + default-jar + none + + + \ No newline at end of file diff --git a/src/main/java/org/bot/App.java b/src/main/java/org/bot/App.java index 14cf3fe..0d58949 100644 --- a/src/main/java/org/bot/App.java +++ b/src/main/java/org/bot/App.java @@ -1,38 +1,34 @@ package org.bot; import org.bot.application.Bot; -import org.bot.domain.commands.AuthCommand; -import org.bot.domain.commands.Command; -import org.bot.domain.commands.HelpCommand; -import org.bot.domain.commands.LettersListCommand; import org.bot.infrastructure.JakartaMailInterface; -import org.bot.infrastructure.interfaces.BotInterface; -import org.bot.application.BotLogic; -import org.bot.infrastructure.ConsoleBotInterface; +import org.bot.infrastructure.PropertyParser; import org.bot.infrastructure.interfaces.MailInterface; +import org.telegram.telegrambots.meta.TelegramBotsApi; +import org.telegram.telegrambots.meta.exceptions.TelegramApiException; +import org.telegram.telegrambots.updatesreceivers.DefaultBotSession; + +import java.io.IOException; +import java.util.Properties; -import java.time.Duration; public class App { - public static void main(String[] args) { - BotInterface botInterface = new ConsoleBotInterface(); + public static void main(String[] args) throws IOException { MailInterface mailInterface = new JakartaMailInterface(); - Command[] commands = createCommands(mailInterface); - - BotLogic botLogic = new BotLogic(commands); - Bot bot = new Bot(botInterface, botLogic); - bot.run(); - } + // src/main/resources/config.properties + Properties properties = PropertyParser.parseProperties(args[0]); - private static Command[] createCommands(MailInterface mailInterface) { // TODO: send messages in commands - HelpCommand helpCommand = new HelpCommand(); - Command[] commands = { - new AuthCommand(mailInterface, Duration.ofDays(1)), - new LettersListCommand(mailInterface), - helpCommand - }; - helpCommand.generateHelpMessage(commands); - return commands; + Bot bot = new Bot( + mailInterface, + properties.getProperty("bot.token"), + properties.getProperty("bot.name") + ); + try { + TelegramBotsApi telegramBotsApi = new TelegramBotsApi(DefaultBotSession.class); + telegramBotsApi.registerBot(bot); + } catch (TelegramApiException e) { + e.printStackTrace(); + } } } \ No newline at end of file diff --git a/src/main/java/org/bot/application/Bot.java b/src/main/java/org/bot/application/Bot.java index a47903d..26ed03c 100644 --- a/src/main/java/org/bot/application/Bot.java +++ b/src/main/java/org/bot/application/Bot.java @@ -1,25 +1,199 @@ package org.bot.application; -import org.bot.domain.Message; -import org.bot.infrastructure.interfaces.BotInterface; +import org.bot.domain.User; +import org.bot.domain.UserRepository; +import org.bot.application.commands.AuthCommand; +import org.bot.application.commands.Command; +import org.bot.application.commands.HelpCommand; +import org.bot.application.commands.LettersListCommand; +import org.bot.enums.MessagesTemplates; +import org.bot.infrastructure.TelegramBotInterface; +import org.bot.infrastructure.interfaces.MailInterface; +import org.telegram.abilitybots.api.bot.AbilityBot; +import org.telegram.abilitybots.api.objects.Ability; +import org.telegram.telegrambots.meta.api.methods.botapimethods.BotApiMethodSerializable; +import org.telegram.telegrambots.meta.api.methods.send.SendMessage; +import org.telegram.telegrambots.meta.api.objects.Message; +import org.telegram.telegrambots.meta.api.objects.Update; +import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; -public final class Bot { - private final BotInterface botInterface; - private final BotLogic botLogic; +import java.time.Duration; +import java.util.*; - public Bot(BotInterface botInterface, BotLogic botLogic) { - this.botInterface = botInterface; - this.botLogic = botLogic; +import static org.telegram.abilitybots.api.objects.Locality.ALL; +import static org.telegram.abilitybots.api.objects.Privacy.PUBLIC; + +public final class Bot extends AbilityBot { + private final UserRepository userRepository = new UserRepository(); + private final HashMap commands; + + public Bot(MailInterface mailInterface, String BOT_TOKEN, String BOT_USERNAME) { + super(BOT_TOKEN, BOT_USERNAME); + + this.commands = createCommands(mailInterface); } - public void run() { - Message startMessage = botLogic.getStartMessage(); - botInterface.sendMessage(startMessage); + private static HashMap createCommands(MailInterface mailInterface) { + HelpCommand helpCommand = new HelpCommand(); + Command[] commands = { + new AuthCommand(mailInterface, Duration.ofDays(1)), + new LettersListCommand(mailInterface), + helpCommand + }; + + HashMap commandHashMap = new HashMap<>(); + for (Command command : commands) { + commandHashMap.put(command.getAlias(), command); + } + + helpCommand.generateHelpMessage(commands); + return commandHashMap; + } + + @Override + public long creatorId() { + return 123456789; + } + + @Override + public void onUpdateReceived(Update update) { + super.onUpdateReceived(update); + if (!update.hasCallbackQuery()) { + return; + } + User user = userRepository.getUserById(update.getCallbackQuery().getFrom().getId()); + + String callbackData = update.getCallbackQuery().getData(); + String[] callbackDataParts = callbackData.split(" "); + String commandAlias = callbackDataParts[0]; + String fromMessageId = callbackDataParts[1]; + if (commandAlias.equals("letters")) { + user.setTempEmail(callbackDataParts[2]); + + List buttons = new ArrayList<>(); + for (int lettersNumber : new int[]{1, 2, 4}) { + InlineKeyboardButton button = new InlineKeyboardButton(String.valueOf(lettersNumber)); + button.setCallbackData("chooseNum " + fromMessageId + " " + lettersNumber); + buttons.add(button); + } + + org.bot.domain.Message messageToEdit = new org.bot.domain.Message( + "Выберите количество писем", + Integer.parseInt(fromMessageId), + update.getCallbackQuery().getFrom().getId(), + buttons + ); + + List executable = TelegramBotInterface.editMessage(messageToEdit); + + for (BotApiMethodSerializable botApiMethodSerializable : executable) { + silent.execute(botApiMethodSerializable); + } + } else if (commandAlias.equals("chooseNum")) { + List args = Arrays.asList(user.getTempEmail(), callbackDataParts[2]); + sendAll(commands.get("letters").execute(user, args), update.getCallbackQuery().getFrom().getId()); + } + } + + public Ability start() { + return Ability + .builder() + .name("start") + .info("Send start message") + .locality(ALL) + .privacy(PUBLIC) + .action(ctx -> silent.send(MessagesTemplates.START_MESSAGE.text, ctx.chatId())) + .build(); + } + + public Ability help() { + String abilityName = "help"; + return Ability + .builder() + .name(abilityName) + .info("Returns help message") + .locality(ALL) + .privacy(PUBLIC) + .action(ctx -> { + User user = userRepository.getUserById(ctx.chatId()); + sendAll(commands.get(abilityName).execute(user, List.of(ctx.arguments())), ctx.chatId()); + }) + .build(); + } + + public Ability auth() { + String abilityName = "auth"; + return Ability + .builder() + .name(abilityName) + .info("Auth user") + .locality(ALL) + .privacy(PUBLIC) + .action(ctx -> { + User user = userRepository.getUserById(ctx.chatId()); + sendAll(commands.get(abilityName).execute(user, List.of(ctx.arguments())), ctx.chatId()); + }) + .build(); + } + + public Ability letters() { + String abilityName = "letters"; + return Ability + .builder() + .name(abilityName) + .info("Prints letters") + .locality(ALL) + .privacy(PUBLIC) + .action(ctx -> { + User user = userRepository.getUserById(ctx.chatId()); + TelegramBotInterface.setBotAction(ctx.chatId()); + List emails = user.getAllEmails(); + if (emails.isEmpty()) { + silent.send(MessagesTemplates.NOT_AUTH_LIST_IS_UNAVAILABLE.text, ctx.chatId()); + return; + } + org.bot.domain.Message message = new org.bot.domain.Message( + MessagesTemplates.CHOOSE_EMAIL.text, + ctx.chatId() + ); + + SendMessage messageToSend = TelegramBotInterface.sendMessage(message); + + Optional sentMessage = silent.execute(messageToSend); + + if (sentMessage.isEmpty()) { + System.out.println("Message is empty"); + return; + } + Integer sentMessageId = sentMessage.get().getMessageId(); + + List buttons = new ArrayList<>(); + for (String email : emails) { + InlineKeyboardButton button = new InlineKeyboardButton(email); + button.setCallbackData("letters " + sentMessageId + " " + email); + buttons.add(button); + } + + org.bot.domain.Message messageToEdit = new org.bot.domain.Message( + sentMessageId, + ctx.chatId(), + buttons + ); + + List executable = TelegramBotInterface.editMessage(messageToEdit); + + for (BotApiMethodSerializable botApiMethodSerializable : executable) { + silent.execute(botApiMethodSerializable); + } + }) + .build(); + } - while (true) { - Message message = botInterface.readMessage(); - Message response = botLogic.createResponse(message); - botInterface.sendMessage(response); + private void sendAll(List messages, Long userId) { + List sendMessageList = TelegramBotInterface.sendMessageList(messages); + for (SendMessage sendMessage : sendMessageList) { + sendMessage.setChatId(userId); + silent.execute(sendMessage); } } } \ No newline at end of file diff --git a/src/main/java/org/bot/application/BotLogic.java b/src/main/java/org/bot/application/BotLogic.java deleted file mode 100644 index 322a5f8..0000000 --- a/src/main/java/org/bot/application/BotLogic.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.bot.application; - -import org.bot.domain.Message; -import org.bot.domain.User; -import org.bot.domain.UserRepository; -import org.bot.domain.commands.Command; -import org.bot.enums.MessagesTemplates; - -import java.util.Arrays; -import java.util.HashMap; - - -public class BotLogic { - private final UserRepository userRepository = new UserRepository(); - private final HashMap commands = new HashMap<>(); - - public BotLogic(Command[] commands) { - for (Command command : commands) { - this.commands.put(command.getAlias(), command); - } - } - - public Message getStartMessage() { - return new Message(MessagesTemplates.START_MESSAGE.text); - } - - public Message createResponse(Message message) { - Integer userID = message.getUserID(); - User user = userRepository.getUserById(userID); - - String[] args = message.getText().split(" "); - - String commandName = args[0]; - args = Arrays.copyOfRange(args, 1, args.length); - - if (commands.containsKey(commandName)) { - return commands.get(commandName).execute(user, args); - } - return new Message(MessagesTemplates.DEFAULT_MESSAGE.text); - } -} diff --git a/src/main/java/org/bot/application/commands/AuthCommand.java b/src/main/java/org/bot/application/commands/AuthCommand.java new file mode 100644 index 0000000..2abf2a3 --- /dev/null +++ b/src/main/java/org/bot/application/commands/AuthCommand.java @@ -0,0 +1,55 @@ +package org.bot.application.commands; + +import org.bot.domain.Mailbox; +import org.bot.domain.Message; +import org.bot.domain.User; +import org.bot.enums.MessagesTemplates; +import org.bot.infrastructure.interfaces.MailInterface; + +import java.time.Duration; +import java.util.List; + +public class AuthCommand extends Command { + private final MailInterface mailInterface; + private final Duration sessionDuration; + + record Args(String email, String password) { + } + + private Args parseArgs(List args) { + if (args.size() != 2) { + throw new IllegalArgumentException("Wrong args number"); + } + String email = args.get(0); + String password = args.get(1); + if (!email.contains("@")) { + throw new IllegalArgumentException("Invalid email"); + } + return new Args(email, password); + } + + public AuthCommand(MailInterface mailInterface, Duration sessionDuration) { + super( + "auth", + " - authenticate to mailbox" + ); + this.mailInterface = mailInterface; + this.sessionDuration = sessionDuration; + } + + public List execute(User user, List args) { + Args parsedArgs; + try { + parsedArgs = parseArgs(args); + } catch (Exception e) { + return List.of(new Message(MessagesTemplates.AUTH_INCORRECT_MESSAGE.text, user.getId())); + } + Mailbox mailbox = new Mailbox(parsedArgs.email(), parsedArgs.password(), sessionDuration); + if (this.mailInterface.isCredentialsCorrect(mailbox)) { + user.addNewMailbox(mailbox); + return List.of(new Message(MessagesTemplates.AUTH_SUCCESS_MESSAGE.text, user.getId())); + } + return List.of(new Message(MessagesTemplates.AUTH_ERROR_MESSAGE.text, user.getId())); + } +} + diff --git a/src/main/java/org/bot/domain/commands/Command.java b/src/main/java/org/bot/application/commands/Command.java similarity index 76% rename from src/main/java/org/bot/domain/commands/Command.java rename to src/main/java/org/bot/application/commands/Command.java index 075d61a..c8b942d 100644 --- a/src/main/java/org/bot/domain/commands/Command.java +++ b/src/main/java/org/bot/application/commands/Command.java @@ -1,8 +1,10 @@ -package org.bot.domain.commands; +package org.bot.application.commands; import org.bot.domain.Message; import org.bot.domain.User; +import java.util.List; + abstract public class Command { private final String alias; private final String description; @@ -20,5 +22,5 @@ public String getDescription() { return description; } - public abstract Message execute(User user, String[] args); + public abstract List execute(User user, List args); } diff --git a/src/main/java/org/bot/domain/commands/HelpCommand.java b/src/main/java/org/bot/application/commands/HelpCommand.java similarity index 72% rename from src/main/java/org/bot/domain/commands/HelpCommand.java rename to src/main/java/org/bot/application/commands/HelpCommand.java index f1dff52..8d714b1 100644 --- a/src/main/java/org/bot/domain/commands/HelpCommand.java +++ b/src/main/java/org/bot/application/commands/HelpCommand.java @@ -1,14 +1,16 @@ -package org.bot.domain.commands; +package org.bot.application.commands; import org.bot.domain.Message; import org.bot.domain.User; +import java.util.List; + public class HelpCommand extends Command { String helpMessage; public HelpCommand() { super( - "/help", + "help", "- get help" ); } @@ -16,6 +18,7 @@ public HelpCommand() { public void generateHelpMessage(Command[] commands) { StringBuilder helpMessageBuilder = new StringBuilder(); for (Command command : commands) { + helpMessageBuilder.append("/"); helpMessageBuilder.append(command.getAlias()); helpMessageBuilder.append(" "); helpMessageBuilder.append(command.getDescription()); @@ -24,7 +27,7 @@ public void generateHelpMessage(Command[] commands) { helpMessage = helpMessageBuilder.toString(); } - public Message execute(User user, String[] args) { - return new Message(helpMessage); + public List execute(User user, List args) { + return List.of(new Message(helpMessage, user.getId())); } } diff --git a/src/main/java/org/bot/application/commands/LettersListCommand.java b/src/main/java/org/bot/application/commands/LettersListCommand.java new file mode 100644 index 0000000..cd41b6d --- /dev/null +++ b/src/main/java/org/bot/application/commands/LettersListCommand.java @@ -0,0 +1,67 @@ +package org.bot.application.commands; + +import jakarta.mail.MessagingException; +import org.bot.domain.Letter; +import org.bot.domain.Mailbox; +import org.bot.domain.Message; +import org.bot.domain.User; +import org.bot.enums.MessagesTemplates; +import org.bot.exceptions.SessionTimeExpiredException; +import org.bot.infrastructure.interfaces.MailInterface; + +import java.util.ArrayList; +import java.util.List; + +public class LettersListCommand extends Command { + private final MailInterface mailInterface; + + record Args(String email, int lettersCount) {} + + private Args parseArgs(List args) throws NumberFormatException { + String email = args.get(0); + int lettersCount = Integer.parseInt(args.get(1)); + return new Args(email, lettersCount); + } + + public LettersListCommand(MailInterface mailInterface) { + super( + "letters", + " - get n letters" + ); + this.mailInterface = mailInterface; + } + + public List execute(User user, List args) { + return baseStateHandler(user, args); + } + + private List baseStateHandler(User user, List rawArgs) { + Args args; + try { + args = parseArgs(rawArgs); + } catch (Exception e) { + return List.of(new Message(MessagesTemplates.INCORRECT_ARGS.text, user.getId())); + } + Mailbox mailbox = user.getMailbox(args.email); + + if (mailbox == null) { + return List.of(new Message(MessagesTemplates.NOT_AUTH_LIST_IS_UNAVAILABLE.text, user.getId())); + } + + Letter[] letters; + try { + letters = this.mailInterface.readMessages(mailbox, args.lettersCount); + } catch (SessionTimeExpiredException e) { + return List.of(new Message(MessagesTemplates.SESSION_EXPIRED.text, user.getId())); + } catch (MessagingException e) { + return List.of(new Message(MessagesTemplates.ERROR_MESSAGE.text, user.getId())); + } + + //TODO: Telegraph for full letters + List lettersPreviews = new ArrayList<>(); + for (Letter letter : letters) { + lettersPreviews.add(new Message(letter.asString(1000), user.getId())); + } + return lettersPreviews; + } +} diff --git a/src/main/java/org/bot/domain/Letter.java b/src/main/java/org/bot/domain/Letter.java index ad8f320..3f76b7c 100644 --- a/src/main/java/org/bot/domain/Letter.java +++ b/src/main/java/org/bot/domain/Letter.java @@ -25,7 +25,7 @@ public String getBody() { return body; } - public String getSender() { // TODO filter cringe sender names + public String getSender() { return sender; } @@ -33,7 +33,7 @@ public String getDate() { return date; } - public static Letter fromMailMessage(Message message){ + public static Letter fromMailMessage(Message message) { Letter letter = new Letter(); letter.subject = parseSubject(message); letter.body = parseBody(message); @@ -60,7 +60,7 @@ private static String parseSender(Message message) { } } - private static String parseBody(Message message){ + private static String parseBody(Message message) { try { String result = ""; if (message.isMimeType("text/plain")) { @@ -68,19 +68,16 @@ private static String parseBody(Message message){ } else if (message.isMimeType("multipart/*")) { MimeMultipart mimeMultipart = (MimeMultipart) message.getContent(); result = getTextFromMimeMultipart(mimeMultipart); - } - else if (message.isMimeType("text/html")) { + } else if (message.isMimeType("text/html")) { String html = (String) message.getContent(); result = Jsoup.parse(html).text(); - } - else { + } else { System.out.println("Unknown message type " + message.getContentType()); } result = result.replaceAll("[\r\n\s ]{2,}", "\n"); result = result.replaceAll("[\t\s ]{2,}", "\s"); return result; - } - catch (Exception e) { + } catch (Exception e) { System.out.println(e.getMessage()); return null; } @@ -94,7 +91,7 @@ private static String parseDate(Message message) { } } - private static String getTextFromMimeMultipart(MimeMultipart mimeMultipart) throws MessagingException, IOException{ + private static String getTextFromMimeMultipart(MimeMultipart mimeMultipart) throws MessagingException, IOException { ArrayList letterLines = new ArrayList<>(); int count = mimeMultipart.getCount(); for (int i = 0; i < count; i++) { @@ -102,27 +99,40 @@ private static String getTextFromMimeMultipart(MimeMultipart mimeMultipart) thr if (bodyPart.isMimeType("text/plain")) { String text = bodyPart.getContent().toString(); letterLines.add(text); -// break; // without break same text appears twice in my tests } else if (bodyPart.isMimeType("text/html")) { String html = (String) bodyPart.getContent(); String text = Jsoup.parse(html).text(); letterLines.add(text); - } else if (bodyPart.getContent() instanceof MimeMultipart){ + } else if (bodyPart.getContent() instanceof MimeMultipart) { letterLines.add(getTextFromMimeMultipart((MimeMultipart) bodyPart.getContent())); } } return String.join("\n", letterLines); } - public String toString() { // TODO про это говорили что-то мудрое на леции? + + public String asString(int maxLen) { + String letterStr = MessageFormat.format( + """ + Sender: {0} + Subject: {1} + Date: {2} + + {3}""", + sender, subject, date, body + ); + return letterStr.substring(0, Math.min(letterStr.length(), maxLen)) + "\n..."; + } + + public String asString() { return MessageFormat.format( - """ - Sender: {0} - Subject: {1} - Date: {2} - - {3}""", - sender, subject, date, body + """ + Sender: {0} + Subject: {1} + Date: {2} + + {3}""", + sender, subject, date, body ); } } diff --git a/src/main/java/org/bot/domain/Mailbox.java b/src/main/java/org/bot/domain/Mailbox.java index 8327295..91eaa3e 100644 --- a/src/main/java/org/bot/domain/Mailbox.java +++ b/src/main/java/org/bot/domain/Mailbox.java @@ -31,4 +31,16 @@ public boolean isSessionExpired() { public void updateAuthTime() { this.expiresAt = Instant.now().plus(sessionDuration); } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || obj.getClass() != this.getClass()) { + return false; + } + Mailbox mailbox = (Mailbox) obj; + return email.equals(mailbox.email); + } } \ No newline at end of file diff --git a/src/main/java/org/bot/domain/Message.java b/src/main/java/org/bot/domain/Message.java index 3eb68b6..33cfb81 100644 --- a/src/main/java/org/bot/domain/Message.java +++ b/src/main/java/org/bot/domain/Message.java @@ -1,27 +1,73 @@ package org.bot.domain; +import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup; +import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; public class Message { - private final String text; - private Integer userID; + private String text = null; + private Integer messageId = null; + private final Long userId; + private List buttons = null; + public String getText() { return text; } - public Integer getUserID() { - return userID; + public Long getUserId() { + return userId; + } + + public Integer getMessageId() { + return messageId; + } + + public List getButtons() { + return buttons; } - public Message(String text) { + public InlineKeyboardMarkup getMarkup() { + InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup(); + List> rowsInline = new ArrayList<>(); + + if (buttons != null) { + for (InlineKeyboardButton button : buttons) { + List rowInline = new ArrayList<>(); + rowInline.add(button); + rowsInline.add(rowInline); + } + } + + inlineKeyboardMarkup.setKeyboard(rowsInline); + return inlineKeyboardMarkup; + } + + public Message(String text, Long userId) { this.text = text; + this.userId = userId; + } + + public Message(String text, Long userId, List buttons) { + this.text = text; + this.userId = userId; + this.buttons = buttons; + } + + public Message(Integer messageId, Long userId, List buttons) { + this.messageId = messageId; + this.userId = userId; + this.buttons = buttons; } - public Message(String text, Integer userID) { + public Message(String text, Integer messageId, Long userId, List buttons) { this.text = text; - this.userID = userID; + this.messageId = messageId; + this.userId = userId; + this.buttons = buttons; } @Override @@ -33,6 +79,6 @@ public boolean equals(Object object) { return false; } Message message = (Message) object; - return this.text.equals(message.text) && Objects.equals(this.userID, message.userID); + return text.equals(message.text) && Objects.equals(userId, message.userId); } } \ No newline at end of file diff --git a/src/main/java/org/bot/domain/User.java b/src/main/java/org/bot/domain/User.java index 3c8ac89..064096b 100644 --- a/src/main/java/org/bot/domain/User.java +++ b/src/main/java/org/bot/domain/User.java @@ -1,23 +1,21 @@ package org.bot.domain; -import org.bot.enums.UserState; import org.bot.exceptions.EmailNotFoundException; import java.util.HashMap; +import java.util.List; public class User { - private final Integer id; - private UserState state; + private final Long id; private final HashMap mailboxes; - private String tempEmail; + private String tempEmail = null; - public User(Integer id) { + public User(Long id) { this.id = id; mailboxes = new HashMap<>(); - state = UserState.NOT_AUTHED; } - public Integer getID() { + public Long getId() { return id; } @@ -26,26 +24,24 @@ public void addNewMailbox(Mailbox mailbox) { } public void removeMailBox(String email) throws EmailNotFoundException { - if (mailboxes.containsKey(email)) { - mailboxes.remove(email); + if (!mailboxes.containsKey(email)) { + throw new EmailNotFoundException("Email not found."); } - throw new EmailNotFoundException("Email not found."); + mailboxes.remove(email); } public Mailbox getMailbox(String email) { return mailboxes.get(email); } - public UserState getState() { - return state; - } - public void changeState(UserState state) { - this.state = state; + public List getAllEmails() { + return List.copyOf(mailboxes.keySet()); } public void setTempEmail(String email) { tempEmail = email; } + public String getTempEmail() { return tempEmail; } diff --git a/src/main/java/org/bot/domain/UserRepository.java b/src/main/java/org/bot/domain/UserRepository.java index c95358a..744dfb4 100644 --- a/src/main/java/org/bot/domain/UserRepository.java +++ b/src/main/java/org/bot/domain/UserRepository.java @@ -1,30 +1,20 @@ package org.bot.domain; -import org.bot.exceptions.IdNotFoundException; - import java.util.HashMap; public class UserRepository { - private HashMap userRepository; + private HashMap userRepository; public UserRepository() { userRepository = new HashMap<>(); } public void addUser(User user) { - Integer id = user.getID(); + Long id = user.getId(); userRepository.put(id, user); } - public void deleteUserById(Integer id) throws IdNotFoundException { - if (userRepository.containsKey(id)) { - userRepository.remove(id); - return; - } - throw new IdNotFoundException("There is no such identifier in the repository."); - } - - public User getUserById(Integer id) { + public User getUserById(Long id) { if (!userRepository.containsKey(id)) { userRepository.put(id, new User(id)); } diff --git a/src/main/java/org/bot/domain/commands/AuthCommand.java b/src/main/java/org/bot/domain/commands/AuthCommand.java deleted file mode 100644 index 6146089..0000000 --- a/src/main/java/org/bot/domain/commands/AuthCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.bot.domain.commands; - -import org.bot.domain.Mailbox; -import org.bot.domain.Message; -import org.bot.domain.User; -import org.bot.enums.MessagesTemplates; -import org.bot.infrastructure.interfaces.MailInterface; - -import java.time.Duration; - -public class AuthCommand extends Command { - private final MailInterface mailInterface; - private final Duration sessionDuration; - record Args(String email, String password) {} - private Args parseArgs(String[] args) { - String email = args[0]; - String password = args[1]; - return new Args(email, password); - } - - public AuthCommand(MailInterface mailInterface, Duration sessionDuration) { - super( - "/auth", - " - authenticate to mailbox" - ); - this.mailInterface = mailInterface; - this.sessionDuration = sessionDuration; - } - - public Message execute(User user, String[] args) { - Args parsedArgs; - try { - parsedArgs = parseArgs(args); - } - catch (Exception e) { - return new Message(MessagesTemplates.AUTH_INCORRECT_MESSAGE.text); - } - Mailbox mailbox = new Mailbox(parsedArgs.email(), parsedArgs.password(), sessionDuration); - if (this.mailInterface.isCredentialsCorrect(mailbox)) { - user.addNewMailbox(mailbox); - return new Message(MessagesTemplates.AUTH_SUCCESS_MESSAGE.text); - } - return new Message(MessagesTemplates.AUTH_ERROR_MESSAGE.text); - } -} - diff --git a/src/main/java/org/bot/domain/commands/LettersListCommand.java b/src/main/java/org/bot/domain/commands/LettersListCommand.java deleted file mode 100644 index f1c1408..0000000 --- a/src/main/java/org/bot/domain/commands/LettersListCommand.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.bot.domain.commands; - -import jakarta.mail.MessagingException; -import org.bot.domain.Letter; -import org.bot.domain.Mailbox; -import org.bot.domain.Message; -import org.bot.domain.User; -import org.bot.enums.MessagesTemplates; -import org.bot.exceptions.SessionTimeExpiredException; -import org.bot.infrastructure.interfaces.MailInterface; - -import java.util.StringJoiner; - -public class LettersListCommand extends Command { - private final MailInterface mailInterface; - record Args(String email, int lettersCount) {} - private Args parseArgs(String[] args) throws NumberFormatException { - String email = args[0]; - int lettersCount = Integer.parseInt(args[1]); - return new Args(email, lettersCount); - } - - public LettersListCommand(MailInterface mailInterface) { - super( - "/letters", - " - get n letters" - ); - this.mailInterface = mailInterface; - } - - public Message execute(User user, String[] args) { - return baseStateHandler(user, args); - } - - private Message baseStateHandler(User user, String[] rawArgs) { - Args args; - try { - args = parseArgs(rawArgs); - } - catch (Exception e) { - return new Message(MessagesTemplates.INCORRECT_ARGS.text); - } - Mailbox mailbox = user.getMailbox(args.email); - - if (mailbox == null) { - return new Message(MessagesTemplates.NOT_AUTH_LIST_IS_UNAVAILABLE.text); - } - - Letter[] letters; - try { - letters = this.mailInterface.readMessages(mailbox, args.lettersCount); - } - catch (SessionTimeExpiredException e) { - return new Message(MessagesTemplates.SESSION_EXPIRED.text); - } - catch (MessagingException e) { - return new Message(MessagesTemplates.ERROR_MESSAGE.text); - } - - StringJoiner joiner = new StringJoiner("\n\n\n"); - for (Letter letter : letters) { - joiner.add(letter.toString()); - } - return new Message(joiner.toString()); - } -} diff --git a/src/main/java/org/bot/enums/MessagesTemplates.java b/src/main/java/org/bot/enums/MessagesTemplates.java index 05c8e96..75b980e 100644 --- a/src/main/java/org/bot/enums/MessagesTemplates.java +++ b/src/main/java/org/bot/enums/MessagesTemplates.java @@ -2,8 +2,8 @@ public enum MessagesTemplates { - START_MESSAGE("Привет! Я Mailgram bot, я помогу тебе удобно пользоваться почтой без мобильного клиента " + - "посредством Telegram. Чтобы узнать, что я умею, напиши /help"), + START_MESSAGE("Привет \uD83D\uDC4B! Я Mailgram bot, я помогу тебе удобно пользоваться почтой без " + + "мобильного клиента посредством Telegram. Чтобы узнать, что я умею, напиши /help"), DEFAULT_MESSAGE("Я не понимаю тебя. Чтобы узнать, что я умею, напиши /help"), NOT_AUTH_LIST_IS_UNAVAILABLE("Невозможно получить список писем неавторизованного пользователя. " + "Воспользуйся командой /auth, чтобы залогиниться."), @@ -31,8 +31,9 @@ public enum MessagesTemplates { ERROR_MESSAGE("Что-то пошло не так."), SESSION_EXPIRED("Сессия истекла, введите /auth для повторной авторизации"), - INCORRECT_ARGS("Некорректные параметры команды, введите /help для получения справки"); + INCORRECT_ARGS("Некорректные параметры команды, введите /help для получения справки"), + CHOOSE_EMAIL("Выберите почту"); public final String text; MessagesTemplates(String text) { diff --git a/src/main/java/org/bot/enums/UserState.java b/src/main/java/org/bot/enums/UserState.java deleted file mode 100644 index 48e8e6b..0000000 --- a/src/main/java/org/bot/enums/UserState.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.bot.enums; - -public enum UserState { - NOT_AUTHED("Not authed"), - WAITING_FOR_EMAIL("Waiting for email"), - WAITING_FOR_PASSWORD("Waiting for password"), - BASE_STATE("Base state"), - SENDING("Sending"); - - public final String state; - - UserState(String state) { - this.state = state; - } -} \ No newline at end of file diff --git a/src/main/java/org/bot/infrastructure/ConsoleBotInterface.java b/src/main/java/org/bot/infrastructure/ConsoleBotInterface.java deleted file mode 100644 index 226edc7..0000000 --- a/src/main/java/org/bot/infrastructure/ConsoleBotInterface.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.bot.infrastructure; - - -import org.bot.infrastructure.interfaces.BotInterface; -import org.bot.domain.Message; - -import java.util.Scanner; - -public class ConsoleBotInterface implements BotInterface { - - private Scanner in = new Scanner(System.in); - - public Message readMessage() { - String text = in.nextLine(); - return new Message(text, 0); - } - - public void sendMessage(Message message) { - System.out.println(message.getText()); - } -} diff --git a/src/main/java/org/bot/infrastructure/PropertyParser.java b/src/main/java/org/bot/infrastructure/PropertyParser.java new file mode 100644 index 0000000..0abf617 --- /dev/null +++ b/src/main/java/org/bot/infrastructure/PropertyParser.java @@ -0,0 +1,17 @@ +package org.bot.infrastructure; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + + +public class PropertyParser { + public static Properties parseProperties(String path) throws IOException { + FileInputStream fileInputStream; + Properties properties = new Properties(); + + fileInputStream = new FileInputStream(path); + properties.load(fileInputStream); + return properties; + } +} diff --git a/src/main/java/org/bot/infrastructure/TelegramBotInterface.java b/src/main/java/org/bot/infrastructure/TelegramBotInterface.java new file mode 100644 index 0000000..c8c146f --- /dev/null +++ b/src/main/java/org/bot/infrastructure/TelegramBotInterface.java @@ -0,0 +1,58 @@ +package org.bot.infrastructure; + +import org.bot.domain.Message; +import org.telegram.telegrambots.meta.api.methods.ActionType; +import org.telegram.telegrambots.meta.api.methods.botapimethods.BotApiMethodSerializable; +import org.telegram.telegrambots.meta.api.methods.send.SendChatAction; +import org.telegram.telegrambots.meta.api.methods.send.SendMessage; +import org.telegram.telegrambots.meta.api.methods.updatingmessages.EditMessageReplyMarkup; +import org.telegram.telegrambots.meta.api.methods.updatingmessages.EditMessageText; + +import java.util.ArrayList; +import java.util.List; + +public class TelegramBotInterface { + public static void setBotAction(Long chatId) { + SendChatAction sendChatAction = new SendChatAction(); + sendChatAction.setChatId(chatId); + sendChatAction.setAction(ActionType.TYPING); + } + + public static List sendMessageList(List messages) { + List sendMessages = new ArrayList<>(); + for (Message message : messages) { + sendMessages.add(sendMessage(message)); + } + return sendMessages; + } + + public static SendMessage sendMessage(Message message) { + SendMessage sendMessage = new SendMessage(); + sendMessage.setChatId(message.getUserId()); + sendMessage.setText(message.getText()); + sendMessage.setReplyMarkup(message.getMarkup()); + return sendMessage; + } + + public static List editMessage(Message message) { + List editors = new ArrayList<>(); + + if (message.getText() != null) { + EditMessageText editText = new EditMessageText(); + editText.setText(message.getText()); + editText.setChatId(message.getUserId()); + editText.setMessageId(message.getMessageId()); + editors.add(editText); + } + + if (message.getButtons() != null) { + EditMessageReplyMarkup editReplyMarkup = new EditMessageReplyMarkup(); + editReplyMarkup.setReplyMarkup(message.getMarkup()); + editReplyMarkup.setChatId(message.getUserId()); + editReplyMarkup.setMessageId(message.getMessageId()); + editors.add(editReplyMarkup); + } + + return editors; + } +} diff --git a/src/main/java/org/bot/infrastructure/interfaces/BotInterface.java b/src/main/java/org/bot/infrastructure/interfaces/BotInterface.java deleted file mode 100644 index 061fa30..0000000 --- a/src/main/java/org/bot/infrastructure/interfaces/BotInterface.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.bot.infrastructure.interfaces; - -import org.bot.domain.Message; - -public interface BotInterface { - public Message readMessage(); - - public void sendMessage(Message message); -} \ No newline at end of file diff --git a/src/main/java/org/bot/infrastructure/interfaces/MailInterface.java b/src/main/java/org/bot/infrastructure/interfaces/MailInterface.java index 3f732be..a2ef477 100644 --- a/src/main/java/org/bot/infrastructure/interfaces/MailInterface.java +++ b/src/main/java/org/bot/infrastructure/interfaces/MailInterface.java @@ -7,7 +7,7 @@ public interface MailInterface { - public default Letter[] readMessages(Mailbox mailbox, int lettersCount) + default Letter[] readMessages(Mailbox mailbox, int lettersCount) throws MessagingException, SessionTimeExpiredException { if (mailbox.isSessionExpired()) { throw new SessionTimeExpiredException("Your session has expired. You should sign in again."); @@ -15,7 +15,7 @@ public default Letter[] readMessages(Mailbox mailbox, int lettersCount) return new Letter[0]; } - public void sendMessage(Mailbox mailbox, Letter letter); + void sendMessage(Mailbox mailbox, Letter letter); - public boolean isCredentialsCorrect(Mailbox mailbox); + boolean isCredentialsCorrect(Mailbox mailbox); } diff --git a/src/main/resources/config.properties.example b/src/main/resources/config.properties.example new file mode 100644 index 0000000..a7c371d --- /dev/null +++ b/src/main/resources/config.properties.example @@ -0,0 +1,2 @@ +bot.token = {your_bot_token} +bot.name = {your_bot_name} \ No newline at end of file diff --git a/src/test/java/org/bot/BotLogicTest.java b/src/test/java/org/bot/BotLogicTest.java index 321eb7c..21e414b 100644 --- a/src/test/java/org/bot/BotLogicTest.java +++ b/src/test/java/org/bot/BotLogicTest.java @@ -4,14 +4,16 @@ import org.bot.domain.Mailbox; import org.bot.domain.Message; import org.bot.domain.User; -import org.bot.domain.commands.AuthCommand; -import org.bot.domain.commands.Command; -import org.bot.domain.commands.LettersListCommand; +import org.bot.application.commands.AuthCommand; +import org.bot.application.commands.Command; +import org.bot.application.commands.LettersListCommand; import org.bot.enums.MessagesTemplates; import org.bot.infrastructure.interfaces.MailInterface; import org.junit.jupiter.api.Test; import java.time.Duration; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.*; @@ -24,53 +26,74 @@ public void sendMessage(Mailbox mailbox, Letter letter) { @Override public boolean isCredentialsCorrect(Mailbox mailbox) { - return mailbox.getEmail().equals("test@test.com") && mailbox.getPassword().equals("amogus"); + return mailbox.getEmail().equals("johndoe@test.com") && mailbox.getPassword().equals("password"); } } - User user = new User(1); MailInterface mailInterface = new DummyMailInterface(); @Test - public void testGetLettersCommandUnAuthed() { + public void testGetLettersCommandNonAuthed() { + User user = new User(1L); Command lettersListCommand = new LettersListCommand(mailInterface); - Message message = lettersListCommand.execute(user, new String[]{"test@test.com", "3"}); - assertEquals(message.getText(), MessagesTemplates.NOT_AUTH_LIST_IS_UNAVAILABLE.text); + List args = Arrays.asList("johndoe@test.com", "3"); + Message message = lettersListCommand.execute(user, args).get(0); + + String expectedResult = MessagesTemplates.NOT_AUTH_LIST_IS_UNAVAILABLE.text; + String actualResult = message.getText(); + assertEquals(expectedResult, actualResult); } @Test public void testAuthCommandNotValid() { + User user = new User(1L); Command auth = new AuthCommand(mailInterface, Duration.ofSeconds(1)); - Message message = auth.execute(user, new String[]{"test@test.com", "123"}); - assertEquals(MessagesTemplates.AUTH_ERROR_MESSAGE.text, message.getText()); + List args = Arrays.asList("johndoe@test.com", "wrongpassword"); + Message message = auth.execute(user, args).get(0); + + String expectedResult = MessagesTemplates.AUTH_ERROR_MESSAGE.text; + String actualResult = message.getText(); + assertEquals(expectedResult, actualResult); } @Test public void testAuthCommandValid() { + User user = new User(1L); Command auth = new AuthCommand(mailInterface, Duration.ofSeconds(1)); - Message message = auth.execute(user, new String[]{"test@test.com", "amogus"}); - assertEquals(MessagesTemplates.AUTH_SUCCESS_MESSAGE.text, message.getText()); + List args = Arrays.asList("johndoe@test.com", "password"); + Message message = auth.execute(user, args).get(0); + + String expectedResult = MessagesTemplates.AUTH_SUCCESS_MESSAGE.text; + String actualResult = message.getText(); + assertEquals(expectedResult, actualResult); } @Test public void testGetLettersCommandAuthed() { - Command auth = new AuthCommand(mailInterface, Duration.ofSeconds(1)); - auth.execute(user, new String[]{"test@test.com", "amogus"}); - + User user = new User(1L); Command lettersListCommand = new LettersListCommand(mailInterface); - Message message = lettersListCommand.execute(user, new String[]{"test@test.com", "3"}); - assertNotEquals(MessagesTemplates.NOT_AUTH_LIST_IS_UNAVAILABLE.text, message.getText()); + List args = Arrays.asList("johndoe@test.com", "password"); + Message message = lettersListCommand.execute(user, args).get(0); + + String expectedResult = MessagesTemplates.NOT_AUTH_LIST_IS_UNAVAILABLE.text; + String actualResult = message.getText(); + assertNotEquals(expectedResult, actualResult); } @Test public void testSessionExpired() throws InterruptedException { - Command auth = new AuthCommand(mailInterface, Duration.ofSeconds(1)); - auth.execute(user, new String[]{"test@test.com", "amogus"}); - Command lettersListCommand = new LettersListCommand(mailInterface); + User user = new User(1L); + Command auth = new AuthCommand(mailInterface, Duration.ofSeconds(0)); + List args = Arrays.asList("johndoe@test.com", "password"); + auth.execute(user, args); + Command lettersListCommand = new LettersListCommand(mailInterface); TimeUnit.SECONDS.sleep(1); + args = Arrays.asList("johndoe@test.com", "1"); + Message message = lettersListCommand.execute(user, args).get(0); - Message message = lettersListCommand.execute(user, new String[]{"test@test.com", "3"}); - assertEquals(MessagesTemplates.SESSION_EXPIRED.text, message.getText()); + String expectedResult = MessagesTemplates.SESSION_EXPIRED.text; + String actualResult = message.getText(); + assertEquals(expectedResult, actualResult); } } diff --git a/src/test/java/org/bot/units/MailboxTest.java b/src/test/java/org/bot/units/MailboxTest.java new file mode 100644 index 0000000..b43e6ce --- /dev/null +++ b/src/test/java/org/bot/units/MailboxTest.java @@ -0,0 +1,29 @@ +package org.bot.units; + +import org.bot.domain.Mailbox; +import org.junit.jupiter.api.Test; + +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class MailboxTest { + + @Test + public void testSessionNotExpired() { + Mailbox mailbox = new Mailbox("johndoe@test.com", "password", Duration.ofSeconds(10)); + Boolean expectedResult = false; + Boolean actualResult = mailbox.isSessionExpired(); + assertEquals(expectedResult, actualResult); + } + + @Test + public void testSessionExpired() throws InterruptedException { + Mailbox mailbox = new Mailbox("johndoe@test.com", "password", Duration.ofSeconds(1)); + TimeUnit.SECONDS.sleep(1); + Boolean expectedResult = true; + Boolean actualResult = mailbox.isSessionExpired(); + assertEquals(expectedResult, actualResult); + } +} diff --git a/src/test/java/org/bot/units/MessageTest.java b/src/test/java/org/bot/units/MessageTest.java new file mode 100644 index 0000000..fb30306 --- /dev/null +++ b/src/test/java/org/bot/units/MessageTest.java @@ -0,0 +1,68 @@ +package org.bot.units; + +import org.bot.domain.Message; +import org.junit.jupiter.api.Test; +import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup; +import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class MessageTest { + + @Test + public void testGetText() { + String expectedText = "Hello, World!"; + Message message = new Message(expectedText, 1L); + String actualText = message.getText(); + assertEquals(expectedText, actualText); + } + + @Test + public void testGetUserId() { + Long expectedUserId = 1L; + Message message = new Message("Hello, World!", expectedUserId); + Long actualUserId = message.getUserId(); + assertEquals(expectedUserId, actualUserId); + } + + @Test + public void testGetMessageId() { + Integer expectedMessageId = 1; + Message message = new Message(expectedMessageId, 1L, new ArrayList<>()); + Integer actualMessageId = message.getMessageId(); + assertEquals(expectedMessageId, actualMessageId); + } + + @Test + public void testGetButtons() { + List expectedButtons = new ArrayList<>(); + InlineKeyboardButton button = new InlineKeyboardButton(); + button.setText("Test"); + button.setCallbackData("Test"); + expectedButtons.add(button); + Message message = new Message("Hello, World!", 1L, expectedButtons); + List actualButtons = message.getButtons(); + assertEquals(expectedButtons, actualButtons); + } + + @Test + public void testGetMarkup() { + InlineKeyboardMarkup expectedMarkup = new InlineKeyboardMarkup(); + List> rowsInline = new ArrayList<>(); + List rowInline = new ArrayList<>(); + InlineKeyboardButton button = new InlineKeyboardButton(); + button.setText("Test"); + button.setCallbackData("Test"); + rowInline.add(button); + rowsInline.add(rowInline); + expectedMarkup.setKeyboard(rowsInline); + List buttons = new ArrayList<>(); + buttons.add(button); + Message message = new Message("Hello, World!", 1L, buttons); + InlineKeyboardMarkup actualMarkup = message.getMarkup(); + assertEquals(expectedMarkup, actualMarkup); + } +} diff --git a/src/test/java/org/bot/units/UserRepositoryTest.java b/src/test/java/org/bot/units/UserRepositoryTest.java new file mode 100644 index 0000000..31f1f86 --- /dev/null +++ b/src/test/java/org/bot/units/UserRepositoryTest.java @@ -0,0 +1,19 @@ +package org.bot.units; + +import org.bot.domain.User; +import org.bot.domain.UserRepository; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class UserRepositoryTest { + @Test + public void testAddGetUser() { + UserRepository userRepository = new UserRepository(); + User user = new User(1L); + userRepository.addUser(user); + User expectedUser = user; + User actualUser = userRepository.getUserById(1L); + assertEquals(expectedUser, actualUser); + } +} diff --git a/src/test/java/org/bot/units/UserTest.java b/src/test/java/org/bot/units/UserTest.java new file mode 100644 index 0000000..67abbe8 --- /dev/null +++ b/src/test/java/org/bot/units/UserTest.java @@ -0,0 +1,53 @@ +package org.bot.units; + +import org.bot.domain.Mailbox; +import org.bot.domain.User; +import org.junit.jupiter.api.Test; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class UserTest { + User user = new User(1L); + + @Test + public void testGetId() { + Long expectedId = 1L; + Long actualId = user.getId(); + assertEquals(expectedId, actualId); + } + + @Test + public void testAddNewMailbox() { + user.addNewMailbox(new Mailbox("johndoe@test.com", "password", Duration.ofHours(10))); + List expectedMailboxes = new ArrayList<>(); + expectedMailboxes.add("johndoe@test.com"); + List actualMailbox = user.getAllEmails(); + assertEquals(expectedMailboxes, actualMailbox); + } + + @Test + public void testGetMailbox() { + Mailbox expectedMailbox = new Mailbox("johndoe@test.com", "password", Duration.ofHours(10)); + user.addNewMailbox(new Mailbox("johndoe@test.com", "password", Duration.ofHours(10))); + Mailbox actualMailbox = user.getMailbox("johndoe@test.com"); + assertEquals(expectedMailbox, actualMailbox); + } + + @Test + public void testGetAllEmails() { + user.addNewMailbox(new Mailbox("johndoe@test.com", "password", Duration.ofHours(10))); + user.addNewMailbox(new Mailbox("janedoe@test.com", "password", Duration.ofHours(10))); + List expectedMailboxes = new ArrayList<>(); + expectedMailboxes.add("janedoe@test.com"); + expectedMailboxes.add("johndoe@test.com"); + List actualMailboxes = new ArrayList<>(user.getAllEmails()); + Collections.sort(expectedMailboxes); + Collections.sort(actualMailboxes); + assertEquals(expectedMailboxes, actualMailboxes); + } +}