Yana salom. Bu STEP_6 ning yakuniy maqolasi boʻlib, unda biz JRTB-6 vazifasiga funksiya qoʻshish haqida gaplashamiz . Oldingi ikkita maqolada ( 1-qism , 2-qism ) biz sizga kerak bo'lgan deyarli hamma narsani tayyorladik. Ushbu qism jarayonning eng yuqori nuqtasidir. Ushbu turkum maqolalarni boshidan shu paytgacha o'qigan har bir kishiga - katta hurmat. Bu sizda ajoyib ish topish uchun etarli motivatsiya borligini anglatadi. Endi biznesga kirishamiz.
Biz JRTB-6 ni amalga oshiramiz
Bu safar biz telegram boti tomonidan vazifani bajaramiz, chunki ma'lumotlar bazasini yangilash bo'yicha ishlar hammasi tugadi, ma'lumotlar bazasi ob'ektlari sozlangan va ishga tayyor. Buyruqning nomiga yangi qiymat qo'shamiz - LIST_GROUP_SUB:LIST_GROUP_SUB("/listGroupSub");
ListGroupSubCommand buyrug'ini yaratamiz :
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);
}
}
Bu erda hamma narsa iloji boricha sodda - biz foydalanuvchini mavjud chat_id-dan foydalanamiz va uning barcha guruhlarga obunalari uning ob'ektida to'planadi. Biz buni ikkinchi qismda o'rnatdik. Ish paytida yuzaga kelishi mumkin bo'lgan istisnolar bilan ishlashni qo'shishni unutmaslik uchun men yana //todo qo'shdim. Keyingi qadam CommandContainer- ni unga yangi buyruq qo'shish orqali yangilashdir :
put(LIST_GROUP_SUB.getCommandName(), new GroupSubListCommand(sendBotMessageService, telegramUserService))
Bu asosan shunday: endi siz ko'proq testlar yozishingiz, /help buyrug'ini yangilashingiz (yangi buyruqlar uchun tavsif qo'shing) va Telegram orqali yangi funksiyani sinab ko'rishingiz kerak. ListGroupSubCommand uchun test yozamiz . Buyruqning mantig'i odatiy bo'lmaganligi sababli, biz avvalgidek AbstractCommandTest sinfiga bog'lanmasdan test yozamiz:
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;
}
}
Keling, / help buyrug'ini yangilaymiz
Bizning holatda, / help buyrug'i bot bilan ishlash uchun hujjat sifatida ishlaydi, shuning uchun foydalanuvchi undan foydalanishi uchun uni yangilashni unutmasligimiz kerak. Biz ikkita buyruq qo'shdik, shuning uchun keling, keladigan matnni yangilaymiz: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());
Men botning javoblari matnini ham yangiladim: men buni shunday qildimki, u har doim foydalanuvchi bilan ism-sharifda bo‘lsin, aks holda “siz” ham, “siz” ham bo‘lardi... Endi hech bo‘lmaganda yaratish mumkin bo‘ladi. bot ishida qandaydir bog'lanish.
Yangilangan bot sinovdan o'tkazilmoqda
Biz botimizni mahalliy sifatida ishga tushiramiz va quyidagilarni bajaramiz:- Test ishidagi foydalanuvchi ma'lumotlar bazasiga qo'shilganligiga ishonch hosil qilish uchun /start buyrug'ini bajaramiz .
- Biz / help buyrug'ini bajaramiz - biz xohlaganimizdek hammasi yaxshi ekanligini tekshiramiz.
- Keyin /addGroupSub buyrug'ini bajaramiz .
- Taklif etilgan guruh identifikatorlari ro'yxatidan biz aralashmaga bir nechtasini qo'shamiz.
- Guruhlar foydalanuvchiga ro'yxatdan o'tganligiga ishonch hosil qilish uchun /listGroupSub buyrug'ini ishga tushiramiz .
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
Ushbu yangilanishlardan so'ng siz ma'lumotlar bazasidagi barcha ma'lumotlarni o'chirib tashlashingiz va qaytadan boshlashingiz kerak. O'chirish juda oddiy: siz buyruqni bajarishingiz kerak: docker-compose -f docker-compose-test.yml pastga tushadi , shundan so'ng barcha ma'lumotlar va ma'lumotlar bazasi o'chiriladi. Va uni yangilangan kodlash bilan yana ishga tushiring: docker-compose -f docker-compose-test.uml up Ma'lumotlar bazasi tayyor. Keling, yangilangan dasturni ishga tushiramiz va ko'rib chiqamiz. Men buni tezda ko'rib chiqaman va sizga natijani ko'rsataman: Va endi biz xohlagan narsamizga erishdik. Endi bu haqiqatga o'xshaydi.
Tugatish
Endi biz bu bosqichni yakunlashimiz mumkin deb o'ylayman. Ko'p narsa qilindi, haqiqatan ham juda ko'p. Ilova versiyasini 0.5.0-SNAPSHOT va RELEASE_NOTES ga yangilaymiz .
# Relizlar uchun eslatmalar ## 0.5.0-SNAPSHOT * JRTB-5: guruhga obuna bo'lish imkoniyati qo'shildi * JRTB-6: guruh obunalari ro'yxatini olish imkoniyati qo'shildi.
Keyin hamma narsa odatdagidek bo'ladi: biz barcha o'zgarishlar bilan yangi majburiyat yaratamiz. Asosiysi, hisobot berish uchun ushbu bosqichda bajarilgan ikkita vazifaning tavsifini qo'shish. Demak, sharh:
STEP_6 JRTB-5: JRTB-6 guruhiga obuna bo‘lish imkoniyati qo‘shildi: guruh obunalari ro‘yxatini ko‘rish imkoniyati qo‘shildi.
Natijada 47 ta fayl oʻzgardi... Bu katta oʻzgarish. Garchi siz funksionallik tavsifidan ayta olmaysiz. Axir, to'liq chuqurlikni tushunish uchun siz API uchun Java mijozini yozishingiz kerakligini bilishingiz kerak, bu asosan butun dasturni yangilaydi. Bu shunday, serverda ishlash - juda ko'p ish bor, lekin mijoz tomonidan ko'rish kichik...)) Do'stlar, men an'anaviy ravishda ishimga qiziqish ko'rsatish usulini taklif qilaman - githubga obuna bo'ling akkaunt , telegram kanaliga qo'shiling va biror narsa aniq bo'lmasa, maqola haqida savol yozing! Bu STEP_6 uchun oʻzgarishlar bilan tortib olish soʻroviga havola . O'qiganingiz uchun barchaga rahmat. Oldinda - obunani o'chirish, profilni o'chirish va boshqalar haqida gapiraylik. O'zgartirmang))
GO TO FULL VERSION