JavaRush /בלוג Java /Random-HE /אנו מוסיפים את האפשרות להירשם לקבוצת מאמרים. (חלק 3) - "פ...
Roman Beekeeper
רָמָה

אנו מוסיפים את האפשרות להירשם לקבוצת מאמרים. (חלק 3) - "פרויקט ג'אווה מא' עד ת'"

פורסם בקבוצה
היי שוב. זהו המאמר האחרון מתוך STEP_6, בו נדבר על הוספת פונקציונליות למשימה JRTB-6 . בשני המאמרים הקודמים האלה ( חלק 1 , חלק 2 ) כבר הכנו כמעט כל מה שאתה צריך. חלק זה הוא שיאו של התהליך. לכל מי שקרא את סדרת המאמרים הזו עד לנקודה זו מההתחלה - כבוד גדול. זה אומר שיש לך מספיק מוטיבציה למצוא עבודה מצוינת. עכשיו בואו ניגש לעניינים."פרויקט ג'אווה מא' עד ת'": הוספת אפשרות להירשם לקבוצת מאמרים.  חלק 3 - 1

אנו מיישמים JRTB-6

הפעם נבצע את המשימה מהצד של בוט הטלגרם, מכיוון שהעבודה על עדכון בסיס הנתונים מתבצעת כולה, ישויות בסיס הנתונים מוגדרות ומוכנות לעבודה. בואו נוסיף ערך חדש ל- CommandName - LIST_GROUP_SUB:
LIST_GROUP_SUB("/listGroupSub");
בואו ניצור פקודת 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);
   }
}
כאן הכל פשוט ככל האפשר - אנו מקבלים את המשתמש באמצעות ה-chat_id הקיים, וכל המנויים שלו לקבוצות יאספו באובייקט שלו. קבענו את זה בחלק השני. שוב, הוספתי //todo כדי שלא אשכח להוסיף טיפול בחריגים שעלולים להתעורר במהלך הפעולה. השלב הבא הוא לעדכן את CommandContainer על ידי הוספת פקודה חדשה אליו:
put(LIST_GROUP_SUB.getCommandName(), new GroupSubListCommand(sendBotMessageService, telegramUserService))
זהו בעצם: עכשיו אתה צריך לכתוב עוד בדיקות, לעדכן את הפקודה /help (הוסף תיאור עבור פקודות חדשות) ולבדוק את הפונקציונליות החדשה באמצעות Telegram. בואו נכתוב מבחן עבור ListGroupSubCommand . מכיוון שהלוגיקה של הפקודה אינה אופיינית, נכתוב מבחן מבלי להיות קשור למחלקה AbstractCommandTest , כפי שעשינו קודם:
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;
   }
}

בואו נעדכן את הפקודה /help

במקרה שלנו, הפקודה /help פועלת כתיעוד לעבודה עם הבוט, ולכן עלינו לזכור לעדכן אותה כדי שהמשתמש יוכל להשתמש בה. הוספנו שתי פקודות, אז בואו נעדכן את הטקסט שיגיע:
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());
עדכנתי גם את טקסט התגובות של הבוט: עשיתי שזה יהיה תמיד במונחי שם פרטי עם המשתמש, אחרת יהיו גם "אתה" וגם "אתה"... עכשיו אפשר יהיה ליצור לפחות סוג של חיבור בעבודת הבוט.

בודק את הבוט המעודכן

אנו משיקים את הבוט שלנו באופן מקומי ועושים את הפעולות הבאות:
  1. אנו מבצעים את הפקודה /start כדי להיות בטוחים שהמשתמש במקרה הבדיקה נוסף למסד הנתונים.
  2. אנחנו מבצעים את הפקודה /help - אנחנו בודקים שהכל בסדר, כמו שרצינו.
  3. לאחר מכן אנו מבצעים את הפקודה /addGroupSub .
  4. מתוך הרשימה המוצעת של מזהי קבוצות, אנו מוסיפים כמה לתמהיל.
  5. אנו מפעילים את הפקודה /listGroupSub כדי לוודא שהקבוצות רשומות למשתמש.
