JavaRush /Java Blog /Random-ID /Kami menambahkan kemampuan untuk berlangganan sekelompok ...

Kami menambahkan kemampuan untuk berlangganan sekelompok artikel. (Bagian 3) - "Proyek Java dari A sampai Z"

Dipublikasikan di grup Random-ID
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."Proyek Java dari A hingga Z": Menambahkan kemampuan untuk berlangganan sekelompok artikel.  Bagian 3 - 1

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:
  1. Kami menjalankan perintah /start untuk memastikan bahwa pengguna dalam kasus uji telah ditambahkan ke database.
  2. Kami menjalankan perintah /help - kami memeriksa apakah semuanya baik-baik saja, seperti yang kami inginkan.
  3. Selanjutnya kita jalankan perintah /addGroupSub .
  4. Dari daftar ID grup yang diusulkan, kami menambahkan beberapa ke dalam campuran.
  5. Kami menjalankan perintah /listGroupSub untuk memastikan bahwa grup terdaftar ke pengguna.
Pergi! Kami meluncurkan database melalui docker-compose-test.yml dan memulai SpringBoot kami. Selanjutnya, buka bot pengujian kami dan jalankan perintah /start, diikuti oleh /help : "Proyek Java dari A hingga Z": Menambahkan kemampuan untuk berlangganan sekelompok artikel.  Bagian 3 - 2Selanjutnya, masukkan perintah /addGroupSub : "Proyek Java dari A hingga Z": Menambahkan kemampuan untuk berlangganan sekelompok artikel.  Bagian 3 - 3Daftar drop-down mengatakan bahwa klien Java berfungsi sebagaimana mestinya: kami memiliki semua grup dengan grupnya masing-masing ID, deskripsi perintahnya membantu (mudah-mudahan) memahami apa yang kita perlukan selanjutnya, jadi kita menambahkan beberapa grup ke langganan: "Proyek Java dari A hingga Z": Menambahkan kemampuan untuk berlangganan sekelompok artikel.  Bagian 3 - 4Sekarang kita punya 5 langganan, jadi kita bisa menjalankan perintah /listGroupSub : Dan kemudian kita mendapatkan sesuatu yang gila ... Tidak jelas kenapa judulnya"Proyek Java dari A hingga Z": Menambahkan kemampuan untuk berlangganan sekelompok artikel.  Bagian 3 - 5 muncul begitu saja tanpa masalah, tapi tidak di sini. Mari kita buka database untuk melihat apa yang ada di sana: Pertanyaan yang sama dicatat dalam database, tetapi hanya untuk pertanyaan dengan alfabet Cyrillic. Ini berarti ada masalah dengan pengkodeannya. Rupanya, Anda perlu mengkonfigurasi database dan driver untuk menghubungkan ke database. Kami membutuhkan UTF-8. Tapi bagaimana cara menambahkannya? Setelah beberapa menit mencari di Internet, saya menemukan : driver perlu memperbarui variabel url. Dan untuk menyiapkan gambar buruh pelabuhan di docker-compose, tautan pertama , tetapi jawabannya bukan yang pertama)) Oleh karena itu, mengetahui hal ini, mari perbarui properti dan file docker-compose. "Proyek Java dari A hingga Z": Menambahkan kemampuan untuk berlangganan sekelompok artikel.  Bagian 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
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: "Proyek Java dari A hingga Z": Menambahkan kemampuan untuk berlangganan sekelompok artikel.  Bagian 3 - 7Dan 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))

Daftar semua materi dalam seri ini ada di awal artikel ini.

Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION