JavaRush /Java-Blog /Random-DE /Wir fügen die Möglichkeit hinzu, eine Gruppe von Artikeln...

Wir fügen die Möglichkeit hinzu, eine Gruppe von Artikeln zu abonnieren. (Teil 3) - „Java-Projekt von A bis Z“

Veröffentlicht in der Gruppe Random-DE
Hallo nochmal. Dies ist der letzte Artikel von STEP_6, in dem wir über das Hinzufügen von Funktionalität zur JRTB-6- Aufgabe sprechen . In den beiden vorherigen Artikeln ( Teil 1 , Teil 2 ) haben wir bereits fast alles vorbereitet, was Sie brauchen. Dieser Teil ist der Höhepunkt des Prozesses. An alle, die diese Artikelserie bis hierher von Anfang an gelesen haben – großer Respekt. Das bedeutet, dass Sie genug Motivation haben, um einen tollen Job zu finden. Kommen wir nun zur Sache.„Java-Projekt von A bis Z“: Hinzufügen der Möglichkeit, eine Gruppe von Artikeln zu abonnieren.  Teil 3 - 1

Wir implementieren JRTB-6

Dieses Mal werden wir die Aufgabe von der Seite des Telegram-Bots aus erledigen, da die Arbeit zur Aktualisierung der Datenbank abgeschlossen ist und die Datenbankentitäten konfiguriert und einsatzbereit sind. Fügen wir CommandName einen neuen Wert hinzu – LIST_GROUP_SUB:
LIST_GROUP_SUB("/listGroupSub");
Erstellen wir einen ListGroupSubCommand- Befehl :
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);
   }
}
Hier ist alles so einfach wie möglich: Wir erhalten den Benutzer mithilfe der vorhandenen chat_id und alle seine Abonnements für Gruppen werden in seinem Objekt gesammelt. Das haben wir im zweiten Teil aufgebaut. Auch hier habe ich //todo hinzugefügt, damit ich nicht vergesse, die Behandlung von Ausnahmen hinzuzufügen, die während des Betriebs auftreten können. Der nächste Schritt besteht darin, den CommandContainer zu aktualisieren , indem Sie ihm einen neuen Befehl hinzufügen:
put(LIST_GROUP_SUB.getCommandName(), new GroupSubListCommand(sendBotMessageService, telegramUserService))
Das ist im Grunde alles: Jetzt müssen Sie weitere Tests schreiben, den Befehl /help aktualisieren (eine Beschreibung für neue Befehle hinzufügen) und die neue Funktionalität per Telegram testen. Schreiben wir einen Test für ListGroupSubCommand . Da die Logik des Befehls nicht typisch ist, schreiben wir einen Test, ohne an die Klasse „AbstractCommandTest“ gebunden zu sein, wie wir es zuvor getan haben:
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;
   }
}

Lassen Sie uns den Befehl /help aktualisieren

In unserem Fall dient der Befehl /help als Dokumentation für die Arbeit mit dem Bot, daher müssen wir daran denken, ihn zu aktualisieren, damit der Benutzer ihn verwenden kann. Wir haben zwei Befehle hinzugefügt, also aktualisieren wir den kommenden Text:
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());
Ich habe auch den Text der Antworten des Bots aktualisiert: Ich habe ihn so gestaltet, dass er mit dem Benutzer immer mit dem Vornamen gesprochen wird, sonst gäbe es sowohl „Sie“ als auch „Sie“... Jetzt wird es möglich sein, zumindest etwas zu erstellen irgendeine Verbindung in der Arbeit des Bots.

Testen des aktualisierten Bots

Wir starten unseren Bot lokal und gehen wie folgt vor:
  1. Wir führen den Befehl /start aus , um sicherzustellen, dass der Benutzer im Testfall zur Datenbank hinzugefügt wurde.
  2. Wir führen den Befehl /help aus – wir prüfen, ob alles in Ordnung ist, wie wir es wollten.
  3. Als nächstes führen wir den Befehl /addGroupSub aus .
  4. Aus der vorgeschlagenen Liste der Gruppen-IDs fügen wir der Mischung mehrere hinzu.
  5. Wir führen den Befehl /listGroupSub aus , um sicherzustellen, dass die Gruppen beim Benutzer registriert sind.
