/*************************************************************************** * Copyright 2006-2016 by Christian Ihle * * contact@kouchat.net * * * * This file is part of KouChat. * * * * KouChat is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of * * the License, or (at your option) any later version. * * * * KouChat is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with KouChat. * * If not, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ package net.usikkert.kouchat.net; import static org.mockito.Mockito.*; import java.util.concurrent.ExecutorService; import net.usikkert.kouchat.junit.ExpectedException; import net.usikkert.kouchat.misc.Controller; import net.usikkert.kouchat.misc.User; import net.usikkert.kouchat.misc.WaitingList; import net.usikkert.kouchat.util.Sleeper; import net.usikkert.kouchat.util.TestUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; /** * Test of {@link AsyncMessageResponderWrapper}. * * @author Christian Ihle */ @SuppressWarnings("HardCodedStringLiteral") public class AsyncMessageResponderWrapperTest { @Rule public ExpectedException expectedException = ExpectedException.none(); private AsyncMessageResponderWrapper wrapper; private MessageResponder messageResponder; private Controller controller; private ExecutorService executorService; private Sleeper sleeper; private WaitingList waitingList; @Before public void setUp() { messageResponder = mock(MessageResponder.class); controller = mock(Controller.class); waitingList = mock(WaitingList.class); when(controller.getWaitingList()).thenReturn(waitingList); wrapper = spy(new AsyncMessageResponderWrapper(messageResponder, controller)); executorService = TestUtils.setFieldValueWithMock(wrapper, "executorService", ExecutorService.class); sleeper = TestUtils.setFieldValueWithMock(wrapper, "sleeper", Sleeper.class); } @Test public void constructorShouldThrowExceptionIfMessageResponderIsNull() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("MessageResponder can not be null"); new AsyncMessageResponderWrapper(null, controller); } @Test public void constructorShouldThrowExceptionIfControllerIsNull() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Controller can not be null"); new AsyncMessageResponderWrapper(messageResponder, null); } @Test public void messageArrivedShouldPassThroughAndNeverAskOrWaitIfExistingUser() { when(controller.isNewUser(100)).thenReturn(false); wrapper.messageArrived(100, "msg", 200); verify(messageResponder).messageArrived(100, "msg", 200); verifyZeroInteractions(executorService); verify(wrapper, never()).askUserToIdentify(anyInt()); verify(wrapper, never()).waitForUserToIdentify(anyInt()); } @Test public void messageArrivedShouldAskUserToIdentifyIfNewUser() { when(controller.isNewUser(100)).thenReturn(true); wrapper.messageArrived(100, "msg", 200); verify(wrapper).askUserToIdentify(100); } @Test public void messageArrivedShouldWaitForUserToIdentifyAndPassThroughUsingExecutorIfNewUser() { when(controller.isNewUser(100)).thenReturn(true); wrapper.messageArrived(100, "msg", 200); final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class); verifyZeroInteractions(messageResponder); verify(wrapper, never()).waitForUserToIdentify(anyInt()); verify(executorService).execute(runnableCaptor.capture()); runnableCaptor.getValue().run(); verify(wrapper).waitForUserToIdentify(100); verify(messageResponder).messageArrived(100, "msg", 200); } @Test public void topicChangedShouldPassThroughIfExistingUser() { when(controller.isNewUser(100)).thenReturn(false); wrapper.topicChanged(100, "newTopic", "nick", 300); verify(wrapper, never()).askUserToIdentify(anyInt()); verify(messageResponder).topicChanged(100, "newTopic", "nick", 300); } @Test public void topicChangedShouldAskUserToIdentifyIfNewUser() { when(controller.isNewUser(100)).thenReturn(true); wrapper.topicChanged(100, "newTopic", "nick", 300); verify(wrapper).askUserToIdentify(100); verify(messageResponder, never()).topicChanged(anyInt(), anyString(), anyString(), anyLong()); } @Test public void topicRequestedShouldPassThrough() { wrapper.topicRequested(); verify(messageResponder).topicRequested(); } @Test public void awayChangedShouldPassThroughIfExistingUser() { when(controller.isNewUser(100)).thenReturn(false); wrapper.awayChanged(100, true, "awayMsg"); verify(wrapper, never()).askUserToIdentify(anyInt()); verify(messageResponder).awayChanged(100, true, "awayMsg"); } @Test public void awayChangedShouldAskUserToIdentifyIfNewUser() { when(controller.isNewUser(100)).thenReturn(true); wrapper.awayChanged(100, true, "awayMsg"); verify(wrapper).askUserToIdentify(100); verify(messageResponder, never()).awayChanged(anyInt(), anyBoolean(), anyString()); } @Test public void nickChangedShouldPassThroughIfExistingUser() { when(controller.isNewUser(100)).thenReturn(false); wrapper.nickChanged(100, "newNick"); verify(wrapper, never()).askUserToIdentify(anyInt()); verify(messageResponder).nickChanged(100, "newNick"); } @Test public void nickChangedShouldAskUserToIdentifyIfNewUser() { when(controller.isNewUser(100)).thenReturn(true); wrapper.nickChanged(100, "newNick"); verify(wrapper).askUserToIdentify(100); verify(messageResponder, never()).nickChanged(anyInt(), anyString()); } @Test public void nickCrashShouldPassThrough() { wrapper.nickCrash(); verify(messageResponder).nickCrash(); } @Test public void meLogOnShouldPassThrough() { wrapper.meLogOn("ipAddress"); verify(messageResponder).meLogOn("ipAddress"); } @Test public void userLogOnShouldPassThrough() { final User user = new User("User", 123); wrapper.userLogOn(user); verify(messageResponder).userLogOn(user); } @Test public void userLogOffShouldPassThrough() { wrapper.userLogOff(100); verify(messageResponder).userLogOff(100); } @Test public void userExposingShouldPassThrough() { final User user = new User("User", 123); wrapper.userExposing(user); verify(messageResponder).userExposing(user); } @Test public void exposeRequestedShouldPassThrough() { wrapper.exposeRequested(); verify(messageResponder).exposeRequested(); } @Test public void writingChangedShouldPassThrough() { wrapper.writingChanged(100, true); verify(messageResponder).writingChanged(100, true); } @Test public void meIdleShouldPassThrough() { wrapper.meIdle("ipAddress"); verify(messageResponder).meIdle("ipAddress"); } @Test public void userIdleShouldPassThroughIfExistingUser() { when(controller.isNewUser(100)).thenReturn(false); wrapper.userIdle(100, "ipAddress"); verify(wrapper, never()).askUserToIdentify(anyInt()); verify(messageResponder).userIdle(100, "ipAddress"); } @Test public void userIdleShouldAskUserToIdentifyIfNewUser() { when(controller.isNewUser(100)).thenReturn(true); wrapper.userIdle(100, "ipAddress"); verify(wrapper).askUserToIdentify(100); verify(messageResponder, never()).userIdle(anyInt(), anyString()); } @Test public void fileSendShouldAskUserToIdentifyIfNewUser() { when(controller.isNewUser(100)).thenReturn(true); wrapper.fileSend(100, 3000, "fileName", "user", 98765); verify(wrapper).askUserToIdentify(100); } @Test public void fileSendShouldNotAskUserToIdentifyIfExistingUser() { when(controller.isNewUser(100)).thenReturn(false); wrapper.fileSend(100, 3000, "fileName", "user", 98765); verify(wrapper, never()).askUserToIdentify(anyInt()); } @Test public void fileSendShouldWaitForUserToIdentifyAndPassThroughUsingExecutor() { wrapper.fileSend(100, 3000, "fileName", "user", 98765); final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class); verifyZeroInteractions(messageResponder); verify(wrapper, never()).waitForUserToIdentify(anyInt()); verify(executorService).execute(runnableCaptor.capture()); runnableCaptor.getValue().run(); verify(wrapper).waitForUserToIdentify(100); verify(messageResponder).fileSend(100, 3000, "fileName", "user", 98765); } @Test public void fileSendAbortedShouldPassThrough() { wrapper.fileSendAborted(100, "fileName", 98765); verify(messageResponder).fileSendAborted(100, "fileName", 98765); } @Test public void fileSendAcceptedShouldPassThroughUsingExecutor() { wrapper.fileSendAccepted(100, "fileName", 98765, 1050); final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class); verifyZeroInteractions(messageResponder); verify(executorService).execute(runnableCaptor.capture()); runnableCaptor.getValue().run(); verify(messageResponder).fileSendAccepted(100, "fileName", 98765, 1050); } @Test public void clientInfoShouldPassThrough() { wrapper.clientInfo(100, "client", 70000, "os", 4500); verify(messageResponder).clientInfo(100, "client", 70000, "os", 4500); } @Test public void askUserToIdentifyShouldAddWaitingUserAndExposeAndGetTopic() { wrapper.askUserToIdentify(100); verify(waitingList).addWaitingUser(100); verify(controller).sendExposeMessage(); verify(controller).sendGetTopicMessage(); } @Test public void waitForUserToIdentifyShouldAbortAfter40SleepsIfUserNeverIdentifies() { when(waitingList.isWaitingUser(100)).thenReturn(true); wrapper.waitForUserToIdentify(100); verify(sleeper, times(40)).sleep(50); verify(waitingList, times(41)).isWaitingUser(100); } @Test public void waitForUserToIdentifyShouldAbortWhenUserHasIdentified() { when(waitingList.isWaitingUser(100)).thenReturn(true, true, true, false); wrapper.waitForUserToIdentify(100); verify(sleeper, times(3)).sleep(50); verify(waitingList, times(4)).isWaitingUser(100); } @Test public void waitForUserToIdentifyShouldNeverSleepIfUserIsIdentified() { when(waitingList.isWaitingUser(100)).thenReturn(false); wrapper.waitForUserToIdentify(100); verifyZeroInteractions(sleeper); verify(waitingList).isWaitingUser(100); } }