From f1592bf07188ba9d2236e2678e12ccb19b72c774 Mon Sep 17 00:00:00 2001 From: bulatruslanovich Date: Wed, 16 Oct 2024 20:26:03 +0300 Subject: [PATCH] refactor: make more readable dispatcher module --- .../com/bipbup/config/KafkaTopicConfig.java | 39 +-- .../bipbup/config/KafkaTopicProperties.java | 22 ++ .../bipbup/config/TelegramBotProperties.java | 19 ++ ...{MyTelegramBot.java => HeadHunterBot.java} | 20 +- .../bipbup/controllers/UpdateProcessor.java | 240 +++++++----------- .../bipbup/controllers/WebHookController.java | 14 +- .../bipbup/exception/NullUpdateException.java | 7 + .../service/impl/AnswerConsumerImpl.java | 8 +- ...ramBotTest.java => HeadHunterBotTest.java} | 14 +- .../controllers/UpdateProcessorTest.java | 87 ++----- .../controllers/WebHookControllerTest.java | 24 +- 11 files changed, 199 insertions(+), 295 deletions(-) create mode 100644 dispatcher/src/main/java/com/bipbup/config/KafkaTopicProperties.java create mode 100644 dispatcher/src/main/java/com/bipbup/config/TelegramBotProperties.java rename dispatcher/src/main/java/com/bipbup/controllers/{MyTelegramBot.java => HeadHunterBot.java} (70%) create mode 100644 dispatcher/src/main/java/com/bipbup/exception/NullUpdateException.java rename dispatcher/src/test/java/com/bipbup/controllers/{MyTelegramBotTest.java => HeadHunterBotTest.java} (68%) diff --git a/dispatcher/src/main/java/com/bipbup/config/KafkaTopicConfig.java b/dispatcher/src/main/java/com/bipbup/config/KafkaTopicConfig.java index 5a83290..e462ef5 100644 --- a/dispatcher/src/main/java/com/bipbup/config/KafkaTopicConfig.java +++ b/dispatcher/src/main/java/com/bipbup/config/KafkaTopicConfig.java @@ -1,59 +1,34 @@ package com.bipbup.config; -import org.apache.kafka.clients.admin.AdminClientConfig; +import lombok.RequiredArgsConstructor; import org.apache.kafka.clients.admin.NewTopic; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.kafka.config.TopicBuilder; -import org.springframework.kafka.core.KafkaAdmin; - -import java.util.HashMap; -import java.util.Map; @Configuration +@RequiredArgsConstructor public class KafkaTopicConfig { - @Value("${spring.kafka.topics.answer-topic}") - private String answerTopic; - - @Value("${spring.kafka.topics.text-update-topic}") - private String textUpdateTopic; - - @Value("${spring.kafka.topics.callback-query-update-topic}") - private String callbackQueryUpdateTopic; - - @Value("${spring.kafka.topics.edit-topic}") - private String editTopic; - - @Value("${spring.kafka.bootstrap-servers}") - private String server; - - @Bean - public KafkaAdmin admin() { - Map configs = new HashMap<>(); - configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, server); - - return new KafkaAdmin(configs); - } + private final KafkaTopicProperties kafkaTopicProperties; @Bean public NewTopic answerTopic() { - return TopicBuilder.name(answerTopic).build(); + return TopicBuilder.name(kafkaTopicProperties.getAnswerTopic()).build(); } @Bean public NewTopic textUpdateTopic() { - return TopicBuilder.name(textUpdateTopic).build(); + return TopicBuilder.name(kafkaTopicProperties.getTextUpdateTopic()).build(); } @Bean public NewTopic callbackQueryUpdateTopic() { - return TopicBuilder.name(callbackQueryUpdateTopic).build(); + return TopicBuilder.name(kafkaTopicProperties.getCallbackQueryUpdateTopic()).build(); } @Bean public NewTopic editTopic() { - return TopicBuilder.name(editTopic).build(); + return TopicBuilder.name(kafkaTopicProperties.getEditTopic()).build(); } } diff --git a/dispatcher/src/main/java/com/bipbup/config/KafkaTopicProperties.java b/dispatcher/src/main/java/com/bipbup/config/KafkaTopicProperties.java new file mode 100644 index 0000000..0d5cff8 --- /dev/null +++ b/dispatcher/src/main/java/com/bipbup/config/KafkaTopicProperties.java @@ -0,0 +1,22 @@ +package com.bipbup.config; + + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Getter +@Setter +@Configuration +@ConfigurationProperties(prefix = "topics") +public class KafkaTopicProperties { + + private String answerTopic; + + private String editTopic; + + private String textUpdateTopic; + + private String callbackQueryUpdateTopic; +} diff --git a/dispatcher/src/main/java/com/bipbup/config/TelegramBotProperties.java b/dispatcher/src/main/java/com/bipbup/config/TelegramBotProperties.java new file mode 100644 index 0000000..ea862e5 --- /dev/null +++ b/dispatcher/src/main/java/com/bipbup/config/TelegramBotProperties.java @@ -0,0 +1,19 @@ +package com.bipbup.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Getter +@Setter +@Configuration +@ConfigurationProperties(prefix = "bot") +public class TelegramBotProperties { + + private String username; + + private String url; + + private String token; +} diff --git a/dispatcher/src/main/java/com/bipbup/controllers/MyTelegramBot.java b/dispatcher/src/main/java/com/bipbup/controllers/HeadHunterBot.java similarity index 70% rename from dispatcher/src/main/java/com/bipbup/controllers/MyTelegramBot.java rename to dispatcher/src/main/java/com/bipbup/controllers/HeadHunterBot.java index d9c110d..d8eabc6 100644 --- a/dispatcher/src/main/java/com/bipbup/controllers/MyTelegramBot.java +++ b/dispatcher/src/main/java/com/bipbup/controllers/HeadHunterBot.java @@ -1,8 +1,8 @@ package com.bipbup.controllers; +import com.bipbup.config.TelegramBotProperties; import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.telegram.telegrambots.bots.TelegramWebhookBot; import org.telegram.telegrambots.meta.api.methods.BotApiMethod; @@ -12,20 +12,16 @@ @Slf4j @Component -public class MyTelegramBot extends TelegramWebhookBot { +public class HeadHunterBot extends TelegramWebhookBot { private final UpdateProcessor updateProcessor; - @Value("${bot.uri}") - private String botUri; + private final TelegramBotProperties telegramBotProperties; - @Value("${bot.username}") - private String botUsername; - - public MyTelegramBot(final UpdateProcessor updateProcessor, - final @Value("${bot.token}") String botToken) { - super(botToken); + public HeadHunterBot(UpdateProcessor updateProcessor, TelegramBotProperties telegramBotProperties) { + super(telegramBotProperties.getToken()); this.updateProcessor = updateProcessor; + this.telegramBotProperties = telegramBotProperties; } @PostConstruct @@ -34,7 +30,7 @@ private void init() { try { var webhook = SetWebhook.builder() - .url(botUri) + .url(telegramBotProperties.getUrl()) .build(); this.setWebhook(webhook); } catch (TelegramApiException e) { @@ -44,7 +40,7 @@ private void init() { @Override public String getBotUsername() { - return botUsername; + return telegramBotProperties.getUsername(); } @Override diff --git a/dispatcher/src/main/java/com/bipbup/controllers/UpdateProcessor.java b/dispatcher/src/main/java/com/bipbup/controllers/UpdateProcessor.java index eaf4966..1b5e9bc 100644 --- a/dispatcher/src/main/java/com/bipbup/controllers/UpdateProcessor.java +++ b/dispatcher/src/main/java/com/bipbup/controllers/UpdateProcessor.java @@ -1,161 +1,113 @@ package com.bipbup.controllers; +import com.bipbup.config.KafkaTopicProperties; +import com.bipbup.easter.egg.EasterEggService; +import com.bipbup.exception.NullUpdateException; import com.bipbup.service.UpdateProducer; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.slf4j.Marker; -import org.slf4j.MarkerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; -import org.telegram.telegrambots.meta.api.methods.send.SendMessage; +import org.telegram.telegrambots.meta.api.methods.BotApiMethod; import org.telegram.telegrambots.meta.api.methods.send.SendSticker; -import org.telegram.telegrambots.meta.api.methods.updatingmessages.EditMessageText; import org.telegram.telegrambots.meta.api.objects.CallbackQuery; -import org.telegram.telegrambots.meta.api.objects.InputFile; -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 org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException; @Slf4j -@RequiredArgsConstructor @Component +@RequiredArgsConstructor public class UpdateProcessor { - private static final Marker EASTER_EGG_MARKER = MarkerFactory.getMarker("EASTER_EGG"); - - private static final Marker WELCOME_MARKER = MarkerFactory.getMarker("WELCOME"); - - private static final Marker BAD_HUMAN_MARKER = MarkerFactory.getMarker("BAD_HUMAN"); - - private final UpdateProducer updateProducer; - - @Value("${spring.kafka.topics.text-update-topic}") - private String textUpdateTopic; - - @Value("${spring.kafka.topics.callback-query-update-topic}") - private String callbackQueryUpdateTopic; - - private MyTelegramBot myTelegramBot; - - public void registerBot(final MyTelegramBot myTelegramBot) { - this.myTelegramBot = myTelegramBot; - } - - public boolean processUpdate(final Update update) { - if (update == null) { - log.error("Update is null"); - return false; - } - - if (update.hasMessage()) { - processMessage(update); - } else if (update.hasCallbackQuery()) { - processCallbackQuery(update); - } else { - logEmptyMessageUpdate(update); - } - - return true; - } - - private void logEmptyMessageUpdate(final Update update) { - var status = update.getMyChatMember().getNewChatMember().getStatus(); - var user = update.getMyChatMember().getFrom(); - if (status.equals("kicked")) { - log.info(BAD_HUMAN_MARKER, "User {} block the bot", user.getFirstName()); - deactivateUser(user); - } else if (status.equals("member")) { - log.info(WELCOME_MARKER, "User {} joined", user.getFirstName()); - } else { - log.error("Message is null"); - } - } - - protected void deactivateUser(User user) { - var callbackQuery = new CallbackQuery(); - callbackQuery.setFrom(user); - callbackQuery.setData("delete_me_from_db"); - - var update = new Update(); - update.setCallbackQuery(callbackQuery); - - updateProducer.produce(callbackQueryUpdateTopic, update); - } - - private void processMessage(Update update) { - var message = update.getMessage(); - - if (message.hasText()) { - log.info("User {} wrote \"{}\"", message.getFrom().getFirstName(), message.getText()); - easterEgg(update); - updateProducer.produce(textUpdateTopic, update); - } - } - - private void processCallbackQuery(final Update update) { - var callbackQuery = update.getCallbackQuery(); - - log.info("User {} sent callback query with data: {}", - callbackQuery.getFrom().getFirstName(), callbackQuery.getData()); - updateProducer.produce(callbackQueryUpdateTopic, update); - } - - public void setView(final SendMessage message) { - try { - myTelegramBot.execute(message); - } catch (TelegramApiRequestException e) { - if (e.getErrorCode() == HttpStatus.FORBIDDEN.value() - && e.getApiResponse().contains("bot was blocked by the user")) { - log.info("Bot was blocked by user: {}", message.getChatId()); - } - } catch (TelegramApiException e) { - log.error("Error with send message execute", e); - } - } - - - public void setEdit(final EditMessageText message) { - try { - myTelegramBot.execute(message); - } catch (TelegramApiException e) { - log.error("Error with edit message execute", e); - } - } - - protected void easterEgg(Update update) { - var message = update.getMessage(); - var input = message.getText(); - var firstName = update.getMessage().getFrom().getFirstName(); - - String stickerId = switch (input.toLowerCase()) { - case "java" -> "CAACAgIAAxkBAAIFPmbI3jhL4EduWvGuPRYcLQZoZaXJAAK2RwACw115S9Ixcad37Jb7NQQ"; - case "c++" -> "CAACAgIAAxkBAAIFUWbI4zy9Hz75c2HAQ4ktbM5-yGaiAAK9PAACxih4Sy04iZSeWyG0NQQ"; - case "javascript" -> "CAACAgIAAxkBAAIFdmbI5bDHR6rHgpLIXtLtIPy8ro-tAAL2QQACctF4S6_e0ZZv1pzyNQQ"; - case "python" -> "CAACAgIAAxkBAAIFd2bI5hnwHgT_BL5jTZtoeT1aL9JwAALISAAC5PF5S7Se8n5ySpqANQQ"; - case "c#" -> "CAACAgIAAxkBAAIFeGbI5kjF58JJGk4yeE-hYI6RwyvuAAJfQwACJad4SypZPWXZRAYeNQQ"; - case "котик" -> "CAACAgIAAxkBAAIFeWbI5mG6zqA00c19q65qlyCqqJE2AAJ4FAACiQ5BS8wYzPDMMcXINQQ"; - default -> null; - }; - - if (stickerId != null) { - log.info(EASTER_EGG_MARKER, "User {} activates Easter egg by writing \"{}\"", firstName, input); - createAndSendSticker(stickerId, message); - } - } - - private void createAndSendSticker(String stickerId, Message message) { - var sticker = SendSticker.builder() - .sticker(new InputFile(stickerId)) - .chatId(message.getChatId()) - .build(); - - try { - myTelegramBot.execute(sticker); - } catch (TelegramApiException e) { - log.error("Error with send sticker execute", e); - } - } + private final UpdateProducer updateProducer; + + private final KafkaTopicProperties kafkaTopicProperties; + + private final EasterEggService easterEggService; + + private HeadHunterBot headHunterBot; + + public void registerBot(HeadHunterBot headHunterBot) { + this.headHunterBot = headHunterBot; + } + + public void processUpdate(Update update) throws NullPointerException { + if (update == null) { + log.error("Update is null"); + throw new NullUpdateException("Update is null"); + } + + if (update.hasMessage()) + processMessage(update); + else if (update.hasCallbackQuery()) + processCallbackQuery(update); + else + logEmptyMessageUpdate(update); + } + + private void logEmptyMessageUpdate(Update update) { + var status = update.getMyChatMember() + .getNewChatMember() + .getStatus(); + var user = update.getMyChatMember() + .getFrom(); + + if (status.equals("kicked")) { + log.info("User {} block the bot", user.getFirstName()); + deactivateUser(user); + } else if (status.equals("member")) { + log.info("User {} joined", user.getFirstName()); + } else { + log.error("Message is null"); + } + } + + private void processMessage(Update update) { + var message = update.getMessage(); + + if (message.hasText()) { + log.info("User {} wrote \"{}\"", message.getFrom() + .getFirstName(), message.getText()); + + easterEggService.getSendSticker(update) + .ifPresent(this::sendStickerToTelegram); + + updateProducer.produce(kafkaTopicProperties.getTextUpdateTopic(), update); + } + } + + private void processCallbackQuery(Update update) { + var callbackQuery = update.getCallbackQuery(); + + log.info("User {} sent callback query with data: {}", callbackQuery.getFrom() + .getFirstName(), callbackQuery.getData()); + updateProducer.produce(kafkaTopicProperties.getCallbackQueryUpdateTopic(), update); + } + + public void sendToTelegram(BotApiMethod method) { + try { + headHunterBot.execute(method); + } catch (TelegramApiException e) { + log.error("Error with send message execute", e); + } + } + + private void sendStickerToTelegram(SendSticker sticker) { + try { + headHunterBot.execute(sticker); + } catch (TelegramApiException e) { + log.error("Error with send message execute", e); + } + } + + private void deactivateUser(User user) { + var callbackQuery = new CallbackQuery(); + callbackQuery.setFrom(user); + callbackQuery.setData("delete_me_from_db"); + + var update = new Update(); + update.setCallbackQuery(callbackQuery); + + updateProducer.produce(kafkaTopicProperties.getCallbackQueryUpdateTopic(), update); + } } diff --git a/dispatcher/src/main/java/com/bipbup/controllers/WebHookController.java b/dispatcher/src/main/java/com/bipbup/controllers/WebHookController.java index ec86a8b..cf69462 100644 --- a/dispatcher/src/main/java/com/bipbup/controllers/WebHookController.java +++ b/dispatcher/src/main/java/com/bipbup/controllers/WebHookController.java @@ -1,5 +1,6 @@ package com.bipbup.controllers; +import com.bipbup.exception.NullUpdateException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; @@ -16,16 +17,13 @@ public class WebHookController { private final UpdateProcessor processor; @PostMapping("/callback/update") - public ResponseEntity onUpdateReceived(@RequestBody Update update) { + public ResponseEntity onUpdateReceived(@RequestBody Update update) { try { - if (processor.processUpdate(update)) - return ResponseEntity.ok().build(); - else - return ResponseEntity.badRequest().body("Failed to process the update."); - } catch (Exception e) { + processor.processUpdate(update); + return ResponseEntity.ok().build(); + } catch (NullUpdateException e) { log.error("Error processing update: {}", update, e); - return ResponseEntity.internalServerError() - .body("Internal Server Error: " + e.getMessage()); + return ResponseEntity.badRequest().body("Failed to process the update."); } } } diff --git a/dispatcher/src/main/java/com/bipbup/exception/NullUpdateException.java b/dispatcher/src/main/java/com/bipbup/exception/NullUpdateException.java new file mode 100644 index 0000000..72c4d09 --- /dev/null +++ b/dispatcher/src/main/java/com/bipbup/exception/NullUpdateException.java @@ -0,0 +1,7 @@ +package com.bipbup.exception; + +public class NullUpdateException extends RuntimeException { + public NullUpdateException(String message) { + super(message); + } +} diff --git a/dispatcher/src/main/java/com/bipbup/service/impl/AnswerConsumerImpl.java b/dispatcher/src/main/java/com/bipbup/service/impl/AnswerConsumerImpl.java index 9c7dc69..cfeaf5a 100644 --- a/dispatcher/src/main/java/com/bipbup/service/impl/AnswerConsumerImpl.java +++ b/dispatcher/src/main/java/com/bipbup/service/impl/AnswerConsumerImpl.java @@ -16,14 +16,14 @@ public class AnswerConsumerImpl implements AnswerConsumer { private final UpdateProcessor updateProcessor; @Override - @KafkaListener(topics = "${spring.kafka.topics.answer-topic}", groupId = "groupId") + @KafkaListener(topics = "${topics.answer-topic}", groupId = "groupId") public void consumeSendMessage(final SendMessageWrapper sendMessage) { - updateProcessor.setView(sendMessage.getMessage()); + updateProcessor.sendToTelegram(sendMessage.getMessage()); } @Override - @KafkaListener(topics = "${spring.kafka.topics.edit-topic}", groupId = "groupId") + @KafkaListener(topics = "${topics.edit-topic}", groupId = "groupId") public void consumeEditMessage(final EditMessageWrapper editMessage) { - updateProcessor.setEdit(editMessage.getMessage()); + updateProcessor.sendToTelegram(editMessage.getMessage()); } } diff --git a/dispatcher/src/test/java/com/bipbup/controllers/MyTelegramBotTest.java b/dispatcher/src/test/java/com/bipbup/controllers/HeadHunterBotTest.java similarity index 68% rename from dispatcher/src/test/java/com/bipbup/controllers/MyTelegramBotTest.java rename to dispatcher/src/test/java/com/bipbup/controllers/HeadHunterBotTest.java index fcc315f..9569f2f 100644 --- a/dispatcher/src/test/java/com/bipbup/controllers/MyTelegramBotTest.java +++ b/dispatcher/src/test/java/com/bipbup/controllers/HeadHunterBotTest.java @@ -1,5 +1,6 @@ package com.bipbup.controllers; +import com.bipbup.config.TelegramBotProperties; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -10,25 +11,28 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -class MyTelegramBotTest { +class HeadHunterBotTest { @Mock private UpdateProcessor updateProcessor; + @Mock + private TelegramBotProperties telegramBotProperties; + @InjectMocks - private MyTelegramBot myTelegramBot; + private HeadHunterBot headHunterBot; @BeforeEach public void setUp() { MockitoAnnotations.openMocks(this); - myTelegramBot = new MyTelegramBot(updateProcessor, "dummyToken"); + headHunterBot = new HeadHunterBot(updateProcessor, telegramBotProperties); } @Test void testGetBotPath() { // Act - String path = myTelegramBot.getBotPath(); + String path = headHunterBot.getBotPath(); // Assert assertEquals("/update", path); @@ -37,7 +41,7 @@ void testGetBotPath() { @Test void testOnWebhookUpdateReceived() { // Act - BotApiMethod result = myTelegramBot.onWebhookUpdateReceived(null); + BotApiMethod result = headHunterBot.onWebhookUpdateReceived(null); // Assert assertNull(result); diff --git a/dispatcher/src/test/java/com/bipbup/controllers/UpdateProcessorTest.java b/dispatcher/src/test/java/com/bipbup/controllers/UpdateProcessorTest.java index 530318b..68eb3af 100644 --- a/dispatcher/src/test/java/com/bipbup/controllers/UpdateProcessorTest.java +++ b/dispatcher/src/test/java/com/bipbup/controllers/UpdateProcessorTest.java @@ -1,25 +1,25 @@ package com.bipbup.controllers; +import com.bipbup.config.KafkaTopicProperties; +import com.bipbup.easter.egg.EasterEggService; +import com.bipbup.exception.NullUpdateException; import com.bipbup.service.UpdateProducer; -import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.telegram.telegrambots.meta.api.methods.send.SendSticker; import org.telegram.telegrambots.meta.api.objects.CallbackQuery; 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 static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; + +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.any; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -29,7 +29,13 @@ class UpdateProcessorTest { private UpdateProducer updateProducer; @Mock - private MyTelegramBot myTelegramBot; + private EasterEggService easterEggService; + + @Mock + private KafkaTopicProperties kafkaTopicProperties; + + @Mock + private HeadHunterBot headHunterBot; @InjectMocks private UpdateProcessor updateProcessor; @@ -37,14 +43,13 @@ class UpdateProcessorTest { @BeforeEach public void setUp() { MockitoAnnotations.openMocks(this); - updateProcessor.registerBot(myTelegramBot); + updateProcessor.registerBot(headHunterBot); } @Test @DisplayName("Should return false when update is null") void testProcessUpdate_NullUpdate() { - boolean result = updateProcessor.processUpdate(null); - assertFalse(result); + assertThrows(NullUpdateException.class, () -> updateProcessor.processUpdate(null)); } @Test @@ -63,10 +68,9 @@ void testProcessUpdate_Message() { when(user.getFirstName()).thenReturn("TestUser"); // Act - boolean result = updateProcessor.processUpdate(update); + updateProcessor.processUpdate(update); // Assert - assertTrue(result); verify(updateProducer).produce(any(), eq(update)); } @@ -85,68 +89,9 @@ void testProcessUpdate_CallbackQuery() { when(callbackQuery.getData()).thenReturn("some_data"); // Act - boolean result = updateProcessor.processUpdate(update); + updateProcessor.processUpdate(update); // Assert - assertTrue(result); verify(updateProducer).produce(any(), eq(update)); } - - @Test - @DisplayName("Should deactivate user when kicked") - void testDeactivateUser() { - // Arrange - User user = new User(); - user.setFirstName("TestUser"); - - // Act - updateProcessor.deactivateUser(user); - - // Assert - verify(updateProducer).produce(any(), any(Update.class)); - } - - @SneakyThrows - @Test - @DisplayName("Should send sticker when easter egg is activated") - void testEasterEgg_SendSticker() { - // Arrange - Update update = mock(Update.class); - Message message = mock(Message.class); - User user = mock(User.class); - - when(update.getMessage()).thenReturn(message); - when(message.getText()).thenReturn("java"); - when(message.getChatId()).thenReturn(12345L); - when(message.getFrom()).thenReturn(user); - when(user.getFirstName()).thenReturn("TestUser"); - - // Act - updateProcessor.easterEgg(update); - - // Assert - verify(myTelegramBot).execute(any(SendSticker.class)); - } - - @SneakyThrows - @Test - @DisplayName("Should not send sticker if no easter egg is activated") - void testEasterEgg_NoSticker() { - // Arrange - Update update = mock(Update.class); - Message message = mock(Message.class); - User user = mock(User.class); - - when(update.getMessage()).thenReturn(message); - when(message.getText()).thenReturn("unknown"); - when(message.getChatId()).thenReturn(12345L); - when(message.getFrom()).thenReturn(user); - when(user.getFirstName()).thenReturn("TestUser"); - - // Act - updateProcessor.easterEgg(update); - - // Assert - verify(myTelegramBot, never()).execute(any(SendSticker.class)); - } } \ No newline at end of file diff --git a/dispatcher/src/test/java/com/bipbup/controllers/WebHookControllerTest.java b/dispatcher/src/test/java/com/bipbup/controllers/WebHookControllerTest.java index 4b12bd9..d893a46 100644 --- a/dispatcher/src/test/java/com/bipbup/controllers/WebHookControllerTest.java +++ b/dispatcher/src/test/java/com/bipbup/controllers/WebHookControllerTest.java @@ -1,5 +1,6 @@ package com.bipbup.controllers; +import com.bipbup.exception.NullUpdateException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -12,7 +13,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.telegram.telegrambots.meta.api.objects.Update; -import static org.hamcrest.Matchers.containsString; + import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -42,7 +43,7 @@ public void setUp() { void testOnUpdateReceived_Success() throws Exception { // Arrange Update update = new Update(); - when(processor.processUpdate(update)).thenReturn(true); + processor.processUpdate(update); // Act mockMvc.perform(post("/callback/update") @@ -57,7 +58,8 @@ void testOnUpdateReceived_Success() throws Exception { void testOnUpdateReceived_Failure() throws Exception { // Arrange Update update = new Update(); - when(processor.processUpdate(update)).thenReturn(false); + processor.processUpdate(update); + when(processor).thenThrow(NullUpdateException.class); // Act mockMvc.perform(post("/callback/update") @@ -67,20 +69,4 @@ void testOnUpdateReceived_Failure() throws Exception { .andExpect(status().isBadRequest()) .andExpect(content().string("Failed to process the update.")); } - - @Test - @DisplayName("Should return 500 Internal Server Error when an exception occurs during processing") - void testOnUpdateReceived_Exception() throws Exception { - // Arrange - Update update = new Update(); - when(processor.processUpdate(update)).thenThrow(new RuntimeException("Processing error")); - - // Act - mockMvc.perform(post("/callback/update") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(update))) - // Assert - .andExpect(status().isInternalServerError()) - .andExpect(content().string(containsString("Internal Server Error: Processing error"))); - } } \ No newline at end of file