diff --git a/.gitignore b/.gitignore index 63db41c1..9f1ce36b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ src/main/java/org.jointheleague.Launcher.java run.sh appspec.yml .gradle/ +/build/ diff --git a/bin/.gitignore b/bin/.gitignore new file mode 100644 index 00000000..7eed456b --- /dev/null +++ b/bin/.gitignore @@ -0,0 +1,2 @@ +/main/ +/test/ diff --git a/build.gradle b/build.gradle index cf380b09..aba06559 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-webflux:2.4.1' testImplementation "org.junit.jupiter:junit-jupiter:${jupiterVersion}" testImplementation "org.junit.jupiter:junit-jupiter-migrationsupport:${jupiterVersion}" + implementation 'org.apache.commons:commons-text:1.11.0' } group = 'org.jointheleague' diff --git a/src/main/java/org/jointheleague/discord_bot/DiscordBot.java b/src/main/java/org/jointheleague/discord_bot/DiscordBot.java index cefb5f79..049c1d51 100644 --- a/src/main/java/org/jointheleague/discord_bot/DiscordBot.java +++ b/src/main/java/org/jointheleague/discord_bot/DiscordBot.java @@ -13,7 +13,10 @@ import org.jointheleague.features.examples.first_features.CurrentTime; import org.jointheleague.features.examples.first_features.RandomNumber; import org.jointheleague.features.help_embed.HelpListener; +import org.jointheleague.features.student.first_feature.CookieClicker; import org.jointheleague.features.student.first_feature.FeatureOne; +import org.jointheleague.features.student.first_feature.FishingFrenzy; +import org.jointheleague.features.student.first_feature.TriviaAPI; public class DiscordBot { @@ -56,11 +59,9 @@ public void connect(boolean printInvite) throws InterruptedException { api.addEventListener(helpListener); //add features - addFeature(new FeatureOne(channelName)); - addFeature(new CurrentTime(channelName)); - addFeature(new HighLowGame(channelName)); - addFeature(new NewsApi(channelName)); - addFeature(new CatFactsApi(channelName)); + addFeature(new FishingFrenzy(channelName)); + addFeature(new CookieClicker(channelName)); + addFeature(new TriviaAPI(channelName)); } private void addFeature(Feature feature){ diff --git a/src/main/java/org/jointheleague/features/examples/help_embed/HelpListener.java b/src/main/java/org/jointheleague/features/examples/help_embed/HelpListener.java new file mode 100644 index 00000000..30498cea --- /dev/null +++ b/src/main/java/org/jointheleague/features/examples/help_embed/HelpListener.java @@ -0,0 +1,33 @@ +package org.jointheleague.features.examples.help_embed; + +import java.util.ArrayList; +import java.util.List; + +import org.jointheleague.features.help_embed.plain_old_java_objects.help_embed.HelpEmbed; +import org.jointheleague.api_wrapper.ReceivedMessage; +import org.jointheleague.features.abstract_classes.Feature; + +public class HelpListener extends Feature { + + public final String COMMAND = "!help"; + private List helpEmbeds = new ArrayList<>(); + + public HelpListener(String channelName) { + super(channelName); + } + + @Override + public void handle(ReceivedMessage event) { + if(event.getMessageContent().equalsIgnoreCase(COMMAND)) { + for(HelpEmbed helpEmbed : helpEmbeds) { + event.sendResponse(helpEmbed.getEmbed()); + } + } + } + + public void addHelpEmbed(HelpEmbed helpEmbed) { + helpEmbeds.add(helpEmbed); + } + + +} diff --git a/src/main/java/org/jointheleague/features/student/first_feature/CookieClicker.java b/src/main/java/org/jointheleague/features/student/first_feature/CookieClicker.java new file mode 100644 index 00000000..5bf3abca --- /dev/null +++ b/src/main/java/org/jointheleague/features/student/first_feature/CookieClicker.java @@ -0,0 +1,60 @@ +package org.jointheleague.features.student.first_feature; + +import org.jointheleague.api_wrapper.ReceivedMessage; +import org.jointheleague.features.abstract_classes.Feature; +import org.jointheleague.features.help_embed.plain_old_java_objects.help_embed.HelpEmbed; + +public class CookieClicker extends Feature { + + public final String COMMAND = "!cookieClicker"; + int cookies = 0; + int click = 1; + public CookieClicker(String channelName) { + super(channelName); + + //Create a help embed to describe feature when !help command is sent + helpEmbed = new HelpEmbed( + COMMAND, + "Bake cookies, buy upgrades, and climb the leaderboard to become the ultimate baker!" + ); + } + + @Override + public void handle(ReceivedMessage event) { + String messageContent = event.getMessageContent(); + if (messageContent.equals(COMMAND)) { + event.sendResponse("Please type something after the command."); + } + else if (messageContent.equals("!cookieClicker help")) { + //respond to message here + event.sendResponse("Commands:\n`!cookieCliker click` to bake a cookie.\n`!cookieClicker cookies` to see how much cookies you have.\n`!cookieClicker upgrades` to buy upgrades."); + } + else if (messageContent.equals("!cookieClicker click")) { + cookies += click; + event.sendResponse("You gained " + click + " cookie"); + } + else if (messageContent.equals("!cookieClicker cookies")) { + event.sendResponse("You have " + cookies + " cookies in total."); + } + else if (messageContent.equals("!cookieClicker upgrades")) { + event.sendResponse("Upgrades: Increases cookies per click. To buy, just type `!cookieClicker [upgrade name]`\nCursor (+1): 10 cookies\nGramma (+5): 50 cookies\nFarm (+10): 100 cookies\nMine (+50): 300 cookies"); + } + else if (messageContent.equals("!cookieClicker cursor")) { + click += 1; + cookies -= 10; + } + else if (messageContent.equals("!cookieClicker gramma")) { + click += 5; + cookies -= 50; + } + else if (messageContent.equals("!cookieClicker farm")) { + click += 10; + cookies -= 100; + } + else if (messageContent.equals("!cookieClicker mine")) { + click += 50; + cookies -= 300; + } + } + +} diff --git a/src/main/java/org/jointheleague/features/student/first_feature/FishingFrenzy.java b/src/main/java/org/jointheleague/features/student/first_feature/FishingFrenzy.java new file mode 100644 index 00000000..20559985 --- /dev/null +++ b/src/main/java/org/jointheleague/features/student/first_feature/FishingFrenzy.java @@ -0,0 +1,68 @@ +package org.jointheleague.features.student.first_feature; + +import org.jointheleague.api_wrapper.ReceivedMessage; + +import org.jointheleague.features.abstract_classes.Feature; +import org.jointheleague.features.help_embed.plain_old_java_objects.help_embed.HelpEmbed; + +import net.dv8tion.jda.api.EmbedBuilder; + +import java.util.Random; +public class FishingFrenzy extends Feature { + public int coins = 0; + public final String COMMAND = "!fishingFrenzy"; + + public FishingFrenzy(String channelName) { + super(channelName); + + //Create a help embed to describe feature when !help command is sent + helpEmbed = new HelpEmbed( + COMMAND, + "Cast your line and catch all kinds of fish — from common to legendary! Earn coins, buy upgrades, and compete on the leaderboard." + ); + } + + @Override + public void handle(ReceivedMessage event) { + String messageContent = event.getMessageContent(); + if (messageContent.equals("!fishingFrenzy help")) { + //respond to message here + event.sendResponse("Commands:\n`!fishingFrenzy cast` to cast your line.\n`!fishingFrenzy balance` to see how much coins you have. "); + } + else if (messageContent.equals("!fishingFrenzy fish")) { + Random r = new Random(); + double randomNumber = r.nextDouble() * 100; + fishdrops(event, randomNumber); + } + else if (messageContent.equals("!fishingFrenzy balance")) { + event.sendResponse("You have " + coins + " coins."); + } + } + + public void fishdrops(ReceivedMessage event, double randomNumber) { + if (randomNumber < 1) { + event.sendResponse("You caught a Dragonfish! (Legendary: 1%)\nYou gained 750 coins!"); + coins+=750; + } else if (randomNumber < 5){ + event.sendResponse("You caught a Golden Koi! (Mythic: 4%)\nYou gained 300 coins!"); + coins+=300; + } + else if (randomNumber < 15) { + event.sendResponse("You caught a Swordfish! (Epic: 10%)\nYou gained 150 coins!"); + coins+=150; + } + else if (randomNumber < 30) { + event.sendResponse("You caught a Salmon! (Rare: 15%)\nYou gained 75 coins!"); + coins+=75; + } + else if (randomNumber < 55) { + event.sendResponse("You caught a Mackeral! (Uncommon: 25%)\nYou gained 30 coins!"); + coins+=30; + } + else { + event.sendResponse("You caught a Carp! (Common: 45%)\nYou gained 10 coins!"); + coins+=10; + } + } + +} diff --git a/src/main/java/org/jointheleague/features/student/first_feature/Question.java b/src/main/java/org/jointheleague/features/student/first_feature/Question.java new file mode 100644 index 00000000..1cb101af --- /dev/null +++ b/src/main/java/org/jointheleague/features/student/first_feature/Question.java @@ -0,0 +1,152 @@ + +package org.jointheleague.features.student.first_feature; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "type", + "difficulty", + "category", + "question", + "correct_answer", + "incorrect_answers" +}) +@Generated("jsonschema2pojo") +public class Question { + + @JsonProperty("type") + private String type; + @JsonProperty("difficulty") + private String difficulty; + @JsonProperty("category") + private String category; + @JsonProperty("question") + public String question; + @JsonProperty("correct_answer") + public String correctAnswer; + @JsonProperty("incorrect_answers") + private List incorrectAnswers; + @JsonIgnore + private Map additionalProperties = new LinkedHashMap(); + + @JsonProperty("type") + public String getType() { + return type; + } + + @JsonProperty("type") + public void setType(String type) { + this.type = type; + } + + @JsonProperty("difficulty") + public String getDifficulty() { + return difficulty; + } + + @JsonProperty("difficulty") + public void setDifficulty(String difficulty) { + this.difficulty = difficulty; + } + + @JsonProperty("category") + public String getCategory() { + return category; + } + + @JsonProperty("category") + public void setCategory(String category) { + this.category = category; + } + + @JsonProperty("question") + public String getQuestion() { + return question; + } + + @JsonProperty("question") + public void setQuestion(String question) { + this.question = question; + } + + @JsonProperty("correct_answer") + public String getCorrectAnswer() { + return correctAnswer; + } + + @JsonProperty("correct_answer") + public void setCorrectAnswer(String correctAnswer) { + this.correctAnswer = correctAnswer; + } + + @JsonProperty("incorrect_answers") + public List getIncorrectAnswers() { + return incorrectAnswers; + } + + @JsonProperty("incorrect_answers") + public void setIncorrectAnswers(List incorrectAnswers) { + this.incorrectAnswers = incorrectAnswers; + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(Question.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('['); + sb.append("type"); + sb.append('='); + sb.append(((this.type == null)?"":this.type)); + sb.append(','); + sb.append("difficulty"); + sb.append('='); + sb.append(((this.difficulty == null)?"":this.difficulty)); + sb.append(','); + sb.append("category"); + sb.append('='); + sb.append(((this.category == null)?"":this.category)); + sb.append(','); + sb.append("question"); + sb.append('='); + sb.append(((this.question == null)?"":this.question)); + sb.append(','); + sb.append("correctAnswer"); + sb.append('='); + sb.append(((this.correctAnswer == null)?"":this.correctAnswer)); + sb.append(','); + sb.append("incorrectAnswers"); + sb.append('='); + sb.append(((this.incorrectAnswers == null)?"":this.incorrectAnswers)); + sb.append(','); + sb.append("additionalProperties"); + sb.append('='); + sb.append(((this.additionalProperties == null)?"":this.additionalProperties)); + sb.append(','); + if (sb.charAt((sb.length()- 1)) == ',') { + sb.setCharAt((sb.length()- 1), ']'); + } else { + sb.append(']'); + } + return sb.toString(); + } + +} diff --git a/src/main/java/org/jointheleague/features/student/first_feature/TriviaAPI.java b/src/main/java/org/jointheleague/features/student/first_feature/TriviaAPI.java new file mode 100644 index 00000000..5c7d9105 --- /dev/null +++ b/src/main/java/org/jointheleague/features/student/first_feature/TriviaAPI.java @@ -0,0 +1,180 @@ +package org.jointheleague.features.student.first_feature; + +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +import org.jointheleague.api_wrapper.ReceivedMessage; +import org.jointheleague.features.abstract_classes.Feature; +import org.jointheleague.features.examples.third_features.plain_old_java_objects.news_api.ApiExampleWrapper; +import org.jointheleague.features.examples.third_features.plain_old_java_objects.news_api.Article; +import org.jointheleague.features.help_embed.plain_old_java_objects.help_embed.HelpEmbed; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; +import org.apache.commons.text.StringEscapeUtils; + +//Documentation for the API can be found here: https://newsapi.org/docs/get-started +public class TriviaAPI extends Feature { + + public final String COMMAND = "!triviaAPI"; + + private WebClient webClient; + private static final String baseUrl = "https://opentdb.com/api.php"; + public int totalNumberOfQuestions = 10; + public TriviaAPI(String channelName) { + super(channelName); + helpEmbed = new HelpEmbed(COMMAND, "TriviaAPI gives trivia true or false questions of different topics. This starts a trivia quiz related to topic 9 (e.g. !triviaAPI 9)"); + + //build the WebClient + this.webClient = WebClient + .builder() + .baseUrl(baseUrl) + .build(); + } + boolean quizStarted = false; + TriviaQuestions tq; + int currentQuestion = 0; + int score = 0; + Map categories = new TreeMap<>(); + { + categories.put(9, "General Knowledge"); + categories.put(10, "Books"); + categories.put(11, "Film"); + categories.put(12, "Music"); + categories.put(13, "Musical and Theater"); + categories.put(14, "Television"); + categories.put(15, "Video Games"); + categories.put(16, "Board Games"); + categories.put(17, "Science and Nature"); + categories.put(18, "Computers"); + categories.put(19, "Math"); + categories.put(20, "Mythology"); + categories.put(21, "Sports"); + categories.put(22, "Geography"); + categories.put(23, "History"); + categories.put(24, "Politics"); + categories.put(25, "Art"); + categories.put(26, "Celebrities"); + categories.put(27, "Animals"); + categories.put(28, "Vehicles"); + categories.put(29, "Comics"); + categories.put(30, "Gadgets"); + categories.put(31, "Anime"); + categories.put(32, "Cartoons"); + } + @Override + public void handle(ReceivedMessage event) { + String messageContent = event.getMessageContent(); + if (messageContent.startsWith(COMMAND)) { + if (messageContent.equals("!triviaAPI help")) { + event.sendResponse("Commands:\n`!triviaAPI categories` to list all topics.\n`!triviaAPI startQuiz [topic number]` to start a quiz based on a topic.\n`!triviaAPI stopQuiz` to stop the current quiz.\n`!triviaAPI answer [answer]` to answer a question."); + } + if (messageContent.equals("!triviaAPI categories")) { + StringBuilder sb = new StringBuilder(); + for (Integer key : categories.keySet()) { + sb.append(key + " : " + categories.get(key) + "\n"); + } + event.sendResponse(sb.toString()); + } + if (messageContent.equals("!triviaAPI stopQuiz")) { + if (!quizStarted) { + event.sendResponse("There is no quiz started."); + return; + } + quizStarted = false; + event.sendResponse("Quiz stopped. You got a final score of " + score + "/" + currentQuestion); + currentQuestion = 0; + score = 0; + } + if (messageContent.startsWith("!triviaAPI startQuiz")){ + messageContent = messageContent.replace("!triviaAPI startQuiz ", ""); + quizStarted = true; + // String story = findStory(messageContent); + + + + +// try { + + tq = getQuestionsByTopic(messageContent); + event.sendResponse("Starting 10 question quiz about topic: " + (categories.get(Integer.parseInt(messageContent)))); + // + event.sendResponse("Question #" + (currentQuestion+1) + ": " + StringEscapeUtils.unescapeHtml4(tq.getResults().get(currentQuestion).getQuestion() + " True or false?")); +// } +// catch(Exception e) { +// e.printStackTrace(); +// } + } + if (messageContent.startsWith("!triviaAPI answer")) { + if (quizStarted) { + messageContent = messageContent.replace("!triviaAPI answer ", ""); + if (messageContent.toLowerCase().equals(tq.getResults().get(currentQuestion).getCorrectAnswer().toLowerCase())) { + event.sendResponse("Correct!"); + score++; + currentQuestion++; + } + else { + event.sendResponse("Incorrect! The answer was " + tq.getResults().get(currentQuestion).getCorrectAnswer()); + currentQuestion++; + + } + if (currentQuestion == totalNumberOfQuestions) { + event.sendResponse("Congrats! You have finished the quiz! You got a final score of " + score + "/" + currentQuestion); + currentQuestion = 0; + score = 0; + } + else { + event.sendResponse("Question #" + (currentQuestion+1) + ": " + StringEscapeUtils.unescapeHtml4(tq.getResults().get(currentQuestion).getQuestion() + " True or false?")); + } + } + else { + event.sendResponse("There is no quiz started."); + } + } + } + } + + + public TriviaQuestions getQuestionsByTopic(String topic) { + Mono apiExampleWrapperMono = webClient.get() + .uri(uriBuilder -> uriBuilder + .queryParam("amount", 10) + .queryParam("category", topic) + .queryParam("type", "boolean") + .build()) + .retrieve() + .bodyToMono(TriviaQuestions.class); + TriviaQuestions tq = apiExampleWrapperMono.block(); + return tq; + } + +// public String findStory(int topic){ +// +// //Get a story from News API +// Result question = getQuestionByTopic(topic); +// +// //Get the first article +// Article article = apiExampleWrapper.getArticles().get(0); +// +// //Get the title of the article +// String articleTitle = article.getTitle(); +// +// //Get the content of the article +// String articleContent = article.getContent(); +// +// //Get the URL of the article +// String articleUrl = article.getUrl(); +// +// //Create the message +// String message = +// articleTitle + " -\n" +// + articleContent +// + "\nFull article: " + articleUrl; +// +// //Send the message +// return message; +// } + + +} + diff --git a/src/main/java/org/jointheleague/features/student/first_feature/TriviaQuestions.java b/src/main/java/org/jointheleague/features/student/first_feature/TriviaQuestions.java new file mode 100644 index 00000000..72533ace --- /dev/null +++ b/src/main/java/org/jointheleague/features/student/first_feature/TriviaQuestions.java @@ -0,0 +1,84 @@ + +package org.jointheleague.features.student.first_feature; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "response_code", + "results" +}) +@Generated("jsonschema2pojo") +public class TriviaQuestions { + + @JsonProperty("response_code") + private Integer responseCode; + @JsonProperty("results") + public List results; + @JsonIgnore + private Map additionalProperties = new LinkedHashMap(); + + @JsonProperty("response_code") + public Integer getResponseCode() { + return responseCode; + } + + @JsonProperty("response_code") + public void setResponseCode(Integer responseCode) { + this.responseCode = responseCode; + } + + @JsonProperty("results") + public List getResults() { + return results; + } + + @JsonProperty("results") + public void setResults(List results) { + this.results = results; + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(TriviaQuestions.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('['); + sb.append("responseCode"); + sb.append('='); + sb.append(((this.responseCode == null)?"":this.responseCode)); + sb.append(','); + sb.append("results"); + sb.append('='); + sb.append(((this.results == null)?"":this.results)); + sb.append(','); + sb.append("additionalProperties"); + sb.append('='); + sb.append(((this.additionalProperties == null)?"":this.additionalProperties)); + sb.append(','); + if (sb.charAt((sb.length()- 1)) == ',') { + sb.setCharAt((sb.length()- 1), ']'); + } else { + sb.append(']'); + } + return sb.toString(); + } + +} diff --git a/src/test/java/org/jointheleague/features/student/first_feature/CookieClickerTest.java b/src/test/java/org/jointheleague/features/student/first_feature/CookieClickerTest.java new file mode 100644 index 00000000..9d1c36cc --- /dev/null +++ b/src/test/java/org/jointheleague/features/student/first_feature/CookieClickerTest.java @@ -0,0 +1,210 @@ +package org.jointheleague.features.student.first_feature; + +import org.jointheleague.api_wrapper.ReceivedMessage; +import org.jointheleague.features.help_embed.plain_old_java_objects.help_embed.HelpEmbed; +import org.jointheleague.features.templates.FeatureTemplate; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +public class CookieClickerTest { + private final String testChannelName = "test"; + private final CookieClicker featureOne = new CookieClicker(testChannelName); + + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final PrintStream originalOut = System.out; + + @Mock + private ReceivedMessage receivedMessage; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + System.setOut(new PrintStream(outContent)); + } + + @AfterEach + public void itShouldNotPrintToSystemOut() { + String expected = ""; + String actual = outContent.toString(); + + assertEquals(expected, actual); + System.setOut(originalOut); + } + + @Test + void itShouldHaveACommand() { + //Given + + //When + String command = featureOne.COMMAND; + + + + assertNotEquals("", command); + assertNotEquals("!", command); + assertNotEquals("!command", command); + assertEquals('!', command.charAt(0)); + assertNotNull(command); + } + + @Test + void itShouldHandleMessagesWithCommand() { + //Given + HelpEmbed helpEmbed = new HelpEmbed(featureOne.COMMAND, "test"); + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND); + + //When + featureOne.handle(receivedMessage); + + //Then + verify(receivedMessage, times(1)).sendResponse("Please type something after the command."); + } + + @Test + void itShouldNotHandleMessagesWithoutCommand() { + //Given + String command = ""; + when(receivedMessage.getMessageContent()).thenReturn(command); + + //When + featureOne.handle(receivedMessage); + + //Then + verify(receivedMessage, never()).sendResponse(""); + } + + @Test + void itShouldHaveAHelpEmbed() { + //Given + + //When + HelpEmbed actualHelpEmbed = featureOne.getHelpEmbed(); + + //Then + assertNotNull(actualHelpEmbed); + } + + @Test + void itShouldHaveTheCommandAsTheTitleOfTheHelpEmbed() { + //Given + + //When + String helpEmbedTitle = featureOne.getHelpEmbed().getTitle(); + String command = featureOne.COMMAND; + + //Then + assertEquals(command, helpEmbedTitle); + } + @Test + void itShouldHelp() { + //Given + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " help"); + //When + featureOne.handle(receivedMessage); + + //Then + verify(receivedMessage, times(1)).sendResponse("Commands:\n`!cookieCliker click` to bake a cookie.\n`!cookieClicker cookies` to see how much cookies you have.\n`!cookieClicker upgrades` to buy upgrades."); + + } + @Test + void itShouldClick() { + //Given + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " click"); + //When + + featureOne.handle(receivedMessage); + + //Then + verify(receivedMessage, times(1)).sendResponse("You gained " + featureOne.click + " cookie"); + + } + @Test + void itShouldShowCookies() { + //Given + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " cookies"); + //When + featureOne.handle(receivedMessage); + + //Then + verify(receivedMessage, times(1)).sendResponse("You have " + featureOne.cookies + " cookies in total."); + + } + @Test + void itShouldGiveUpgrades() { + //Given + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " upgrades"); + //When + featureOne.handle(receivedMessage); + + //Then + verify(receivedMessage, times(1)).sendResponse("Upgrades: Increases cookies per click. To buy, just type `!cookieClicker [upgrade name]`\nCursor (+1): 10 cookies\nGramma (+5): 50 cookies\nFarm (+10): 100 cookies\nMine (+50): 300 cookies"); + } + @Test + void itShouldBuyCursor() { + //Given + int clicks = featureOne.click; + int cookies = featureOne.cookies; + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " cursor"); + //When + featureOne.handle(receivedMessage); + + //Then + + assertEquals(clicks+1, featureOne.click); + assertEquals(cookies-10, featureOne.cookies); + } + @Test + void itShouldBuyGramma() { + //Given + int clicks = featureOne.click; + int cookies = featureOne.cookies; + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " gramma"); + //When + featureOne.handle(receivedMessage); + + //Then + + assertEquals(clicks+5, featureOne.click); + assertEquals(cookies-50, featureOne.cookies); + } + @Test + void itShouldBuyFarm() { + //Given + int clicks = featureOne.click; + int cookies = featureOne.cookies; + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " farm"); + //When + featureOne.handle(receivedMessage); + + //Then + + assertEquals(clicks+10, featureOne.click); + assertEquals(cookies-100, featureOne.cookies); + } + @Test + void itShouldBuyMine() { + //Given + int clicks = featureOne.click; + int cookies = featureOne.cookies; + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " mine"); + //When + featureOne.handle(receivedMessage); + + //Then + + assertEquals(clicks+50, featureOne.click); + assertEquals(cookies-300, featureOne.cookies); + } +} diff --git a/src/test/java/org/jointheleague/features/student/first_feature/FeatureOneTest.java b/src/test/java/org/jointheleague/features/student/first_feature/FeatureOneTest.java deleted file mode 100644 index 8c95c657..00000000 --- a/src/test/java/org/jointheleague/features/student/first_feature/FeatureOneTest.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.jointheleague.features.student.first_feature; - -import org.jointheleague.api_wrapper.ReceivedMessage; -import org.jointheleague.features.help_embed.plain_old_java_objects.help_embed.HelpEmbed; -import org.jointheleague.features.templates.FeatureTemplate; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; -import static org.mockito.Mockito.never; - -public class FeatureOneTest { - private final String testChannelName = "test"; - private final FeatureOne featureOne = new FeatureOne(testChannelName); - - private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); - private final PrintStream originalOut = System.out; - - @Mock - private ReceivedMessage receivedMessage; - - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - System.setOut(new PrintStream(outContent)); - } - - @AfterEach - public void itShouldNotPrintToSystemOut() { - String expected = ""; - String actual = outContent.toString(); - - assertEquals(expected, actual); - System.setOut(originalOut); - } - - @Test - void itShouldHaveACommand() { - //Given - - //When - String command = featureOne.COMMAND; - - //Then - - if(!(featureOne instanceof FeatureTemplate)){ - assertNotEquals("!command", command); - } - - assertNotEquals("", command); - assertNotEquals("!", command); - assertNotEquals("!command", command); - assertEquals('!', command.charAt(0)); - assertNotNull(command); - } - - @Test - void itShouldHandleMessagesWithCommand() { - //Given - HelpEmbed helpEmbed = new HelpEmbed(featureOne.COMMAND, "test"); - when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND); - - //When - featureOne.handle(receivedMessage); - - //Then - verify(receivedMessage, times(1)).sendResponse(anyString()); - } - - @Test - void itShouldNotHandleMessagesWithoutCommand() { - //Given - String command = ""; - when(receivedMessage.getMessageContent()).thenReturn(command); - - //When - featureOne.handle(receivedMessage); - - //Then - verify(receivedMessage, never()).sendResponse(""); - } - - @Test - void itShouldHaveAHelpEmbed() { - //Given - - //When - HelpEmbed actualHelpEmbed = featureOne.getHelpEmbed(); - - //Then - assertNotNull(actualHelpEmbed); - } - - @Test - void itShouldHaveTheCommandAsTheTitleOfTheHelpEmbed() { - //Given - - //When - String helpEmbedTitle = featureOne.getHelpEmbed().getTitle(); - String command = featureOne.COMMAND; - - //Then - assertEquals(command, helpEmbedTitle); - } - -} diff --git a/src/test/java/org/jointheleague/features/student/first_feature/FishingFrenzyTest.java b/src/test/java/org/jointheleague/features/student/first_feature/FishingFrenzyTest.java new file mode 100644 index 00000000..084332ac --- /dev/null +++ b/src/test/java/org/jointheleague/features/student/first_feature/FishingFrenzyTest.java @@ -0,0 +1,151 @@ +package org.jointheleague.features.student.first_feature; + +import org.jointheleague.api_wrapper.ReceivedMessage; +import org.jointheleague.features.help_embed.plain_old_java_objects.help_embed.HelpEmbed; +import org.jointheleague.features.templates.FeatureTemplate; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.never; + +public class FishingFrenzyTest { + private final String testChannelName = "general"; + private final FishingFrenzy fishingFrenzy = new FishingFrenzy(testChannelName); + + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final PrintStream originalOut = System.out; + + @Mock + private ReceivedMessage receivedMessage; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + System.setOut(new PrintStream(outContent)); + } + + @AfterEach + public void itShouldNotPrintToSystemOut() { + String expected = ""; + String actual = outContent.toString(); + + assertEquals(expected, actual); + System.setOut(originalOut); + } + + @Test + void itShouldHaveACommand() { + //Given + + //When + String command = fishingFrenzy.COMMAND; + + //Then + + + + assertNotEquals("", command); + assertNotEquals("!", command); + assertNotEquals("!command", command); + assertEquals('!', command.charAt(0)); + assertNotNull(command); + } + + @Test + void itShouldHandleMessagesWithCommandAndHelp() { + //Given + when(receivedMessage.getMessageContent()).thenReturn(fishingFrenzy.COMMAND + " help"); + + //When + fishingFrenzy.handle(receivedMessage); + + //Then + verify(receivedMessage, times(1)).sendResponse("Commands:\n`!fishingFrenzy cast` to cast your line.\n`!fishingFrenzy balance` to see how much coins you have. "); + } + + @Test + void itShouldNotHandleMessagesWithoutCommand() { + //Given + String command = ""; + when(receivedMessage.getMessageContent()).thenReturn(command); + + //When + fishingFrenzy.handle(receivedMessage); + + //Then + verify(receivedMessage, never()).sendResponse(""); + } + + @Test + void itShouldHaveAHelpEmbed() { + //Given + + //When + HelpEmbed actualHelpEmbed = fishingFrenzy.getHelpEmbed(); + + //Then + assertNotNull(actualHelpEmbed); + } + + @Test + void itShouldHaveTheCommandAsTheTitleOfTheHelpEmbed() { + //Given + + //When + String helpEmbedTitle = fishingFrenzy.getHelpEmbed().getTitle(); + String command = fishingFrenzy.COMMAND; + + //Then + assertEquals(command, helpEmbedTitle); + } + @Test + void itShouldGiveFishDrops() { + //Given + fishingFrenzy.fishdrops(receivedMessage, 0); + verify(receivedMessage, times(1)).sendResponse("You caught a Dragonfish! (Legendary: 1%)\nYou gained 750 coins!"); + fishingFrenzy.fishdrops(receivedMessage, 1); + verify(receivedMessage, times(1)).sendResponse("You caught a Golden Koi! (Mythic: 4%)\nYou gained 300 coins!"); + fishingFrenzy.fishdrops(receivedMessage, 10); + verify(receivedMessage, times(1)).sendResponse("You caught a Swordfish! (Epic: 10%)\nYou gained 150 coins!"); + fishingFrenzy.fishdrops(receivedMessage, 20); + verify(receivedMessage, times(1)).sendResponse("You caught a Salmon! (Rare: 15%)\nYou gained 75 coins!"); + fishingFrenzy.fishdrops(receivedMessage, 50); + verify(receivedMessage, times(1)).sendResponse("You caught a Mackeral! (Uncommon: 25%)\nYou gained 30 coins!"); + fishingFrenzy.fishdrops(receivedMessage, 60); + verify(receivedMessage, times(1)).sendResponse("You caught a Carp! (Common: 45%)\nYou gained 10 coins!"); + + } + @Test + void itShouldFish() { + //Given + when(receivedMessage.getMessageContent()).thenReturn(fishingFrenzy.COMMAND + " fish"); + + //When + fishingFrenzy.handle(receivedMessage); + + //Then + verify(receivedMessage, times(1)).sendResponse(anyString()); + } + @Test + void itShouldBalance() { + //Given + when(receivedMessage.getMessageContent()).thenReturn(fishingFrenzy.COMMAND + " balance"); + + //When + fishingFrenzy.handle(receivedMessage); + + //Then + verify(receivedMessage, times(1)).sendResponse("You have " + fishingFrenzy.coins + " coins."); + } +} diff --git a/src/test/java/org/jointheleague/features/student/first_feature/TriviaAPITest.java b/src/test/java/org/jointheleague/features/student/first_feature/TriviaAPITest.java new file mode 100644 index 00000000..7846229d --- /dev/null +++ b/src/test/java/org/jointheleague/features/student/first_feature/TriviaAPITest.java @@ -0,0 +1,220 @@ +package org.jointheleague.features.student.first_feature; + +import org.apache.commons.text.StringEscapeUtils; +import org.jointheleague.api_wrapper.ReceivedMessage; +import org.jointheleague.features.examples.third_features.plain_old_java_objects.news_api.ApiExampleWrapper; +import org.jointheleague.features.help_embed.plain_old_java_objects.help_embed.HelpEmbed; +import org.jointheleague.features.templates.FeatureTemplate; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.web.reactive.function.client.WebClient; + +import reactor.core.publisher.Mono; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +public class TriviaAPITest { + private final String testChannelName = "test"; + private final TriviaAPI featureOne = new TriviaAPI(testChannelName); + + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final PrintStream originalOut = System.out; + + @Mock + private ReceivedMessage receivedMessage; + @Mock + WebClient webClientMock; + @Mock + WebClient.RequestHeadersUriSpec requestHeadersUriSpecMock; + + @Mock + WebClient.RequestHeadersSpec requestHeadersSpecMock; + + @Mock + WebClient.ResponseSpec responseSpecMock; + @Mock + Mono apiExampleWrapperMonoMock; + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + System.setOut(new PrintStream(outContent)); + } + + @AfterEach + public void itShouldNotPrintToSystemOut() { + String expected = ""; + String actual = outContent.toString(); + + assertEquals(expected, actual); + System.setOut(originalOut); + } + @Test + void itShouldNotHandleMessagesWithoutCommand() { + //Given + String command = ""; + when(receivedMessage.getMessageContent()).thenReturn(command); + + //When + featureOne.handle(receivedMessage); + + //Then + verify(receivedMessage, never()).sendResponse(""); + } + + @Test + void itShouldHaveAHelpEmbed() { + //Given + + //When + HelpEmbed actualHelpEmbed = featureOne.getHelpEmbed(); + + //Then + assertNotNull(actualHelpEmbed); + } + + @Test + void itShouldHaveTheCommandAsTheTitleOfTheHelpEmbed() { + //Given + + //When + String helpEmbedTitle = featureOne.getHelpEmbed().getTitle(); + String command = featureOne.COMMAND; + + //Then + assertEquals(command, helpEmbedTitle); + } + @Test + void itShouldHelp() { + //Given + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " help"); + //When + featureOne.handle(receivedMessage); + + //Then + verify(receivedMessage, times(1)).sendResponse("Commands:\n`!triviaAPI categories` to list all topics.\n`!triviaAPI startQuiz [topic number]` to start a quiz based on a topic.\n`!triviaAPI stopQuiz` to stop the current quiz.\n`!triviaAPI answer [answer]` to answer a question."); + + } + @Test + void itShouldGiveCategories() { + //Given + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " categories"); + //When + featureOne.handle(receivedMessage); + StringBuilder sb = new StringBuilder(); + for (Integer key : featureOne.categories.keySet()) { + sb.append(key + " : " + featureOne.categories.get(key) + "\n"); + } + //Then + verify(receivedMessage, times(1)).sendResponse(sb.toString()); + + } + @Test + void itShouldStopQuiz() { + //Given + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " stopQuiz"); + //When + featureOne.handle(receivedMessage); + if (!featureOne.quizStarted) { + verify(receivedMessage, times(1)).sendResponse("There is no quiz started."); + } + featureOne.quizStarted = true; + featureOne.handle(receivedMessage); + assertEquals(featureOne.quizStarted, false); + verify(receivedMessage, times(1)).sendResponse("Quiz stopped. You got a final score of " + featureOne.score + "/" + featureOne.currentQuestion); + assertEquals(featureOne.currentQuestion, 0); + assertEquals(featureOne.score, 0); + + } + @Test + void itShouldStartQuiz() { + //Given + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " startQuiz 15"); + //When + featureOne.handle(receivedMessage); + verify(receivedMessage).sendResponse("Starting 10 question quiz about topic: " + (featureOne.categories.get(15))); + verify(receivedMessage).sendResponse("Question #" + (featureOne.currentQuestion+1) + ": " + StringEscapeUtils.unescapeHtml4(featureOne.tq.getResults().get(featureOne.currentQuestion).getQuestion() + " True or false?")); + } + @Test + void testUserSendsAnswerWithoutQuizStarted() { + featureOne.quizStarted = false; + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " answer true"); + featureOne.handle(receivedMessage); + verify(receivedMessage).sendResponse("There is no quiz started."); + } + @Test + void itShouldHaveIncorrectAnswer() { + Question q = new Question(); + q.question = "1+1 = 2"; + q.correctAnswer = "true"; + Question q2 = new Question(); + q2.question = "2+2 = 5"; + q2.correctAnswer = "false"; + TriviaQuestions tq = new TriviaQuestions(); + tq.results = new ArrayList (); + tq.results.add(q); + tq.results.add(q2); + featureOne.tq = tq; + int currentQuestion = featureOne.currentQuestion; + featureOne.quizStarted = true; + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " answer false"); + featureOne.handle(receivedMessage); + verify(receivedMessage).sendResponse("Incorrect! The answer was " + featureOne.tq.getResults().get(currentQuestion).getCorrectAnswer()); + assertEquals(currentQuestion+1, featureOne.currentQuestion); + } + @Test + void itShouldHaveCorrectAnswer() { + Question q = new Question(); + q.question = "1+1 = 2"; + q.correctAnswer = "true"; + Question q2 = new Question(); + q2.question = "2+2 = 5"; + q2.correctAnswer = "false"; + TriviaQuestions tq = new TriviaQuestions(); + tq.results = new ArrayList (); + tq.results.add(q); + tq.results.add(q2); + featureOne.tq = tq; + //Given + featureOne.quizStarted = true; + int score = featureOne.score; + int currentQuestion = featureOne.currentQuestion; + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " answer true"); + featureOne.handle(receivedMessage); + verify(receivedMessage).sendResponse("Correct!"); + assertEquals(currentQuestion+1, featureOne.currentQuestion); + assertEquals(score+1, featureOne.score); + } + @Test + void itShouldHave10Questions() { + featureOne.totalNumberOfQuestions = 1; + Question q = new Question(); + q.question = "1+1 = 2"; + q.correctAnswer = "true"; + TriviaQuestions tq = new TriviaQuestions(); + tq.results = new ArrayList (); + tq.results.add(q); + featureOne.tq = tq; + featureOne.currentQuestion = 0; + //Given + featureOne.quizStarted = true; + int score = featureOne.score; + int currentQuestion = featureOne.currentQuestion; + when(receivedMessage.getMessageContent()).thenReturn(featureOne.COMMAND + " answer false"); + featureOne.handle(receivedMessage); + verify(receivedMessage).sendResponse("Incorrect! The answer was " + tq.getResults().get(0).getCorrectAnswer()); + verify(receivedMessage).sendResponse("Congrats! You have finished the quiz! You got a final score of " + score + "/" + (currentQuestion+1)); + assertEquals(featureOne.score, 0); + assertEquals(featureOne.currentQuestion, 0); + } +}