test: add test for createCampaign command. Still wip
continuous-integration/drone/push Build is passing Details

create-campaign
Davide Polonio 2023-05-11 12:13:34 +02:00
parent 81b25404b8
commit 0169d28ffd
11 changed files with 606 additions and 15 deletions

View File

@ -16,7 +16,7 @@ public class Campaign extends Base {
@Length(256)
@NotNull
private String campaignName;
private String name;
@Nullable @Null private String description;
@ -25,7 +25,7 @@ public class Campaign extends Base {
public Campaign(String id, String campaignName, @Nullable String description) {
this.id = id;
this.campaignName = campaignName;
this.name = campaignName;
this.description = description;
}
@ -33,12 +33,12 @@ public class Campaign extends Base {
return id;
}
public String getCampaignName() {
return campaignName;
public String getName() {
return name;
}
public void setCampaignName(String campaignName) {
this.campaignName = campaignName;
public void setName(String name) {
this.name = name;
}
@Nullable

View File

@ -47,6 +47,7 @@ public class ChatUtil {
chatContext.setStage(stageName);
chatContext.setStep(stepNumber);
chatContext.setPreviousMessageUnixTimestampInSeconds(clock.now());
chatContext.getAdditionalProperties().clear();
additionalFields.forEach(chatContext::setAdditionalProperty);
chat.setChatContext(chatContext);

View File

@ -109,7 +109,7 @@ public class CreateCampaign implements Processor {
return templateContentGenerator.mergeTemplate(
ctx -> ctx.put(CAMPAIGN_NAME_TEMPLATE_CTX_FIELD, campaignName),
chat.getLocale(),
"template/telegram/createCampaign.2.vm");
"template/telegram/createCampaign.1.vm");
})
// We don't update the context here on purpose. If the user wants to try another
// campaign name is free to do so!
@ -159,7 +159,7 @@ public class CreateCampaign implements Processor {
chatUtil.updateChatContext(
chat, TRIGGERING_KEYWORD, 3, Collections.emptyMap());
return templateContentGenerator.mergeTemplate(
ctx -> {}, chat.getLocale(), "template/telegram/createCampaign.3.vm");
ctx -> {}, chat.getLocale(), "template/telegram/createCampaign.2.vm");
})
.orElseGet(
() ->

View File

@ -21,3 +21,11 @@ help.buttonsToo=You can do the same operations you''d do with the commands afore
help.cmdDescription=Print the help message
notfound.description=Mmm I''m not able to find command {0}, are you sure to have it typed correctly?
notfound.howToHelp=Let me show you what I can do by typing /help in the chat!
createCampaign.letsStartName=Very well, give me a second that I go grab some scroll, ink and quill...
createCampaign.pickUpAction=*Searches frenetically in the desk between piles of books and written scrolls for a free piece of scroll*
createCampaign.readyPromptName=Here we are! Please, tell me, how would you like to call your new campaign?
createCampaign.optionalDescription=Uhmm yes, {0}... Very well, great name choice by the way! Now, would you like to give me a short description of your campaign? You can skip this step if you don''t want, otherwise just reply with the description
createCampaign.creationDone=All done! I have successfully added your campaign to my archives! Let me store it properly...
createCampaign.finalCreationAction=*Finishes to write down on the scroll the last details*
createCampaign.lookToPileAction=*Moves the scroll into a pile of other, disorganized, scrolls*
createCampaign.shareCampaign=Now, if you want, you can share this campaign to other players so that they can join! To do this, just click on the button below and then select the user or the group you want to share this campaign with! They will be able to add their characters and see the other characters in this campaign

View File

@ -21,3 +21,11 @@ help.buttonsToo=You can do the same operations you''d do with the commands afore
help.cmdDescription=Print the help message
notfound.description=Mmm I''m not able to find command {0}, are you sure to have it typed correctly?
notfound.howToHelp=Let me show you what I can do by typing /help in the chat!
createCampaign.letsStartName=Very well, give me a second that I go grab some scroll, ink and quill...
createCampaign.pickUpAction=*Searches frenetically in the desk between piles of books and written scrolls for a free piece of scroll*
createCampaign.readyPromptName=Here we are! Please, tell me, how would you like to call your new campaign?
createCampaign.optionalDescription=Uhmm yes, {0}... Very well, great name choice by the way! Now, would you like to give me a short description of your campaign? You can skip this step if you don''t want, otherwise just reply with the description
createCampaign.creationDone=All done! I have successfully added your campaign to my archives! Let me store it properly...
createCampaign.finalCreationAction=*Finishes to write down on the scroll the last details*
createCampaign.lookToPileAction=*Moves the scroll into a pile of other, disorganized, scrolls*
createCampaign.shareCampaign=Now, if you want, you can share this campaign to other players so that they can join! To do this, just click on the button below and then select the user or the group you want to share this campaign with! They will be able to add their characters and see the other characters in this campaign

View File

@ -1 +1,5 @@
${i18n.createCampaign.letsStartName}
${i18n.createCampaign.letsStartName}
_${i18n.createCampaign.pickUpAction}_
${i18n.createCampaign.readyPromptName}

View File

@ -1 +1 @@
${i18n.createCampaign.optionalDescription}
${i18n.createCampaign.optionalDescription.insert(${campaignName})}

View File

@ -1 +1,7 @@
${i18n.createCampaign.done}
_${i18n.createCampaign.finalCreationAction}_
${i18n.createCampaign.creationDone}
_${i18n.createCampaign.lookToPileAction}_
${i18n.createCampaign.shareCampaign}

View File

@ -67,4 +67,27 @@ class ChatUtilTest {
assertEquals(obj1, gotAdditionalProperties.get("field1"));
assertEquals(obj2, gotAdditionalProperties.get("field2"));
}
@Test
void shouldEmptyAdditionalElementsIfEmptyMapIsPassed() {
final TgChat fakeTgChat = mock(TgChat.class);
final ChatContext chatContext = new ChatContext();
chatContext.setAdditionalProperty("en example", "a value");
when(fakeTgChat.getChatContext()).thenReturn(chatContext);
when(fakeClock.now()).thenReturn(69420L);
chatUtil.updateChatContext(fakeTgChat, "/test1", 42, Collections.emptyMap());
verify(fakeTgChat, times(1)).getChatContext();
final ArgumentCaptor<ChatContext> chatContextArgumentCaptor =
ArgumentCaptor.forClass(ChatContext.class);
verify(fakeTgChat, times(1)).setChatContext(chatContextArgumentCaptor.capture());
final ChatContext capturedChatContextValue = chatContextArgumentCaptor.getValue();
final Map<String, Object> gotAdditionalProperties =
capturedChatContextValue.getAdditionalProperties();
assertEquals(
0,
gotAdditionalProperties.size(),
"The map should be empty in this case, but some elements where found");
}
}

View File

@ -0,0 +1,273 @@
package com.github.polpetta.mezzotre.telegram.command;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.github.polpetta.mezzotre.helper.Loader;
import com.github.polpetta.mezzotre.helper.TestConfig;
import com.github.polpetta.mezzotre.i18n.LocalizedMessageFactory;
import com.github.polpetta.mezzotre.i18n.TemplateContentGenerator;
import com.github.polpetta.mezzotre.orm.model.Campaign;
import com.github.polpetta.mezzotre.orm.model.TgChat;
import com.github.polpetta.mezzotre.orm.model.query.QCampaign;
import com.github.polpetta.mezzotre.orm.model.query.QTgChat;
import com.github.polpetta.mezzotre.orm.telegram.CampaignUtil;
import com.github.polpetta.mezzotre.orm.telegram.ChatUtil;
import com.github.polpetta.mezzotre.util.Clock;
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 com.pengrad.telegrambot.request.SendMessage;
import io.ebean.Database;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.velocity.app.VelocityEngine;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@Tag("slow")
@Tag("database")
@Tag("velocity")
@Testcontainers
class CreateCampaignIntegrationTest {
private static Gson gson;
@Container
private final PostgreSQLContainer<?> postgresServer =
new PostgreSQLContainer<>(TestConfig.POSTGRES_DOCKER_IMAGE);
private VelocityEngine velocityEngine;
private Database database;
private UUIDGenerator fakeUUIDGenerator;
private Clock fakeClock;
private ChatUtil chatUtil;
private CampaignUtil campaignUtil;
private CreateCampaign createCampaign;
@BeforeAll
static void beforeAll() {
gson = new Gson();
}
@BeforeEach
void setUp() throws Exception {
database =
Loader.connectToDatabase(Loader.loadDefaultEbeanConfigWithPostgresSettings(postgresServer));
velocityEngine = Loader.defaultVelocityEngine();
fakeClock = mock(Clock.class);
fakeUUIDGenerator = mock(UUIDGenerator.class);
chatUtil = new ChatUtil(fakeClock);
campaignUtil = new CampaignUtil(fakeUUIDGenerator);
createCampaign =
new CreateCampaign(
new TemplateContentGenerator(new LocalizedMessageFactory(velocityEngine)),
Executors.newSingleThreadExecutor(),
fakeUUIDGenerator,
chatUtil,
campaignUtil);
}
static Stream<Arguments> getValidCampaignEntries() {
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("getValidCampaignEntries")
@Timeout(value = 1, unit = TimeUnit.MINUTES)
void shouldCreateANewCampaign(String name, String description) throws Exception {
when(fakeUUIDGenerator.generateAsString()).thenReturn("64b483b4-7de8-4632-9117-927756d26210");
final TgChat chat =
new TgChat(
42L, new ChatContext(), "en-US", true // doesn't really matter
);
chat.save();
{
final Update firstMessage =
gson.fromJson(
"{\n"
+ "\"update_id\":10000,\n"
+ "\"message\":{\n"
+ " \"date\":1441645532,\n"
+ " \"chat\":{\n"
+ " \"last_name\":\"Test Lastname\",\n"
+ " \"id\":42,\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(chat, firstMessage);
final Optional<BaseRequest<?, ?>> baseRequestOptional = got.get();
final BaseRequest<?, ?> gotResponse = baseRequestOptional.get();
assertInstanceOf(SendMessage.class, gotResponse);
assertEquals(
"Very well, give me a second that I go grab some scroll, ink and quill...\n"
+ "\n"
+ "_*Searches frenetically in the desk between piles of books and written scrolls for"
+ " a free piece of scroll*_\n"
+ "\n"
+ "Here we are! Please, tell me, how would you like to call your new campaign?",
gotResponse.getParameters().get("text"));
final ChatContext retrievedChatContext =
Objects.requireNonNull(new QTgChat().id.eq(42L).findOne()).getChatContext();
assertEquals(1, retrievedChatContext.getStep());
assertEquals("/createCampaign", retrievedChatContext.getStage());
}
{
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(chat, secondMessageName);
final Optional<BaseRequest<?, ?>> baseRequestOptional = got.get();
final BaseRequest<?, ?> gotResponse = baseRequestOptional.get();
assertInstanceOf(SendMessage.class, gotResponse);
assertEquals(
"Uhmm yes, "
+ name
+ "... Very well, great name choice by the way! Now, would you like to give me a"
+ " short description of your campaign? You can skip this step if you don't want,"
+ " otherwise just reply with the description",
gotResponse.getParameters().get("text"));
final ChatContext retrievedChatContext =
Objects.requireNonNull(new QTgChat().id.eq(42L).findOne()).getChatContext();
assertEquals(2, retrievedChatContext.getStep());
assertEquals("/createCampaign", retrievedChatContext.getStage());
assertEquals(name, retrievedChatContext.getAdditionalProperties().get("campaign_name"));
}
{
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(chat, thirdMessageDescription);
final Optional<BaseRequest<?, ?>> baseRequestOptional = got.get();
final BaseRequest<?, ?> gotResponse = baseRequestOptional.get();
assertInstanceOf(SendMessage.class, gotResponse);
assertEquals(
"_*Finishes to write down on the scroll the last details*_\n"
+ "\n"
+ "All done! I have successfully added your campaign to my archives! Let me store it"
+ " properly...\n"
+ "\n"
+ "_*Moves the scroll into a pile of other, disorganized, scrolls*_\n"
+ "\n"
+ "Now, if you want, you can share this campaign to other players so that they can"
+ " join! To do this, just click on the button below and then select the user or the"
+ " group you want to share this campaign with! They will be able to add their"
+ " characters and see the other characters in this campaign",
gotResponse.getParameters().get("text"));
final ChatContext retrievedChatContext =
Objects.requireNonNull(new QTgChat().id.eq(42L).findOne()).getChatContext();
assertEquals(3, retrievedChatContext.getStep());
assertEquals("/createCampaign", retrievedChatContext.getStage());
assertEquals(
0,
retrievedChatContext.getAdditionalProperties().size(),
() ->
"Additional Properties should be empty, instead got: \n"
+ retrievedChatContext.getAdditionalProperties().entrySet().stream()
.map(e -> "key: " + e.getKey() + " -> value: " + e.getValue())
.collect(Collectors.joining("\n")));
}
final Campaign gotCampaign =
new QCampaign().name.eq(name).id.eq("64b483b4-7de8-4632-9117-927756d26210").findOne();
assertNotNull(gotCampaign);
// First two assertions kinda pointless btw
assertEquals("64b483b4-7de8-4632-9117-927756d26210", gotCampaign.getId());
assertEquals(name, gotCampaign.getName());
assertEquals(description, gotCampaign.getDescription());
}
// TODO add invalid name tests, add InlineButtonTests too
}

View File

@ -13,6 +13,7 @@ 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 com.pengrad.telegrambot.request.SendMessage;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
@ -62,7 +63,7 @@ class CreateCampaignTest {
fakeCampaignUtil);
}
public static Stream<Arguments> getMultipleValidCampaignEntries() {
static Stream<Arguments> getValidCampaignEntries() {
return Stream.of(
Arguments.of("a simple name", "a simple description"),
Arguments.of("a simple name", "a simple\nmultiline\n description"),
@ -73,7 +74,7 @@ class CreateCampaignTest {
}
@ParameterizedTest
@MethodSource("getMultipleValidCampaignEntries")
@MethodSource("getValidCampaignEntries")
@Timeout(value = 1, unit = TimeUnit.MINUTES)
void shouldGenerateANewCampaign(String name, String description) throws Exception {
@ -116,6 +117,7 @@ class CreateCampaignTest {
createCampaign.process(fakeTgChat, firstMessage);
final Optional<BaseRequest<?, ?>> baseRequestOptional = got.get();
final BaseRequest<?, ?> gotResponse = baseRequestOptional.get();
assertInstanceOf(SendMessage.class, gotResponse);
assertEquals("a string", gotResponse.getParameters().get("text"));
verify(fakeChatUtil, times(1))
@ -124,7 +126,7 @@ class CreateCampaignTest {
{
when(fakeTemplateContentGenerator.mergeTemplate(
any(), eq("en-US"), eq("template/telegram/createCampaign.2.vm")))
any(), eq("en-US"), eq("template/telegram/createCampaign.1.vm")))
.thenReturn("a second string");
final ChatContext chatContext = new ChatContext();
chatContext.setStep(1);
@ -161,6 +163,7 @@ class CreateCampaignTest {
createCampaign.process(fakeTgChat, secondMessageName);
final Optional<BaseRequest<?, ?>> baseRequestOptional = got.get();
final BaseRequest<?, ?> gotResponse = baseRequestOptional.get();
assertInstanceOf(SendMessage.class, gotResponse);
assertEquals("a second string", gotResponse.getParameters().get("text"));
final ArgumentCaptor<Map<String, Object>> capturedChatCtx =
@ -175,7 +178,7 @@ class CreateCampaignTest {
{
when(fakeTemplateContentGenerator.mergeTemplate(
any(), eq("en-US"), eq("template/telegram/createCampaign.3.vm")))
any(), eq("en-US"), eq("template/telegram/createCampaign.2.vm")))
.thenReturn("a third string");
final ChatContext chatContext = new ChatContext();
chatContext.setStep(2);
@ -213,6 +216,7 @@ class CreateCampaignTest {
createCampaign.process(fakeTgChat, thirdMessageDescription);
final Optional<BaseRequest<?, ?>> baseRequestOptional = got.get();
final BaseRequest<?, ?> gotResponse = baseRequestOptional.get();
assertInstanceOf(SendMessage.class, gotResponse);
assertEquals("a third string", gotResponse.getParameters().get("text"));
verify(fakeCampaignUtil, times(1)).insertNewCampaign(name, description);
@ -222,4 +226,268 @@ class CreateCampaignTest {
}
// TODO test failures, check InlineButtons too
static Stream<Arguments> getInvalidCampaignNameEntries() {
// In the future we can add more invalid test cases
return Stream.of(
Arguments.of(
"jDjonwP0iRSDGwRfUbdwOoF9iq478mRvMjaFCB9mtwKHyymOp0neEj3XU5aOafffyFeKyJS0sFuleeYVHDavMeoZf6ozM86MfB82K0ONtBztEiWy35gWmxefTfLf6xyhXdI8Monev9F6J68lqgedHYGuzORvMbfMiAu673v7tv5ZNkaoBko3q4aiI4zDL1IWZx1drucRc4puZq9XUeNEyw9Fahpn33nCt15CzC9YTVqNDGu6vR3P52GUZKlv8hRv33nCt15CzC9YTVqNDGu6vR3P52GUZKlv8hRv"));
}
@ParameterizedTest
@Timeout(value = 1, unit = TimeUnit.MINUTES)
@MethodSource("getInvalidCampaignNameEntries")
void shouldNotPassNameValidation(String name) 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();
assertInstanceOf(SendMessage.class, gotResponse);
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.nameNotValid.vm")))
.thenReturn("an error message");
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();
assertInstanceOf(SendMessage.class, gotResponse);
assertEquals("an error message", gotResponse.getParameters().get("text"));
verify(fakeChatUtil, times(0))
.updateChatContext(eq(fakeTgChat), eq("/createCampaign"), eq(2), any());
}
}
static Stream<Arguments> getInvalidCampaignDescriptionEntries() {
// In the future we can add more invalid test cases
return Stream.of(
Arguments.of(
"a campaign name",
"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"));
}
@ParameterizedTest
@Timeout(value = 1, unit = TimeUnit.MINUTES)
@MethodSource("getInvalidCampaignDescriptionEntries")
void shouldNotPassDescriptionValidation(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();
assertInstanceOf(SendMessage.class, gotResponse);
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.1.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();
assertInstanceOf(SendMessage.class, gotResponse);
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.descriptionNotValid.vm")))
.thenReturn("an error message");
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();
assertInstanceOf(SendMessage.class, gotResponse);
assertEquals("an error message", gotResponse.getParameters().get("text"));
verify(fakeCampaignUtil, times(1)).insertNewCampaign(name, description);
verify(fakeChatUtil, times(1))
.updateChatContext(fakeTgChat, "/createCampaign", 3, Collections.emptyMap());
}
}
}