هيلو سڀ! اسان ڪم تي ڪم جاري رکون ٿا جيڪو اسان گذريل هفتي شروع ڪيو .
اسان JRTB-5 لاڳو ڪندا آهيون
ھاڻي اسان کي ھڪڙي حڪم شامل ڪرڻ جي ضرورت آھي ته جيئن اسان جاوا رش کان مضمونن جي ڪجھ گروپ جي رڪنيت حاصل ڪري سگھون. اهو ڪيئن ڪجي؟ اسان سڀ کان سادو منظر جي پيروي ڪنداسين جنهن سان آئون آيو آهيان. جيئن ته اسان وٽ گروپ ID ذريعي رسائي آهي، اسان کي صارف کي ان کي منتقل ڪرڻ جي ضرورت آهي. هن کي ڪرڻ لاءِ، استعمال ڪندڙ ڪمانڊ داخل ڪندو /addGroupSub GROUP_ID، جيڪو ڪم ڪندو ٻن طريقن مان: جيڪڏهن صرف ڪمانڊ پاڻ اچي: /addGroupSub ، سڀني گروپن جي لسٽ ۽ انهن جي سڃاڻپ جواب ۾ موڪلي ويندي. پوءِ استعمال ڪندڙ گروپ ID چونڊڻ جي قابل هوندو جنهن جي هن کي ضرورت آهي ۽ هن حڪم ۾ درخواست جو ٻيو نسخو ٺاهي: /addGroupSub GROUP_ID - ۽ پوءِ هن صارف وٽ هن گروپ جو رڪارڊ هوندو. منهنجو خيال آهي ته اسان مستقبل ۾ بهتر ڪري سگهون ٿا. اسان جو مقصد ترقي کي ڏيکارڻ آهي، ۽ نه سپر ٿڌو صارف تجربو (مان چوڻ ۾ شرمسار آهيان، پر مون کي خبر ناهي ته روسي ۾ اصطلاح جنهن جو مطلب هي هوندو). ڪارڪردگي کي صحيح طور تي شامل ڪرڻ لاءِ جيڪا پوري ايپليڪيشن ذريعي وڃي ٿي (اسان جي صورت ۾ ، ٽيليگرام بوٽ ڪلائنٽ کان ڊيٽابيس تائين) ، توهان کي ڪجهه آخر ۾ شروع ڪرڻ جي ضرورت آهي. اسان هن کي ڊيٽابيس جي پاسي کان ڪنداسين.ڊيٽابيس ۾ نئين لڏپلاڻ شامل ڪرڻ
ڪرڻ جي پهرين شيء هڪ نئين ڊيٽابيس لڏپلاڻ ۽ JR ۾ صارف گروپ سبسڪرپشن ڊيٽا محفوظ ڪرڻ جي صلاحيت شامل ڪرڻ آهي. ياد رکڻ لاءِ ته اهو ڪيئن هئڻ گهرجي، مضمون ڏانهن واپس وڃو ” پروجيڪٽ پلاننگ: ماپ ست ڀيرا “. اتي ٻئي تصوير ۾ ڊيٽابيس جي هڪ اندازي مطابق ڊراگرام آهي. گروپ جي معلومات کي ذخيرو ڪرڻ لاء اسان کي ٽيبل شامل ڪرڻو پوندو:- JavaRush ۾ گروپ جي ID به اسان جي ID هوندي. اسان انهن تي ڀروسو ڪريون ٿا ۽ يقين رکون ٿا ته اهي IDs منفرد آهن؛
- عنوان - اسان جي تصويرن ۾ اهو نالو هو - گروپ جو غير رسمي نالو؛ اھو آھي، جيڪو اسان JavaRush ويب سائيٽ تي ڏسون ٿا؛
- last_article_id - ۽ هي هڪ دلچسپ ميدان آهي. اهو هن گروپ ۾ آرٽيڪل جي آخري ID کي محفوظ ڪندو، جيڪو بوٽ اڳ ۾ ئي پنهنجي رڪنن ڏانهن موڪليو آهي. هن فيلڊ کي استعمال ڪندي، نون مضمونن جي ڳولا جو ميکانيزم ڪم ڪندو. نون رڪنن کي صارف جي رڪنيت حاصل ڪرڻ کان اڳ شايع ٿيل آرٽيڪل وصول نه ٿيندا: صرف اھي جيڪي گروپ ۾ رڪنيت حاصل ڪرڻ کان پوء شايع ٿيل آھن.
V00002__created_groupsub_many_to_many.sql:
-- add PRIMARY KEY FOR tg_user
ALTER TABLE tg_user ADD PRIMARY KEY (chat_id);
-- ensure that the tables with these names are removed before creating a new one.
DROP TABLE IF EXISTS group_sub;
DROP TABLE IF EXISTS group_x_user;
CREATE TABLE group_sub (
id INT,
title VARCHAR(100),
last_article_id INT,
PRIMARY KEY (id)
);
CREATE TABLE group_x_user (
group_sub_id INT NOT NULL,
user_id VARCHAR(100) NOT NULL,
FOREIGN KEY (user_id) REFERENCES tg_user(chat_id),
FOREIGN KEY (group_sub_id) REFERENCES group_sub(id),
UNIQUE(user_id, group_sub_id)
);
اهو نوٽ ڪرڻ ضروري آهي ته پهرين آئون پراڻي ٽيبل کي تبديل ڪريان ٿو - آئون ان ۾ هڪ پرائمري ڪيچ شامل ڪريان ٿو. مون کي ان وقت ڪنهن نه ڪنهن طرح ياد اچي ويو، پر هاڻي MySQL مون کي FOREIGN KEY شامل ڪرڻ جو موقعو نه ڏنو gorup_x_user ٽيبل لاءِ، ۽ هن لڏپلاڻ جي حصي طور مون ڊيٽابيس کي اپڊيٽ ڪيو. مهرباني ڪري هڪ اهم پاسو نوٽ ڪريو. ڊيٽابيس کي تبديل ڪرڻ بلڪل هن طريقي سان ٿيڻ گهرجي - هر شيء جيڪا گهربل آهي نئين لڏپلاڻ ۾، پر اڳ ۾ ئي جاري ٿيل لڏپلاڻ کي اپڊيٽ ڪرڻ سان نه. ها، اسان جي صورت ۾ ڪجھ به نه ٿيندو، ڇو ته هي هڪ آزمائشي منصوبو آهي ۽ اسان ڄاڻون ٿا ته اهو صرف هڪ جڳهه تي لڳايو ويو آهي، پر اهو غلط طريقو هوندو. پر اسان چاهيون ٿا ته سڀ ڪجهه صحيح هجي. اڳيان اچي ٿو انهن کي ٺاهڻ کان پهريان ٽيبل کي حذف ڪرڻ. ائين ڇو آهي؟ انهي ڪري ته جيڪڏهن ڪنهن اتفاق سان ڊيٽابيس ۾ اهڙن نالن سان جدول موجود هئا، لڏپلاڻ ناڪام نه ٿيندي ۽ بلڪل توقع وانگر ڪم ڪندو. ۽ پوء اسان ٻه ٽيبل شامل ڪندا آهيون. سڀ ڪجهه ائين هو جيئن اسان چاهيون ٿا. هاڻي اسان کي اسان جي اپليڪيشن شروع ڪرڻ جي ضرورت آهي. جيڪڏهن سڀ ڪجهه شروع ٿئي ٿو ۽ نه ڀڃي، پوء لڏپلاڻ رڪارڊ ٿيل آهي. ۽ ان کي ٻه ڀيرا چيڪ ڪرڻ لاءِ، اسان ڊيٽابيس ڏانهن وڃون ٿا ته پڪ ڪرڻ لاءِ ته: الف) اهڙيون ٽيبلون ظاهر ٿيون آهن؛ ب) فلائي وي ٽيڪنيڪل ٽيبل ۾ هڪ نئين داخلا آهي. هي لڏپلاڻ وارو ڪم مڪمل ڪري ٿو، اچو ته مخزن ڏانهن وڃو.
مخزن جي پرت کي شامل ڪرڻ
اسپرنگ بوٽ ڊيٽا جي مهرباني، هتي سڀ ڪجهه بلڪل سادو آهي: اسان کي GroupSub ادارو شامل ڪرڻ جي ضرورت آهي، TelegramUser کي ٿوري اپڊيٽ ڪرڻ ۽ هڪ لڳ ڀڳ خالي GroupSubRepository شامل ڪرڻ جي ضرورت آهي: اسان GroupSub انٽيٽي کي ساڳئي پيڪيج ۾ شامل ڪريو جيئن TelegramUser:package com.github.javarushcommunity.jrtb.repository.entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import static java.util.Objects.isNull;
@Data
@Entity
@Table(name = "group_sub")
@EqualsAndHashCode
public class GroupSub {
@Id
private Integer id;
@Column(name = "title")
private String title;
@Column(name = "last_article_id")
private Integer lastArticleId;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "group_x_user",
joinColumns = @JoinColumn(name = "group_sub_id"),
inverseJoinColumns = @JoinColumn(name = "user_id")
)
private List<TelegramUser> users;
public void addUser(TelegramUser telegramUser) {
if (isNull(users)) {
users = new ArrayList<>();
}
users.add(telegramUser);
}
}
هڪ ڳالهه نوٽ ڪرڻ جي قابل آهي ته اسان وٽ هڪ اضافي استعمال ڪندڙ فيلڊ آهي جنهن ۾ سڀني صارفين جو هڪ مجموعو هوندو جيڪو گروپ ۾ رڪنيت حاصل ڪيو ويو آهي. ۽ ٻه تشريحون - ManyToMany ۽ JoinTable - بلڪل اهي آهن جيڪي اسان کي هن جي ضرورت آهي. ٽيليگرام استعمال ڪندڙ لاءِ ساڳيو فيلڊ شامل ڪرڻ جي ضرورت آهي:
@ManyToMany(mappedBy = "users", fetch = FetchType.EAGER)
private List<GroupSub> groupSubs;
ھي فيلڊ استعمال ڪري ٿو جوائن جو لکيل آھي GroupSub entity ۾. ۽، حقيقت ۾، گروپسب لاءِ اسان جو مخزن وارو طبقو آهي GroupSubRepository :
package com.github.javarushcommunity.jrtb.repository;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* {@link Repository} for {@link GroupSub} entity.
*/
@Repository
public interface GroupSubRepository extends JpaRepository<GroupSub, Integer> {
}
هن مرحلي تي، اسان کي اضافي طريقن جي ضرورت نه آهي: جيڪي JpaRepository ابن ڏاڏن ۾ لاڳو ڪيا ويا آهن اسان لاء ڪافي آهن. اچو ته TelegramUserRepositoryIT ۾ هڪ ٽيسٽ لکون جيڪو چيڪ ڪندو ته اسان جا ڪيترائي کان گھڻا ڪم. ٽيسٽ جو خيال اهو آهي ته اسان هڪ sql اسڪرپٽ ذريعي ڊيٽابيس ۾ في صارف جي رڪنيت جا 5 گروپ شامل ڪنداسين، هن صارف کي هن جي ID ذريعي حاصل ڪريو ۽ چيڪ ڪريو ته اسان کي اهي گروپ مليا آهن ۽ بلڪل ساڳين قدرن سان. اهو ڪيئن ڪجي؟ توهان ڊيٽا ۾ هڪ ڪائونٽر داخل ڪري سگهو ٿا، جنهن کي اسين پوءِ وڃو ۽ چيڪ ڪري سگهون ٿا. ھتي آھي FiveGroupSubsForUser.sql اسڪرپٽ:
INSERT INTO tg_user VALUES (1, 1);
INSERT INTO group_sub VALUES
(1, 'g1', 1),
(2, 'g2', 2),
(3, 'g3', 3),
(4, 'g4', 4),
(5, 'g5', 5);
INSERT INTO group_x_user VALUES
(1, 1),
(2, 1),
(3, 1),
(4, 1),
(5, 1);
۽ امتحان پاڻ:
@Sql(scripts = {"/sql/clearDbs.sql", "/sql/fiveGroupSubsForUser.sql"})
@Test
public void shouldProperlyGetAllGroupSubsForUser() {
//when
Optional<TelegramUser> userFromDB = telegramUserRepository.findById("1");
//then
Assertions.assertTrue(userFromDB.isPresent());
List<GroupSub> groupSubs = userFromDB.get().getGroupSubs();
for (int i = 0; i < groupSubs.size(); i++) {
Assertions.assertEquals(String.format("g%s", (i + 1)), groupSubs.get(i).getTitle());
Assertions.assertEquals(i + 1, groupSubs.get(i).getId());
Assertions.assertEquals(i + 1, groupSubs.get(i).getLastArticleId());
}
}
ھاڻي اچو ته ساڳي معنيٰ جو ھڪڙو ٽيسٽ شامل ڪريون GroupSub entity لاءِ. ائين ڪرڻ لاء، اچو ته هڪ ٽيسٽ ڪلاس گروپSubRepositoryIT ساڳي پيڪيج ۾ ٺاهيون جيئن groupSubRepositoryIT :
package com.github.javarushcommunity.jrtb.repository;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.repository.entity.TelegramUser;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.jdbc.Sql;
import java.util.List;
import java.util.Optional;
import static org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace.NONE;
/**
* Integration-level testing for {@link GroupSubRepository}.
*/
@ActiveProfiles("test")
@DataJpaTest
@AutoConfigureTestDatabase(replace = NONE)
public class GroupSubRepositoryIT {
@Autowired
private GroupSubRepository groupSubRepository;
@Sql(scripts = {"/sql/clearDbs.sql", "/sql/fiveUsersForGroupSub.sql"})
@Test
public void shouldProperlyGetAllUsersForGroupSub() {
//when
Optional<GroupSub> groupSubFromDB = groupSubRepository.findById(1);
//then
Assertions.assertTrue(groupSubFromDB.isPresent());
Assertions.assertEquals(1, groupSubFromDB.get().getId());
List<TelegramUser> users = groupSubFromDB.get().getUsers();
for(int i=0; i<users.size(); i++) {
Assertions.assertEquals(String.valueOf(i + 1), users.get(i).getChatId());
Assertions.assertTrue(users.get(i).isActive());
}
}
}
۽ غائب FiveUsersForGroupSub.sql اسڪرپٽ:
INSERT INTO tg_user VALUES
(1, 1),
(2, 1),
(3, 1),
(4, 1),
(5, 1);
INSERT INTO group_sub VALUES (1, 'g1', 1);
INSERT INTO group_x_user VALUES
(1, 1),
(1, 2),
(1, 3),
(1, 4),
(1, 5);
هن نقطي تي، مخزن سان ڪم جو حصو مڪمل سمجهي سگهجي ٿو. هاڻي اچو ته هڪ سروس پرت لکون.
اسان GroupSubService لکندا آهيون
هن مرحلي تي، رڪنيتن جي گروپن سان ڪم ڪرڻ لاءِ، اسان کي صرف انهن کي محفوظ ڪرڻ جي ضرورت آهي، تنهن ڪري ڪو مسئلو ناهي: اسان هڪ پيڪيج ۾ GroupSubServiceImpl جي GroupSubService سروس ۽ ان تي عمل درآمد ڪريون ٿا جنهن ۾ ٻيون خدمتون شامل آهن - خدمت:package com.github.javarushcommunity.jrtb.service;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
/**
* Service for manipulating with {@link GroupSub}.
*/
public interface GroupSubService {
GroupSub save(String chatId, GroupDiscussionInfo groupDiscussionInfo);
}
۽ ان تي عملدرآمد:
package com.github.javarushcommunity.jrtb.service;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.repository.GroupSubRepository;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.repository.entity.TelegramUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.ws.rs.NotFoundException;
import java.util.Optional;
@Service
public class GroupSubServiceImpl implements GroupSubService {
private final GroupSubRepository groupSubRepository;
private final TelegramUserService telegramUserService;
@Autowired
public GroupSubServiceImpl(GroupSubRepository groupSubRepository, TelegramUserService telegramUserService) {
this.groupSubRepository = groupSubRepository;
this.telegramUserService = telegramUserService;
}
@Override
public GroupSub save(String chatId, GroupDiscussionInfo groupDiscussionInfo) {
TelegramUser telegramUser = telegramUserService.findByChatId(chatId).orElseThrow(NotFoundException::new);
//TODO add exception handling
GroupSub groupSub;
Optional<GroupSub> groupSubFromDB = groupSubRepository.findById(groupDiscussionInfo.getId());
if(groupSubFromDB.isPresent()) {
groupSub = groupSubFromDB.get();
Optional<TelegramUser> first = groupSub.getUsers().stream()
.filter(it -> it.getChatId().equalsIgnoreCase(chatId))
.findFirst();
if(first.isEmpty()) {
groupSub.addUser(telegramUser);
}
} else {
groupSub = new GroupSub();
groupSub.addUser(telegramUser);
groupSub.setId(groupDiscussionInfo.getId());
groupSub.setTitle(groupDiscussionInfo.getTitle());
}
return groupSubRepository.save(groupSub);
}
}
اسپرنگ ڊيٽا کي صحيح طريقي سان ڪم ڪرڻ لاءِ ۽ هڪ کان وڌيڪ رڪارڊ ٺاهڻ لاءِ، اسان کي صارف کي اسان جي ڊيٽابيس مان حاصل ڪرڻ جي ضرورت آهي سبسڪرپشن گروپ لاءِ جيڪو اسان ٺاهي رهيا آهيون ۽ ان کي GroupSub اعتراض ۾ شامل ڪريون. اهڙيء طرح، جڏهن اسان هن رڪنيت کي محفوظ ڪرڻ لاء منتقل ڪندا آهيون، هڪ ڪنيڪشن پڻ ٺاهي ويندي گروپ_x_user ٽيبل ذريعي. ٿي سگهي ٿو هڪ اهڙي صورتحال جڏهن اهڙي سبسڪرپشن گروپ ٺاهي وئي هجي ۽ توهان کي صرف ان ۾ هڪ ٻيو صارف شامل ڪرڻو پوندو. هن کي ڪرڻ لاء، اسان پهريان ڊيٽابيس مان گروپ جي سڃاڻپ حاصل ڪندا آهيون، ۽ جيڪڏهن ڪو رڪارڊ آهي، اسان ان سان ڪم ڪريون ٿا، جيڪڏهن نه، اسان هڪ نئين ٺاهيندا آهيون. اهو نوٽ ڪرڻ ضروري آهي ته TelegramUser سان ڪم ڪرڻ لاءِ اسان استعمال ڪريون ٿا TelegramUserService جي آخري SOLID اصولن تي عمل ڪرڻ لاءِ. هن وقت، جيڪڏهن اسان کي ID طرفان رڪارڊ نه ملي، مان صرف هڪ استثنا اڇلائيندس. اهو هاڻي ڪنهن به طريقي سان عمل نه ڪيو پيو وڃي: اسان هن کي آخر ۾ ڪنداسين، ايم وي پي کان اڳ. اچو ته GroupSubServiceTest ڪلاس لاءِ ٻه يونٽ ٽيسٽ لکون . اسان کي ڪهڙي ضرورت آهي؟ مان پڪ ڪرڻ چاهيان ٿو ته محفوظ ڪرڻ جو طريقو GroupSubRepository ۾ سڏيو ويندو ۽ هڪ واحد صارف سان هڪ ادارو GroupSub ڏانهن منتقل ڪيو ويندو - اهو جيڪو اسان کي ڏنل ID استعمال ڪندي TelegramUserService واپس ڪندو. ۽ ٻيو آپشن، جڏهن هڪ گروپ جي ساڳي ID سان گڏ ڊيٽابيس ۾ اڳ ۾ ئي آهي ۽ هن گروپ ۾ اڳ ۾ ئي هڪ صارف آهي، ۽ توهان کي چيڪ ڪرڻ جي ضرورت آهي ته ٻيو صارف هن گروپ ۾ شامل ڪيو ويندو ۽ هي اعتراض محفوظ ڪيو ويندو. هتي عمل درآمد آهي:
package com.github.javarushcommunity.jrtb.service;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.repository.GroupSubRepository;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.repository.entity.TelegramUser;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.Optional;
@DisplayName("Unit-level testing for GroupSubService")
public class GroupSubServiceTest {
private GroupSubService groupSubService;
private GroupSubRepository groupSubRepository;
private TelegramUser newUser;
private final static String CHAT_ID = "1";
@BeforeEach
public void init() {
TelegramUserService telegramUserService = Mockito.mock(TelegramUserService.class);
groupSubRepository = Mockito.mock(GroupSubRepository.class);
groupSubService = new GroupSubServiceImpl(groupSubRepository, telegramUserService);
newUser = new TelegramUser();
newUser.setActive(true);
newUser.setChatId(CHAT_ID);
Mockito.when(telegramUserService.findByChatId(CHAT_ID)).thenReturn(Optional.of(newUser));
}
@Test
public void shouldProperlySaveGroup() {
//given
GroupDiscussionInfo groupDiscussionInfo = new GroupDiscussionInfo();
groupDiscussionInfo.setId(1);
groupDiscussionInfo.setTitle("g1");
GroupSub expectedGroupSub = new GroupSub();
expectedGroupSub.setId(groupDiscussionInfo.getId());
expectedGroupSub.setTitle(groupDiscussionInfo.getTitle());
expectedGroupSub.addUser(newUser);
//when
groupSubService.save(CHAT_ID, groupDiscussionInfo);
//then
Mockito.verify(groupSubRepository).save(expectedGroupSub);
}
@Test
public void shouldProperlyAddUserToExistingGroup() {
//given
TelegramUser oldTelegramUser = new TelegramUser();
oldTelegramUser.setChatId("2");
oldTelegramUser.setActive(true);
GroupDiscussionInfo groupDiscussionInfo = new GroupDiscussionInfo();
groupDiscussionInfo.setId(1);
groupDiscussionInfo.setTitle("g1");
GroupSub groupFromDB = new GroupSub();
groupFromDB.setId(groupDiscussionInfo.getId());
groupFromDB.setTitle(groupDiscussionInfo.getTitle());
groupFromDB.addUser(oldTelegramUser);
Mockito.when(groupSubRepository.findById(groupDiscussionInfo.getId())).thenReturn(Optional.of(groupFromDB));
GroupSub expectedGroupSub = new GroupSub();
expectedGroupSub.setId(groupDiscussionInfo.getId());
expectedGroupSub.setTitle(groupDiscussionInfo.getTitle());
expectedGroupSub.addUser(oldTelegramUser);
expectedGroupSub.addUser(newUser);
//when
groupSubService.save(CHAT_ID, groupDiscussionInfo);
//then
Mockito.verify(groupSubRepository).findById(groupDiscussionInfo.getId());
Mockito.verify(groupSubRepository).save(expectedGroupSub);
}
}
مون پڻ شامل ڪيو init() طريقو BeforeEach تشريح سان. هن طريقي سان، اهي عام طور تي هڪ طريقو ٺاهيندا آهن جيڪي هر ٽيسٽ هلائڻ کان اڳ عمل ۾ ايندا، ۽ اهو ممڪن آهي ته ان ۾ سڀني تجربن لاء عام منطق شامل ڪيو وڃي. اسان جي حالت ۾، اسان کي لازمي طور تي بند ڪرڻ جي ضرورت آهي TelegramUserService هن طبقي جي سڀني ٽيسٽن لاء، تنهنڪري هن منطق کي عام طريقي سان منتقل ڪرڻ جو احساس آهي. هتي ٻه mokito ڊيزائن استعمال ڪيا ويا آهن:
-
Mockito.when(o1.m1(a1)).ThenReturn(o2) - ان ۾ اسان چئون ٿا ته جڏهن ميٿڊ m1 سڏيو ويندو آهي اعتراض o1 تي آرگيومينٽ a1 سان ، طريقو واپس ڪندو اعتراض o2 . اها تقريبن سڀ کان اهم ڪارڪردگي آهي موڪيٽو - ٺٺولي اعتراض کي واپس ڪرڻ لاءِ مجبور ڪرڻ لاءِ جيڪو اسان کي گهربل آهي؛
-
Mockito.verify(o1).m1(a1) - جيڪو انهي طريقي جي تصديق ڪري ٿو m1 اعتراض o1 تي دليل a1 سان سڏيو ويو . اهو ممڪن هو، يقينا، محفوظ طريقي جي واپسي اعتراض کي استعمال ڪرڻ لاء، پر مون ان کي ٿورو وڌيڪ پيچيده ڪرڻ جو فيصلو ڪيو ٻيو ممڪن طريقو ڏيکاريندي. جڏهن اهو مفيد ٿي سگهي ٿو؟ ڪيسن ۾ جتي ٺٺوليون طبقن جا طريقا باطل موٽندا آهن. پوءِ Mockito.verify کان سواءِ ڪو ڪم نه ٿيندو)))
ڪمانڊ ٺاهيو /addGroupSub
هتي اسان کي هيٺين منطق کي انجام ڏيڻ جي ضرورت آهي: جيڪڏهن اسان کي صرف هڪ حڪم ملي ٿو، بغير ڪنهن حوالي جي، اسان صارف جي مدد ڪريون ٿا ۽ کيس سڀني گروپن جي هڪ فهرست ڏيون ٿا انهن جي سڃاڻپ سان ته جيئن هو بوٽ کي ضروري معلومات منتقل ڪري سگهي. ۽ جيڪڏهن صارف ڪنهن ٻئي لفظ سان بوٽ ڏانهن هڪ حڪم موڪلي ٿو، انهي ID سان هڪ گروپ ڳوليو يا لکو ته اهڙو ڪو گروپ ناهي. اچو ته اسان جي نالي ۾ هڪ نئين قيمت شامل ڪريو - CommandName:ADD_GROUP_SUB("/addgroupsub")
اچو ته ڊيٽابيس کان ٽيليگرام بوٽ ڏانهن اڳتي وڌون - ڪمانڊ پيڪيج ۾ AddGroupSubCommand ڪلاس ٺاهيو:
package com.github.javarushcommunity.jrtb.command;
import com.github.javarushcommunity.jrtb.javarushclient.JavaRushGroupClient;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupRequestArgs;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.service.GroupSubService;
import com.github.javarushcommunity.jrtb.service.SendBotMessageService;
import org.telegram.telegrambots.meta.api.objects.Update;
import java.util.stream.Collectors;
import static com.github.javarushcommunity.jrtb.command.CommandName.ADD_GROUP_SUB;
import static com.github.javarushcommunity.jrtb.command.CommandUtils.getChatId;
import static com.github.javarushcommunity.jrtb.command.CommandUtils.getMessage;
import static java.util.Objects.isNull;
import static org.apache.commons.lang3.StringUtils.SPACE;
import static org.apache.commons.lang3.StringUtils.isNumeric;
/**
* Add Group subscription {@link Command}.
*/
public class AddGroupSubCommand implements Command {
private final SendBotMessageService sendBotMessageService;
private final JavaRushGroupClient javaRushGroupClient;
private final GroupSubService groupSubService;
public AddGroupSubCommand(SendBotMessageService sendBotMessageService, JavaRushGroupClient javaRushGroupClient,
GroupSubService groupSubService) {
this.sendBotMessageService = sendBotMessageService;
this.javaRushGroupClient = javaRushGroupClient;
this.groupSubService = groupSubService;
}
@Override
public void execute(Update update) {
if (getMessage(update).equalsIgnoreCase(ADD_GROUP_SUB.getCommandName())) {
sendGroupIdList(getChatId(update));
return;
}
String groupId = getMessage(update).split(SPACE)[1];
String chatId = getChatId(update);
if (isNumeric(groupId)) {
GroupDiscussionInfo groupById = javaRushGroupClient.getGroupById(Integer.parseInt(groupId));
if (isNull(groupById.getId())) {
sendGroupNotFound(chatId, groupId);
}
GroupSub savedGroupSub = groupSubService.save(chatId, groupById);
sendBotMessageService.sendMessage(chatId, "Подписал на группу " + savedGroupSub.getTitle());
} else {
sendGroupNotFound(chatId, groupId);
}
}
private void sendGroupNotFound(String chatId, String groupId) {
String groupNotFoundMessage = "Нет группы с ID = \"%s\"";
sendBotMessageService.sendMessage(chatId, String.format(groupNotFoundMessage, groupId));
}
private void sendGroupIdList(String chatId) {
String groupIds = javaRushGroupClient.getGroupList(GroupRequestArgs.builder().build()).stream()
.map(group -> String.format("%s - %s \n", group.getTitle(), group.getId()))
.collect(Collectors.joining());
String message = "Whatбы подписаться на группу - передай комадну вместе с ID группы. \n" +
"Например: /addGroupSub 16. \n\n" +
"я подготовил список всех групп - выберай Howую хочешь :) \n\n" +
"Name группы - ID группы \n\n" +
"%s";
sendBotMessageService.sendMessage(chatId, String.format(message, groupIds));
}
}
هي ڪلاس استعمال ڪري ٿو isNumeric طريقو apache-commons لائبريري مان، تنهنڪري اچو ته ان کي پنهنجي ياداشت ۾ شامل ڪريون:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${apache.commons.version}</version>
</dependency>
۽ ملڪيت جي بلاڪ ۾:
<apache.commons.version>3.11</apache.commons.version>
هي سڀ منطق ڪلاس ۾ آهي. ان کي غور سان پڙهو. جيڪڏھن توھان وٽ ڪي سوال / صلاحون آھن، انھن کي تبصرن ۾ لکو. ان کان پوء، اسان کي اسان جي حڪم جي نقشي ۾ CommandContainer کي حڪم شامل ڪرڻو پوندو.
.put(ADD_GROUP_SUB.getCommandName(), new AddGroupSubCommand(sendBotMessageService, javaRushGroupClient, groupSubService))
۽ هن ٽيم لاء سڀ ڪجهه. مان ڪنهن به طرح هن ڪارڪردگي کي جانچڻ چاهيان ٿو، پر اڃا تائين مان صرف ان کي ڊيٽابيس ۾ ڏسي سگهان ٿو. ڀاڱي ٽي ۾، آئون JRTB-6 مان تبديليون شامل ڪندس ته جيئن اسان انهن گروپن جي لسٽ ڏسي سگهون ٿا جن جي صارف رڪنيت حاصل ڪئي آهي. هاڻي اهو سڀ ڪجهه چيڪ ڪرڻ سٺو ٿيندو. هن کي ڪرڻ لاء، اسان ٽيليگرام ۾ سڀني عملن کي انجام ڏينداسين ۽ ڊيٽابيس ۾ چيڪ ڪنداسين. جيئن ته اسان وٽ لکيل امتحان آهن، سڀ ڪجهه ٺيڪ هجڻ گهرجي. مضمون اڳ ۾ ئي ڪافي ڊگهو آهي، تنهنڪري اسان بعد ۾ AddGroupSubCommand لاءِ ٽيسٽ لکنداسين، ۽ ڪوڊ ۾ TODO شامل ڪنداسين ته جيئن وساري نه وڃي.
GO TO FULL VERSION