feat: campaign draft, wip
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
5788d59516
commit
d93fe8d3b9
|
@ -0,0 +1,60 @@
|
|||
package com.github.polpetta.mezzotre.orm.model;
|
||||
|
||||
import io.ebean.annotation.Length;
|
||||
import io.ebean.annotation.NotNull;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.Null;
|
||||
|
||||
@Entity
|
||||
public class Campaign extends Base {
|
||||
|
||||
@Id
|
||||
@Length(64)
|
||||
private final String id;
|
||||
|
||||
@Length(256)
|
||||
@NotNull
|
||||
private String campaignName;
|
||||
|
||||
@Nullable @Null private String description;
|
||||
|
||||
@ManyToMany(fetch = FetchType.LAZY)
|
||||
private List<User> users;
|
||||
|
||||
public Campaign(String id, String campaignName, @Nullable String description) {
|
||||
this.id = id;
|
||||
this.campaignName = campaignName;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getCampaignName() {
|
||||
return campaignName;
|
||||
}
|
||||
|
||||
public void setCampaignName(String campaignName) {
|
||||
this.campaignName = campaignName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(@Nullable String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public List<User> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public void setUsers(List<User> users) {
|
||||
this.users = users;
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import io.ebean.annotation.ConstraintMode;
|
|||
import io.ebean.annotation.DbForeignKey;
|
||||
import io.ebean.annotation.Length;
|
||||
import io.ebean.annotation.NotNull;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.*;
|
||||
|
||||
|
@ -22,17 +23,20 @@ public class User extends Base {
|
|||
@OneToOne(fetch = FetchType.LAZY, optional = true)
|
||||
@DbForeignKey(onDelete = ConstraintMode.CASCADE)
|
||||
@JoinColumn(name = "telegram_id", referencedColumnName = "id")
|
||||
private TgChat telegramId;
|
||||
private TgChat telegramChat;
|
||||
|
||||
@ManyToMany(fetch = FetchType.LAZY)
|
||||
private List<Campaign> campaigns;
|
||||
|
||||
@Length(256)
|
||||
@Nullable
|
||||
private String emailAddress;
|
||||
|
||||
public User(String id, String emailAddress, Boolean isActive, TgChat telegramId) {
|
||||
public User(String id, String emailAddress, Boolean isActive, TgChat telegramChat) {
|
||||
this.id = id;
|
||||
this.emailAddress = emailAddress;
|
||||
this.isActive = isActive;
|
||||
this.telegramId = telegramId;
|
||||
this.telegramChat = telegramChat;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
|
@ -47,19 +51,28 @@ public class User extends Base {
|
|||
isActive = active;
|
||||
}
|
||||
|
||||
public TgChat getTelegramId() {
|
||||
return telegramId;
|
||||
public TgChat getTelegramChat() {
|
||||
return telegramChat;
|
||||
}
|
||||
|
||||
public void setTelegramId(TgChat telegramId) {
|
||||
this.telegramId = telegramId;
|
||||
public void setTelegramChat(TgChat telegramChat) {
|
||||
this.telegramChat = telegramChat;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getEmailAddress() {
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
public void setEmailAddress(String emailAddress) {
|
||||
public void setEmailAddress(@Nullable String emailAddress) {
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
|
||||
public List<Campaign> getCampaigns() {
|
||||
return campaigns;
|
||||
}
|
||||
|
||||
public void setCampaigns(List<Campaign> campaigns) {
|
||||
this.campaigns = campaigns;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package com.github.polpetta.mezzotre.orm.telegram;
|
||||
|
||||
import com.github.polpetta.mezzotre.orm.model.Campaign;
|
||||
import com.github.polpetta.mezzotre.util.UUIDGenerator;
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class CampaignUtil {
|
||||
|
||||
private final UUIDGenerator uuidGenerator;
|
||||
|
||||
@Inject
|
||||
public CampaignUtil(UUIDGenerator uuidGenerator) {
|
||||
this.uuidGenerator = uuidGenerator;
|
||||
}
|
||||
|
||||
public Campaign insertNewCampaign(String name, String description) {
|
||||
final Campaign campaign = new Campaign(uuidGenerator.generateAsString(), name, description);
|
||||
|
||||
campaign.save();
|
||||
return campaign;
|
||||
}
|
||||
}
|
|
@ -34,18 +34,18 @@ public class ChatUtil {
|
|||
* then saved in the database
|
||||
*
|
||||
* @param chat the chat that will be updated with the new {@link ChatContext} values
|
||||
* @param stepName the step name to set
|
||||
* @param stageNumber the stage number to set
|
||||
* @param stageName the stage name to set
|
||||
* @param stepNumber the step number to set
|
||||
* @param additionalFields if there are, additional custom fields that will be added to {@link
|
||||
* ChatContext}. Note that these values will have to be manually retrieved since no method is
|
||||
* available for custom entries. Use {@link Collections#emptyMap()} if you don't wish to add
|
||||
* any additional field
|
||||
*/
|
||||
public void updateChatContext(
|
||||
TgChat chat, String stepName, int stageNumber, Map<String, Object> additionalFields) {
|
||||
TgChat chat, String stageName, int stepNumber, Map<String, Object> additionalFields) {
|
||||
final ChatContext chatContext = chat.getChatContext();
|
||||
chatContext.setStage(stepName);
|
||||
chatContext.setStep(stageNumber);
|
||||
chatContext.setStage(stageName);
|
||||
chatContext.setStep(stepNumber);
|
||||
chatContext.setPreviousMessageUnixTimestampInSeconds(clock.now());
|
||||
additionalFields.forEach(chatContext::setAdditionalProperty);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.util.Optional;
|
|||
* @author Davide Polonio
|
||||
* @since 1.0
|
||||
*/
|
||||
public class Util {
|
||||
class Util {
|
||||
|
||||
/**
|
||||
* Extract the message id of the given {@link Update}
|
||||
|
@ -19,7 +19,7 @@ public class Util {
|
|||
* @return an {@link Optional} containing a {@link Integer} with the message id if it is present,
|
||||
* otherwise a {@link Optional#empty()} if it is not found.
|
||||
*/
|
||||
public static Optional<Integer> extractMessageId(Update update) {
|
||||
static Optional<Integer> extractMessageId(Update update) {
|
||||
return Optional.ofNullable(update.callbackQuery().message()).map(Message::messageId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,10 +37,12 @@ public class CommandDI extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
@Named("commandProcessor")
|
||||
public Map<String, Processor> getCommandProcessor(Start start, Help help) {
|
||||
public Map<String, Processor> getCommandProcessor(
|
||||
Start start, Help help, CreateCampaign createCampaign) {
|
||||
final HashMap<String, Processor> commandMap = new HashMap<>();
|
||||
commandMap.putAll(mapForProcessor(start));
|
||||
commandMap.putAll(mapForProcessor(help));
|
||||
commandMap.putAll(mapForProcessor(createCampaign));
|
||||
|
||||
return commandMap;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
package com.github.polpetta.mezzotre.telegram.command;
|
||||
|
||||
import com.github.polpetta.mezzotre.i18n.TemplateContentGenerator;
|
||||
import com.github.polpetta.mezzotre.orm.model.TgChat;
|
||||
import com.github.polpetta.mezzotre.orm.telegram.CampaignUtil;
|
||||
import com.github.polpetta.mezzotre.orm.telegram.ChatUtil;
|
||||
import com.github.polpetta.mezzotre.util.UUIDGenerator;
|
||||
import com.pengrad.telegrambot.model.Update;
|
||||
import com.pengrad.telegrambot.model.request.ParseMode;
|
||||
import com.pengrad.telegrambot.request.BaseRequest;
|
||||
import com.pengrad.telegrambot.request.SendMessage;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
// FIXME tests, doc
|
||||
public class CreateCampaign implements Processor {
|
||||
|
||||
private static final String TRIGGERING_KEYWORD = "/createCampaign";
|
||||
// FIXME create the label
|
||||
private static final String BUTTON_CREATE_IT_LOCALE_KEY = "createCampaign.createItButton";
|
||||
private static final String CAMPAIGN_NAME_CHAT_CTX_FIELD = "campaign_name";
|
||||
private static final String CAMPAIGN_NAME_TEMPLATE_CTX_FIELD = "campaignName";
|
||||
private static final int MAX_CAMPAIGN_NAME_LENGTH = 256;
|
||||
private static final int MAX_CAMPAIGN_DESCRIPTION_LENGTH = 4096;
|
||||
private final TemplateContentGenerator templateContentGenerator;
|
||||
private final Executor threadPool;
|
||||
private final UUIDGenerator uuidGenerator;
|
||||
private final ChatUtil chatUtil;
|
||||
private final CampaignUtil campaignUtil;
|
||||
|
||||
@Inject
|
||||
public CreateCampaign(
|
||||
TemplateContentGenerator templateContentGenerator,
|
||||
@Named("eventThreadPool") Executor threadPool,
|
||||
UUIDGenerator uuidGenerator,
|
||||
ChatUtil chatUtil,
|
||||
CampaignUtil campaignUtil) {
|
||||
|
||||
this.templateContentGenerator = templateContentGenerator;
|
||||
this.threadPool = threadPool;
|
||||
this.uuidGenerator = uuidGenerator;
|
||||
this.chatUtil = chatUtil;
|
||||
this.campaignUtil = campaignUtil;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getTriggerKeywords() {
|
||||
return Set.of(TRIGGERING_KEYWORD, "/newCampaign");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Optional<BaseRequest<?, ?>>> process(TgChat chat, Update update) {
|
||||
// There are multiple steps, we have to route the incoming campaign creation to the right one
|
||||
return switch ((int) chat.getChatContext().getStep()) {
|
||||
default -> promptCampaignName(chat);
|
||||
case 1 -> verifyCampaignNameAndPromptCampaignDescription(chat, update);
|
||||
case 2 -> verifyDescriptionAndCompleteCreation(chat, update);
|
||||
};
|
||||
}
|
||||
|
||||
private CompletableFuture<Optional<BaseRequest<?, ?>>> promptCampaignName(TgChat chat) {
|
||||
return CompletableFuture.supplyAsync(
|
||||
() ->
|
||||
templateContentGenerator.mergeTemplate(
|
||||
ctx -> {}, chat.getLocale(), "template/telegram/createCampaign.0.vm"),
|
||||
threadPool)
|
||||
.thenApplyAsync(
|
||||
message -> {
|
||||
chatUtil.updateChatContext(chat, TRIGGERING_KEYWORD, 1, Collections.emptyMap());
|
||||
|
||||
return Optional.of(
|
||||
new SendMessage(chat.getId(), message).parseMode(ParseMode.Markdown));
|
||||
},
|
||||
threadPool);
|
||||
}
|
||||
|
||||
private CompletableFuture<Optional<BaseRequest<?, ?>>>
|
||||
verifyCampaignNameAndPromptCampaignDescription(TgChat chat, Update update) {
|
||||
/*
|
||||
Flow:
|
||||
1 - Input validation (name length, etc...)
|
||||
2 - Build message according to validation output
|
||||
3 - Send message back
|
||||
4 - ???
|
||||
5 - Profit
|
||||
*/
|
||||
return CompletableFuture.completedFuture(chat)
|
||||
.thenApply(
|
||||
// 1 - Perform input validation
|
||||
ignored ->
|
||||
Util.extractText(update)
|
||||
.filter(campaignName -> campaignName.length() <= MAX_CAMPAIGN_NAME_LENGTH))
|
||||
.thenApplyAsync(
|
||||
nameOpt -> {
|
||||
// 2 - create appropriate message and update chat context
|
||||
return nameOpt
|
||||
.map(
|
||||
campaignName -> {
|
||||
chatUtil.updateChatContext(
|
||||
chat,
|
||||
TRIGGERING_KEYWORD,
|
||||
2,
|
||||
Collections.singletonMap(CAMPAIGN_NAME_CHAT_CTX_FIELD, campaignName));
|
||||
return templateContentGenerator.mergeTemplate(
|
||||
ctx -> ctx.put(CAMPAIGN_NAME_TEMPLATE_CTX_FIELD, campaignName),
|
||||
chat.getLocale(),
|
||||
"template/telegram/createCampaign.2.vm");
|
||||
})
|
||||
// We don't update the context here on purpose. If the user wants to try another
|
||||
// campaign name is free to do so!
|
||||
.orElseGet(
|
||||
() ->
|
||||
templateContentGenerator.mergeTemplate(
|
||||
ctx -> {},
|
||||
chat.getLocale(),
|
||||
"template/telegram/createCampaign.nameNotValid.vm"));
|
||||
})
|
||||
.thenApply(
|
||||
// 3 - send message back
|
||||
message ->
|
||||
Optional.of(new SendMessage(chat.getId(), message).parseMode(ParseMode.Markdown)));
|
||||
}
|
||||
|
||||
private CompletableFuture<Optional<BaseRequest<?, ?>>> verifyDescriptionAndCompleteCreation(
|
||||
TgChat chat, Update update) {
|
||||
/*
|
||||
Flow:
|
||||
1 - Input validation (description length, etc...)
|
||||
2 - Build message according to validation output
|
||||
3 - Send message back
|
||||
4 - ???
|
||||
5 - Profit
|
||||
*/
|
||||
return CompletableFuture.completedFuture(chat)
|
||||
.thenApply(
|
||||
ignored ->
|
||||
Util.extractText(update)
|
||||
.filter(description -> description.length() <= MAX_CAMPAIGN_DESCRIPTION_LENGTH))
|
||||
.thenApplyAsync(
|
||||
descriptionOpt ->
|
||||
descriptionOpt
|
||||
.map(
|
||||
campaignDescription -> {
|
||||
// We go full beans here because we know that the property will never be
|
||||
// null at this point - if it is null, then there are bigger problems, and
|
||||
// we should start questioning our life (and our programming skills
|
||||
// really)
|
||||
final String campaignName =
|
||||
(String)
|
||||
chat.getChatContext()
|
||||
.getAdditionalProperties()
|
||||
.get(CAMPAIGN_NAME_CHAT_CTX_FIELD);
|
||||
campaignUtil.insertNewCampaign(campaignName, campaignDescription);
|
||||
chatUtil.updateChatContext(
|
||||
chat, TRIGGERING_KEYWORD, 3, Collections.emptyMap());
|
||||
return templateContentGenerator.mergeTemplate(
|
||||
ctx -> {}, chat.getLocale(), "template/telegram/createCampaign.3.vm");
|
||||
})
|
||||
.orElseGet(
|
||||
() ->
|
||||
templateContentGenerator.mergeTemplate(
|
||||
ctx -> {},
|
||||
chat.getLocale(),
|
||||
"template/telegram/createCampaign.descriptionNotValid.vm")))
|
||||
.thenApply(
|
||||
message ->
|
||||
Optional.of(new SendMessage(chat.getId(), message).parseMode(ParseMode.Markdown)));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.github.polpetta.mezzotre.telegram.command;
|
||||
|
||||
import com.pengrad.telegrambot.model.Message;
|
||||
import com.pengrad.telegrambot.model.Update;
|
||||
import com.pengrad.telegrambot.model.User;
|
||||
import java.util.Optional;
|
||||
|
||||
class Util {
|
||||
|
||||
static Optional<Long> extractSenderId(Update update) {
|
||||
return Optional.ofNullable(update).map(Update::message).map(Message::from).map(User::id);
|
||||
}
|
||||
|
||||
static Optional<String> extractText(Update update) {
|
||||
return Optional.ofNullable(update).map(Update::message).map(Message::text);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
${i18n.createCampaign.letsStartName}
|
|
@ -0,0 +1 @@
|
|||
${i18n.createCampaign.optionalDescription}
|
|
@ -0,0 +1 @@
|
|||
${i18n.createCampaign.done}
|
|
@ -0,0 +1 @@
|
|||
${i18n.createCampaign.descriptionNotValid}
|
|
@ -0,0 +1 @@
|
|||
${i18n.createCampaign.nameNotValid}
|
|
@ -69,6 +69,6 @@ public class UserIntegrationTest {
|
|||
final User id123 = new QUser().id.eq("id123").findOne();
|
||||
assertNotNull(id123);
|
||||
assertTrue(id123.isActive());
|
||||
assertNull(id123.getTelegramId());
|
||||
assertNull(id123.getTelegramChat());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
package com.github.polpetta.mezzotre.telegram.command;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import com.github.polpetta.mezzotre.i18n.TemplateContentGenerator;
|
||||
import com.github.polpetta.mezzotre.orm.model.TgChat;
|
||||
import com.github.polpetta.mezzotre.orm.telegram.CampaignUtil;
|
||||
import com.github.polpetta.mezzotre.orm.telegram.ChatUtil;
|
||||
import com.github.polpetta.mezzotre.util.UUIDGenerator;
|
||||
import com.github.polpetta.types.json.ChatContext;
|
||||
import com.google.gson.Gson;
|
||||
import com.pengrad.telegrambot.model.Update;
|
||||
import com.pengrad.telegrambot.request.BaseRequest;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
import org.junit.jupiter.api.parallel.Execution;
|
||||
import org.junit.jupiter.api.parallel.ExecutionMode;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
@Execution(ExecutionMode.CONCURRENT)
|
||||
class CreateCampaignTest {
|
||||
|
||||
private static Gson gson;
|
||||
private TemplateContentGenerator fakeTemplateContentGenerator;
|
||||
private UUIDGenerator fakeUUIDGenerator;
|
||||
private ChatUtil fakeChatUtil;
|
||||
private CampaignUtil fakeCampaignUtil;
|
||||
private CreateCampaign createCampaign;
|
||||
|
||||
@BeforeAll
|
||||
static void beforeAll() {
|
||||
gson = new Gson();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
fakeTemplateContentGenerator = mock(TemplateContentGenerator.class);
|
||||
fakeUUIDGenerator = mock(UUIDGenerator.class);
|
||||
fakeChatUtil = mock(ChatUtil.class);
|
||||
fakeCampaignUtil = mock(CampaignUtil.class);
|
||||
|
||||
createCampaign =
|
||||
new CreateCampaign(
|
||||
fakeTemplateContentGenerator,
|
||||
Executors.newSingleThreadExecutor(),
|
||||
fakeUUIDGenerator,
|
||||
fakeChatUtil,
|
||||
fakeCampaignUtil);
|
||||
}
|
||||
|
||||
public static Stream<Arguments> getMultipleValidCampaignEntries() {
|
||||
return Stream.of(
|
||||
Arguments.of("a simple name", "a simple description"),
|
||||
Arguments.of("a simple name", "a simple\nmultiline\n description"),
|
||||
Arguments.of(
|
||||
"an \uD83E\uDD21 emoji \uD83D\uDCAF name \uD83D\uDD25",
|
||||
"a very \uD83E\uDDE8 campaign description \uD83E\uDD16"),
|
||||
Arguments.of("一个简单的名字", "一个简单的描述"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("getMultipleValidCampaignEntries")
|
||||
@Timeout(value = 1, unit = TimeUnit.MINUTES)
|
||||
void shouldGenerateANewCampaign(String name, String description) throws Exception {
|
||||
|
||||
final TgChat fakeTgChat = mock(TgChat.class);
|
||||
final ChatContext initialChatContext = new ChatContext();
|
||||
initialChatContext.setStep(0); // implicit but better specify just for clarity
|
||||
when(fakeTgChat.getChatContext()).thenReturn(initialChatContext);
|
||||
when(fakeTgChat.getLocale()).thenReturn("en-US");
|
||||
|
||||
{
|
||||
when(fakeTemplateContentGenerator.mergeTemplate(
|
||||
any(), eq("en-US"), eq("template/telegram/createCampaign.0.vm")))
|
||||
.thenReturn("a string");
|
||||
final Update firstMessage =
|
||||
gson.fromJson(
|
||||
"{\n"
|
||||
+ "\"update_id\":10000,\n"
|
||||
+ "\"message\":{\n"
|
||||
+ " \"date\":1441645532,\n"
|
||||
+ " \"chat\":{\n"
|
||||
+ " \"last_name\":\"Test Lastname\",\n"
|
||||
+ " \"id\":1111111,\n"
|
||||
+ " \"type\": \"private\",\n"
|
||||
+ " \"first_name\":\"Test Firstname\",\n"
|
||||
+ " \"username\":\"Testusername\"\n"
|
||||
+ " },\n"
|
||||
+ " \"message_id\":1365,\n"
|
||||
+ " \"from\":{\n"
|
||||
+ " \"last_name\":\"Test Lastname\",\n"
|
||||
+ " \"id\":1111111,\n"
|
||||
+ " \"first_name\":\"Test Firstname\",\n"
|
||||
+ " \"username\":\"Testusername\"\n"
|
||||
+ " },\n"
|
||||
+ " \"text\":\"/createCampaign\"\n"
|
||||
+ "}\n"
|
||||
+ "}",
|
||||
Update.class);
|
||||
|
||||
final CompletableFuture<Optional<BaseRequest<?, ?>>> got =
|
||||
createCampaign.process(fakeTgChat, firstMessage);
|
||||
final Optional<BaseRequest<?, ?>> baseRequestOptional = got.get();
|
||||
final BaseRequest<?, ?> gotResponse = baseRequestOptional.get();
|
||||
assertEquals("a string", gotResponse.getParameters().get("text"));
|
||||
|
||||
verify(fakeChatUtil, times(1))
|
||||
.updateChatContext(fakeTgChat, "/createCampaign", 1, Collections.emptyMap());
|
||||
}
|
||||
|
||||
{
|
||||
when(fakeTemplateContentGenerator.mergeTemplate(
|
||||
any(), eq("en-US"), eq("template/telegram/createCampaign.2.vm")))
|
||||
.thenReturn("a second string");
|
||||
final ChatContext chatContext = new ChatContext();
|
||||
chatContext.setStep(1);
|
||||
when(fakeTgChat.getChatContext()).thenReturn(chatContext);
|
||||
|
||||
final Update secondMessageName =
|
||||
gson.fromJson(
|
||||
"{\n"
|
||||
+ "\"update_id\":10000,\n"
|
||||
+ "\"message\":{\n"
|
||||
+ " \"date\":1441645532,\n"
|
||||
+ " \"chat\":{\n"
|
||||
+ " \"last_name\":\"Test Lastname\",\n"
|
||||
+ " \"id\":1111111,\n"
|
||||
+ " \"type\": \"private\",\n"
|
||||
+ " \"first_name\":\"Test Firstname\",\n"
|
||||
+ " \"username\":\"Testusername\"\n"
|
||||
+ " },\n"
|
||||
+ " \"message_id\":1365,\n"
|
||||
+ " \"from\":{\n"
|
||||
+ " \"last_name\":\"Test Lastname\",\n"
|
||||
+ " \"id\":1111111,\n"
|
||||
+ " \"first_name\":\"Test Firstname\",\n"
|
||||
+ " \"username\":\"Testusername\"\n"
|
||||
+ " },\n"
|
||||
+ " \"text\":\""
|
||||
+ name
|
||||
+ "\"\n"
|
||||
+ "}\n"
|
||||
+ "}",
|
||||
Update.class);
|
||||
|
||||
final CompletableFuture<Optional<BaseRequest<?, ?>>> got =
|
||||
createCampaign.process(fakeTgChat, secondMessageName);
|
||||
final Optional<BaseRequest<?, ?>> baseRequestOptional = got.get();
|
||||
final BaseRequest<?, ?> gotResponse = baseRequestOptional.get();
|
||||
assertEquals("a second string", gotResponse.getParameters().get("text"));
|
||||
|
||||
final ArgumentCaptor<Map<String, Object>> capturedChatCtx =
|
||||
ArgumentCaptor.forClass(Map.class);
|
||||
verify(fakeChatUtil, times(1))
|
||||
.updateChatContext(
|
||||
eq(fakeTgChat), eq("/createCampaign"), eq(2), capturedChatCtx.capture());
|
||||
|
||||
final Map<String, Object> chatCtxValue = capturedChatCtx.getValue();
|
||||
assertEquals(name, chatCtxValue.get("campaign_name"));
|
||||
}
|
||||
|
||||
{
|
||||
when(fakeTemplateContentGenerator.mergeTemplate(
|
||||
any(), eq("en-US"), eq("template/telegram/createCampaign.3.vm")))
|
||||
.thenReturn("a third string");
|
||||
final ChatContext chatContext = new ChatContext();
|
||||
chatContext.setStep(2);
|
||||
chatContext.setAdditionalProperty("campaign_name", name);
|
||||
when(fakeTgChat.getChatContext()).thenReturn(chatContext);
|
||||
|
||||
final Update thirdMessageDescription =
|
||||
gson.fromJson(
|
||||
"{\n"
|
||||
+ "\"update_id\":10000,\n"
|
||||
+ "\"message\":{\n"
|
||||
+ " \"date\":1441645532,\n"
|
||||
+ " \"chat\":{\n"
|
||||
+ " \"last_name\":\"Test Lastname\",\n"
|
||||
+ " \"id\":1111111,\n"
|
||||
+ " \"type\": \"private\",\n"
|
||||
+ " \"first_name\":\"Test Firstname\",\n"
|
||||
+ " \"username\":\"Testusername\"\n"
|
||||
+ " },\n"
|
||||
+ " \"message_id\":1365,\n"
|
||||
+ " \"from\":{\n"
|
||||
+ " \"last_name\":\"Test Lastname\",\n"
|
||||
+ " \"id\":1111111,\n"
|
||||
+ " \"first_name\":\"Test Firstname\",\n"
|
||||
+ " \"username\":\"Testusername\"\n"
|
||||
+ " },\n"
|
||||
+ " \"text\":\""
|
||||
+ description
|
||||
+ "\"\n"
|
||||
+ "}\n"
|
||||
+ "}",
|
||||
Update.class);
|
||||
|
||||
final CompletableFuture<Optional<BaseRequest<?, ?>>> got =
|
||||
createCampaign.process(fakeTgChat, thirdMessageDescription);
|
||||
final Optional<BaseRequest<?, ?>> baseRequestOptional = got.get();
|
||||
final BaseRequest<?, ?> gotResponse = baseRequestOptional.get();
|
||||
assertEquals("a third string", gotResponse.getParameters().get("text"));
|
||||
|
||||
verify(fakeCampaignUtil, times(1)).insertNewCampaign(name, description);
|
||||
verify(fakeChatUtil, times(1))
|
||||
.updateChatContext(fakeTgChat, "/createCampaign", 3, Collections.emptyMap());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue