JavaRush /مدونة جافا /Random-AR /نحن نضيف القدرة على الاشتراك في مجموعة من المقالات. (الجز...
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);
   }
}
هنا كل شيء بسيط قدر الإمكان - نحصل على المستخدم باستخدام معرف الدردشة الحالي، وسيتم جمع جميع اشتراكاته في المجموعات في كائنه. لقد وضعنا هذا في الجزء الثاني. مرة أخرى، أضفت //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ظهور العنوان دون أي مشاكل، ولكن ليس هنا. دعنا نذهب إلى قاعدة البيانات لنرى ما هو موجود هناك: "مشروع جافا من الألف إلى الياء": إضافة إمكانية الاشتراك في مجموعة من المقالات.  الجزء 3 - 6يتم تسجيل نفس الأسئلة في قاعدة البيانات، ولكن فقط لأولئك الذين يستخدمون الأبجدية السيريلية. هذا يعني أن هناك مشكلة ما في التشفير. على ما يبدو، تحتاج إلى تكوين قاعدة البيانات وبرنامج التشغيل للاتصال بقاعدة البيانات. نحن بحاجة إلى UTF-8. ولكن كيف لإضافته؟ بعد عدة دقائق من البحث على الإنترنت، وجدت : يحتاج برنامج التشغيل إلى تحديث متغير عنوان url. ولإعداد صورة عامل الإرساء في docker-compose، الرابط الأول ، لكن الإجابة ليست الأولى)) لذلك، بمعرفة ذلك، فلنقم بتحديث الخصائص وملفات إنشاء عامل الإرساء.
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)، وتحديث التطبيق بالكامل بشكل أساسي. هذا هو الحال، العمل على الخادم - هناك الكثير من العمل، ولكن الرؤية من جانب العميل صغيرة...)) أيها الأصدقاء، أقدم لكم تقليديًا طريقة لإظهار الاهتمام بعملي - اشترك في جيثب الحساب ، انضم إلى قناة التليجرام واكتب سؤالاً حول المقال إذا كان هناك شيء غير واضح! إليك رابط لطلب السحب مع التغييرات الخاصة بهذه الخطوة STEP_6 . شكرا للجميع على القراءة. المزيد في المستقبل - فلنتحدث عن حذف الاشتراك وإلغاء تنشيط الملف الشخصي والمزيد. لا تبديل))

توجد قائمة بجميع المواد الموجودة في السلسلة في بداية هذه المقالة.

تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION