Merge remote-tracking branch 'upstream/master' into runelite

Also pulled out a couple of our merged apis into our own classes. Getting much easier to keep up to date with their data

# Conflicts:
#	.github/FUNDING.yml
#	.github/workflows/CI.yml
#	cache-client/pom.xml
#	cache-updater/pom.xml
#	cache/pom.xml
#	cache/src/main/java/net/runelite/cache/fs/jagex/DiskStorage.java
#	ci/build.sh
#	http-api/pom.xml
#	http-service/pom.xml
#	http-service/src/main/java/net/runelite/http/service/chat/ChatController.java
#	http-service/src/main/java/net/runelite/http/service/config/ConfigController.java
#	http-service/src/main/java/net/runelite/http/service/config/ConfigService.java
#	http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java
#	http-service/src/main/java/net/runelite/http/service/ge/Trade.java
#	http-service/src/test/java/net/runelite/http/service/config/ConfigServiceTest.java
#	http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java
#	pom.xml
#	runelite-api/pom.xml
#	runelite-api/src/main/java/net/runelite/api/Client.java
#	runelite-api/src/main/java/net/runelite/api/ObjectID.java
#	runelite-api/src/main/java/net/runelite/api/ParamHolder.java
#	runelite-api/src/main/java/net/runelite/api/ParamID.java
#	runelite-api/src/main/java/net/runelite/api/Preferences.java
#	runelite-api/src/main/java/net/runelite/api/ScriptEvent.java
#	runelite-api/src/main/java/net/runelite/api/ScriptID.java
#	runelite-api/src/main/java/net/runelite/api/SettingID.java
#	runelite-api/src/main/java/net/runelite/api/StructComposition.java
#	runelite-api/src/main/java/net/runelite/api/StructID.java
#	runelite-api/src/main/java/net/runelite/api/Varbits.java
#	runelite-api/src/main/java/net/runelite/api/events/PlayerChanged.java
#	runelite-api/src/main/java/net/runelite/api/events/PostStructComposition.java
#	runelite-api/src/main/java/net/runelite/api/events/WidgetClosed.java
#	runelite-api/src/main/java/net/runelite/api/events/WidgetHiddenChanged.java
#	runelite-api/src/main/java/net/runelite/api/events/WidgetPositioned.java
#	runelite-api/src/main/java/net/runelite/api/events/WorldChanged.java
#	runelite-api/src/main/java/net/runelite/api/widgets/Widget.java
#	runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java
#	runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java
#	runelite-api/src/main/java/net/runelite/api/widgets/WidgetModalMode.java
#	runelite-api/src/test/java/net/runelite/api/plugins/combatlevel/CombatLevelOverlayTest.java
#	runelite-client/pom.xml
#	runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java
#	runelite-client/src/main/java/net/runelite/client/callback/Hooks.java
#	runelite-client/src/main/java/net/runelite/client/plugins/config/PluginToggleButton.java
#	runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursor.java
#	runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java
#	runelite-client/src/main/java/net/runelite/client/plugins/mta/alchemy/AlchemyRoomTimer.java
#	runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixOverlay.java
#	runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixPlugin.java
#	runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java
#	runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java
#	runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java
#	runelite-client/src/main/resources/net/runelite/client/runelite.properties
#	runelite-client/src/main/scripts/OptionsPanelZoomUpdater.hash
#	runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java
#	runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java
#	runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java
#	runelite-client/src/test/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPluginTest.java
#	runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java
#	runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangePluginTest.java
#	runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java
#	runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java
#	runelite-client/src/test/java/net/runelite/client/plugins/timers/TimersPluginTest.java
#	runelite-client/src/test/java/net/runelite/client/util/ColorUtilTest.java
#	runelite-script-assembler-plugin/pom.xml
This commit is contained in:
TheRealNull
2021-01-14 14:41:17 -05:00
99 changed files with 7485 additions and 1754 deletions

View File

@@ -0,0 +1,663 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.chatcommands;
import com.google.common.collect.Sets;
import com.google.inject.Guice;
import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.io.IOException;
import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject;
import net.runelite.api.ChatMessageType;
import static net.runelite.api.ChatMessageType.FRIENDSCHATNOTIFICATION;
import static net.runelite.api.ChatMessageType.GAMEMESSAGE;
import static net.runelite.api.ChatMessageType.TRADE;
import net.runelite.api.Client;
import net.runelite.api.MessageNode;
import net.runelite.api.Player;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget;
import static net.runelite.api.widgets.WidgetID.ADVENTURE_LOG_ID;
import static net.runelite.api.widgets.WidgetID.GENERIC_SCROLL_GROUP_ID;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.chat.ChatCommandManager;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ChatColorConfig;
import net.runelite.client.config.ConfigManager;
import net.runelite.http.api.chat.ChatClient;
import net.runelite.http.api.hiscore.HiscoreClient;
import net.runelite.http.api.hiscore.HiscoreSkill;
import net.runelite.http.api.hiscore.SingleHiscoreSkillResult;
import net.runelite.http.api.hiscore.Skill;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ChatCommandsPluginTest
{
private static final String PLAYER_NAME = "Adam";
@Mock
@Bind
Client client;
@Mock
@Bind
ConfigManager configManager;
@Mock
@Bind
ScheduledExecutorService scheduledExecutorService;
@Mock
@Bind
ChatColorConfig chatColorConfig;
@Mock
@Bind
ChatCommandManager chatCommandManager;
@Mock
@Bind
HiscoreClient hiscoreClient;
@Mock
@Bind
ChatMessageManager chatMessageManager;
@Mock
@Bind
ChatClient chatClient;
@Mock
@Bind
ChatCommandsConfig chatCommandsConfig;
@Inject
ChatCommandsPlugin chatCommandsPlugin;
@Before
public void before()
{
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
Player player = mock(Player.class);
when(player.getName()).thenReturn(PLAYER_NAME);
when(client.getLocalPlayer()).thenReturn(player);
}
@Test
public void testStartupShutdown()
{
chatCommandsPlugin.startUp();
chatCommandsPlugin.shutDown();
ArgumentCaptor<String> registerCaptor = ArgumentCaptor.forClass(String.class);
verify(chatCommandManager, atLeastOnce()).registerCommand(registerCaptor.capture(), any());
verify(chatCommandManager, atLeastOnce()).registerCommandAsync(registerCaptor.capture(), any());
verify(chatCommandManager, atLeastOnce()).registerCommandAsync(registerCaptor.capture(), any(), any());
ArgumentCaptor<String> unregisterCaptor = ArgumentCaptor.forClass(String.class);
verify(chatCommandManager, atLeastOnce()).unregisterCommand(unregisterCaptor.capture());
assertEquals(Sets.newHashSet(registerCaptor.getAllValues()), Sets.newHashSet(unregisterCaptor.getAllValues()));
}
@Test
public void testCorporealBeastKill()
{
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your Corporeal Beast kill count is: <col=ff0000>4</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessageEvent);
verify(configManager).setRSProfileConfiguration("killcount", "corporeal beast", 4);
}
@Test
public void testTheatreOfBlood()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: <col=ff0000>5:04</col><br>Theatre of Blood wave completion time: <col=ff0000>37:04</col> (Personal best!)", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Theatre of Blood count is: <col=ff0000>73</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessageEvent);
verify(configManager).setRSProfileConfiguration("killcount", "theatre of blood", 73);
verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 37 * 60 + 4);
}
@Test
public void testTheatreOfBloodNoPb()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: <col=ff0000>5:04</col><br>Theatre of Blood wave completion time: <col=ff0000>38:17</col><br></col>Personal best: 37:04", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Theatre of Blood count is: <col=ff0000>73</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessageEvent);
verify(configManager).setRSProfileConfiguration("killcount", "theatre of blood", 73);
verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 37 * 60 + 4);
}
@Test
public void testWintertodt()
{
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your subdued Wintertodt count is: <col=ff0000>4</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessageEvent);
verify(configManager).setRSProfileConfiguration("killcount", "wintertodt", 4);
}
@Test
public void testKreearra()
{
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your Kree'arra kill count is: <col=ff0000>4</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessageEvent);
verify(configManager).setRSProfileConfiguration("killcount", "kree'arra", 4);
}
@Test
public void testBarrows()
{
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your Barrows chest count is: <col=ff0000>277</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessageEvent);
verify(configManager).setRSProfileConfiguration("killcount", "barrows chests", 277);
}
@Test
public void testHerbiboar()
{
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your herbiboar harvest count is: <col=ff0000>4091</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessageEvent);
verify(configManager).setRSProfileConfiguration("killcount", "herbiboar", 4091);
}
@Test
public void testGauntlet()
{
ChatMessage gauntletMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: <col=ff0000>123</col>.", null, 0);
chatCommandsPlugin.onChatMessage(gauntletMessage);
verify(configManager).setRSProfileConfiguration("killcount", "gauntlet", 123);
}
@Test
public void testCorruptedGauntlet()
{
ChatMessage corruptedGauntletMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Corrupted Gauntlet completion count is: <col=ff0000>4729</col>.", null, 0);
chatCommandsPlugin.onChatMessage(corruptedGauntletMessage);
verify(configManager).setRSProfileConfiguration("killcount", "corrupted gauntlet", 4729);
}
@Test
public void testPersonalBest()
{
final String FIGHT_DURATION = "Fight duration: <col=ff0000>2:06</col>. Personal best: 1:19.";
// This sets lastBoss
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Kree'arra kill count is: <col=ff0000>4</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", FIGHT_DURATION, null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "kree'arra", 79);
}
@Test
public void testPersonalBestNoTrailingPeriod()
{
final String FIGHT_DURATION = "Fight duration: <col=ff0000>0:59</col>. Personal best: 0:55";
// This sets lastBoss
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Zulrah kill count is: <col=ff0000>4</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", FIGHT_DURATION, null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "zulrah", 55);
}
@Test
public void testNewPersonalBest()
{
final String NEW_PB = "Fight duration: <col=ff0000>3:01</col> (new personal best).";
// This sets lastBoss
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Kree'arra kill count is: <col=ff0000>4</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", NEW_PB, null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "kree'arra", 181);
}
@Test
public void testDuelArenaWin()
{
ChatMessage chatMessageEvent = new ChatMessage(null, TRADE, "", "You won! You have now won 27 duels.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessageEvent);
verify(configManager).setRSProfileConfiguration("killcount", "duel arena wins", 27);
verify(configManager).setRSProfileConfiguration("killcount", "duel arena win streak", 1);
}
@Test
public void testDuelArenaWin2()
{
ChatMessage chatMessageEvent = new ChatMessage(null, TRADE, "", "You were defeated! You have won 22 duels.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessageEvent);
verify(configManager).setRSProfileConfiguration("killcount", "duel arena wins", 22);
}
@Test
public void testDuelArenaLose()
{
ChatMessage chatMessageEvent = new ChatMessage(null, TRADE, "", "You have now lost 999 duels.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessageEvent);
verify(configManager).setRSProfileConfiguration("killcount", "duel arena losses", 999);
}
@Test
public void testAgilityLap()
{
final String NEW_PB = "Lap duration: <col=ff0000>1:01</col> (new personal best).";
// This sets lastBoss
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Prifddinas Agility Course lap count is: <col=ff0000>2</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", NEW_PB, null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "prifddinas agility course", 61);
verify(configManager).setRSProfileConfiguration("killcount", "prifddinas agility course", 2);
}
@Test
public void testZukNewPb()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzKal-Zuk kill count is: <col=ff0000>2</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Duration: <col=ff0000>104:31</col> (new personal best)", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "tzkal-zuk", 104 * 60 + 31);
verify(configManager).setRSProfileConfiguration("killcount", "tzkal-zuk", 2);
}
@Test
public void testZukKill()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzKal-Zuk kill count is: <col=ff0000>3</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Duration: <col=ff0000>172:18</col>. Personal best: 134:52", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "tzkal-zuk", 134 * 60 + 52);
verify(configManager).setRSProfileConfiguration("killcount", "tzkal-zuk", 3);
}
@Test
public void testGgNewPb()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Fight duration: <col=ff0000>1:36</col> (new personal best)", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Grotesque Guardians kill count is: <col=ff0000>179</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "grotesque guardians", 96);
verify(configManager).setRSProfileConfiguration("killcount", "grotesque guardians", 179);
}
@Test
public void testGgKill()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Fight duration: <col=ff0000>2:41</col>. Personal best: 2:14", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Grotesque Guardians kill count is: <col=ff0000>32</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "grotesque guardians", 2 * 60 + 14);
verify(configManager).setRSProfileConfiguration("killcount", "grotesque guardians", 32);
}
@Test
public void testGuantletPersonalBest()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Challenge duration: <col=ff0000>10:24</col>. Personal best: 7:59.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: <col=ff0000>124</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("killcount", "gauntlet", 124);
verify(configManager).setRSProfileConfiguration("personalbest", "gauntlet", 7 * 60 + 59);
}
@Test
public void testGuantletNewPersonalBest()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Challenge duration: <col=ff0000>10:24</col> (new personal best).", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: <col=ff0000>124</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "gauntlet", 10 * 60 + 24);
verify(configManager).setRSProfileConfiguration("killcount", "gauntlet", 124);
}
@Test
public void testCoXKill()
{
ChatMessage chatMessage = new ChatMessage(null, FRIENDSCHATNOTIFICATION, "", "<col=ef20ff>Congratulations - your raid is complete!</col><br>Team size: <col=ff0000>24+ players</col> Duration:</col> <col=ff0000>37:04</col> (new personal best)</col>>", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Chambers of Xeric count is: <col=ff0000>51</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("killcount", "chambers of xeric", 51);
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric", 37 * 60 + 4);
}
@Test
public void testCoXKillNoPb()
{
ChatMessage chatMessage = new ChatMessage(null, FRIENDSCHATNOTIFICATION, "", "<col=ef20ff>Congratulations - your raid is complete!</col><br>Team size: <col=ff0000>11-15 players</col> Duration:</col> <col=ff0000>23:25</col> Personal best: </col><col=ff0000>20:19</col>", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Chambers of Xeric count is: <col=ff0000>52</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("killcount", "chambers of xeric", 52);
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric", 20 * 60 + 19);
}
@Test
public void testAdventureLogCountersPage()
{
Widget advLogWidget = mock(Widget.class);
Widget advLogExploitsTextWidget = mock(Widget.class);
when(advLogWidget.getChild(ChatCommandsPlugin.ADV_LOG_EXPLOITS_TEXT_INDEX)).thenReturn(advLogExploitsTextWidget);
when(advLogExploitsTextWidget.getText()).thenReturn("The Exploits of " + PLAYER_NAME);
when(client.getWidget(WidgetInfo.ADVENTURE_LOG)).thenReturn(advLogWidget);
when(configManager.getRSProfileConfiguration(anyString(), anyString(), any(Class.class))).thenReturn(2224);
WidgetLoaded advLogEvent = new WidgetLoaded();
advLogEvent.setGroupId(ADVENTURE_LOG_ID);
chatCommandsPlugin.onWidgetLoaded(advLogEvent);
chatCommandsPlugin.onGameTick(new GameTick());
String COUNTER_TEXT = "Duel Arena<br>Wins: <col=d0c0b0>4</col><br>Losses: <col=d0c0b0>2</col>" +
"<br><br>Last Man Standing<br>Rank: <col=d0c0b0>0</col>" +
"<br><br>Treasure Trails<br>Beginner: <col=d0c0b0>0</col><br>Easy: <col=d0c0b0>7</col>" +
"<br>Medium: <col=d0c0b0>28</col><br>Hard: <col=d0c0b0>108</col><br>Elite: <col=d0c0b0>15</col>" +
"<br>Master: <col=d0c0b0>27</col><br>Rank: <col=d0c0b0>Novice</col>" +
"<br><br>Chompy Hunting<br>Kills: <col=d0c0b0>1,000</col><br>Rank: <col=d0c0b0>Ogre Expert</col>" +
"<br><br>Order of the White Knights<br>Rank: <col=d0c0b0>Master</col><br>with a kill score of <col=d0c0b0>1,300</col>" +
"<br><br>TzHaar Fight Cave<br>Fastest run: <col=d0c0b0>38:10</col>" +
"<br><br>Inferno<br>Fastest run: <col=d0c0b0>-</col><br><br>Zulrah<br>" +
"Fastest kill: <col=d0c0b0>5:48</col><br><br>Vorkath<br>Fastest kill: <col=d0c0b0>1:21</col>" +
"<br><br>Galvek<br>Fastest kill: <col=d0c0b0>-</col><br><br>Grotesque Guardians<br>" +
"Fastest kill: <col=d0c0b0>2:49</col><br><br>Alchemical Hydra<br>Fastest kill: <col=d0c0b0>-</col>" +
"<br><br>Hespori<br>Fastest kill: <col=d0c0b0>0:57</col><br><br>Nightmare<br>" +
"Fastest kill: <col=d0c0b0>3:30</col><br><br>The Gauntlet<br>Fastest run: <col=d0c0b0>-</col>" +
"<br><br>The Corrupted Gauntlet<br>Fastest run: <col=d0c0b0>-</col><br><br>Fragment of Seren<br>Fastest kill: <col=d0c0b0>-</col>" +
"<br><br>Chambers of Xeric<br>Fastest run - (Team size: 24+ players): <col=d0c0b0>24:17</col>" +
"<br><br>Chambers of Xeric - Challenge mode<br>Fastest run - (Team size: Solo): <col=d0c0b0>22:15</col>" +
"<br><br>Barbarian Assault<br>High-level gambles: <col=d0c0b0>0</col><br><br>Fremennik spirits rested: <col=d0c0b0>0</col>";
Widget countersPage = mock(Widget.class);
when(countersPage.getText()).thenReturn(COUNTER_TEXT);
when(client.getWidget(WidgetInfo.GENERIC_SCROLL_TEXT)).thenReturn(countersPage);
WidgetLoaded countersLogEvent = new WidgetLoaded();
countersLogEvent.setGroupId(GENERIC_SCROLL_GROUP_ID);
chatCommandsPlugin.onWidgetLoaded(countersLogEvent);
chatCommandsPlugin.onGameTick(new GameTick());
verify(configManager).setRSProfileConfiguration("personalbest", "tztok-jad", 38 * 60 + 10);
verify(configManager).setRSProfileConfiguration("personalbest", "zulrah", 5 * 60 + 48);
verify(configManager).setRSProfileConfiguration("personalbest", "vorkath", 1 * 60 + 21);
verify(configManager).setRSProfileConfiguration("personalbest", "grotesque guardians", 2 * 60 + 49);
verify(configManager).setRSProfileConfiguration("personalbest", "hespori", 57);
verify(configManager).setRSProfileConfiguration("personalbest", "nightmare", 3 * 60 + 30);
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric", 24 * 60 + 17);
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric challenge mode", 22 * 60 + 15);
}
@Test
public void testAdventurerLogCountersPage2()
{
Widget advLogWidget = mock(Widget.class);
Widget advLogExploitsTextWidget = mock(Widget.class);
when(advLogWidget.getChild(ChatCommandsPlugin.ADV_LOG_EXPLOITS_TEXT_INDEX)).thenReturn(advLogExploitsTextWidget);
when(advLogExploitsTextWidget.getText()).thenReturn("The Exploits of " + PLAYER_NAME);
when(client.getWidget(WidgetInfo.ADVENTURE_LOG)).thenReturn(advLogWidget);
WidgetLoaded advLogEvent = new WidgetLoaded();
advLogEvent.setGroupId(ADVENTURE_LOG_ID);
chatCommandsPlugin.onWidgetLoaded(advLogEvent);
chatCommandsPlugin.onGameTick(new GameTick());
String COUNTER_TEXT = "Duel Arena<br>Wins: <col=d0c0b0>12</col><br>Losses: <col=d0c0b0>20</col>" +
"<br><br>Last Man Standing<br>Rank: <col=d0c0b0>0</col>" +
"<br><br>Treasure Trails<br>Beginner: <col=d0c0b0>1</col><br>Easy: <col=d0c0b0>4</col>" +
"<br>Medium: <col=d0c0b0>35</col><br>Hard: <col=d0c0b0>66</col><br>Elite: <col=d0c0b0>2</col>" +
"<br>Master: <col=d0c0b0>0</col><br>Rank: <col=d0c0b0>Novice</col>" +
"<br><br>Chompy Hunting<br>Kills: <col=d0c0b0>300</col><br>Rank: <col=d0c0b0>Ogre Forester</col>" +
"<br><br>Order of the White Knights<br>Rank: <col=d0c0b0>Unrated</col><br>with a kill score of <col=d0c0b0>99</col>" +
"<br><br>TzHaar Fight Cave<br>Fastest run: <col=d0c0b0>65:12</col>" +
"<br><br>Inferno<br>Fastest run: <col=d0c0b0>-</col><br><br>Zulrah<br>" +
"Fastest kill: <col=d0c0b0>2:55</col><br><br>Vorkath<br>Fastest kill: <col=d0c0b0>1:37</col>" +
"<br><br>Galvek<br>Fastest kill: <col=d0c0b0>-</col><br><br>Grotesque Guardians<br>" +
"Fastest kill: <col=d0c0b0>-</col><br><br>Alchemical Hydra<br>Fastest kill: <col=d0c0b0>-</col>" +
"<br><br>Hespori<br>Fastest kill: <col=d0c0b0>1:42</col><br><br>Nightmare<br>" +
"Fastest kill: <col=d0c0b0>-</col><br><br>The Gauntlet<br>Fastest run: <col=d0c0b0>-</col>" +
"<br><br>The Corrupted Gauntlet<br>Fastest run: <col=d0c0b0>-</col><br><br>Fragment of Seren<br>Fastest kill: <col=d0c0b0>-</col>" +
"<br><br>Chambers of Xeric<br>Fastest run - (Team size: Solo): <col=d0c0b0>21:23</col><br>Fastest run - (Team size: 3 players): <col=d0c0b0>27:16</col>" +
"<br><br>Chambers of Xeric - Challenge mode<br>Fastest run - (Team size: Solo): <col=d0c0b0>34:30</col><br>Fastest run - (Team size: 4 players): <col=d0c0b0>21:26</col>" +
"<br><br>Barbarian Assault<br>High-level gambles: <col=d0c0b0>0</col><br><br>Fremennik spirits rested: <col=d0c0b0>0</col>";
Widget countersPage = mock(Widget.class);
when(countersPage.getText()).thenReturn(COUNTER_TEXT);
when(client.getWidget(WidgetInfo.GENERIC_SCROLL_TEXT)).thenReturn(countersPage);
WidgetLoaded countersLogEvent = new WidgetLoaded();
countersLogEvent.setGroupId(GENERIC_SCROLL_GROUP_ID);
chatCommandsPlugin.onWidgetLoaded(countersLogEvent);
chatCommandsPlugin.onGameTick(new GameTick());
verify(configManager).setRSProfileConfiguration("personalbest", "tztok-jad", 65 * 60 + 12);
verify(configManager).setRSProfileConfiguration("personalbest", "zulrah", 2 * 60 + 55);
verify(configManager).setRSProfileConfiguration("personalbest", "vorkath", 1 * 60 + 37);
verify(configManager).setRSProfileConfiguration("personalbest", "hespori", 1 * 60 + 42);
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric", 21 * 60 + 23);
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric challenge mode", 21 * 60 + 26);
}
@Test
public void testNotYourAdventureLogCountersPage()
{
Widget advLogWidget = mock(Widget.class);
Widget advLogExploitsTextWidget = mock(Widget.class);
when(advLogWidget.getChild(ChatCommandsPlugin.ADV_LOG_EXPLOITS_TEXT_INDEX)).thenReturn(advLogExploitsTextWidget);
when(advLogExploitsTextWidget.getText()).thenReturn("The Exploits of " + "not the player");
when(client.getWidget(WidgetInfo.ADVENTURE_LOG)).thenReturn(advLogWidget);
WidgetLoaded advLogEvent = new WidgetLoaded();
advLogEvent.setGroupId(ADVENTURE_LOG_ID);
chatCommandsPlugin.onWidgetLoaded(advLogEvent);
chatCommandsPlugin.onGameTick(new GameTick());
WidgetLoaded countersLogEvent = new WidgetLoaded();
countersLogEvent.setGroupId(GENERIC_SCROLL_GROUP_ID);
chatCommandsPlugin.onWidgetLoaded(countersLogEvent);
chatCommandsPlugin.onGameTick(new GameTick());
verifyNoMoreInteractions(configManager);
}
@Test
public void testPlayerSkillLookup() throws IOException
{
when(chatCommandsConfig.lvl()).thenReturn(true);
SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult();
skillResult.setPlayer(PLAYER_NAME);
skillResult.setSkill(new Skill(10, 1000, -1));
when(hiscoreClient.lookup(PLAYER_NAME, HiscoreSkill.ZULRAH, null)).thenReturn(skillResult);
MessageNode messageNode = mock(MessageNode.class);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setName(PLAYER_NAME);
chatMessage.setMessageNode(messageNode);
chatCommandsPlugin.playerSkillLookup(chatMessage, "!lvl zulrah");
verify(messageNode).setRuneLiteFormatMessage("<colNORMAL>Level <colHIGHLIGHT>Zulrah: 1000<colNORMAL> Rank: <colHIGHLIGHT>10");
}
@Test
public void testHsFloorNoPb()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 1 time: <col=ff0000>1:19</col>. Personal best: 0:28", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 1", 28);
}
@Test
public void testHsFloorPb()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 2 time: <col=ff0000>0:47</col> (new personal best)", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 2", 47);
}
@Test
public void testHsOverallPb_Pb()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 5 time: <col=ff0000>4:46</col> (new personal best)<br>Overall time: <col=ff0000>9:53</col> (new personal best)<br>", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 5", 4 * 60 + 46);
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre", 9 * 60 + 53);
}
@Test
public void testHsOverallPb_NoPb()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 5 time: <col=ff0000>3:26</col> (new personal best)<br>Overall time: <col=ff0000>9:17</col>. Personal best: 9:15<br>", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 5", 3 * 60 + 26);
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre", 9 * 60 + 15);
}
@Test
public void testHsOverallNoPb_NoPb()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 5 time: <col=ff0000>3:56</col>. Personal best: 3:05<br>Overall time: <col=ff0000>9:14</col>. Personal best: 7:49<br>", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 5", 3 * 60 + 5);
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre", 7 * 60 + 49);
}
@Test
public void testHsOverallNoPb_Pb()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 5 time: <col=ff0000>3:10</col>. Personal best: 3:04<br>Overall time: <col=ff0000>7:47</col> (new personal best)<br>", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 5", 3 * 60 + 4);
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre", 7 * 60 + 47);
}
@Test
public void testHsFloorKc()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "You have completed Floor 5 of the Hallowed Sepulchre! Total completions: <col=ff0000>81</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("killcount", "hallowed sepulchre floor 5", 81);
}
@Test
public void testHsGhcKc()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "You have opened the Grand Hallowed Coffin <col=ff0000>36</col> times!", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("killcount", "hallowed sepulchre", 36);
}
@Test
public void testJadNewPbWithLeagueTask()
{
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzTok-Jad kill count is: <col=ff0000>2</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Congratulations, you've completed a master task: <col=7f3700>Complete the Fight Caves in 25:00</col>.", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Duration: <col=ff0000>21:58</col> (new personal best)", null, 0);
chatCommandsPlugin.onChatMessage(chatMessage);
verify(configManager).setRSProfileConfiguration("personalbest", "tztok-jad", 21 * 60 + 58);
verify(configManager).setRSProfileConfiguration("killcount", "tztok-jad", 2);
}
}

View File

@@ -0,0 +1,424 @@
/*
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* Copyright (c) 2019, osrs-music-map <osrs-music-map@users.noreply.github.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.chatfilter;
import com.google.inject.Guice;
import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule;
import javax.inject.Inject;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.IterableHashTable;
import net.runelite.api.MessageNode;
import net.runelite.api.Player;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.client.game.FriendChatManager;
import static net.runelite.client.plugins.chatfilter.ChatFilterPlugin.CENSOR_MESSAGE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ChatFilterPluginTest
{
@Mock
@Bind
private Client client;
@Mock
@Bind
private ChatFilterConfig chatFilterConfig;
@Mock
@Bind
private FriendChatManager friendChatManager;
@Mock
private Player localPlayer;
@Inject
private ChatFilterPlugin chatFilterPlugin;
@Before
public void before()
{
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_WORDS);
when(chatFilterConfig.filteredWords()).thenReturn("");
when(chatFilterConfig.filteredRegex()).thenReturn("");
when(chatFilterConfig.filteredNames()).thenReturn("");
when(client.getLocalPlayer()).thenReturn(localPlayer);
}
private ScriptCallbackEvent createCallbackEvent(final String sender, final String chatMessage, final ChatMessageType messageType)
{
ScriptCallbackEvent event = new ScriptCallbackEvent();
event.setScript(null);
event.setEventName("chatFilterCheck");
int[] simulatedIntStack =
new int[]{1, messageType.getType(), 1}; // is msg allowed to show, ChatMessageType.PUBLICCHAT, message id
String[] simulatedStringStack = new String[]{chatMessage};
IterableHashTable<MessageNode> messageTable = mock(IterableHashTable.class);
MessageNode mockedMsgNode = mockMessageNode(sender);
when(client.getIntStack()).thenReturn(simulatedIntStack);
when(client.getIntStackSize()).thenReturn(simulatedIntStack.length);
when(client.getStringStack()).thenReturn(simulatedStringStack);
when(client.getStringStackSize()).thenReturn(simulatedStringStack.length);
when(client.getMessages()).thenReturn(messageTable);
when(messageTable.get(1)).thenReturn(mockedMsgNode);
return event;
}
private MessageNode mockMessageNode(String sender)
{
MessageNode node = mock(MessageNode.class);
when(node.getName()).thenReturn(sender);
return node;
}
private MessageNode mockMessageNode(int id)
{
MessageNode node = mock(MessageNode.class);
when(node.getId()).thenReturn(id);
return node;
}
private MessageNode mockMessageNode(int id, String sender, String value)
{
MessageNode node = mock(MessageNode.class);
when(node.getId()).thenReturn(id);
when(node.getName()).thenReturn(sender);
when(node.getValue()).thenReturn(value);
return node;
}
@Test
public void testCensorWords()
{
when(chatFilterConfig.filteredWords()).thenReturn("hat");
chatFilterPlugin.updateFilteredPatterns();
assertEquals("w***s up", chatFilterPlugin.censorMessage("Blue", "whats up"));
}
@Test
public void testCensorRegex()
{
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
when(chatFilterConfig.filteredRegex()).thenReturn("5[0-9]x2\n(");
chatFilterPlugin.updateFilteredPatterns();
assertNull(chatFilterPlugin.censorMessage("Blue", "55X2 Dicing | Trusted Ranks | Huge Pay Outs!"));
}
@Test
public void testBrokenRegex()
{
when(chatFilterConfig.filteredRegex()).thenReturn("Test\n)\n73");
chatFilterPlugin.updateFilteredPatterns();
assertEquals("** isn't funny", chatFilterPlugin.censorMessage("Blue", "73 isn't funny"));
}
@Test
public void testCaseSensitivity()
{
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_MESSAGE);
when(chatFilterConfig.filteredWords()).thenReturn("ReGeX!!!");
chatFilterPlugin.updateFilteredPatterns();
assertEquals(CENSOR_MESSAGE, chatFilterPlugin.censorMessage("Blue", "I love regex!!!!!!!!"));
}
@Test
public void testNonPrintableCharacters()
{
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
when(chatFilterConfig.filteredWords()).thenReturn("test");
chatFilterPlugin.updateFilteredPatterns();
assertNull(chatFilterPlugin.censorMessage("Blue", "te\u008Cst"));
}
@Test
public void testReplayedMessage()
{
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
when(chatFilterConfig.filteredWords()).thenReturn("hello osrs");
chatFilterPlugin.updateFilteredPatterns();
assertNull(chatFilterPlugin.censorMessage("Blue", "hello\u00A0osrs"));
}
@Test
public void testMessageFromFriendIsFiltered()
{
when(friendChatManager.isMember("Iron Mammal")).thenReturn(false);
when(chatFilterConfig.filterFriends()).thenReturn(true);
assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("Iron Mammal"));
}
@Test
public void testMessageFromFriendIsNotFiltered()
{
when(client.isFriended("Iron Mammal", false)).thenReturn(true);
when(chatFilterConfig.filterFriends()).thenReturn(false);
assertFalse(chatFilterPlugin.shouldFilterPlayerMessage("Iron Mammal"));
}
@Test
public void testMessageFromFriendsChatIsFiltered()
{
when(client.isFriended("B0aty", false)).thenReturn(false);
when(chatFilterConfig.filterFriendsChat()).thenReturn(true);
assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("B0aty"));
}
@Test
public void testMessageFromFriendsChatIsNotFiltered()
{
when(friendChatManager.isMember("B0aty")).thenReturn(true);
when(chatFilterConfig.filterFriendsChat()).thenReturn(false);
assertFalse(chatFilterPlugin.shouldFilterPlayerMessage("B0aty"));
}
@Test
public void testMessageFromSelfIsNotFiltered()
{
when(localPlayer.getName()).thenReturn("Swampletics");
assertFalse(chatFilterPlugin.shouldFilterPlayerMessage("Swampletics"));
}
@Test
public void testMessageFromNonFriendNonFCIsFiltered()
{
when(client.isFriended("Woox", false)).thenReturn(false);
when(friendChatManager.isMember("Woox")).thenReturn(false);
assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("Woox"));
}
@Test
public void testShouldFilterByName()
{
when(chatFilterConfig.filteredNames()).thenReturn("Gamble [0-9]*");
chatFilterPlugin.updateFilteredPatterns();
assertTrue(chatFilterPlugin.shouldFilterByName("Gamble 1234"));
assertFalse(chatFilterPlugin.shouldFilterByName("Adam"));
}
@Test
public void testCensorWordsByName()
{
when(chatFilterConfig.filteredNames()).thenReturn("Blue");
chatFilterPlugin.updateFilteredPatterns();
assertEquals("************", chatFilterPlugin.censorMessage("Blue", "Gamble today"));
}
@Test
public void textCensorMessageByName()
{
when(chatFilterConfig.filteredNames()).thenReturn("Blue");
chatFilterPlugin.updateFilteredPatterns();
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_MESSAGE);
assertEquals(CENSOR_MESSAGE,
chatFilterPlugin.censorMessage("Blue", "Meet swampletics, my morytania locked ultimate ironman"));
}
@Test
public void testRemoveMessageByName()
{
when(chatFilterConfig.filteredNames()).thenReturn("Blue");
chatFilterPlugin.updateFilteredPatterns();
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
assertNull(
chatFilterPlugin.censorMessage("Blue", "What about now it's time to rock with the biggity buck bumble"));
}
@Test
public void testEventRemoveByName()
{
when(chatFilterConfig.filteredNames()).thenReturn("Gamble [0-9]*");
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
chatFilterPlugin.updateFilteredPatterns();
ScriptCallbackEvent event = createCallbackEvent("Gamble 1234", "filterme", ChatMessageType.PUBLICCHAT);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals(0, client.getIntStack()[client.getIntStackSize() - 3]);
}
@Test
public void testEventRemoveByText()
{
when(chatFilterConfig.filteredWords()).thenReturn("filterme");
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
chatFilterPlugin.updateFilteredPatterns();
ScriptCallbackEvent event = createCallbackEvent("Adam", "please filterme plugin", ChatMessageType.PUBLICCHAT);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals(0, client.getIntStack()[client.getIntStackSize() - 3]);
}
@Test
public void testEventCensorWordsByName()
{
when(chatFilterConfig.filteredNames()).thenReturn("Gamble [0-9]*");
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_WORDS);
chatFilterPlugin.updateFilteredPatterns();
ScriptCallbackEvent event = createCallbackEvent("Gamble 1234", "filterme", ChatMessageType.PUBLICCHAT);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals("********", client.getStringStack()[client.getStringStackSize() - 1]);
}
@Test
public void testEventCensorWordsByText()
{
when(chatFilterConfig.filteredWords()).thenReturn("filterme");
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_WORDS);
chatFilterPlugin.updateFilteredPatterns();
ScriptCallbackEvent event = createCallbackEvent("Adam", "please filterme plugin", ChatMessageType.PUBLICCHAT);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals("please ******** plugin", client.getStringStack()[client.getStringStackSize() - 1]);
}
@Test
public void testEventCensorMessageByName()
{
when(chatFilterConfig.filteredNames()).thenReturn("Gamble [0-9]*");
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_MESSAGE);
chatFilterPlugin.updateFilteredPatterns();
ScriptCallbackEvent event = createCallbackEvent("Gamble 1234", "filterme", ChatMessageType.PUBLICCHAT);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals(CENSOR_MESSAGE, client.getStringStack()[client.getStringStackSize() - 1]);
}
@Test
public void testEventCensorMessageByText()
{
when(chatFilterConfig.filteredWords()).thenReturn("filterme");
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_MESSAGE);
chatFilterPlugin.updateFilteredPatterns();
ScriptCallbackEvent event = createCallbackEvent("Adam", "please filterme plugin", ChatMessageType.PUBLICCHAT);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals(CENSOR_MESSAGE, client.getStringStack()[client.getStringStackSize() - 1]);
}
@Test
public void testDuplicateChatFiltered()
{
when(chatFilterConfig.collapseGameChat()).thenReturn(true);
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(0, null, "testMessage"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
ScriptCallbackEvent event = createCallbackEvent(null, "testMessage", ChatMessageType.GAMEMESSAGE);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals(0, client.getIntStack()[client.getIntStackSize() - 3]);
}
@Test
public void testNoDuplicate()
{
when(chatFilterConfig.collapseGameChat()).thenReturn(true);
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1), ChatMessageType.GAMEMESSAGE, null, "testMessage", null, 0));
ScriptCallbackEvent event = createCallbackEvent(null, "testMessage", ChatMessageType.GAMEMESSAGE);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals(1, client.getIntStack()[client.getIntStackSize() - 3]);
assertEquals("testMessage", client.getStringStack()[client.getStringStackSize() - 1]);
}
@Test
public void testDuplicateChatCount()
{
when(chatFilterConfig.collapseGameChat()).thenReturn(true);
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(4, null, "testMessage"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(3, null, "testMessage"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(2, null, "testMessage"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1, null, "testMessage"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
ScriptCallbackEvent event = createCallbackEvent(null, "testMessage", ChatMessageType.GAMEMESSAGE);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals(1, client.getIntStack()[client.getIntStackSize() - 3]);
assertEquals("testMessage (4)", client.getStringStack()[client.getStringStackSize() - 1]);
}
@Test
public void publicChatFilteredOnDuplicate()
{
when(chatFilterConfig.collapsePlayerChat()).thenReturn(true);
when(chatFilterConfig.maxRepeatedPublicChats()).thenReturn(2);
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1, "testName", "testMessage"), ChatMessageType.PUBLICCHAT, null, null, null, 0));
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1, "testName", "testMessage"), ChatMessageType.PUBLICCHAT, null, null, null, 0));
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1, "testName", "testMessage"), ChatMessageType.PUBLICCHAT, null, null, null, 0));
ScriptCallbackEvent event = createCallbackEvent("testName", "testMessage", ChatMessageType.PUBLICCHAT);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals(0, client.getIntStack()[client.getIntStackSize() - 3]);
}
@Test
public void testDuplicateChatFilterIgnoresFormatting()
{
when(chatFilterConfig.collapseGameChat()).thenReturn(true);
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(4, null, "<col=000000>testMessage</col>"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(3, null, "<col=000000>testMessage</col>"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(2, null, "<col=000000>testMessage</col>"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1, null, "<col=000000>testMessage</col>"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
ScriptCallbackEvent event = createCallbackEvent(null, "<col=000000>testMessage</col>", ChatMessageType.GAMEMESSAGE);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals(1, client.getIntStack()[client.getIntStackSize() - 3]);
assertEquals("<col=000000>testMessage</col> (4)", client.getStringStack()[client.getStringStackSize() - 1]);
}
@Test
public void testChatIcons()
{
when(chatFilterConfig.filteredWords()).thenReturn("test");
// if this test is broken, this stubbing is required to trip the assert
lenient().when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
when(friendChatManager.isMember("Lazark")).thenReturn(true);
chatFilterPlugin.updateFilteredPatterns();
ScriptCallbackEvent event = createCallbackEvent("<img=22>Lazark", "test", ChatMessageType.PUBLICCHAT);
chatFilterPlugin.onScriptCallbackEvent(event);
assertEquals(1, client.getIntStack()[client.getIntStackSize() - 3]); // not filtered
}
}

View File

@@ -0,0 +1,289 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.chatnotifications;
import com.google.inject.Guice;
import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.util.Iterator;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.MessageNode;
import net.runelite.api.Player;
import net.runelite.api.events.ChatMessage;
import net.runelite.client.Notifier;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.util.Text;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ChatNotificationsPluginTest
{
@Mock
@Bind
private Client client;
@Mock
@Bind
private ChatNotificationsConfig config;
@Mock
@Bind
private ChatMessageManager chatMessageManager;
@Mock
@Bind
private Notifier notifier;
@Bind
@Named("runelite.title")
private String runeliteTitle = "RuneLite";
@Inject
private ChatNotificationsPlugin chatNotificationsPlugin;
@Before
public void before()
{
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
}
@Test
public void onChatMessage()
{
when(config.highlightWordsString()).thenReturn("Deathbeam, Deathbeam OSRS , test");
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn("Deathbeam, Deathbeam OSRS");
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
chatNotificationsPlugin.startUp(); // load highlight config
chatNotificationsPlugin.onChatMessage(chatMessage);
verify(messageNode).setValue("<colHIGHLIGHT>Deathbeam<colNORMAL>, <colHIGHLIGHT>Deathbeam<colNORMAL> OSRS");
}
@Test
public void testLtGt()
{
when(config.highlightWordsString()).thenReturn("<test>");
String message = "test <lt>test<gt> test";
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn(message);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
chatNotificationsPlugin.startUp(); // load highlight config
chatNotificationsPlugin.onChatMessage(chatMessage);
verify(messageNode).setValue("test <colHIGHLIGHT><lt>test<gt><colNORMAL> test");
}
@Test
public void testMatchEntireMessage()
{
when(config.highlightWordsString()).thenReturn(".Your divine potion effect is about to expire.");
String message = ".Your divine potion effect is about to expire.";
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn(message);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
chatNotificationsPlugin.startUp(); // load highlight config
chatNotificationsPlugin.onChatMessage(chatMessage);
verify(messageNode).setValue("<colHIGHLIGHT>.Your divine potion effect is about to expire.<colNORMAL>");
}
@Test
public void testFullStop()
{
when(config.highlightWordsString()).thenReturn("test");
String message = "foo test. bar";
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn(message);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
chatNotificationsPlugin.startUp(); // load highlight config
chatNotificationsPlugin.onChatMessage(chatMessage);
verify(messageNode).setValue("foo <colHIGHLIGHT>test<colNORMAL>. bar");
}
@Test
public void testColor()
{
when(config.highlightWordsString()).thenReturn("you. It");
String message = "Your dodgy necklace protects you. <col=ff0000>It has 1 charge left.</col>";
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn(message);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
chatNotificationsPlugin.startUp(); // load highlight config
chatNotificationsPlugin.onChatMessage(chatMessage);
verify(messageNode).setValue("Your dodgy necklace protects <colHIGHLIGHT>you. It<col=ff0000> has 1 charge left.</col>");
}
@Test
public void testPreceedingColor()
{
when(config.highlightWordsString()).thenReturn("you. It");
String message = "Your dodgy <col=00ff00>necklace protects you. It has 1 charge left.</col>";
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn(message);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
chatNotificationsPlugin.startUp(); // load highlight config
chatNotificationsPlugin.onChatMessage(chatMessage);
verify(messageNode).setValue("Your dodgy <col=00ff00>necklace protects <colHIGHLIGHT>you. It<col=00ff00> has 1 charge left.</col>");
}
@Test
public void testEmoji()
{
when(config.highlightWordsString()).thenReturn("test");
String message = "emoji test <img=29>";
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn(message);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
chatNotificationsPlugin.startUp(); // load highlight config
chatNotificationsPlugin.onChatMessage(chatMessage);
verify(messageNode).setValue("emoji <colHIGHLIGHT>test<colNORMAL> <img=29>");
}
@Test
public void testNonMatchedColors()
{
when(config.highlightWordsString()).thenReturn("test");
String message = "<col=ff0000>color</col> test <img=29>";
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn(message);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
chatNotificationsPlugin.startUp(); // load highlight config
chatNotificationsPlugin.onChatMessage(chatMessage);
verify(messageNode).setValue("<col=ff0000>color</col> <colHIGHLIGHT>test<colNORMAL> <img=29>");
}
@Test
public void highlightListTest()
{
when(config.highlightWordsString()).thenReturn("this,is, a , test, ");
final List<String> higlights = Text.fromCSV(config.highlightWordsString());
assertEquals(4, higlights.size());
final Iterator<String> iterator = higlights.iterator();
assertEquals("this", iterator.next());
assertEquals("is", iterator.next());
assertEquals("a", iterator.next());
assertEquals("test", iterator.next());
}
@Test
public void testStripColor()
{
assertEquals("you. It", ChatNotificationsPlugin.stripColor("you. <col=ff0000>It"));
}
@Test
public void testHighlightOwnName()
{
Player player = mock(Player.class);
when(player.getName()).thenReturn("Logic Knot");
when(client.getLocalPlayer()).thenReturn(player);
when(config.highlightOwnName()).thenReturn(true);
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn("<col=005f00>Logic Knot received a drop: Adamant longsword</col>");
ChatMessage chatMessage = new ChatMessage(messageNode, ChatMessageType.GAMEMESSAGE, "", "", "", 0);
chatNotificationsPlugin.onChatMessage(chatMessage);
verify(messageNode).setValue("<col=005f00><colHIGHLIGHT><u>Logic Knot</u><colNORMAL> received a drop: Adamant longsword</col>");
}
@Test
public void testHighlightOwnNameNbsp()
{
Player player = mock(Player.class);
when(player.getName()).thenReturn("Logic Knot");
when(client.getLocalPlayer()).thenReturn(player);
when(config.highlightOwnName()).thenReturn(true);
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn("<col=005f00>Logic\u00a0Knot received a drop: Adamant longsword</col>");
ChatMessage chatMessage = new ChatMessage(messageNode, ChatMessageType.GAMEMESSAGE, "", "", "", 0);
chatNotificationsPlugin.onChatMessage(chatMessage);
// set value uses our player name, which has nbsp replaced
verify(messageNode).setValue("<col=005f00><colHIGHLIGHT><u>Logic Knot</u><colNORMAL> received a drop: Adamant longsword</col>");
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.discord;
import com.google.inject.Guice;
import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;
import javax.inject.Inject;
import javax.inject.Named;
import net.runelite.api.Client;
import net.runelite.client.discord.DiscordPresence;
import net.runelite.client.discord.DiscordService;
import net.runelite.client.ws.PartyService;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import static org.mockito.ArgumentMatchers.any;
import org.mockito.Mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class DiscordStateTest
{
@Inject
DiscordState discordState;
@Mock
@Bind
DiscordConfig discordConfig;
@Mock
@Bind
DiscordService discordService;
@Mock
@Bind
Client client;
@Mock
@Bind
PartyService partyService;
@Bind
@Named("runelite.title")
private String runeliteTitle = "RuneLite";
@Bind
@Named("runelite.version")
private String runeliteVersion = "version";
@Before
public void before()
{
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
when(partyService.getLocalPartyId()).thenReturn(UUID.nameUUIDFromBytes("test".getBytes(StandardCharsets.UTF_8)));
}
@Test
public void testStatusReset()
{
when(discordConfig.actionTimeout()).thenReturn(-1);
when(discordConfig.elapsedTimeType()).thenReturn(DiscordConfig.ElapsedTimeType.ACTIVITY);
discordState.triggerEvent(DiscordGameEventType.IN_MENU);
verify(discordService).updatePresence(any(DiscordPresence.class));
discordState.checkForTimeout();
ArgumentCaptor<DiscordPresence> captor = ArgumentCaptor.forClass(DiscordPresence.class);
verify(discordService, times(2)).updatePresence(captor.capture());
List<DiscordPresence> captured = captor.getAllValues();
assertNull(captured.get(captured.size() - 1).getEndTimestamp());
}
@Test
public void testStatusTimeout()
{
when(discordConfig.actionTimeout()).thenReturn(-1);
when(discordConfig.elapsedTimeType()).thenReturn(DiscordConfig.ElapsedTimeType.ACTIVITY);
discordState.triggerEvent(DiscordGameEventType.TRAINING_AGILITY);
verify(discordService).updatePresence(any(DiscordPresence.class));
discordState.checkForTimeout();
verify(discordService, times(1)).clearPresence();
}
@Test
public void testAreaChange()
{
when(discordConfig.elapsedTimeType()).thenReturn(DiscordConfig.ElapsedTimeType.TOTAL);
// Start with state of IN_GAME
ArgumentCaptor<DiscordPresence> captor = ArgumentCaptor.forClass(DiscordPresence.class);
discordState.triggerEvent(DiscordGameEventType.IN_GAME);
verify(discordService, times(1)).updatePresence(captor.capture());
assertEquals(DiscordGameEventType.IN_GAME.getState(), captor.getValue().getState());
// IN_GAME -> CITY
discordState.triggerEvent(DiscordGameEventType.CITY_VARROCK);
verify(discordService, times(2)).updatePresence(captor.capture());
assertEquals(DiscordGameEventType.CITY_VARROCK.getState(), captor.getValue().getState());
// CITY -> IN_GAME
discordState.triggerEvent(DiscordGameEventType.IN_GAME);
verify(discordService, times(3)).updatePresence(captor.capture());
assertEquals(DiscordGameEventType.IN_GAME.getState(), captor.getValue().getState());
}
}

View File

@@ -0,0 +1,332 @@
/*
* Copyright (c) 2020, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.grandexchange;
import com.google.inject.Guice;
import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.GrandExchangeOffer;
import net.runelite.api.GrandExchangeOfferState;
import net.runelite.api.ItemComposition;
import net.runelite.api.ItemID;
import net.runelite.api.WorldType;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GrandExchangeOfferChanged;
import net.runelite.client.Notifier;
import net.runelite.client.account.SessionManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.game.ItemManager;
import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseManager;
import static net.runelite.client.plugins.grandexchange.GrandExchangePlugin.findFuzzyIndices;
import static net.runelite.http.api.RuneLiteAPI.GSON;
import net.runelite.http.api.ge.GrandExchangeClient;
import net.runelite.http.api.ge.GrandExchangeTrade;
import net.runelite.http.api.osbuddy.OSBGrandExchangeClient;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import org.mockito.Mock;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class GrandExchangePluginTest
{
@Inject
private GrandExchangePlugin grandExchangePlugin;
@Mock
@Bind
private GrandExchangeConfig grandExchangeConfig;
@Mock
@Bind
private Notifier notifier;
@Mock
@Bind
private SessionManager sessionManager;
@Mock
@Bind
private ConfigManager configManager;
@Mock
@Bind
private ItemManager itemManager;
@Mock
@Bind
private KeyManager keyManager;
@Mock
@Bind
private MouseManager mouseManager;
@Mock
@Bind
private ScheduledExecutorService scheduledExecutorService;
@Mock
@Bind
private GrandExchangeClient grandExchangeClient;
@Mock
@Bind
private OSBGrandExchangeClient osbGrandExchangeClient;
@Mock
@Bind
private Client client;
@Mock
@Bind
private RuneLiteConfig runeLiteConfig;
@Before
public void setUp()
{
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
when(client.getWorldType()).thenReturn(EnumSet.noneOf(WorldType.class));
}
@Test
public void testFindFuzzyIndices()
{
List<Integer> fuzzyIndices = findFuzzyIndices("Ancestral robe bottom", "obby");
// r<u>ob</u>e <u>b</u>ottom
assertEquals(Arrays.asList(11, 12, 15), fuzzyIndices);
}
@Test
public void testSubmitTrade()
{
// 1 @ 25
SavedOffer savedOffer = new SavedOffer();
savedOffer.setItemId(ItemID.ABYSSAL_WHIP);
savedOffer.setQuantitySold(1);
savedOffer.setTotalQuantity(10);
savedOffer.setPrice(1000);
savedOffer.setSpent(25);
savedOffer.setState(GrandExchangeOfferState.BUYING);
when(configManager.getRSProfileConfiguration("geoffer", "0")).thenReturn(GSON.toJson(savedOffer));
// buy 2 @ 10/ea
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
when(grandExchangeOffer.getQuantitySold()).thenReturn(1 + 2);
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
when(grandExchangeOffer.getPrice()).thenReturn(1000);
when(grandExchangeOffer.getSpent()).thenReturn(25 + 10 * 2);
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.BUYING);
grandExchangePlugin.submitTrade(0, grandExchangeOffer);
ArgumentCaptor<GrandExchangeTrade> captor = ArgumentCaptor.forClass(GrandExchangeTrade.class);
verify(grandExchangeClient).submit(captor.capture());
GrandExchangeTrade trade = captor.getValue();
assertTrue(trade.isBuy());
assertEquals(ItemID.ABYSSAL_WHIP, trade.getItemId());
assertEquals(2, trade.getDqty());
assertEquals(10, trade.getTotal());
assertEquals(45, trade.getSpent());
assertEquals(20, trade.getDspent());
}
@Test
public void testDuplicateTrade()
{
SavedOffer savedOffer = new SavedOffer();
savedOffer.setItemId(ItemID.ABYSSAL_WHIP);
savedOffer.setQuantitySold(1);
savedOffer.setTotalQuantity(10);
savedOffer.setPrice(1000);
savedOffer.setSpent(25);
savedOffer.setState(GrandExchangeOfferState.BUYING);
when(configManager.getRSProfileConfiguration("geoffer", "0")).thenReturn(GSON.toJson(savedOffer));
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
when(grandExchangeOffer.getQuantitySold()).thenReturn(1);
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
when(grandExchangeOffer.getPrice()).thenReturn(1000);
lenient().when(grandExchangeOffer.getSpent()).thenReturn(25);
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.BUYING);
grandExchangePlugin.submitTrade(0, grandExchangeOffer);
verify(grandExchangeClient, never()).submit(any(GrandExchangeTrade.class));
}
@Test
public void testCancelTrade()
{
SavedOffer savedOffer = new SavedOffer();
savedOffer.setItemId(ItemID.ABYSSAL_WHIP);
savedOffer.setQuantitySold(1);
savedOffer.setTotalQuantity(10);
savedOffer.setPrice(1000);
savedOffer.setSpent(25);
savedOffer.setState(GrandExchangeOfferState.BUYING);
when(configManager.getRSProfileConfiguration("geoffer", "0")).thenReturn(GSON.toJson(savedOffer));
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
when(grandExchangeOffer.getQuantitySold()).thenReturn(1);
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
when(grandExchangeOffer.getPrice()).thenReturn(1000);
when(grandExchangeOffer.getSpent()).thenReturn(25);
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.CANCELLED_BUY);
grandExchangePlugin.submitTrade(0, grandExchangeOffer);
ArgumentCaptor<GrandExchangeTrade> captor = ArgumentCaptor.forClass(GrandExchangeTrade.class);
verify(grandExchangeClient).submit(captor.capture());
GrandExchangeTrade trade = captor.getValue();
assertTrue(trade.isBuy());
assertTrue(trade.isCancel());
assertEquals(ItemID.ABYSSAL_WHIP, trade.getItemId());
assertEquals(1, trade.getQty());
assertEquals(10, trade.getTotal());
assertEquals(25, trade.getSpent());
}
@Test
public void testHop()
{
when(client.getGameState()).thenReturn(GameState.HOPPING);
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.EMPTY);
GrandExchangeOfferChanged grandExchangeOfferChanged = new GrandExchangeOfferChanged();
grandExchangeOfferChanged.setOffer(grandExchangeOffer);
grandExchangePlugin.onGrandExchangeOfferChanged(grandExchangeOfferChanged);
verify(configManager, never()).unsetRSProfileConfiguration(anyString(), anyString());
}
@Test
public void testLogin()
{
GrandExchangePanel panel = mock(GrandExchangePanel.class);
when(panel.getOffersPanel()).thenReturn(mock(GrandExchangeOffersPanel.class));
grandExchangePlugin.setPanel(panel);
when(itemManager.getItemComposition(anyInt())).thenReturn(mock(ItemComposition.class));
// provide config support so getOffer and setOffer work
final Map<String, Object> config = new HashMap<>();
doAnswer(a ->
{
Object[] arguments = a.getArguments();
config.put((String) arguments[1], arguments[2]);
return null;
}).when(configManager).setRSProfileConfiguration(eq("geoffer"), anyString(), anyString());
when(configManager.getRSProfileConfiguration(eq("geoffer"), anyString())).thenAnswer(a ->
{
Object[] arguments = a.getArguments();
return config.get((String) arguments[1]);
});
// set loginBurstGeUpdates
GameStateChanged gameStateChanged = new GameStateChanged();
gameStateChanged.setGameState(GameState.LOGIN_SCREEN);
grandExchangePlugin.onGameStateChanged(gameStateChanged);
// 8x buy 10 whip @ 1k ea, bought 1 sofar.
for (int i = 0; i < GrandExchangePlugin.GE_SLOTS; ++i)
{
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
when(grandExchangeOffer.getQuantitySold()).thenReturn(1);
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
when(grandExchangeOffer.getPrice()).thenReturn(1000);
when(grandExchangeOffer.getSpent()).thenReturn(1000);
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.SELLING);
GrandExchangeOfferChanged grandExchangeOfferChanged = new GrandExchangeOfferChanged();
grandExchangeOfferChanged.setSlot(i);
grandExchangeOfferChanged.setOffer(grandExchangeOffer);
grandExchangePlugin.onGrandExchangeOfferChanged(grandExchangeOfferChanged);
}
// Now send update for one of the slots
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
when(grandExchangeOffer.getQuantitySold()).thenReturn(2);
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
when(grandExchangeOffer.getPrice()).thenReturn(1000);
when(grandExchangeOffer.getSpent()).thenReturn(2000);
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.SELLING);
GrandExchangeOfferChanged grandExchangeOfferChanged = new GrandExchangeOfferChanged();
grandExchangeOfferChanged.setSlot(2);
grandExchangeOfferChanged.setOffer(grandExchangeOffer);
grandExchangePlugin.onGrandExchangeOfferChanged(grandExchangeOfferChanged);
// verify trade update
ArgumentCaptor<GrandExchangeTrade> captor = ArgumentCaptor.forClass(GrandExchangeTrade.class);
verify(grandExchangeClient).submit(captor.capture());
GrandExchangeTrade trade = captor.getValue();
assertFalse(trade.isBuy());
assertEquals(ItemID.ABYSSAL_WHIP, trade.getItemId());
assertEquals(2, trade.getQty());
assertEquals(1, trade.getDqty());
assertEquals(10, trade.getTotal());
assertEquals(1000, trade.getDspent());
assertEquals(2000, trade.getSpent());
assertEquals(1000, trade.getOffer());
assertEquals(2, trade.getSlot());
assertTrue(trade.isLogin());
}
}

View File

@@ -0,0 +1,318 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.screenshot;
import com.google.inject.Guice;
import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Consumer;
import javax.inject.Inject;
import static net.runelite.api.ChatMessageType.GAMEMESSAGE;
import net.runelite.api.Client;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.Widget;
import static net.runelite.api.widgets.WidgetID.DIALOG_SPRITE_GROUP_ID;
import static net.runelite.api.widgets.WidgetID.LEVEL_UP_GROUP_ID;
import static net.runelite.api.widgets.WidgetInfo.DIALOG_SPRITE_TEXT;
import static net.runelite.api.widgets.WidgetInfo.LEVEL_UP_LEVEL;
import net.runelite.client.Notifier;
import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.DrawManager;
import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.util.ImageCapture;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import org.mockito.Mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ScreenshotPluginTest
{
private static final String CLUE_SCROLL = "<col=3300ff>You have completed 28 medium Treasure Trails</col>";
private static final String BARROWS_CHEST = "Your Barrows chest count is <col=ff0000>310</col>";
private static final String CHAMBERS_OF_XERIC_CHEST = "Your completed Chambers of Xeric count is: <col=ff0000>489</col>.";
private static final String THEATRE_OF_BLOOD_CHEST = "Your completed Theatre of Blood count is: <col=ff0000>73</col>.";
private static final String VALUABLE_DROP = "<col=ef1020>Valuable drop: 6 x Bronze arrow (42 coins)</col>";
private static final String UNTRADEABLE_DROP = "<col=ef1020>Untradeable drop: Rusty sword";
private static final String BA_HIGH_GAMBLE_REWARD = "Raw shark (x 300)!<br>High level gamble count: <col=7f0000>100</col>";
private static final String HUNTER_LEVEL_2_TEXT = "<col=000080>Congratulations, you've just advanced a Hunter level.<col=000000><br><br>Your Hunter level is now 2.";
@Mock
@Bind
private Client client;
@Inject
private ScreenshotPlugin screenshotPlugin;
@Mock
@Bind
private ScreenshotConfig screenshotConfig;
@Mock
@Bind
Notifier notifier;
@Mock
@Bind
ClientUI clientUi;
@Mock
@Bind
DrawManager drawManager;
@Mock
@Bind
RuneLiteConfig config;
@Mock
@Bind
ScheduledExecutorService service;
@Mock
@Bind
private OverlayManager overlayManager;
@Mock
@Bind
private InfoBoxManager infoBoxManager;
@Mock
@Bind
private ImageCapture imageCapture;
@Before
public void before()
{
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
when(screenshotConfig.screenshotLevels()).thenReturn(true);
when(screenshotConfig.screenshotValuableDrop()).thenReturn(true);
when(screenshotConfig.screenshotUntradeableDrop()).thenReturn(true);
}
@Test
public void testClueScroll()
{
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Seth", CLUE_SCROLL, null, 0);
screenshotPlugin.onChatMessage(chatMessageEvent);
assertEquals("medium", screenshotPlugin.getClueType());
assertEquals(28, screenshotPlugin.getClueNumber());
}
@Test
public void testBarrowsChest()
{
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Seth", BARROWS_CHEST, null, 0);
screenshotPlugin.onChatMessage(chatMessageEvent);
assertEquals(310, screenshotPlugin.getBarrowsNumber());
}
@Test
public void testChambersOfXericChest()
{
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Seth", CHAMBERS_OF_XERIC_CHEST, null, 0);
screenshotPlugin.onChatMessage(chatMessageEvent);
assertEquals(489, screenshotPlugin.getChambersOfXericNumber());
}
@Test
public void testTheatreOfBloodChest()
{
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Magic fTail", THEATRE_OF_BLOOD_CHEST, null, 0);
screenshotPlugin.onChatMessage(chatMessageEvent);
assertEquals(73, screenshotPlugin.gettheatreOfBloodNumber());
}
@Test
public void testValuableDrop()
{
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", VALUABLE_DROP, null, 0);
screenshotPlugin.onChatMessage(chatMessageEvent);
verify(drawManager).requestNextFrameListener(any(Consumer.class));
}
@Test
public void testUntradeableDrop()
{
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", UNTRADEABLE_DROP, null, 0);
screenshotPlugin.onChatMessage(chatMessageEvent);
verify(drawManager).requestNextFrameListener(any(Consumer.class));
}
@Test
public void testHitpointsLevel99()
{
Widget levelChild = mock(Widget.class);
when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild);
when(levelChild.getText()).thenReturn("Your Hitpoints are now 99.");
assertEquals("Hitpoints(99)", screenshotPlugin.parseLevelUpWidget(LEVEL_UP_LEVEL));
WidgetLoaded event = new WidgetLoaded();
event.setGroupId(LEVEL_UP_GROUP_ID);
screenshotPlugin.onWidgetLoaded(event);
GameTick tick = new GameTick();
screenshotPlugin.onGameTick(tick);
verify(drawManager).requestNextFrameListener(any(Consumer.class));
}
@Test
public void testFiremakingLevel9()
{
Widget levelChild = mock(Widget.class);
when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild);
when(levelChild.getText()).thenReturn("Your Firemaking level is now 9.");
assertEquals("Firemaking(9)", screenshotPlugin.parseLevelUpWidget(LEVEL_UP_LEVEL));
WidgetLoaded event = new WidgetLoaded();
event.setGroupId(LEVEL_UP_GROUP_ID);
screenshotPlugin.onWidgetLoaded(event);
GameTick tick = new GameTick();
screenshotPlugin.onGameTick(tick);
verify(drawManager).requestNextFrameListener(any(Consumer.class));
}
@Test
public void testAttackLevel70()
{
Widget levelChild = mock(Widget.class);
when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild);
when(levelChild.getText()).thenReturn("Your Attack level is now 70.");
assertEquals("Attack(70)", screenshotPlugin.parseLevelUpWidget(LEVEL_UP_LEVEL));
WidgetLoaded event = new WidgetLoaded();
event.setGroupId(LEVEL_UP_GROUP_ID);
screenshotPlugin.onWidgetLoaded(event);
GameTick tick = new GameTick();
screenshotPlugin.onGameTick(tick);
verify(drawManager).requestNextFrameListener(any(Consumer.class));
}
@Test
public void testHunterLevel2()
{
Widget levelChild = mock(Widget.class);
when(client.getWidget(eq(DIALOG_SPRITE_TEXT))).thenReturn(levelChild);
when(levelChild.getText()).thenReturn(HUNTER_LEVEL_2_TEXT);
assertEquals("Hunter(2)", screenshotPlugin.parseLevelUpWidget(DIALOG_SPRITE_TEXT));
WidgetLoaded event = new WidgetLoaded();
event.setGroupId(DIALOG_SPRITE_GROUP_ID);
screenshotPlugin.onWidgetLoaded(event);
GameTick tick = new GameTick();
screenshotPlugin.onGameTick(tick);
verify(drawManager).requestNextFrameListener(any(Consumer.class));
}
@Test
public void testQuestParsing()
{
assertEquals("Quest(The Corsair Curse)", ScreenshotPlugin.parseQuestCompletedWidget("You have completed The Corsair Curse!"));
assertEquals("Quest(One Small Favour)", ScreenshotPlugin.parseQuestCompletedWidget("'One Small Favour' completed!"));
assertEquals("Quest(Hazeel Cult partial completion)", ScreenshotPlugin.parseQuestCompletedWidget("You have... kind of... completed the Hazeel Cult Quest!"));
assertEquals("Quest(Rag and Bone Man II)", ScreenshotPlugin.parseQuestCompletedWidget("You have completely completed Rag and Bone Man!"));
assertEquals("Quest(Recipe for Disaster - Culinaromancer)", ScreenshotPlugin.parseQuestCompletedWidget("Congratulations! You have defeated the Culinaromancer!"));
assertEquals("Quest(Recipe for Disaster - Another Cook's Quest)", ScreenshotPlugin.parseQuestCompletedWidget("You have completed Another Cook's Quest!"));
assertEquals("Quest(Doric's Quest)", ScreenshotPlugin.parseQuestCompletedWidget("You have completed Doric's Quest!"));
assertEquals("Quest(quest not found)", ScreenshotPlugin.parseQuestCompletedWidget("Sins of the Father forgiven!"));
}
@Test
public void testBAHighGambleRewardParsing()
{
assertEquals("High Gamble(100)", ScreenshotPlugin.parseBAHighGambleWidget(BA_HIGH_GAMBLE_REWARD));
}
@Test
public void testLevelUpScreenshotsDisabled()
{
// Level up dialogs use the same widget interface as BA high gamble results
when(screenshotConfig.screenshotLevels()).thenReturn(false);
when(screenshotConfig.screenshotHighGamble()).thenReturn(true);
Widget dialogChild = mock(Widget.class);
when(dialogChild.getText()).thenReturn(HUNTER_LEVEL_2_TEXT);
when(client.getWidget(DIALOG_SPRITE_TEXT)).thenReturn(dialogChild);
WidgetLoaded event = new WidgetLoaded();
event.setGroupId(DIALOG_SPRITE_GROUP_ID);
screenshotPlugin.onWidgetLoaded(event);
screenshotPlugin.onGameTick(new GameTick());
verify(drawManager, times(0)).requestNextFrameListener(any(Consumer.class));
}
@Test
public void testBAHighGambleScreenshotsDisabled()
{
// BA high gamble results use the same widget interface as level up dialogs
when(screenshotConfig.screenshotLevels()).thenReturn(true);
when(screenshotConfig.screenshotHighGamble()).thenReturn(false);
Widget dialogChild = mock(Widget.class);
when(dialogChild.getText()).thenReturn(BA_HIGH_GAMBLE_REWARD);
when(client.getWidget(DIALOG_SPRITE_TEXT)).thenReturn(dialogChild);
WidgetLoaded event = new WidgetLoaded();
event.setGroupId(DIALOG_SPRITE_GROUP_ID);
screenshotPlugin.onWidgetLoaded(event);
screenshotPlugin.onGameTick(new GameTick());
verify(drawManager, times(0)).requestNextFrameListener(any(Consumer.class));
}
}

View File

@@ -0,0 +1,297 @@
/*
* Copyright (c) 2020, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.specialcounter;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule;
import net.runelite.api.Actor;
import net.runelite.api.Client;
import net.runelite.api.EquipmentInventorySlot;
import net.runelite.api.Hitsplat;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemContainer;
import net.runelite.api.ItemID;
import net.runelite.api.NPC;
import net.runelite.api.Player;
import net.runelite.api.VarPlayer;
import net.runelite.api.events.HitsplatApplied;
import net.runelite.api.events.InteractingChanged;
import net.runelite.api.events.VarbitChanged;
import net.runelite.client.Notifier;
import net.runelite.client.game.ItemManager;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import net.runelite.client.ws.PartyService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.ArgumentMatchers.any;
import org.mockito.Mock;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class SpecialCounterPluginTest
{
@Mock
@Bind
private Client client;
@Mock
@Bind
private InfoBoxManager infoBoxManager;
@Mock
@Bind
private PartyService partyService;
@Mock
@Bind
private ItemManager itemManager;
@Mock
@Bind
private Notifier notifier;
@Mock
@Bind
private SpecialCounterConfig specialCounterConfig;
@Inject
private SpecialCounterPlugin specialCounterPlugin;
@Before
public void before()
{
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
// Set up spec weapon
ItemContainer equipment = mock(ItemContainer.class);
when(equipment.getItem(EquipmentInventorySlot.WEAPON.getSlotIdx())).thenReturn(new Item(ItemID.BANDOS_GODSWORD, 1));
when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(equipment);
// Set up special attack energy
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(100);
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
}
private static HitsplatApplied hitsplat(Actor target, Hitsplat.HitsplatType type)
{
Hitsplat hitsplat = new Hitsplat(type, type == Hitsplat.HitsplatType.DAMAGE_ME ? 1 : 0, 42);
HitsplatApplied hitsplatApplied = new HitsplatApplied();
hitsplatApplied.setActor(target);
hitsplatApplied.setHitsplat(hitsplat);
return hitsplatApplied;
}
@Test
public void testSpecDamage()
{
NPC target = mock(NPC.class);
Player player = mock(Player.class);
when(client.getLocalPlayer()).thenReturn(player);
// spec npc
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
lenient().when(player.getInteracting()).thenReturn(target);
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, target));
// hit 1
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
verify(infoBoxManager).addInfoBox(any(SpecialCounter.class));
}
@Test
public void testSpecBlock()
{
NPC target = mock(NPC.class);
Player player = mock(Player.class);
when(client.getLocalPlayer()).thenReturn(player);
// spec npc
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
lenient().when(player.getInteracting()).thenReturn(target);
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, target));
// block 0
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.BLOCK_ME));
// hit 1
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
verify(infoBoxManager, never()).addInfoBox(any(SpecialCounter.class));
}
@Test
public void testUnaggro()
{
NPC target = mock(NPC.class);
Player player = mock(Player.class);
when(client.getLocalPlayer()).thenReturn(player);
// tick 1: attack npc
when(player.getInteracting()).thenReturn(target);
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, target));
// tick 2: spec fires and un-interact npc
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
lenient().when(player.getInteracting()).thenReturn(null);
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, null));
// tick 3: hit 1
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
verify(infoBoxManager).addInfoBox(any(SpecialCounter.class));
}
@Test
public void testSameTick()
{
NPC targetA = mock(NPC.class);
NPC targetB = mock(NPC.class);
Player player = mock(Player.class);
when(client.getLocalPlayer()).thenReturn(player);
// tick 1: attack npc A
when(player.getInteracting()).thenReturn(targetA);
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, targetA));
// tick 2: spec npc B
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
lenient().when(player.getInteracting()).thenReturn(targetB);
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, targetB));
// tick 3: hitsplat A, hitsplat B
specialCounterPlugin.onHitsplatApplied(hitsplat(targetA, Hitsplat.HitsplatType.DAMAGE_ME));
verify(infoBoxManager, never()).addInfoBox(any(SpecialCounter.class));
specialCounterPlugin.onHitsplatApplied(hitsplat(targetB, Hitsplat.HitsplatType.DAMAGE_ME));
verify(infoBoxManager).addInfoBox(any(SpecialCounter.class));
}
@Test
public void testReset()
{
NPC targetA = mock(NPC.class);
NPC targetB = mock(NPC.class);
when(targetB.getId()).thenReturn(1); // a different npc type
Player player = mock(Player.class);
when(client.getLocalPlayer()).thenReturn(player);
// spec npc
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
lenient().when(player.getInteracting()).thenReturn(targetA);
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, targetA));
// hit 1
specialCounterPlugin.onHitsplatApplied(hitsplat(targetA, Hitsplat.HitsplatType.DAMAGE_ME));
verify(infoBoxManager).addInfoBox(any(SpecialCounter.class));
// attack npc 2
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, targetB));
// hit 1
specialCounterPlugin.onHitsplatApplied(hitsplat(targetB, Hitsplat.HitsplatType.DAMAGE_ME));
verify(infoBoxManager).removeInfoBox(any(SpecialCounter.class));
}
@Test
public void testNotification()
{
// Create an enemy
NPC target = mock(NPC.class);
// Create player
Player player = mock(Player.class);
when(client.getLocalPlayer()).thenReturn(player);
when(specialCounterConfig.bandosGodswordThreshold()).thenReturn(2);
when(specialCounterConfig.thresholdNotification()).thenReturn(true);
// Attack enemy
when(player.getInteracting()).thenReturn(target);
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, target));
// First special attack
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
// Second special attack
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(0);
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
verify(notifier).notify("Bandos Godsword special attack threshold reached!");
}
@Test
public void testNotificationNotThreshold()
{
// Create an enemy
NPC target = mock(NPC.class);
// Create player
Player player = mock(Player.class);
when(client.getLocalPlayer()).thenReturn(player);
when(specialCounterConfig.bandosGodswordThreshold()).thenReturn(3);
lenient().when(specialCounterConfig.thresholdNotification()).thenReturn(true);
// Attack enemy
when(player.getInteracting()).thenReturn(target);
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, target));
// First special attack
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
// Second special attack
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(0);
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
verify(notifier, never()).notify(any());
}
}

View File

@@ -0,0 +1,372 @@
/*
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.timers;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.time.Duration;
import java.time.Instant;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.InventoryID;
import net.runelite.api.ItemContainer;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ItemContainerChanged;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.SpriteManager;
import net.runelite.client.ui.overlay.infobox.InfoBox;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.nullable;
import org.mockito.Mock;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
@RunWith(MockitoJUnitRunner.class)
public class TimersPluginTest
{
@Inject
private TimersPlugin timersPlugin;
@Mock
@Bind
private TimersConfig timersConfig;
@Mock
@Bind
private Client client;
@Mock
@Bind
private ItemManager itemManager;
@Mock
@Bind
private SpriteManager spriteManager;
@Mock
@Bind
private InfoBoxManager infoBoxManager;
@Before
public void before()
{
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
}
@Test
public void testHalfTeleblock()
{
when(timersConfig.showTeleblock()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 2 minutes, 30 seconds.</col>", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
assertEquals(Duration.ofSeconds(2 * 60 + 30), infoBox.getDuration());
}
@Test
public void testFullTeleblock()
{
when(timersConfig.showTeleblock()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 5 minutes.</col>", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
assertEquals(Duration.ofMinutes(5), infoBox.getDuration());
}
@Test
public void testDmmHalfTb()
{
when(timersConfig.showTeleblock()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 1 minute, 15 seconds.</col>", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
assertEquals(Duration.ofSeconds(60 + 15), infoBox.getDuration());
}
@Test
public void testDmmFullTb()
{
when(timersConfig.showTeleblock()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 2 minutes, 30 seconds.</col>", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
assertEquals(Duration.ofSeconds(60 * 2 + 30), infoBox.getDuration());
}
@Test
public void testDivineBastion()
{
when(timersConfig.showDivine()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "You drink some of your divine bastion potion.", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.DIVINE_BASTION, infoBox.getTimer());
}
@Test
public void testDivineBattlemage()
{
when(timersConfig.showDivine()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "You drink some of your divine battlemage potion.", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.DIVINE_BATTLEMAGE, infoBox.getTimer());
}
@Test
public void testTransparentChatboxTb()
{
when(timersConfig.showTeleblock()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=c356ef>A Tele Block spell has been cast on you by Alexsuperfly. It will expire in 5 minutes.</col>", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
assertEquals(Duration.ofMinutes(5), infoBox.getDuration());
}
@Test
public void testTransparentChatboxTbRemoved()
{
when(timersConfig.showTeleblock()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=c356ef>Your Tele Block has been removed because you killed Alexsuperfly.</col>", "", 0);
timersPlugin.onChatMessage(chatMessage);
verify(infoBoxManager, atLeastOnce()).removeIf(any());
}
@Test
public void testMageArena2TbFull()
{
when(timersConfig.showTeleblock()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=c356ef>A Tele Block spell has been cast on you. It will expire in 2 minutes.</col>", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
assertEquals(Duration.ofMinutes(2), infoBox.getDuration());
}
@Test
public void testMageArena2TbHalf()
{
when(timersConfig.showTeleblock()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=c356ef>A Tele Block spell has been cast on you. It will expire in 1 minute.</col>", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
assertEquals(Duration.ofMinutes(1), infoBox.getDuration());
}
@Test
public void testStamina()
{
when(timersConfig.showStamina()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "You drink some of your stamina potion.", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.STAMINA, infoBox.getTimer());
assertEquals(Duration.ofMinutes(2), infoBox.getDuration());
}
@Test
public void testSireStunTimer()
{
when(timersConfig.showAbyssalSireStun()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "The Sire has been disorientated temporarily.", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.ABYSSAL_SIRE_STUN, infoBox.getTimer());
assertEquals(Duration.ofSeconds(30), infoBox.getDuration());
}
@Test
public void testEndurance()
{
when(timersConfig.showStamina()).thenReturn(true);
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "Your Ring of endurance doubles the duration of your stamina potion's effect.", "", 0);
timersPlugin.onChatMessage(chatMessage);
chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "You drink some of your stamina potion.", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager).addInfoBox(captor.capture());
TimerTimer infoBox = (TimerTimer) captor.getValue();
assertEquals(GameTimer.STAMINA, infoBox.getTimer());
assertEquals(Duration.ofMinutes(4), infoBox.getDuration());
// unwield ring
timersPlugin.onItemContainerChanged(new ItemContainerChanged(InventoryID.EQUIPMENT.getId(), mock(ItemContainer.class)));
// some time has elapsed in the test; this should be just under 2 mins
int mins = (int) infoBox.getDuration().toMinutes();
assertTrue(mins == 1 || mins == 2);
}
@Test
public void testTzhaarTimer()
{
when(timersConfig.showTzhaarTimers()).thenReturn(true);
when(client.getMapRegions()).thenReturn(new int[]{TimersPlugin.FIGHT_CAVES_REGION_ID});
class InstantRef
{
Instant i;
}
InstantRef startTime = new InstantRef();
when(timersConfig.tzhaarStartTime()).then(a -> startTime.i);
doAnswer((Answer<Void>) invocationOnMock ->
{
Object argument = invocationOnMock.getArguments()[0];
startTime.i = (Instant) argument;
return null;
}).when(timersConfig).tzhaarStartTime(nullable(Instant.class));
InstantRef lastTime = new InstantRef();
when(timersConfig.tzhaarLastTime()).then(a -> lastTime.i);
doAnswer((Answer<Void>) invocationOnMock ->
{
Object argument = invocationOnMock.getArguments()[0];
lastTime.i = (Instant) argument;
return null;
}).when(timersConfig).tzhaarLastTime(nullable(Instant.class));
// test timer creation: verify the infobox was added and that it is an ElapsedTimer
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "<col=ef1020>Wave: 1</col>", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager, times(1)).addInfoBox(captor.capture());
assertTrue(captor.getValue() instanceof ElapsedTimer);
// test timer pause: verify the added ElapsedTimer has a non-null lastTime
chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "<col=ef1020>The Inferno has been paused. You may now log out.", "", 0);
timersPlugin.onChatMessage(chatMessage);
verify(infoBoxManager, times(1)).removeInfoBox(captor.capture());
verify(infoBoxManager, times(2)).addInfoBox(captor.capture());
assertTrue(captor.getValue() instanceof ElapsedTimer);
ElapsedTimer timer = (ElapsedTimer) captor.getValue();
assertNotEquals(timer.getLastTime(), null);
Instant oldTime = ((ElapsedTimer) captor.getValue()).getStartTime();
// test timer unpause: verify the last time is null after being unpaused
chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "<col=ef1020>Wave: 2</col>", "", 0);
timersPlugin.onChatMessage(chatMessage);
verify(infoBoxManager, times(2)).removeInfoBox(captor.capture());
verify(infoBoxManager, times(3)).addInfoBox(captor.capture());
assertTrue(captor.getValue() instanceof ElapsedTimer);
timer = (ElapsedTimer) captor.getValue();
assertNull(timer.getLastTime());
// test timer remove: verify the infobox was removed (and no more were added)
chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "You have been defeated!", "", 0);
timersPlugin.onChatMessage(chatMessage);
verify(infoBoxManager, times(3)).removeInfoBox(captor.capture());
verify(infoBoxManager, times(3)).addInfoBox(captor.capture());
}
@Test
public void testInfernoTimerStartOffset()
{
when(timersConfig.showTzhaarTimers()).thenReturn(true);
when(client.getMapRegions()).thenReturn(new int[]{TimersPlugin.INFERNO_REGION_ID});
class InstantRef
{
Instant i;
}
InstantRef startTime = new InstantRef();
when(timersConfig.tzhaarStartTime()).then(a -> startTime.i);
doAnswer((Answer<Void>) invocationOnMock ->
{
Object argument = invocationOnMock.getArguments()[0];
startTime.i = (Instant) argument;
return null;
}).when(timersConfig).tzhaarStartTime(nullable(Instant.class));
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "<col=ef1020>Wave: 1</col>", "", 0);
timersPlugin.onChatMessage(chatMessage);
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
verify(infoBoxManager, times(1)).addInfoBox(captor.capture());
assertTrue(captor.getValue() instanceof ElapsedTimer);
ElapsedTimer timer = (ElapsedTimer) captor.getValue();
assertEquals("00:06", timer.getText());
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.util;
import com.google.common.collect.ImmutableMap;
import java.awt.Color;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class ColorUtilTest
{
private static final Map<Color, String> COLOR_HEXSTRING_MAP = new ImmutableMap.Builder<Color, String>().
put(Color.BLACK, "000000").
put(new Color(0x1), "000001").
put(new Color(0x100000), "100000").
put(Color.RED, "ff0000").
put(Color.GREEN, "00ff00").
put(Color.BLUE, "0000ff").
put(new Color(0xA1B2C3), "a1b2c3").
put(Color.WHITE, "ffffff").build();
private static final Map<Color, String> COLOR_ALPHA_HEXSTRING_MAP = ImmutableMap.of(
new Color(0x00000000, true), "00000000",
new Color(0xA1B2C3D4, true), "a1b2c3d4"
);
@Test
public void colorTag()
{
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
{
assertEquals("<col=" + hex + ">", ColorUtil.colorTag(color));
});
}
@Test
public void prependColorTag()
{
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
{
assertEquals("<col=" + hex + ">test", ColorUtil.prependColorTag("test", color));
assertEquals("<col=" + hex + ">", ColorUtil.prependColorTag("", color));
});
assertEquals("<col=ff0000>94<col=ffffff>/99", ColorUtil.prependColorTag("94" + ColorUtil.prependColorTag("/99", Color.WHITE), Color.RED));
}
@Test
public void wrapWithColorTag()
{
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
{
assertEquals("<col=" + hex + ">test</col>", ColorUtil.wrapWithColorTag("test", color));
assertEquals("<col=" + hex + "></col>", ColorUtil.wrapWithColorTag("", color));
});
}
@Test
public void toHexColor()
{
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
{
assertEquals("#" + hex, ColorUtil.toHexColor(color));
});
}
@Test
public void colorWithAlpha()
{
int[] alpha = {73};
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
{
assertEquals(new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha[0]),
ColorUtil.colorWithAlpha(color, alpha[0]));
alpha[0] += 73;
alpha[0] %= 255;
});
COLOR_ALPHA_HEXSTRING_MAP.forEach((color, hex) ->
{
assertEquals(new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha[0]),
ColorUtil.colorWithAlpha(color, alpha[0]));
alpha[0] += 73;
alpha[0] %= 255;
});
}
@Test
public void colorLerp()
{
assertEquals(Color.WHITE, ColorUtil.colorLerp(Color.WHITE, Color.WHITE, 0.9));
assertEquals(new Color(128, 128, 128), ColorUtil.colorLerp(Color.BLACK, Color.WHITE, 0.5));
assertEquals(Color.BLACK, ColorUtil.colorLerp(Color.BLACK, Color.CYAN, 0));
assertEquals(Color.CYAN, ColorUtil.colorLerp(Color.BLACK, Color.CYAN, 1));
}
@Test
public void colorToHexCode()
{
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
{
assertEquals(hex, ColorUtil.colorToHexCode(color));
});
}
}