أهلا مرة أخرى. هذه هي المقالة الأخيرة من STEP_6، والتي سنتحدث فيها عن إضافة وظيفة إلى مهمة JRTB-6 . في هاتين المقالتين السابقتين ( الجزء 1 ، الجزء 2 ) قمنا بالفعل بإعداد كل ما تحتاجه تقريبًا. هذا الجزء هو تتويجا لهذه العملية. لكل من قرأ هذه السلسلة من المقالات حتى هذه اللحظة منذ البداية - احترامًا كبيرًا. هذا يعني أن لديك الدافع الكافي للعثور على وظيفة رائعة. الآن دعونا ننتقل إلى العمل.
نحن ننفذ JRTB-6
هذه المرة سنقوم بالمهمة من جانب روبوت التليجرام، لأن العمل على تحديث قاعدة البيانات قد تم بالكامل، وتم تكوين كيانات قاعدة البيانات وجاهزة للعمل. دعونا نضيف قيمة جديدة إلى CommandName - LIST_GROUP_SUB:LIST_GROUP_SUB("/listGroupSub");
لنقم بإنشاء أمر ListGroupSubCommand :
package com.github.javarushcommunity.jrtb.command;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.repository.entity.TelegramUser;
import com.github.javarushcommunity.jrtb.service.SendBotMessageService;
import com.github.javarushcommunity.jrtb.service.TelegramUserService;
import org.telegram.telegrambots.meta.api.objects.Update;
import javax.ws.rs.NotFoundException;
import java.util.stream.Collectors;
import static com.github.javarushcommunity.jrtb.command.CommandUtils.getChatId;
/**
* {@link Command} for getting list of {@link GroupSub}.
*/
public class ListGroupSubCommand implements Command {
private final SendBotMessageService sendBotMessageService;
private final TelegramUserService telegramUserService;
public ListGroupSubCommand(SendBotMessageService sendBotMessageService, TelegramUserService telegramUserService) {
this.sendBotMessageService = sendBotMessageService;
this.telegramUserService = telegramUserService;
}
@Override
public void execute(Update update) {
//todo add exception handling
TelegramUser telegramUser = telegramUserService.findByChatId(getChatId(update))
.orElseThrow(NotFoundException::new);
String message = "Я нашел все подписки на группы: \n\n";
String collectedGroups = telegramUser.getGroupSubs().stream()
.map(it -> "Группа: " + it.getTitle() + " , ID = " + it.getId() + " \n")
.collect(Collectors.joining());
sendBotMessageService.sendMessage(telegramUser.getChatId(), message + collectedGroups);
}
}
هنا كل شيء بسيط قدر الإمكان - نحصل على المستخدم باستخدام معرف الدردشة الحالي، وسيتم جمع جميع اشتراكاته في المجموعات في كائنه. لقد وضعنا هذا في الجزء الثاني. مرة أخرى، أضفت //todo حتى لا أنسى إضافة معالجة الاستثناءات التي قد تنشأ أثناء العملية. الخطوة التالية هي تحديث CommandContainer عن طريق إضافة أمر جديد إليه:
put(LIST_GROUP_SUB.getCommandName(), new GroupSubListCommand(sendBotMessageService, telegramUserService))
هذا هو كل ما في الأمر: الآن تحتاج إلى كتابة المزيد من الاختبارات، وتحديث الأمر /help (إضافة وصف للأوامر الجديدة) واختبار الوظيفة الجديدة عبر Telegram. لنكتب اختبارًا لـ ListGroupSubCommand . نظرًا لأن منطق الأمر ليس نموذجيًا، فسنكتب اختبارًا دون الارتباط بفئة AbstractCommandTest ، كما فعلنا من قبل:
package com.github.javarushcommunity.jrtb.command;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.repository.entity.TelegramUser;
import com.github.javarushcommunity.jrtb.service.SendBotMessageService;
import com.github.javarushcommunity.jrtb.service.TelegramUserService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.Update;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import static com.github.javarushcommunity.jrtb.command.CommandName.LIST_GROUP_SUB;
@DisplayName("Unit-level testing for ListGroupSubCommand")
public class ListGroupSubCommandTest {
@Test
public void shouldProperlyShowsListGroupSub() {
//given
TelegramUser telegramUser = new TelegramUser();
telegramUser.setActive(true);
telegramUser.setChatId("1");
List<GroupSub> groupSubList = new ArrayList<>();
groupSubList.add(populateGroupSub(1, "gs1"));
groupSubList.add(populateGroupSub(2, "gs2"));
groupSubList.add(populateGroupSub(3, "gs3"));
groupSubList.add(populateGroupSub(4, "gs4"));
telegramUser.setGroupSubs(groupSubList);
SendBotMessageService sendBotMessageService = Mockito.mock(SendBotMessageService.class);
TelegramUserService telegramUserService = Mockito.mock(TelegramUserService.class);
Mockito.when(telegramUserService.findByChatId(telegramUser.getChatId())).thenReturn(Optional.of(telegramUser));
ListGroupSubCommand command = new ListGroupSubCommand(sendBotMessageService, telegramUserService);
Update update = new Update();
Message message = Mockito.mock(Message.class);
Mockito.when(message.getChatId()).thenReturn(Long.valueOf(telegramUser.getChatId()));
Mockito.when(message.getText()).thenReturn(LIST_GROUP_SUB.getCommandName());
update.setMessage(message);
String collectedGroups = "Я нашел все подписки на группы: \n\n" +
telegramUser.getGroupSubs().stream()
.map(it -> "Группа: " + it.getTitle() + " , ID = " + it.getId() + " \n")
.collect(Collectors.joining());
//when
command.execute(update);
//then
Mockito.verify(sendBotMessageService).sendMessage(telegramUser.getChatId(), collectedGroups);
}
private GroupSub populateGroupSub(Integer id, String title) {
GroupSub gs = new GroupSub();
gs.setId(id);
gs.setTitle(title);
return gs;
}
}
لنقم بتحديث الأمر /help
في حالتنا، يعمل الأمر /help بمثابة توثيق للعمل مع الروبوت، لذلك يجب أن نتذكر تحديثه حتى يتمكن المستخدم من استخدامه. لقد أضفنا أمرين، لذلك دعونا نقوم بتحديث النص الذي سيأتي:public static final String HELP_MESSAGE = String.format("✨Дотупные команды✨\n\n"
+ "Начать\\закончить работу с ботом:\n"
+ "%s - начать работу со мной\n"
+ "%s - приостановить работу со мной\n\n"
+ "Работа с подписками на группы:\n"
+ "%s - подписаться на группу статей\n"
+ "%s - получить список групп, на которые подписан\n\n"
+ "%s - получить помощь в работе со мной\n"
+ "%s - получить мою статистику использования\n",
START.getCommandName(), STOP.getCommandName(), ADD_GROUP_SUB.getCommandName(),
LIST_GROUP_SUB.getCommandName(), HELP.getCommandName(), STAT.getCommandName());
لقد قمت أيضًا بتحديث نص ردود الروبوت: لقد قمت بذلك بحيث يكون دائمًا وفقًا لمصطلحات الاسم الأول مع المستخدم، وإلا فسيكون هناك "أنت" و"أنت"... الآن سيكون من الممكن إنشاء ما لا يقل عن نوع من الاتصال في عمل الروبوت.
اختبار البوت المحدث
نطلق الروبوت الخاص بنا محليًا ونقوم بما يلي:- نقوم بتنفيذ الأمر /start للتأكد من إضافة المستخدم في حالة الاختبار إلى قاعدة البيانات.
- نقوم بتنفيذ الأمر /help - ونتأكد من أن كل شيء على ما يرام، كما أردنا.
- بعد ذلك نقوم بتنفيذ الأمر /addGroupSub .
- من القائمة المقترحة لمعرفات المجموعة، نضيف العديد منها إلى هذا المزيج.
- نقوم بتشغيل الأمر /listGroupSub للتأكد من تسجيل المجموعات للمستخدم.
application.properties:
spring.datasource.url=jdbc:mysql://jrtb-db:3306/jrtb_db?characterEncoding=UTF-8
application-test.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/dev_jrtb_db?characterEncoding=UTF-8
docker-compose.yml (добавил последнюю строку):
jrtb-db:
image: mysql:5.7
restart: always
environment:
MYSQL_USER: ${BOT_DB_USERNAME}
MYSQL_PASSWORD: ${BOT_DB_PASSWORD}
MYSQL_DATABASE: 'jrtb_db'
MYSQL_ROOT_PASSWORD: 'root'
ports:
- '3306:3306'
expose:
- '3306'
command: --character-set-server=utf8 --collation-server=utf8_general_ci
docker-compose-test.yml (добавил последнюю строку)
jrtb-db-dev:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: 'dev_jrtb_db'
# So you don't have to use root, but you can if you like
MYSQL_USER: 'dev_jrtb_db_user'
# You can use whatever password you like
MYSQL_PASSWORD: 'dev_jrtb_db_password'
# Password for root access
MYSQL_ROOT_PASSWORD: 'root'
ports:
# <Port exposed> : < MySQL Port running inside container>
- '3306:3306'
expose:
# Opens port 3306 on the container
- '3306'
command: --character-set-server=utf8 --collation-server=utf8_general_ci
بعد هذه التحديثات، تحتاج إلى مسح جميع البيانات الموجودة في قاعدة البيانات والبدء من جديد. عملية المحو بسيطة للغاية: تحتاج إلى تشغيل الأمر: docker-compose -f docker-compose-test.yml، وبعد ذلك يتم حذف جميع البيانات وقاعدة البيانات. وقم بتشغيلها مرة أخرى بالترميز المحدث: docker-compose -f docker-compose-test.uml up قاعدة البيانات جاهزة. لنقم بتشغيل التطبيق المحدث ونلقي نظرة عليه. سأراجع الأمر سريعًا وأظهر لك النتيجة: والآن حصلنا على ما أردناه بالضبط. الآن يبدو هذا مثل الحقيقة.
إنهاء
الآن أعتقد أنه يمكننا إكمال هذه الخطوة. لقد تم إنجاز الكثير، الكثير حقًا. لنقم بتحديث إصدار التطبيق إلى 0.5.0-SNAPSHOT وRELEASE_NOTES.
# ملاحظات الإصدار ## 0.5.0-SNAPSHOT * JRTB-5: إمكانية إضافية للاشتراك في المجموعة * JRTB-6: إمكانية إضافية للحصول على قائمة اشتراكات المجموعة.
ثم يصبح كل شيء كالمعتاد: نقوم بإنشاء التزام جديد مع كل التغييرات. الشيء الرئيسي هو إضافة وصف للمهمتين اللتين تم إكمالهما خلال هذه الخطوة لأغراض إعداد التقارير. إذن هذا هو التعليق:
STEP_6 JRTB-5: تمت إضافة إمكانية الاشتراك في المجموعة JRTB-6: تمت إضافة إمكانية رؤية قائمة اشتراك المجموعة.
أدى ذلك إلى تغيير 47 ملفًا... وهذا تغيير كبير. على الرغم من أنه لا يمكنك معرفة ذلك من خلال وصف الوظيفة. بعد كل شيء، لفهم العمق الكامل، عليك أن تعرف أنك بحاجة إلى كتابة عميل Java لواجهة برمجة التطبيقات (API)، وتحديث التطبيق بالكامل بشكل أساسي. هذا هو الحال، العمل على الخادم - هناك الكثير من العمل، ولكن الرؤية من جانب العميل صغيرة...)) أيها الأصدقاء، أقدم لكم تقليديًا طريقة لإظهار الاهتمام بعملي - اشترك في جيثب الحساب ، انضم إلى قناة التليجرام واكتب سؤالاً حول المقال إذا كان هناك شيء غير واضح! إليك رابط لطلب السحب مع التغييرات الخاصة بهذه الخطوة STEP_6 . شكرا للجميع على القراءة. المزيد في المستقبل - فلنتحدث عن حذف الاشتراك وإلغاء تنشيط الملف الشخصي والمزيد. لا تبديل))
GO TO FULL VERSION