JavaRush /Java блогу /Random-KY /Биз макалалардын тобуна жазылуу мүмкүнчүлүгүн кошуп жатаб...
Roman Beekeeper
Деңгээл

Биз макалалардын тобуна жазылуу мүмкүнчүлүгүн кошуп жатабыз. (3-бөлүк) - "Java долбоору Адан Яга чейин"

Группада жарыяланган
Дагы бир жолу салам. Бул STEP_6нын акыркы макаласы, анда биз JRTB-6 тапшырмасына функцияларды кошуу жөнүндө сүйлөшөбүз . Мурунку эки макалада ( 1-бөлүк , 2-бөлүк ) биз сизге керектүү нерселердин бардыгын даярдап койгонбуз. Бул бөлүк процесстин туу чокусу болуп саналат. Бул макалалар сериясын башынан баштап ушул кезге чейин окугандардын баарына - чоң урмат. Бул сонун жумуш табуу үчүн сизде жетиштүү мотивация бар экенин билдирет. Эми ишке киришели."Java долбоору Адан Яга": макалалардын тобуна жазылуу мүмкүнчүлүгүн кошуу.  3-1-бөлүк

JRTB-6-ны ишке ашырабыз

Бул жолу биз тапшырманы телеграмма бот тарабынан аткарабыз, анткени маалымат базасын жаңылоо боюнча иштер бүттү, маалымат базасы an objectтери конфигурацияланган жана ишке даяр. Келиңиз, 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 аркылуу алабыз жана анын бардык топторго жазылуулары анын an objectисинде чогултулат. Биз муну экинчи бөлүктө койдук. Дагы, мен операция учурунда пайда болушу мүмкүн болгон өзгөчөлүктөр менен иштөөнү кошууну унутпаш үчүн //todo коштум. Кийинки кадам CommandContainerди жаңыртуу, ага жаңы буйрукту кошуу:
put(LIST_GROUP_SUB.getCommandName(), new GroupSubListCommand(sendBotMessageService, telegramUserService))
Бул негизинен: азыр сиз көбүрөөк тесттерди жазып, / жардам буйругун жаңыртышыңыз керек (жаңы буйруктарга сүрөттөмө кошуу) жана 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 буйругу бот менен иштөө үчүн document катары иштейт, андыктан колдонуучу аны колдоно алышы үчүн, аны жаңыртууну унутпашыбыз керек. Биз эки буйрук коштук, андыктан келе турган текстти жаңырталы:
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());
Мен ошондой эле боттун жоопторунун текстин жаңырттым: мен аны колдонуучу менен дайыма аты-жөнү боюнча боло тургандай кылып жасадым, антпесе “сен” да, “сен” да болмок... Эми жок дегенде түзүүгө болот. боттун ишинде кандайдыр бир байланыш.

Жаңыртылган бот сыналууда

Биз өзүбүздүн ботту жергorктүү түрдө ишке киргизип, төмөнкүлөрдү жасайбыз:
  1. Сыноодогу колдонуучу маалымат базасына кошулганына ынануу үчүн /start буйругун аткарабыз .
  2. Биз / help командасын аткарабыз - биз каалагандай баары жакшы экенин текшеребиз.
  3. Андан кийин биз / addGroupSub буйругун аткарабыз .
  4. Топтун идентификаторлорунун сунушталган тизмесинен биз аралашмага бир нече кошобуз.
  5. Топтор колдонуучуга катталганын текшерүү үчүн /listGroupSub буйругун иштетебиз .
