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.
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:- 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.
- 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.
- Tiếp theo chúng ta thực thi lệnh /addGroupSub .
- 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.
- 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.
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ả: Và 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))
GO TO FULL VERSION