Gehen! Wir starten die Datenbank über docker-compose-test.yml und starten unser SpringBoot. Gehen Sie als Nächstes zu unserem Testbot und führen Sie den Befehl /start aus, gefolgt von /help : „Java-Projekt von A bis Z“: Hinzufügen der Möglichkeit, eine Gruppe von Artikeln zu abonnieren.  Teil 3 - 2Geben Sie als Nächstes den Befehl /addGroupSub ein : „Java-Projekt von A bis Z“: Hinzufügen der Möglichkeit, eine Gruppe von Artikeln zu abonnieren.  Teil 3 - 3Die Dropdown-Liste besagt, dass der Java-Client ordnungsgemäß funktioniert: Wir haben alle Gruppen mit ihren IDs, eine Beschreibung des Befehls hilft (hoffentlich) zu verstehen, was wir als nächstes brauchen, also fügen wir dem Abonnement mehrere Gruppen hinzu: „Java-Projekt von A bis Z“: Hinzufügen der Möglichkeit, eine Gruppe von Artikeln zu abonnieren.  Teil 3 - 4Jetzt haben wir 5 Abonnements, also können wir den Befehl /listGroupSub ausführen : Und dann bekommen wir etwas Verrücktes ... Es ist nicht klar, warum der Titel einfach ohne Probleme „Java-Projekt von A bis Z“: Hinzufügen der Möglichkeit, eine Gruppe von Artikeln zu abonnieren.  Teil 3 - 5angezeigt wurde , aber nicht hier. Schauen wir mal in der Datenbank nach, was da steht: In der Datenbank sind die gleichen Fragen erfasst, allerdings nur für solche mit kyrillischem Alphabet. Das bedeutet, dass es ein Problem mit der Kodierung gibt. Anscheinend müssen Sie die Datenbank und den Treiber für die Verbindung zur Datenbank konfigurieren. Wir brauchen UTF-8. Aber wie fügt man es hinzu? Nachdem ich mehrere Minuten im Internet gesucht hatte, stellte ich fest : Der Treiber muss die URL-Variable aktualisieren. Und zum Einrichten eines Docker-Images in Docker-Compose der allererste Link , aber die Antwort ist nicht die erste)) Daher aktualisieren wir in diesem Wissen die Eigenschaften und Docker-Compose-Dateien. „Java-Projekt von A bis Z“: Hinzufügen der Möglichkeit, eine Gruppe von Artikeln zu abonnieren.  Teil 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
Nach diesen Aktualisierungen müssen Sie alle Daten in der Datenbank löschen und von vorne beginnen. Das Löschen ist ganz einfach: Sie müssen den folgenden Befehl ausführen: docker-compose -f docker-compose-test.yml down, woraufhin alle Daten und die Datenbank gelöscht werden. Und führen Sie es erneut mit der aktualisierten Codierung aus: docker-compose -f docker-compose-test.uml up Die Datenbank ist bereit. Lassen Sie uns die aktualisierte Anwendung starten und einen Blick darauf werfen. Ich gehe es kurz durch und zeige Ihnen das Ergebnis: „Java-Projekt von A bis Z“: Hinzufügen der Möglichkeit, eine Gruppe von Artikeln zu abonnieren.  Teil 3 - 7Und jetzt haben wir genau das bekommen, was wir wollten. Das scheint nun die Wahrheit zu sein.

Ende

Jetzt denke ich, dass wir diesen Schritt abschließen können. Es hat sich viel getan, wirklich viel. Aktualisieren wir die Anwendungsversion auf 0.5.0-SNAPSHOT und RELEASE_NOTES.
# Versionshinweise ## 0.5.0-SNAPSHOT * JRTB-5: Möglichkeit zum Abonnieren einer Gruppe hinzugefügt * JRTB-6: Möglichkeit hinzugefügt, eine Liste von Gruppenabonnements abzurufen.
Dann ist alles wie gewohnt: Wir erstellen ein neues Commit mit allen Änderungen. Die Hauptsache ist, zu Berichtszwecken eine Beschreibung der beiden Aufgaben hinzuzufügen, die in diesem Schritt erledigt wurden. Hier also der Kommentar:
STEP_6 JRTB-5: Möglichkeit zum Abonnieren einer Gruppe hinzugefügt. JRTB-6: Möglichkeit hinzugefügt, die Liste der Gruppenabonnements anzuzeigen.
Dies führte zu 47 geänderten Dateien ... Das ist eine große Veränderung. Allerdings kann man das anhand der Funktionsbeschreibung nicht erkennen. Um die ganze Tiefe zu verstehen, müssen Sie schließlich wissen, dass Sie einen Java-Client für die API schreiben müssen, der im Wesentlichen die gesamte Anwendung aktualisiert. So ist es, auf einem Server zu arbeiten – es gibt viel Arbeit, aber die Sichtbarkeit auf der Clientseite ist gering...)) Freunde, ich biete euch traditionell eine Möglichkeit an, Interesse an meiner Arbeit zu zeigen – abonnieren Sie einen Github Konto , treten Sie dem Telegram-Kanal bei und schreiben Sie eine Frage zum Artikel, wenn etwas nicht klar ist! Hier ist ein Link zum Pull-Request mit Änderungen für diesen STEP_6 . Vielen Dank an alle fürs Lesen. Es folgt noch mehr – sprechen wir über das Löschen eines Abonnements, das Deaktivieren eines Profils und mehr. Nicht wechseln))

Eine Liste aller Materialien der Serie finden Sie am Anfang dieses Artikels.

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