Go! Биз базаны docker-compose-test.yml аркылуу ишке киргизип, SpringBoot программасын ишке киргизебиз. Андан кийин, биздин сыноо ботубузга барып, /start буйругун аткарыңыз, андан кийин /help : Андан кийин, /addGroupSub"Java долбоору Адан Яга": макалалардын тобуна жазылуу мүмкүнчүлүгүн кошуу.  3-2-бөлүк буйругун киргизиңиз : ачылуучу тизмеде Java кардары керек болсо иштеп жатат деп айтылат: бизде бардык топтор бар. Идентификаторлор, буйруктун сүрөттөлүшү бизге мындан ары эмне керек экенин түшүнүүгө жардам берет (умиттенем), ошондуктан биз жазылууга бир нече топту кошобуз: Азыр бизде 5 жазылуу бар, ошондуктан /listGroupSub буйругун иштете алабыз : Анан биз жинди нерсени алабыз.. Эмне үчүн аталышы эч кандай көйгөйсүз көрсөтүлүп жатканы түшүнүксүз , бирок бул жерде эмес. Анда эмне бар экенин көрүү үчүн базага баралы: Базада ошол эле суроолор жазылган, бирок кириллица алфавитиндегилер үчүн гана. Бул codeдоодо кандайдыр бир көйгөй бар экенин билдирет. Сыягы, сиз маалымат базасын жана маалымат базасына туташуу үчүн драйверди конфигурациялашыңыз керек. Бизге UTF-8 керек. Бирок аны кантип кошуу керек? Интернетте бир нече мүнөт издегенден кийин, мен таптым : драйвер url өзгөрмөсүн жаңыртышы керек. Ал эми docker-composeде докер сүрөтүн орнотуу үчүн эң биринчи шилтеме , бирок жооп биринчи эмес)) Ошондуктан, муну бorп туруп, касиеттерди жана докер-композит файлдарын жаңырталы. "Java долбоору Адан Яга": макалалардын тобуна жазылуу мүмкүнчүлүгүн кошуу.  3-3-бөлүк"Java долбоору Адан Яга": макалалардын тобуна жазылуу мүмкүнчүлүгүн кошуу.  3-4-бөлүк"Java долбоору Адан Яга": макалалардын тобуна жазылуу мүмкүнчүлүгүн кошуу.  3-5-бөлүк"Java долбоору Адан Яга": макалалардын тобуна жазылуу мүмкүнчүлүгүн кошуу.  3-6-бөлүк
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 Маалымат базасы даяр. Жаңыртылган тиркемени ишке киргизип, карап көрөлү. Мен аны тез эле карап чыгып, натыйжаны көрсөтөм: "Java долбоору Адан Яга": макалалардын тобуна жазылуу мүмкүнчүлүгүн кошуу.  3-7-бөлүкЭми биз каалаган нерсеге ээ болдук. Эми бул чындык окшойт.

Аяктоо

Эми бул кадамды аягына чыгара алабыз деп ойлойм. Көп нерсе жасалды, чынында эле көп. Колдонмонун versionсын 0.5.0-SNAPSHOT жана RELEASE_NOTESге жаңырталы .
# Release Notes ## 0.5.0-SNAPSHOT * JRTB-5: топко жазылуу мүмкүнчүлүгү кошулду * JRTB-6: топко жазылуулардын тизмесин алуу үчүн кошумча мүмкүнчүлүк.
Ошондо баары кадимкидей болот: биз бардык өзгөртүүлөр менен жаңы милдеттенме түзөбүз. Негизгиси - отчеттук максаттар үчүн бул кадамдын жүрүшүндө аткарылган эки иштин сыпаттамасын кошуу. Ошентип, бул жерде комментарий:
STEP_6 JRTB-5: JRTB-6 тобуна жазылуу мүмкүнчүлүгү кошулду: топко жазылуунун тизмесин көрүү мүмкүнчүлүгү кошулду.
Натыйжада 47 файл өзгөрдү... Бул чоң өзгөрүү. Функционалдык сыпаттамадан айта албайсыз да. Анын үстүнө, толук тереңдикти түшүнүү үчүн, сиз API үчүн Java кардарын жазуу керек экенин бorшиңиз керек, негизинен бүт тиркемени жаңыртуу. Мына ушундай, serverде иштөө - жумуш көп, бирок кардар тараптан көрүнүү аз...)) Достор, мен сиздерге өзүмдүн жумушума кызыгуу көрсөтүүнүн жолун сунуштайм - githubга жазылыңыз аккаунту , Telegram каналына кошулуңуз жана бир нерсе түшүнүксүз болсо, макала боюнча суроо жазыңыз! Бул STEP_6 үчүн өзгөртүүлөр менен тартуу өтүнүчүнө шилтеме . Окуу үчүн баарына рахмат. Дагы алдыда - жазылууну жок кылуу, профилди өчүрүү жана башкалар жөнүндө сүйлөшөлү. Которушпа))

Сериядагы бардык материалдардын тизмеси ушул макаланын башында.

Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION