Тағы да сәлем. Бұл 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 пәрменін жаңарту (жаңа пәрмендерге сипаттама қосу) және 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 пәрменін орындау керек, содан кейін барлық деректер мен дерекқор жойылады. Және оны жаңартылған codeтаумен қайта іске қосыңыз: 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 файл өзгерді... Бұл үлкен өзгеріс. Функционалдық сипаттамасынан айта алмайсыз. Ақыр соңында, толық тереңдікті түсіну үшін сіз API үшін Java клиентін жазуыңыз керек екенін білуіңіз керек, бұл бүкіл қолданбаны жаңартады. Міне осылай, serverде жұмыс істеу - жұмыс көп, бірақ клиент жағынан көріну аз...)) Достар, мен сіздерге өз жұмысыма қызығушылық танытудың дәстүрлі әдісін ұсынамын - github -қа жазылыңыз. тіркелгі , телеграм каналына қосылыңыз және бірдеңе түсініксіз болса, мақала туралы сұрақ жазыңыз! Мұнда осы STEP_6 үшін өзгертулері бар тарту сұрауына сілтеме берілген . Оқығаныңыз үшін барлығына рахмет. Алдағы уақытта жазылымды жою, профильді өшіру және т.б. туралы сөйлесейік. Ауыспа))
GO TO FULL VERSION