سلام دوباره این آخرین مقاله از 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);
}
}
در اینجا همه چیز تا حد امکان ساده است - ما کاربر را با استفاده از chat_id موجود دریافت می کنیم و تمام اشتراک های او در گروه ها در شی او جمع آوری می شود. این را در قسمت دوم تنظیم کردیم. دوباره، //todo را اضافه کردم تا فراموش نکنم که کنترل استثناهایی را که ممکن است در حین کار ایجاد شود اضافه کنم. مرحله بعدی این است که CommandContainer را با افزودن یک دستور جدید به آن به روز کنید:
put(LIST_GROUP_SUB.getCommandName(), new GroupSubListCommand(sendBotMessageService, telegramUserService))
اساساً همین است: اکنون باید تست های بیشتری بنویسید، دستور help / را به روز کنید (برای دستورات جدید توضیحات اضافه کنید) و عملکرد جدید را از طریق تلگرام آزمایش کنید. بیایید یک تست برای 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: قابلیت اضافه شده برای دریافت لیستی از اشتراک های گروهی.
سپس همه چیز طبق معمول است: ما یک commit جدید با تمام تغییرات ایجاد می کنیم. نکته اصلی اضافه کردن شرحی از دو وظیفه است که در این مرحله برای اهداف گزارش تکمیل شده است. بنابراین این نظر است:
STEP_6 JRTB-5: قابلیت اضافه شده برای اشتراک در گروه JRTB-6: قابلیت اضافه شده برای مشاهده لیست اشتراک گروهی.
این منجر به 47 فایل تغییر شد... این یک تغییر بزرگ است. اگر چه شما نمی توانید از شرح عملکرد تشخیص دهید. پس از همه، برای درک عمق کامل، باید بدانید که باید یک کلاینت جاوا برای API بنویسید، که اساساً کل برنامه را به روز می کند. اینطوری است، کار روی سرور - کار زیاد است، اما دید از سمت کلاینت کم است...)) دوستان، من به طور سنتی راهی برای نشان دادن علاقه به کار من به شما پیشنهاد می کنم - در یک github مشترک شوید. حساب کاربری ، به کانال تلگرام بپیوندید و اگر چیزی مشخص نیست در مورد مقاله سوال بنویسید! در اینجا پیوندی به درخواست کشش با تغییرات برای این STEP_6 است . با تشکر از همه برای خواندن. بیشتر در راه است - بیایید در مورد حذف اشتراک، غیرفعال کردن نمایه و موارد دیگر صحبت کنیم. عوض نکن))
GO TO FULL VERSION