Merge remote-tracking branch 'upstream/master' into runelite
# Conflicts: # cache-client/pom.xml # cache-updater/pom.xml # cache/pom.xml # http-api/pom.xml # http-service/pom.xml # pom.xml # runelite-api/pom.xml # runelite-api/src/main/java/net/runelite/api/Client.java # runelite-api/src/main/java/net/runelite/api/FarmingTrackerTest.java # runelite-client/pom.xml # runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java # runelite-client/src/test/java/net/runelite/client/chat/ChatMessageManagerTest.java # runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/ClueScrollPluginTest.java # runelite-client/src/test/java/net/runelite/client/plugins/emojis/EmojiPluginTest.java # runelite-client/src/test/java/net/runelite/client/plugins/grounditems/GroundItemsPluginTest.java # runelite-client/src/test/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPluginTest.java # runelite-script-assembler-plugin/pom.xml
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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.chat;
|
||||
|
||||
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.awt.Color;
|
||||
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.config.ChatColorConfig;
|
||||
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 ChatMessageManagerTest
|
||||
{
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ChatColorConfig chatColorConfig;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
|
||||
chatMessageManager.loadColors();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageRecoloring()
|
||||
{
|
||||
when(chatColorConfig.opaqueServerMessage()).thenReturn(Color.decode("#b20000"));
|
||||
|
||||
chatMessageManager.loadColors();
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.GAMEMESSAGE);
|
||||
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
|
||||
when(messageNode.getValue()).thenReturn("Your dodgy necklace protects you. It has <col=ff0000>1</col> charge left.");
|
||||
chatMessageManager.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("<col=b20000>Your dodgy necklace protects you. It has <col=ff0000>1<col=b20000> charge left.</col>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicFriendUsernameRecolouring()
|
||||
{
|
||||
final String localPlayerName = "RuneLite";
|
||||
final String friendName = "Zezima";
|
||||
|
||||
when(chatColorConfig.opaquePublicFriendUsernames()).thenReturn(Color.decode("#b20000"));
|
||||
|
||||
chatMessageManager.loadColors();
|
||||
|
||||
// Setup message
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setName(friendName);
|
||||
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
when(messageNode.getName()).thenReturn(friendName);
|
||||
|
||||
// Setup friend checking
|
||||
Player localPlayer = mock(Player.class);
|
||||
|
||||
when(client.isFriended(friendName, true)).thenReturn(true);
|
||||
when(client.getLocalPlayer()).thenReturn(localPlayer);
|
||||
when(localPlayer.getName()).thenReturn(localPlayerName);
|
||||
|
||||
chatMessageManager.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setName("<col=b20000>" + friendName + "</col>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicIronmanFriendUsernameRecolouring()
|
||||
{
|
||||
final String localPlayerName = "RuneLite";
|
||||
final String friendName = "<img=3>BuddhaPuck";
|
||||
final String sanitizedFriendName = "BuddhaPuck";
|
||||
|
||||
when(chatColorConfig.opaquePublicFriendUsernames()).thenReturn(Color.decode("#b20000"));
|
||||
|
||||
chatMessageManager.loadColors();
|
||||
|
||||
// Setup message
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setName(friendName);
|
||||
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
when(messageNode.getName()).thenReturn(friendName);
|
||||
|
||||
// Setup friend checking
|
||||
Player localPlayer = mock(Player.class);
|
||||
|
||||
when(client.isFriended(sanitizedFriendName, true)).thenReturn(true);
|
||||
when(client.getLocalPlayer()).thenReturn(localPlayer);
|
||||
when(localPlayer.getName()).thenReturn(localPlayerName);
|
||||
|
||||
chatMessageManager.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setName("<col=b20000>" + friendName + "</col>");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Hydrox6 <ikada@protonmail.ch>
|
||||
* 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.cluescrolls;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.banktags.TagManager;
|
||||
import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdLocation;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
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.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 ClueScrollPluginTest
|
||||
{
|
||||
@Mock
|
||||
@Bind
|
||||
Client client;
|
||||
|
||||
@Inject
|
||||
ClueScrollPlugin plugin;
|
||||
|
||||
@Bind
|
||||
@Named("developerMode")
|
||||
boolean developerMode;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ClueScrollConfig config;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
OverlayManager overlayManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ItemManager itemManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
TagManager tagManager;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getGetMirrorPoint()
|
||||
{
|
||||
WorldPoint point, converted;
|
||||
|
||||
// Zalcano's entrance portal
|
||||
point = new WorldPoint(3282, 6058, 0);
|
||||
converted = ClueScrollPlugin.getMirrorPoint(point, true);
|
||||
assertNotEquals(point, converted);
|
||||
|
||||
// Elven Crystal Chest, which is upstairs
|
||||
point = new WorldPoint(3273, 6082, 2);
|
||||
converted = ClueScrollPlugin.getMirrorPoint(point, true);
|
||||
assertNotEquals(point, converted);
|
||||
|
||||
// Around the area of the Elite coordinate clue
|
||||
point = new WorldPoint(2185, 3280, 0);
|
||||
// To overworld
|
||||
converted = ClueScrollPlugin.getMirrorPoint(point, true);
|
||||
assertEquals(point, converted);
|
||||
// To real
|
||||
converted = ClueScrollPlugin.getMirrorPoint(point, false);
|
||||
assertNotEquals(point, converted);
|
||||
|
||||
// Brugsen Bursen, Grand Exchange
|
||||
point = new WorldPoint(3165, 3477, 0);
|
||||
converted = ClueScrollPlugin.getMirrorPoint(point, false);
|
||||
assertEquals(point, converted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocationHintArrowCleared()
|
||||
{
|
||||
final Widget clueWidget = mock(Widget.class);
|
||||
when(clueWidget.getText()).thenReturn("Buried beneath the ground, who knows where it's found. Lucky for you, A man called Reldo may have a clue.");
|
||||
final ChatMessage hotColdMessage = new ChatMessage();
|
||||
hotColdMessage.setType(ChatMessageType.GAMEMESSAGE);
|
||||
final Player localPlayer = mock(Player.class);
|
||||
|
||||
when(client.getWidget(WidgetInfo.CLUE_SCROLL_TEXT)).thenReturn(clueWidget);
|
||||
when(client.getLocalPlayer()).thenReturn(localPlayer);
|
||||
when(client.getPlane()).thenReturn(0);
|
||||
when(client.getCachedNPCs()).thenReturn(new NPC[] {});
|
||||
when(config.displayHintArrows()).thenReturn(true);
|
||||
|
||||
// The hint arrow should be reset each game tick from when the clue is read onward
|
||||
// This is to verify the arrow is cleared the correct number of times during the clue updating process.
|
||||
int clueSetupHintArrowClears = 0;
|
||||
|
||||
// Initialize a beginner hot-cold clue (which will have an end point of LUMBRIDGE_COW_FIELD)
|
||||
plugin.onGameTick(new GameTick());
|
||||
verify(client, times(++clueSetupHintArrowClears)).clearHintArrow();
|
||||
|
||||
// Perform the first hot-cold check in Lumbridge near sheep pen (get 2 possible points: LUMBRIDGE_COW_FIELD and DRAYNOR_WHEAT_FIELD)
|
||||
when(localPlayer.getWorldLocation()).thenReturn(new WorldPoint(3208, 3254, 0));
|
||||
hotColdMessage.setMessage("The device is hot.");
|
||||
plugin.onChatMessage(hotColdMessage);
|
||||
|
||||
// Move to SW of DRAYNOR_WHEAT_FIELD (hint arrow should be visible here)
|
||||
when(localPlayer.getWorldLocation()).thenReturn(new WorldPoint(3105, 3265, 0));
|
||||
when(client.getBaseX()).thenReturn(3056);
|
||||
when(client.getBaseY()).thenReturn(3216);
|
||||
plugin.onGameTick(new GameTick());
|
||||
verify(client, times(++clueSetupHintArrowClears)).clearHintArrow();
|
||||
verify(client).setHintArrow(HotColdLocation.DRAYNOR_WHEAT_FIELD.getWorldPoint());
|
||||
|
||||
// Test in that location (get 1 possible location: LUMBRIDGE_COW_FIELD)
|
||||
hotColdMessage.setMessage("The device is hot, and warmer than last time.");
|
||||
plugin.onChatMessage(hotColdMessage);
|
||||
plugin.onGameTick(new GameTick());
|
||||
|
||||
// Hint arrow should be cleared and not re-set now as the only remaining location is outside of the current
|
||||
// scene
|
||||
verify(client, times(++clueSetupHintArrowClears)).clearHintArrow();
|
||||
verify(client, times(1)).setHintArrow(any(WorldPoint.class));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.emojis;
|
||||
|
||||
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.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.IndexedSprite;
|
||||
import net.runelite.api.MessageNode;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
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;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class EmojiPluginTest
|
||||
{
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
@Inject
|
||||
private EmojiPlugin emojiPlugin;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnChatMessage()
|
||||
{
|
||||
when(client.getGameState()).thenReturn(GameState.LOGGED_IN);
|
||||
when(client.getModIcons()).thenReturn(new IndexedSprite[0]);
|
||||
when(client.createIndexedSprite()).thenReturn(mock(IndexedSprite.class));
|
||||
|
||||
// Trip emoji loading
|
||||
GameStateChanged gameStateChanged = new GameStateChanged();
|
||||
gameStateChanged.setGameState(GameState.LOGGED_IN);
|
||||
emojiPlugin.onGameStateChanged(gameStateChanged);
|
||||
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
// With chat recolor, message may be wrapped in col tags
|
||||
when(messageNode.getValue()).thenReturn("<col=ff0000>:) :) :)</col>");
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
|
||||
emojiPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("<col=ff0000><img=0> <img=0> <img=0></col>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGtLt()
|
||||
{
|
||||
when(client.getGameState()).thenReturn(GameState.LOGGED_IN);
|
||||
when(client.getModIcons()).thenReturn(new IndexedSprite[0]);
|
||||
when(client.createIndexedSprite()).thenReturn(mock(IndexedSprite.class));
|
||||
|
||||
// Trip emoji loading
|
||||
GameStateChanged gameStateChanged = new GameStateChanged();
|
||||
gameStateChanged.setGameState(GameState.LOGGED_IN);
|
||||
emojiPlugin.onGameStateChanged(gameStateChanged);
|
||||
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
when(messageNode.getValue()).thenReturn("<gt>:D<lt>");
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
|
||||
emojiPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("<img=10>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmojiUpdateMessage()
|
||||
{
|
||||
String PARTY_POPPER = "<img=" + (-1 + Emoji.getEmoji("@@@").ordinal()) + '>';
|
||||
String OPEN_MOUTH = "<img=" + (-1 + Emoji.getEmoji(":O").ordinal()) + '>';
|
||||
assertNull(emojiPlugin.updateMessage("@@@@@"));
|
||||
assertEquals(PARTY_POPPER, emojiPlugin.updateMessage("@@@"));
|
||||
assertEquals(PARTY_POPPER + ' ' + PARTY_POPPER, emojiPlugin.updateMessage("@@@ @@@"));
|
||||
assertEquals(PARTY_POPPER + ' ' + OPEN_MOUTH, emojiPlugin.updateMessage("@@@\u00A0:O"));
|
||||
assertEquals(PARTY_POPPER + ' ' + OPEN_MOUTH + ' ' + PARTY_POPPER, emojiPlugin.updateMessage("@@@\u00A0:O @@@"));
|
||||
assertEquals(PARTY_POPPER + " Hello World " + PARTY_POPPER, emojiPlugin.updateMessage("@@@\u00A0Hello World\u00A0@@@"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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.grounditems;
|
||||
|
||||
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 javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.ItemLayer;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Tile;
|
||||
import net.runelite.api.TileItem;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.ItemSpawned;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.input.MouseManager;
|
||||
import net.runelite.client.plugins.grounditems.config.HighlightTier;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
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.doAnswer;
|
||||
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 GroundItemsPluginTest
|
||||
{
|
||||
@Inject
|
||||
private GroundItemsPlugin groundItemsPlugin;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private MouseManager mouseManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private KeyManager keyManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private GroundItemsConfig config;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private GroundItemsOverlay overlay;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Notifier notifier;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ScheduledExecutorService executor;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
|
||||
doAnswer(a ->
|
||||
{
|
||||
a.<Runnable>getArgument(0).run();
|
||||
return null;
|
||||
}).when(executor).execute(any(Runnable.class));
|
||||
|
||||
when(client.getLocalPlayer()).thenReturn(mock(Player.class));
|
||||
when(config.getHiddenItems()).thenReturn("");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyHighlightedItem()
|
||||
{
|
||||
when(config.getHighlightItems()).thenReturn("abyssal whip");
|
||||
when(config.notifyTier()).thenReturn(HighlightTier.OFF);
|
||||
when(config.notifyHighlightedDrops()).thenReturn(true);
|
||||
|
||||
when(itemManager.getItemComposition(ItemID.ABYSSAL_WHIP)).thenAnswer(a ->
|
||||
{
|
||||
ItemComposition itemComposition = mock(ItemComposition.class);
|
||||
when(itemComposition.getName()).thenReturn("Abyssal whip");
|
||||
return itemComposition;
|
||||
});
|
||||
|
||||
// trigger reload of highlighted items list
|
||||
ConfigChanged configChanged = new ConfigChanged();
|
||||
configChanged.setGroup("grounditems");
|
||||
groundItemsPlugin.onConfigChanged(configChanged);
|
||||
|
||||
// spawn whip
|
||||
Tile tile = mock(Tile.class);
|
||||
when(tile.getItemLayer()).thenReturn(mock(ItemLayer.class));
|
||||
when(tile.getWorldLocation()).thenReturn(new WorldPoint(0, 0, 0));
|
||||
|
||||
TileItem tileItem = mock(TileItem.class);
|
||||
when(tileItem.getId()).thenReturn(ItemID.ABYSSAL_WHIP);
|
||||
when(tileItem.getQuantity()).thenReturn(1);
|
||||
|
||||
groundItemsPlugin.onItemSpawned(new ItemSpawned(tile, tileItem));
|
||||
|
||||
verify(notifier).notify("You received a highlighted drop: Abyssal whip");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@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.plugins.idlenotifier;
|
||||
|
||||
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.AnimationID;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.Hitsplat;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NPCComposition;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.VarPlayer;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.HitsplatApplied;
|
||||
import net.runelite.api.events.InteractingChanged;
|
||||
import net.runelite.client.Notifier;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
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.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class IdleNotifierPluginTest
|
||||
{
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private IdleNotifierConfig config;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Notifier notifier;
|
||||
|
||||
@Inject
|
||||
private IdleNotifierPlugin plugin;
|
||||
|
||||
@Mock
|
||||
private NPC monster;
|
||||
|
||||
@Mock
|
||||
private NPC randomEvent;
|
||||
|
||||
@Mock
|
||||
private NPC fishingSpot;
|
||||
|
||||
@Mock
|
||||
private Player player;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
|
||||
// Mock monster
|
||||
final String[] monsterActions = new String[] { "Attack", "Examine" };
|
||||
final NPCComposition monsterComp = mock(NPCComposition.class);
|
||||
when(monsterComp.getActions()).thenReturn(monsterActions);
|
||||
when(monster.getComposition()).thenReturn(monsterComp);
|
||||
|
||||
// Mock random event
|
||||
final String[] randomEventActions = new String[] { "Talk-to", "Dismiss", "Examine" };
|
||||
final NPCComposition randomEventComp = mock(NPCComposition.class);
|
||||
when(randomEventComp.getActions()).thenReturn(randomEventActions);
|
||||
when(randomEvent.getComposition()).thenReturn(randomEventComp);
|
||||
|
||||
// Mock Fishing Spot
|
||||
final String[] fishingSpotActions = new String[] { "Use-rod", "Examine" };
|
||||
final NPCComposition fishingSpotComp = mock(NPCComposition.class);
|
||||
when(fishingSpotComp.getActions()).thenReturn(fishingSpotActions);
|
||||
when(fishingSpot.getComposition()).thenReturn(fishingSpotComp);
|
||||
when(fishingSpot.getName()).thenReturn("Fishing spot");
|
||||
|
||||
// Mock player
|
||||
when(player.getAnimation()).thenReturn(AnimationID.IDLE);
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
|
||||
// Mock config
|
||||
when(config.logoutIdle()).thenReturn(true);
|
||||
when(config.animationIdle()).thenReturn(true);
|
||||
when(config.interactionIdle()).thenReturn(true);
|
||||
when(config.getIdleNotificationDelay()).thenReturn(0);
|
||||
when(config.getHitpointsThreshold()).thenReturn(42);
|
||||
when(config.getPrayerThreshold()).thenReturn(42);
|
||||
|
||||
// Mock client
|
||||
when(client.getGameState()).thenReturn(GameState.LOGGED_IN);
|
||||
when(client.getKeyboardIdleTicks()).thenReturn(42);
|
||||
when(client.getMouseLastPressedMillis()).thenReturn(System.currentTimeMillis() - 100_000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkAnimationIdle()
|
||||
{
|
||||
when(player.getAnimation()).thenReturn(AnimationID.WOODCUTTING_BRONZE);
|
||||
AnimationChanged animationChanged = new AnimationChanged();
|
||||
animationChanged.setActor(player);
|
||||
plugin.onAnimationChanged(animationChanged);
|
||||
plugin.onGameTick(new GameTick());
|
||||
when(player.getAnimation()).thenReturn(AnimationID.IDLE);
|
||||
plugin.onAnimationChanged(animationChanged);
|
||||
plugin.onGameTick(new GameTick());
|
||||
verify(notifier).notify("You are now idle!");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkAnimationReset()
|
||||
{
|
||||
when(player.getAnimation()).thenReturn(AnimationID.WOODCUTTING_BRONZE);
|
||||
AnimationChanged animationChanged = new AnimationChanged();
|
||||
animationChanged.setActor(player);
|
||||
plugin.onAnimationChanged(animationChanged);
|
||||
plugin.onGameTick(new GameTick());
|
||||
when(player.getAnimation()).thenReturn(AnimationID.LOOKING_INTO);
|
||||
plugin.onAnimationChanged(animationChanged);
|
||||
plugin.onGameTick(new GameTick());
|
||||
when(player.getAnimation()).thenReturn(AnimationID.IDLE);
|
||||
plugin.onAnimationChanged(animationChanged);
|
||||
plugin.onGameTick(new GameTick());
|
||||
verify(notifier, times(0)).notify(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkAnimationLogout()
|
||||
{
|
||||
when(player.getAnimation()).thenReturn(AnimationID.WOODCUTTING_BRONZE);
|
||||
AnimationChanged animationChanged = new AnimationChanged();
|
||||
animationChanged.setActor(player);
|
||||
plugin.onAnimationChanged(animationChanged);
|
||||
plugin.onGameTick(new GameTick());
|
||||
|
||||
// Logout
|
||||
when(client.getGameState()).thenReturn(GameState.LOGIN_SCREEN);
|
||||
GameStateChanged gameStateChanged = new GameStateChanged();
|
||||
gameStateChanged.setGameState(GameState.LOGIN_SCREEN);
|
||||
plugin.onGameStateChanged(gameStateChanged);
|
||||
|
||||
// Log back in
|
||||
when(client.getGameState()).thenReturn(GameState.LOGGED_IN);
|
||||
gameStateChanged.setGameState(GameState.LOGGED_IN);
|
||||
plugin.onGameStateChanged(gameStateChanged);
|
||||
|
||||
// Tick
|
||||
when(player.getAnimation()).thenReturn(AnimationID.IDLE);
|
||||
plugin.onAnimationChanged(animationChanged);
|
||||
plugin.onGameTick(new GameTick());
|
||||
verify(notifier, times(0)).notify(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkCombatIdle()
|
||||
{
|
||||
when(player.getInteracting()).thenReturn(monster);
|
||||
plugin.onInteractingChanged(new InteractingChanged(player, monster));
|
||||
plugin.onGameTick(new GameTick());
|
||||
when(player.getInteracting()).thenReturn(null);
|
||||
plugin.onInteractingChanged(new InteractingChanged(player, null));
|
||||
plugin.onGameTick(new GameTick());
|
||||
verify(notifier).notify("You are now out of combat!");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkCombatReset()
|
||||
{
|
||||
when(player.getInteracting()).thenReturn(mock(Actor.class));
|
||||
plugin.onInteractingChanged(new InteractingChanged(player, monster));
|
||||
plugin.onGameTick(new GameTick());
|
||||
plugin.onInteractingChanged(new InteractingChanged(player, randomEvent));
|
||||
plugin.onGameTick(new GameTick());
|
||||
plugin.onInteractingChanged(new InteractingChanged(player, null));
|
||||
plugin.onGameTick(new GameTick());
|
||||
verify(notifier, times(0)).notify(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkCombatLogout()
|
||||
{
|
||||
plugin.onInteractingChanged(new InteractingChanged(player, monster));
|
||||
when(player.getInteracting()).thenReturn(mock(Actor.class));
|
||||
plugin.onGameTick(new GameTick());
|
||||
|
||||
// Logout
|
||||
when(client.getGameState()).thenReturn(GameState.LOGIN_SCREEN);
|
||||
GameStateChanged gameStateChanged = new GameStateChanged();
|
||||
gameStateChanged.setGameState(GameState.LOGIN_SCREEN);
|
||||
plugin.onGameStateChanged(gameStateChanged);
|
||||
|
||||
// Log back in
|
||||
when(client.getGameState()).thenReturn(GameState.LOGGED_IN);
|
||||
gameStateChanged.setGameState(GameState.LOGGED_IN);
|
||||
plugin.onGameStateChanged(gameStateChanged);
|
||||
|
||||
// Tick
|
||||
plugin.onInteractingChanged(new InteractingChanged(player, null));
|
||||
plugin.onGameTick(new GameTick());
|
||||
verify(notifier, times(0)).notify(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkCombatLogoutIdle()
|
||||
{
|
||||
// Player is idle
|
||||
when(client.getMouseIdleTicks()).thenReturn(80_000);
|
||||
|
||||
// But player is being damaged (is in combat)
|
||||
final HitsplatApplied hitsplatApplied = new HitsplatApplied();
|
||||
hitsplatApplied.setActor(player);
|
||||
hitsplatApplied.setHitsplat(new Hitsplat(Hitsplat.HitsplatType.DAMAGE_ME, 0, 0));
|
||||
plugin.onHitsplatApplied(hitsplatApplied);
|
||||
plugin.onGameTick(new GameTick());
|
||||
verify(notifier, times(0)).notify(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doubleNotifyOnMouseReset()
|
||||
{
|
||||
// Player is idle, but in combat so the idle packet is getting set repeatedly
|
||||
// make sure we are not notifying
|
||||
|
||||
when(client.getKeyboardIdleTicks()).thenReturn(80_000);
|
||||
when(client.getMouseIdleTicks()).thenReturn(14_500);
|
||||
|
||||
plugin.onGameTick(new GameTick());
|
||||
plugin.onGameTick(new GameTick());
|
||||
verify(notifier, times(1)).notify(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendOneNotificationForAnimationAndInteract()
|
||||
{
|
||||
when(player.getInteracting()).thenReturn(fishingSpot);
|
||||
when(player.getAnimation()).thenReturn(AnimationID.FISHING_POLE_CAST);
|
||||
|
||||
AnimationChanged animationChanged = new AnimationChanged();
|
||||
animationChanged.setActor(player);
|
||||
|
||||
plugin.onInteractingChanged(new InteractingChanged(player, fishingSpot));
|
||||
plugin.onAnimationChanged(animationChanged);
|
||||
plugin.onGameTick(new GameTick());
|
||||
|
||||
verify(notifier, never()).notify(anyString());
|
||||
|
||||
when(player.getAnimation()).thenReturn(AnimationID.IDLE);
|
||||
lenient().when(player.getInteracting()).thenReturn(null);
|
||||
|
||||
plugin.onAnimationChanged(animationChanged);
|
||||
plugin.onInteractingChanged(new InteractingChanged(player, null));
|
||||
plugin.onGameTick(new GameTick());
|
||||
|
||||
verify(notifier).notify("You are now idle!");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecRegen()
|
||||
{
|
||||
when(config.getSpecEnergyThreshold()).thenReturn(50);
|
||||
|
||||
when(client.getVar(eq(VarPlayer.SPECIAL_ATTACK_PERCENT))).thenReturn(400); // 40%
|
||||
plugin.onGameTick(new GameTick()); // once to set lastSpecEnergy to 400
|
||||
verify(notifier, never()).notify(any());
|
||||
|
||||
when(client.getVar(eq(VarPlayer.SPECIAL_ATTACK_PERCENT))).thenReturn(500); // 50%
|
||||
plugin.onGameTick(new GameTick());
|
||||
verify(notifier).notify(eq("You have restored spec energy!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMovementIdle()
|
||||
{
|
||||
when(config.movementIdle()).thenReturn(true);
|
||||
|
||||
when(player.getWorldLocation()).thenReturn(new WorldPoint(0, 0, 0));
|
||||
plugin.onGameTick(new GameTick());
|
||||
when(player.getWorldLocation()).thenReturn(new WorldPoint(1, 0, 0));
|
||||
plugin.onGameTick(new GameTick());
|
||||
// No movement here
|
||||
plugin.onGameTick(new GameTick());
|
||||
|
||||
verify(notifier).notify(eq("You have stopped moving!"));
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,7 @@ 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.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@@ -67,7 +68,8 @@ public class ScreenshotPluginTest
|
||||
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 NOT_SO_VALUABLE_DROP = "<col=ef1020>Valuable drop: 6 x Bronze arrow (42 coins)</col>";
|
||||
private static final String VALUABLE_DROP = "<col=ef1020>Valuable drop: Rune scimitar (25,600 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.";
|
||||
@@ -121,6 +123,7 @@ public class ScreenshotPluginTest
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
when(screenshotConfig.screenshotLevels()).thenReturn(true);
|
||||
when(screenshotConfig.screenshotValuableDrop()).thenReturn(true);
|
||||
when(screenshotConfig.valuableDropThreshold()).thenReturn(1000);
|
||||
when(screenshotConfig.screenshotUntradeableDrop()).thenReturn(true);
|
||||
}
|
||||
|
||||
@@ -161,10 +164,30 @@ public class ScreenshotPluginTest
|
||||
assertEquals(73, screenshotPlugin.gettheatreOfBloodNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotSoValuableDrop()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", NOT_SO_VALUABLE_DROP, null, 0);
|
||||
screenshotPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verifyNoInteractions(drawManager);
|
||||
|
||||
when(screenshotConfig.valuableDropThreshold()).thenReturn(0);
|
||||
screenshotPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(drawManager).requestNextFrameListener(any(Consumer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValuableDrop()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", VALUABLE_DROP, null, 0);
|
||||
when(screenshotConfig.valuableDropThreshold()).thenReturn(100_000);
|
||||
screenshotPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verifyNoInteractions(drawManager);
|
||||
|
||||
when(screenshotConfig.valuableDropThreshold()).thenReturn(1000);
|
||||
screenshotPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(drawManager).requestNextFrameListener(any(Consumer.class));
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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.timetracking.farming;
|
||||
|
||||
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.util.EnumSet;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Varbits;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.config.RuneScapeProfile;
|
||||
import net.runelite.client.config.RuneScapeProfileType;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.timetracking.TimeTrackingConfig;
|
||||
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 FarmingTrackerTest
|
||||
{
|
||||
@Inject
|
||||
private FarmingTracker farmingTracker;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ConfigManager configManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private TimeTrackingConfig config;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private FarmingWorld farmingWorld;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Notifier notifier;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
|
||||
when(client.getGameState()).thenReturn(GameState.LOGGED_IN);
|
||||
when(client.getWorldType()).thenReturn(EnumSet.noneOf(WorldType.class));
|
||||
|
||||
Player player = mock(Player.class);
|
||||
when(player.getName()).thenReturn("Adam");
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testEmptyNotification()
|
||||
{
|
||||
RuneScapeProfile runeScapeProfile = new RuneScapeProfile("Adam", RuneScapeProfileType.STANDARD, null, null);
|
||||
|
||||
PatchPrediction patchPrediction = new PatchPrediction(Produce.EMPTY_COMPOST_BIN, CropState.EMPTY, 0L, 0, 0);
|
||||
FarmingRegion region = new FarmingRegion("Ardougne", 10548, false,
|
||||
new FarmingPatch("North", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
new FarmingPatch("", Varbits.FARMING_4774, PatchImplementation.HERB),
|
||||
new FarmingPatch("", Varbits.FARMING_4775, PatchImplementation.COMPOST)
|
||||
);
|
||||
FarmingPatch patch = region.getPatches()[4];
|
||||
patch.setRegion(region);
|
||||
farmingTracker.sendNotification(runeScapeProfile, patchPrediction, patch);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHarvestableNotification()
|
||||
{
|
||||
RuneScapeProfile runeScapeProfile = new RuneScapeProfile("Adam", RuneScapeProfileType.STANDARD, null, null);
|
||||
|
||||
PatchPrediction patchPrediction = new PatchPrediction(Produce.RANARR, CropState.HARVESTABLE, 0L, 0, 0);
|
||||
FarmingRegion region = new FarmingRegion("Ardougne", 10548, false,
|
||||
new FarmingPatch("North", Varbits.FARMING_4771, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("South", Varbits.FARMING_4772, PatchImplementation.ALLOTMENT),
|
||||
new FarmingPatch("", Varbits.FARMING_4773, PatchImplementation.FLOWER),
|
||||
new FarmingPatch("", Varbits.FARMING_4774, PatchImplementation.HERB),
|
||||
new FarmingPatch("", Varbits.FARMING_4775, PatchImplementation.COMPOST)
|
||||
);
|
||||
FarmingPatch patch = region.getPatches()[3];
|
||||
patch.setRegion(region);
|
||||
farmingTracker.sendNotification(runeScapeProfile, patchPrediction, patch);
|
||||
|
||||
verify(notifier).notify("Your Ranarr is ready to harvest in Ardougne.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user