JavaRush /Blog Java /Random-VI /Chúng tôi đang thêm khả năng đăng ký một nhóm bài viết. (...
Roman Beekeeper
Mức độ

Chúng tôi đang thêm khả năng đăng ký một nhóm bài viết. (Phần 3) - "Dự án Java từ A đến Z"

Xuất bản trong nhóm
Chào bạn lần nữa nhé. Đây là bài viết cuối cùng của STEP_6, trong đó chúng ta sẽ nói về việc thêm chức năng vào tác vụ JRTB-6 . Trong hai bài viết trước ( phần 1 , phần 2 ) chúng tôi đã chuẩn bị hầu hết mọi thứ bạn cần. Phần này là đỉnh cao của quá trình. Gửi tới tất cả những ai đã đọc loạt bài này cho đến thời điểm này ngay từ đầu - sự tôn trọng sâu sắc. Điều này có nghĩa là bạn có đủ động lực để tìm được một công việc tuyệt vời. Bây giờ chúng ta hãy bắt tay vào công việc."Dự án Java từ A đến Z": Thêm tính năng đăng ký theo dõi một nhóm bài viết.  Phần 3 - 1

Chúng tôi triển khai JRTB-6

Lần này chúng ta sẽ thực hiện nhiệm vụ từ phía bot telegram, vì công việc cập nhật cơ sở dữ liệu đã hoàn tất, các thực thể cơ sở dữ liệu đã được cấu hình và sẵn sàng hoạt động. Hãy thêm một giá trị mới vào CommandName - LIST_GROUP_SUB:
LIST_GROUP_SUB("/listGroupSub");
Hãy tạo một lệnh 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);
   }
}
Ở đây mọi thứ đều đơn giản nhất có thể - chúng tôi thu hút người dùng sử dụng chat_id hiện có và tất cả các đăng ký của anh ấy vào nhóm sẽ được thu thập trong đối tượng của anh ấy. Chúng tôi thiết lập điều này trong phần thứ hai. Một lần nữa, tôi đã thêm //todo để không quên thêm việc xử lý các ngoại lệ có thể xuất hiện trong quá trình hoạt động. Bước tiếp theo là cập nhật CommandContainer bằng cách thêm lệnh mới vào nó:
put(LIST_GROUP_SUB.getCommandName(), new GroupSubListCommand(sendBotMessageService, telegramUserService))
Về cơ bản là như vậy: bây giờ bạn cần viết thêm các bài kiểm tra, cập nhật lệnh /help (thêm mô tả cho các lệnh mới) và kiểm tra chức năng mới thông qua Telegram. Hãy viết một bài kiểm tra cho ListGroupSubCommand . Vì logic của lệnh không điển hình nên chúng ta sẽ viết một bài kiểm thử mà không bị ràng buộc với lớp Tóm tắtCommandTest , như chúng ta đã làm trước đây:
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;
   }
}

Hãy cập nhật lệnh /help

Trong trường hợp của chúng tôi, lệnh /help đóng vai trò là tài liệu để làm việc với bot, vì vậy chúng tôi phải nhớ cập nhật nó để người dùng có thể sử dụng nó. Chúng tôi đã thêm hai lệnh, vì vậy hãy cập nhật văn bản sẽ xuất hiện:
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());
Tôi cũng đã cập nhật văn bản phản hồi của bot: Tôi đã làm nó để nó luôn có tên riêng với người dùng, nếu không sẽ có cả “bạn” và “bạn”... Bây giờ có thể tạo ít nhất một số loại kết nối trong công việc của bot.

Kiểm tra bot cập nhật

Chúng tôi khởi chạy bot của mình tại địa phương và thực hiện như sau:
  1. Chúng tôi thực thi lệnh /start để đảm bảo rằng người dùng trong trường hợp thử nghiệm đã được thêm vào cơ sở dữ liệu.
  2. Chúng tôi thực thi lệnh /help - chúng tôi kiểm tra xem mọi thứ có ổn như chúng tôi mong muốn không.
  3. Tiếp theo chúng ta thực thi lệnh /addGroupSub .
  4. Từ danh sách ID nhóm được đề xuất, chúng tôi thêm một số ID vào danh sách kết hợp.
  5. Chúng tôi chạy lệnh /listGroupSub để đảm bảo rằng các nhóm đã được đăng ký cho người dùng.
