JavaRush /Blog Java /Random-MS /Kami menambah keupayaan untuk melanggan kumpulan artikel....

Kami menambah keupayaan untuk melanggan kumpulan artikel. (Bahagian 3) - "Projek Java dari A hingga Z"

Diterbitkan dalam kumpulan
Hai sekali lagi. Ini ialah artikel akhir daripada STEP_6, di mana kita akan bercakap tentang menambah fungsi pada tugas JRTB-6 . Dalam dua artikel sebelumnya ( bahagian 1 , bahagian 2 ) kami telah menyediakan hampir semua yang anda perlukan. Bahagian ini adalah kemuncak proses. Kepada semua orang yang telah membaca siri artikel ini hingga ke tahap ini dari awal - penghormatan yang besar. Ini bermakna anda mempunyai motivasi yang cukup untuk mencari pekerjaan yang hebat. Sekarang mari kita turun ke perniagaan."Projek Java dari A hingga Z": Menambah keupayaan untuk melanggan sekumpulan artikel.  Bahagian 3 - 1

Kami melaksanakan JRTB-6

Kali ini kami akan melakukan tugas dari sisi bot telegram, kerana kerja mengemas kini pangkalan data sudah selesai, entiti pangkalan data telah dikonfigurasikan dan bersedia untuk bekerja. Mari tambah nilai baharu pada CommandName - LIST_GROUP_SUB:
LIST_GROUP_SUB("/listGroupSub");
Mari buat arahan 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);
   }
}
Di sini semuanya semudah mungkin - kami mendapatkan pengguna menggunakan chat_id sedia ada, dan semua langganannya kepada kumpulan akan dikumpulkan dalam objeknya. Kami menetapkan ini di bahagian kedua. Sekali lagi, saya menambah //todo supaya saya tidak lupa untuk menambah pengendalian pengecualian yang mungkin muncul semasa operasi. Langkah seterusnya ialah mengemas kini CommandContainer dengan menambahkan arahan baharu kepadanya:
put(LIST_GROUP_SUB.getCommandName(), new GroupSubListCommand(sendBotMessageService, telegramUserService))
Itu pada asasnya: kini anda perlu menulis lebih banyak ujian, mengemas kini arahan /help (tambah penerangan untuk arahan baharu) dan menguji fungsi baharu melalui Telegram. Mari kita tulis ujian untuk ListGroupSubCommand . Oleh kerana logik arahan itu tidak tipikal, kami akan menulis ujian tanpa terikat dengan kelas AbstractCommandTest , seperti yang kami lakukan sebelum ini:
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 kemas kini arahan /help

Dalam kes kami, arahan /help bertindak sebagai dokumentasi untuk bekerja dengan bot, jadi kami mesti ingat untuk mengemas kininya supaya pengguna boleh menggunakannya. Kami telah menambah dua arahan, jadi mari kemas kini 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 mengemas kini teks jawapan bot: Saya membuatnya supaya sentiasa menggunakan istilah nama pertama dengan pengguna, jika tidak, kedua-dua "anda" dan "anda" akan ada... Kini anda boleh membuat sekurang-kurangnya beberapa jenis sambungan dalam kerja bot.

Menguji bot yang dikemas kini

Kami melancarkan bot kami secara tempatan dan melakukan perkara berikut:
  1. Kami melaksanakan perintah /start untuk memastikan bahawa pengguna dalam kes ujian telah ditambahkan ke pangkalan data.
  2. Kami melaksanakan perintah /help - kami menyemak sama ada semuanya ok, seperti yang kami mahu.
  3. Seterusnya kita laksanakan arahan /addGroupSub .
  4. Daripada senarai ID kumpulan yang dicadangkan, kami menambah beberapa pada campuran.
  5. Kami menjalankan arahan /listGroupSub untuk memastikan kumpulan itu didaftarkan kepada pengguna.
Pergi! Kami melancarkan pangkalan data melalui docker-compose-test.yml dan memulakan SpringBoot kami. Seterusnya, pergi ke bot ujian kami dan laksanakan arahan /start, diikuti dengan /help : "Projek Java dari A hingga Z": Menambah keupayaan untuk melanggan sekumpulan artikel.  Bahagian 3 - 2Seterusnya, masukkan arahan /addGroupSub : "Projek Java dari A hingga Z": Menambah keupayaan untuk melanggan sekumpulan artikel.  Bahagian 3 - 3Senarai juntai bawah mengatakan bahawa klien Java berfungsi sebagaimana mestinya: kami mempunyai semua kumpulan dengan mereka ID, perihalan arahan membantu (mudah-mudahan) memahami perkara yang kami perlukan seterusnya, jadi kami menambah beberapa kumpulan pada langganan: "Projek Java dari A hingga Z": Menambah keupayaan untuk melanggan sekumpulan artikel.  Bahagian 3 - 4Sekarang kami mempunyai 5 langganan, jadi kami boleh menjalankan perintah /listGroupSub : Dan kemudian kami mendapat sesuatu yang gila ... Tidak jelas mengapa tajuk itu"Projek Java dari A hingga Z": Menambah keupayaan untuk melanggan sekumpulan artikel.  Bahagian 3 - 5 hanya dipaparkan tanpa sebarang masalah, tetapi tidak di sini. Mari pergi ke pangkalan data untuk melihat apa yang ada: Soalan yang sama direkodkan dalam pangkalan data, tetapi hanya untuk mereka yang mempunyai abjad Cyrillic. Ini bermakna terdapat beberapa masalah dengan pengekodan. Nampaknya, anda perlu mengkonfigurasi pangkalan data dan pemacu untuk menyambung ke pangkalan data. Kami memerlukan UTF-8. Tetapi bagaimana untuk menambahnya? Selepas beberapa minit mencari di Internet, saya dapati : pemandu perlu mengemas kini pembolehubah url. Dan untuk menyediakan imej docker dalam docker-compose, pautan pertama , tetapi jawapannya bukanlah yang pertama)) Oleh itu, mengetahui perkara ini, mari mengemas kini sifat dan fail docker-compose. "Projek Java dari A hingga Z": Menambah keupayaan untuk melanggan sekumpulan artikel.  Bahagian 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
Selepas kemas kini ini, anda perlu memadamkan semua data dalam pangkalan data dan mulakan semula. Memadam adalah sangat mudah: anda perlu menjalankan perintah: docker-compose -f docker-compose-test.yml down selepas itu semua data dan pangkalan data dipadamkan. Dan jalankannya semula, dengan pengekodan yang dikemas kini: docker-compose -f docker-compose-test.uml up Pangkalan data sudah sedia. Mari kita lancarkan aplikasi yang dikemas kini dan lihat. Saya akan menyelesaikannya dengan cepat dan menunjukkan kepada anda hasilnya: "Projek Java dari A hingga Z": Menambah keupayaan untuk melanggan sekumpulan artikel.  Bahagian 3 - 7Dan kini kami mendapat apa yang kami mahukan. Sekarang ini kelihatan seperti kebenaran.

Berakhir

Sekarang saya rasa kita boleh melengkapkan langkah ini. Banyak yang telah dilakukan, sungguh banyak. Mari kemas kini versi aplikasi kepada 0.5.0-SNAPSHOT dan RELEASE_NOTES.
# Nota Keluaran ## 0.5.0-SNAPSHOT * JRTB-5: keupayaan tambahan untuk melanggan kumpulan * JRTB-6: keupayaan tambahan untuk mendapatkan senarai langganan kumpulan.
Kemudian semuanya seperti biasa: kami membuat komitmen baharu dengan semua perubahan. Perkara utama ialah menambah penerangan tentang dua tugasan yang telah diselesaikan semasa langkah ini untuk tujuan pelaporan. Jadi inilah komennya:
STEP_6 JRTB-5: menambahkan keupayaan untuk melanggan kumpulan JRTB-6: menambahkan keupayaan untuk melihat senarai langganan kumpulan.
Ini mengakibatkan 47 fail ditukar... Itu perubahan besar. Walaupun anda tidak dapat mengetahui dari perihalan fungsi. Lagipun, untuk memahami kedalaman penuh, anda perlu tahu bahawa anda perlu menulis klien Java untuk API, pada asasnya mengemas kini keseluruhan aplikasi. Beginilah keadaannya, bekerja di pelayan - terdapat banyak kerja, tetapi keterlihatan dari sisi pelanggan adalah kecil...)) Kawan-kawan, saya secara tradisinya menawarkan cara untuk menunjukkan minat dalam kerja saya - melanggan github akaun , sertai saluran telegram dan tulis soalan tentang artikel itu, jika ada yang tidak jelas! Berikut ialah pautan kepada permintaan tarik dengan perubahan untuk STEP_6 ini . Terima kasih semua kerana membaca. Lebih banyak lagi akan datang - mari kita bincangkan tentang memadamkan langganan, menyahaktifkan profil dan banyak lagi. Jangan tukar))

Senarai semua bahan dalam siri ini adalah pada permulaan artikel ini.

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