Bir daha salamlar. Bu, JRTB-6 tapşırığına funksionallıq əlavə etmək haqqında danışacağımız STEP_6-nın son məqaləsidir . Əvvəlki iki məqalədə ( 1-ci hissə , 2-ci hissə ) biz sizə lazım olan demək olar ki, hər şeyi hazırlamışıq. Bu hissə prosesin kulminasiya nöqtəsidir. Bu məqalə silsiləsi ilə bu nöqtəyə qədər əvvəldən oxuyan hər kəsə - böyük hörmət. Bu o deməkdir ki, sizin əla iş tapmaq üçün kifayət qədər motivasiyanız var. İndi işə keçək.
Biz JRTB-6 tətbiq edirik
Bu dəfə biz tapşırığı teleqram bot tərəfindən yerinə yetirəcəyik, çünki verilənlər bazasını yeniləmək üzrə bütün işlər tamamlanıb, verilənlər bazası obyektləri konfiqurasiya olunub və işə hazırdır. Gəlin CommandName- ə yeni dəyər əlavə edək - LIST_GROUP_SUB:LIST_GROUP_SUB("/listGroupSub");
ListGroupSubCommand əmrini yaradaq :
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);
}
}
Burada hər şey mümkün qədər sadədir - istifadəçini mövcud chat_id-dən istifadə edirik və onun qruplara bütün abunələri onun obyektində toplanacaq. Bunu ikinci hissədə qurduq. Yenə //todo əlavə etdim ki, əməliyyat zamanı yarana biləcək istisnaların idarə edilməsini əlavə etməyi unutmayaq. Növbəti addım CommandContainer- ə yeni bir əmr əlavə edərək yeniləməkdir :
put(LIST_GROUP_SUB.getCommandName(), new GroupSubListCommand(sendBotMessageService, telegramUserService))
Əsasən budur: indi daha çox test yazmalı, /help əmrini yeniləməlisən (yeni əmrlər üçün təsvir əlavə et) və Telegram vasitəsilə yeni funksionallığı sınamalısan. ListGroupSubCommand üçün test yazaq . Komandanın məntiqi səciyyəvi olmadığı üçün biz əvvəllər etdiyimiz kimi AbstractCommandTest sinfinə bağlanmadan test yazacağıq :
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 əmrini yeniləyək
Bizim vəziyyətimizdə /help əmri botla işləmək üçün sənəd kimi çıxış edir, ona görə də istifadəçinin ondan istifadə edə bilməsi üçün onu yeniləməyi yadda saxlamalıyıq. Biz iki əmr əlavə etdik, ona görə də gələcək mətni yeniləyək: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());
Botun cavablarının mətnini də yenilədim: elə etdim ki, istifadəçi ilə həmişə ad şərti olsun, əks halda həm “sən”, həm də “sən” olardı... İndi heç olmasa yaratmaq mümkün olacaq. botun işində bir növ əlaqə.
Yenilənmiş botun sınaqdan keçirilməsi
Biz yerli olaraq botu işə salırıq və aşağıdakıları edirik:- Test işindəki istifadəçinin verilənlər bazasına əlavə olunduğundan əmin olmaq üçün /start əmrini yerinə yetiririk .
- Biz / help əmrini yerinə yetiririk - istədiyimiz kimi hər şeyin qaydasında olduğunu yoxlayırıq.
- Sonra /addGroupSub əmrini yerinə yetiririk .
- Təklif olunan qrup identifikatorları siyahısından biz qarışığa bir neçəsini əlavə edirik.
- Qrupların istifadəçiyə qeydiyyatdan keçdiyinə əmin olmaq üçün /listGroupSub əmrini işlədirik .
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
Bu yeniləmələrdən sonra verilənlər bazasındakı bütün məlumatları silməli və yenidən başlamalısınız. Silinmə çox sadədir: docker-compose -f docker-compose-test.yml əmrini yerinə yetirməlisiniz, bundan sonra bütün məlumatlar və verilənlər bazası silinir. Və onu yenilənmiş kodlaşdırma ilə yenidən işə salın: docker-compose -f docker-compose-test.uml up Verilənlər bazası hazırdır. Gəlin yenilənmiş proqramı işə salaq və nəzər salaq. Mən tez bunun üzərindən keçəcəyəm və nəticəni sizə göstərəcəyəm: İndi tam olaraq istədiyimizə nail olduq. İndi bu həqiqət kimi görünür.
Son
İndi düşünürəm ki, biz bu addımı tamamlaya bilərik. Çox işlər görülüb, həqiqətən də çox. Tətbiq versiyasını 0.5.0-SNAPSHOT və RELEASE_NOTES -ə yeniləyək .
# Buraxılış Qeydləri ## 0.5.0-SNAPSHOT * JRTB-5: qrupa abunə olmaq imkanı əlavə edildi * JRTB-6: qrup abunəliklərinin siyahısını əldə etmək imkanı əlavə edildi.
Sonra hər şey həmişəki kimidir: biz bütün dəyişikliklərlə yeni öhdəlik yaradırıq. Əsas odur ki, hesabat məqsədləri üçün bu addımda tamamlanmış iki tapşırığın təsvirini əlavə edin. Beləliklə, şərh budur:
STEP_6 JRTB-5: JRTB-6 qrupuna abunə olmaq imkanı əlavə edildi: qrup abunəlik siyahısını görmək imkanı əlavə edildi.
Bu, 47 faylın dəyişdirilməsi ilə nəticələndi... Bu, böyük dəyişiklikdir. Baxmayaraq ki, funksionallığın təsvirindən deyə bilməzsiniz. Axı, tam dərinliyi başa düşmək üçün bilməlisiniz ki, API üçün Java müştəri yazmalısınız, mahiyyətcə bütün tətbiqi yeniləməlisiniz. Bu belədir, serverdə işləmək - iş çoxdur, lakin müştəri tərəfdən görünmə azdır...)) Dostlar, mən sizə ənənəvi olaraq işimə maraq göstərməyin yolunu təklif edirəm - github -a abunə olun hesab , telegram kanalına qoşulun və bir şey aydın deyilsə, məqalə haqqında sual yazın! Bu STEP_6 üçün dəyişikliklərlə çəkilmə sorğusuna keçid . Oxuduğunuz üçün hər kəsə təşəkkür edirəm. Gələcək daha çox - abunəni silmək, profili deaktiv etmək və daha çox şey haqqında danışaq. dəyişməyin))
GO TO FULL VERSION