ללכת! אנו משיקים את מסד הנתונים דרך docker-compose-test.yml ומתחילים את SpringBoot שלנו. לאחר מכן, עבור אל בוט הבדיקה שלנו ובצע את הפקודה /start, ולאחר מכן /help : "פרויקט ג'אווה מא' עד ת'": הוספת אפשרות להירשם לקבוצת מאמרים.  חלק 3 - 2לאחר מכן, הזן את הפקודה /addGroupSub : "פרויקט ג'אווה מא' עד ת'": הוספת אפשרות להירשם לקבוצת מאמרים.  חלק 3 - 3הרשימה הנפתחת אומרת שלקוח Java עובד כמו שצריך: יש לנו את כל הקבוצות שלהם מזהים, תיאור של הפקודה עוזר (בתקווה) להבין מה אנחנו צריכים הלאה, אז אנחנו מוסיפים כמה קבוצות למנוי: "פרויקט ג'אווה מא' עד ת'": הוספת אפשרות להירשם לקבוצת מאמרים.  חלק 3 - 4עכשיו יש לנו 5 מנויים, כדי שנוכל להריץ את הפקודה /listGroupSub : ואז נקבל משהו מטורף ... לא ברור מדוע הכותרת"פרויקט ג'אווה מא' עד ת'": הוספת אפשרות להירשם לקבוצת מאמרים.  חלק 3 - 5 הופיעה רק ללא בעיות, אבל לא כאן. בוא נלך למסד הנתונים כדי לראות מה יש שם: אותן שאלות רשומות במסד הנתונים, אבל רק לבעלי האלפבית הקירילי. זה אומר שיש בעיה כלשהי בקידוד. ככל הנראה, אתה צריך להגדיר את מסד הנתונים ואת מנהל ההתקן לחיבור למסד הנתונים. אנחנו צריכים UTF-8. אבל איך מוסיפים את זה? לאחר מספר דקות של חיפוש באינטרנט, מצאתי : מנהל ההתקן צריך לעדכן את משתנה ה-url. ולהגדרת תמונת docker ב-docker-compose, הקישור הראשון מאוד , אבל התשובה היא לא הראשונה)) לכן, בידיעה זו, בואו נעדכן את המאפיינים וקבצי docker-compose. "פרויקט ג'אווה מא' עד ת'": הוספת אפשרות להירשם לקבוצת מאמרים.  חלק 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
לאחר העדכונים הללו, עליך למחוק את כל הנתונים במסד הנתונים ולהתחיל מחדש. המחיקה פשוטה מאוד: עליך להפעיל את הפקודה: docker-compose -f docker-compose-test.yml למטה ולאחר מכן כל הנתונים ומסד הנתונים נמחקים. והפעל אותו שוב, עם הקידוד המעודכן: docker-compose -f docker-compose-test.uml up מסד הנתונים מוכן. בואו נפעיל את האפליקציה המעודכנת ונסתכל. אני אעבור על זה במהירות ואראה לכם את התוצאה: "פרויקט ג'אווה מא' עד ת'": הוספת אפשרות להירשם לקבוצת מאמרים.  חלק 3 - 7ועכשיו קיבלנו בדיוק את מה שרצינו. עכשיו זה נראה כמו האמת.

סִיוּם

עכשיו אני חושב שאנחנו יכולים להשלים את השלב הזה. נעשה הרבה, באמת הרבה. בואו נעדכן את גרסת האפליקציה ל -0.5.0-SNAPSHOT ול-RELEASE_NOTES.
# הערות שחרור ## 0.5.0-SNAPSHOT * JRTB-5: נוספה יכולת להירשם בקבוצה * JRTB-6: נוספה יכולת לקבל רשימה של מנויי קבוצה.
ואז הכל כרגיל: אנחנו יוצרים מחויבות חדשה עם כל השינויים. העיקר להוסיף תיאור של שתי המשימות שהושלמו בשלב זה לצורכי דיווח. אז הנה ההערה:
STEP_6 JRTB-5: נוספה יכולת להירשם בקבוצה JRTB-6: נוספה יכולת לראות את רשימת המנוי הקבוצתי.
זה הביא ל-47 קבצים שהשתנו... זה שינוי גדול. למרות שאתה לא יכול לדעת מהתיאור של הפונקציונליות. אחרי הכל, כדי להבין את מלוא העומק, אתה צריך לדעת שאתה צריך לכתוב לקוח Java עבור ה-API, בעצם עדכון היישום כולו. ככה זה, עבודה על שרת - יש הרבה עבודה, אבל הנראות מצד הלקוח קטנה...)) חברים, אני מציע לכם באופן מסורתי דרך לגלות עניין בעבודה שלי - הירשמו ל- github חשבון , הצטרף לערוץ הטלגרם וכתוב שאלה על המאמר, אם משהו לא ברור! הנה קישור לבקשת המשיכה עם שינויים עבור STEP_6 זה . תודה לכולם על הקריאה. עוד יבואו - בואו נדבר על מחיקת מנוי, ביטול פרופיל ועוד. אל תחליף))

רשימה של כל החומרים בסדרה נמצאת בתחילת מאמר זה.

הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION