Halo lagi. Ini adalah artikel terakhir dari STEP_6, di mana kita akan membahas tentang menambahkan fungsionalitas ke tugas JRTB-6 . Pada dua artikel sebelumnya ( part 1 , part 2 ) kami sudah menyiapkan hampir semua yang Anda butuhkan. Bagian ini merupakan puncak dari proses tersebut. Kepada semua orang yang telah membaca rangkaian artikel ini hingga saat ini sejak awal - rasa hormat yang besar. Artinya, Anda memiliki motivasi yang cukup untuk mencari pekerjaan yang bagus. Sekarang mari kita mulai berbisnis.
Kami menerapkan JRTB-6
Kali ini kita akan melakukan tugas dari sisi bot telegram, karena pekerjaan memperbarui database sudah selesai, entitas database sudah dikonfigurasi dan siap bekerja. Mari tambahkan nilai baru ke CommandName - LIST_GROUP_SUB:LIST_GROUP_SUB("/listGroupSub");
Mari kita buat perintah 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);
}
}
Semuanya di sini sesederhana mungkin - kami mendapatkan pengguna menggunakan chat_id yang ada, dan semua langganan grupnya akan dikumpulkan di objeknya. Kami mengaturnya di bagian kedua. Sekali lagi saya menambahkan //todo agar saya tidak lupa menambahkan penanganan pengecualian yang mungkin muncul selama pengoperasian. Langkah selanjutnya adalah memperbarui CommandContainer dengan menambahkan perintah baru ke dalamnya:
put(LIST_GROUP_SUB.getCommandName(), new GroupSubListCommand(sendBotMessageService, telegramUserService))
Itu pada dasarnya: sekarang Anda perlu menulis lebih banyak tes, memperbarui perintah /help (menambahkan deskripsi untuk perintah baru) dan menguji fungsionalitas baru melalui Telegram. Mari kita menulis tes untuk ListGroupSubCommand . Karena logika perintahnya tidak umum, kita akan menulis pengujian tanpa terikat ke kelas AbstrakCommandTest , seperti yang kita lakukan sebelumnya:
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;
}
}
Mari perbarui perintah /help
Dalam kasus kita, perintah /help bertindak sebagai dokumentasi untuk bekerja dengan bot, jadi kita harus ingat untuk memperbaruinya agar pengguna dapat menggunakannya. Kami telah menambahkan dua perintah, jadi mari perbarui teks yang akan datang: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());
Saya juga memperbarui teks tanggapan bot: Saya membuatnya agar selalu sesuai dengan nama depan pengguna, jika tidak, akan ada "Anda" dan "Anda"... Sekarang setidaknya dimungkinkan untuk membuat semacam koneksi dalam pekerjaan bot.
Menguji bot yang diperbarui
Kami meluncurkan bot kami secara lokal dan melakukan hal berikut:- Kami menjalankan perintah /start untuk memastikan bahwa pengguna dalam kasus uji telah ditambahkan ke database.
- Kami menjalankan perintah /help - kami memeriksa apakah semuanya baik-baik saja, seperti yang kami inginkan.
- Selanjutnya kita jalankan perintah /addGroupSub .
- Dari daftar ID grup yang diusulkan, kami menambahkan beberapa ke dalam campuran.
- Kami menjalankan perintah /listGroupSub untuk memastikan bahwa grup terdaftar ke pengguna.
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
Setelah pembaruan ini, Anda perlu menghapus semua data dalam database dan memulai kembali. Penghapusannya sangat sederhana: Anda perlu menjalankan perintah: docker-compose -f docker-compose-test.yml down setelah itu semua data dan database dihapus. Dan jalankan lagi, dengan pengkodean yang diperbarui: docker-compose -f docker-compose-test.uml up Basis data sudah siap. Mari luncurkan aplikasi yang diperbarui dan lihat. Saya akan membahasnya dengan cepat dan menunjukkan hasilnya: Dan sekarang kita mendapatkan apa yang kita inginkan. Sekarang ini sepertinya kebenarannya.
Akhir
Sekarang saya rasa kita bisa menyelesaikan langkah ini. Banyak yang telah dilakukan, sungguh banyak. Ayo update versi aplikasi ke 0.5.0-SNAPSHOT dan RELEASE_NOTES.
# Catatan Rilis ## 0.5.0-SNAPSHOT * JRTB-5: menambahkan kemampuan untuk berlangganan di grup * JRTB-6: menambahkan kemampuan untuk mendapatkan daftar langganan grup.
Kemudian semuanya seperti biasa: kita membuat komit baru dengan semua perubahannya. Hal utama adalah menambahkan deskripsi dua tugas yang diselesaikan selama langkah ini untuk tujuan pelaporan. Jadi inilah komentarnya:
STEP_6 JRTB-5: menambahkan kemampuan untuk berlangganan pada grup JRTB-6: menambahkan kemampuan untuk melihat daftar langganan grup.
Hal ini mengakibatkan 47 file berubah... Itu perubahan besar. Meskipun Anda tidak dapat membedakannya dari deskripsi fungsinya. Lagi pula, untuk memahami secara mendalam, Anda perlu tahu bahwa Anda perlu menulis klien Java untuk API, yang pada dasarnya memperbarui seluruh aplikasi. Beginilah, bekerja di server - ada banyak pekerjaan, tetapi visibilitas dari sisi klien kecil...)) Teman-teman, saya biasanya menawarkan Anda cara untuk menunjukkan minat pada pekerjaan saya - berlangganan ke github akun , bergabunglah dengan saluran telegram dan tulis pertanyaan tentang artikel tersebut, jika ada yang kurang jelas! Berikut ini tautan ke permintaan penarikan dengan perubahan untuk STEP_6 ini . Terima kasih semuanya telah membaca. Masih banyak lagi yang akan datang - mari kita bahas tentang menghapus langganan, menonaktifkan profil, dan banyak lagi. Jangan beralih))
GO TO FULL VERSION