Đi! Chúng tôi khởi chạy cơ sở dữ liệu thông qua docker-compose-test.yml và khởi động SpringBoot. Tiếp theo, đi đến bot thử nghiệm của chúng tôi và thực thi lệnh /start, sau đó là /help : "Dự án Java từ A đến Z": Thêm tính năng đăng ký theo dõi một nhóm bài viết.  Phần 3 - 2Tiếp theo, nhập lệnh /addGroupSub : "Dự án Java từ A đến Z": Thêm tính năng đăng ký theo dõi một nhóm bài viết.  Phần 3 - 3Danh sách thả xuống cho biết máy khách Java đang hoạt động như bình thường: chúng tôi có tất cả các nhóm với ID, mô tả lệnh sẽ giúp (hy vọng) hiểu những gì chúng tôi cần tiếp theo, vì vậy chúng tôi thêm một số nhóm vào đăng ký: "Dự án Java từ A đến Z": Thêm tính năng đăng ký theo dõi một nhóm bài viết.  Phần 3 - 4Bây giờ chúng tôi có 5 đăng ký, vì vậy chúng tôi có thể chạy lệnh /listGroupSub : Và sau đó chúng tôi nhận được một điều điên rồ nào đó ... Không rõ tại sao tiêu đề"Dự án Java từ A đến Z": Thêm tính năng đăng ký theo dõi một nhóm bài viết.  Phần 3 - 5 chỉ hiển thị mà không gặp vấn đề gì, còn ở đây thì không. Chúng ta hãy vào cơ sở dữ liệu để xem có gì: Các câu hỏi tương tự được ghi lại trong cơ sở dữ liệu, nhưng chỉ dành cho những câu hỏi có bảng chữ cái Cyrillic. Điều này có nghĩa là có một số vấn đề với việc mã hóa. Rõ ràng, bạn cần định cấu hình cơ sở dữ liệu và trình điều khiển để kết nối với cơ sở dữ liệu. Chúng tôi cần UTF-8. Nhưng làm thế nào để thêm nó? Sau vài phút tìm kiếm trên Internet, tôi thấy : trình điều khiển cần cập nhật biến url. Và để thiết lập hình ảnh docker trong docker-compose, liên kết đầu tiên , nhưng câu trả lời không phải là đầu tiên)) Do đó, biết điều này, hãy cập nhật các thuộc tính và tệp docker-compose. "Dự án Java từ A đến Z": Thêm tính năng đăng ký theo dõi một nhóm bài viết.  Phần 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
Sau những cập nhật này, bạn cần xóa tất cả dữ liệu trong cơ sở dữ liệu và bắt đầu lại. Việc xóa rất đơn giản: bạn cần chạy lệnh: docker-compose -f docker-compose-test.yml down sau đó tất cả dữ liệu và cơ sở dữ liệu sẽ bị xóa. Và chạy lại nó, với mã hóa được cập nhật: docker-compose -f docker-compose-test.uml up Cơ sở dữ liệu đã sẵn sàng. Hãy khởi chạy ứng dụng cập nhật và xem qua. Tôi sẽ trình bày nhanh và cho bạn xem kết quả: "Dự án Java từ A đến Z": Thêm tính năng đăng ký theo dõi một nhóm bài viết.  Phần 3 - 7Và bây giờ chúng tôi đã có được chính xác những gì mình muốn. Bây giờ điều này có vẻ giống như sự thật.

Kết thúc

Bây giờ tôi nghĩ chúng ta có thể hoàn thành bước này. Rất nhiều điều đã được thực hiện, thực sự rất nhiều. Hãy cập nhật phiên bản ứng dụng lên 0.5.0-SNAPSHOT và RELEASE_NOTES.
# Ghi chú phát hành ## 0.5.0-SNAPSHOT * JRTB-5: đã thêm khả năng đăng ký theo nhóm * JRTB-6: đã thêm khả năng lấy danh sách đăng ký nhóm.
Sau đó, mọi thứ vẫn như bình thường: chúng tôi tạo một cam kết mới với tất cả các thay đổi. Điều chính là thêm mô tả về hai nhiệm vụ đã được hoàn thành trong bước này nhằm mục đích báo cáo. Vì vậy, đây là nhận xét:
STEP_6 JRTB-5: thêm khả năng đăng ký vào nhóm JRTB-6: thêm khả năng xem danh sách đăng ký nhóm.
Điều này dẫn đến 47 tập tin bị thay đổi... Đó là một thay đổi lớn. Mặc dù bạn không thể biết được từ mô tả chức năng. Rốt cuộc, để hiểu toàn bộ chiều sâu, bạn cần biết rằng bạn cần viết một ứng dụng khách Java cho API, về cơ bản là cập nhật toàn bộ ứng dụng. Mọi chuyện là như thế này, làm việc trên máy chủ - có rất nhiều công việc, nhưng khả năng hiển thị từ phía khách hàng rất nhỏ...)) Các bạn ơi, theo truyền thống, tôi sẽ cung cấp cho bạn một cách để thể hiện sự quan tâm đến công việc của tôi - đăng ký một github tài khoản , tham gia kênh telegram và viết câu hỏi về bài viết, nếu có điều gì chưa rõ! Đây là liên kết đến yêu cầu kéo với những thay đổi cho STEP_6 này . Cảm ơn mọi người đã đọc. Sắp tới - hãy nói về việc xóa đăng ký, hủy kích hoạt hồ sơ, v.v. Đừng chuyển đổi))

Danh sách tất cả các tài liệu trong loạt bài này nằm ở đầu bài viết này.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION