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:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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>");
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user