package rmblworx.tools.timey.gui; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.isA; import static org.mockito.Matchers.isNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import java.awt.TrayIcon; import java.util.ResourceBundle; import javafx.application.Platform; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.input.KeyCode; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.loadui.testfx.categories.TestFX; import org.loadui.testfx.utils.FXTestUtils; import rmblworx.tools.timey.ITimey; import rmblworx.tools.timey.event.CountdownExpiredEvent; import rmblworx.tools.timey.event.TimeyEvent; import rmblworx.tools.timey.gui.component.TimePicker; /* * Copyright 2014-2015 Christian Raue * MIT License http://opensource.org/licenses/mit-license.php */ /** * GUI-Tests für den Countdown. * @author Christian Raue {@literal <christian.raue@gmail.com>} */ @Category(TestFX.class) public class CountdownControllerTest extends FxmlGuiControllerTest { /** * Container für Elemente. */ private Scene scene; // GUI-Elemente private Label countdownTimeLabel; private Button countdownStartButton; private Button countdownStopButton; private TimePicker countdownTimePicker; /** * {@inheritDoc} */ @Override protected final String getFxmlFilename() { return "Countdown.fxml"; } @Before public final void setUp() { scene = stage.getScene(); countdownTimeLabel = (Label) scene.lookup("#countdownTimeLabel"); countdownStartButton = (Button) scene.lookup("#countdownStartButton"); countdownStopButton = (Button) scene.lookup("#countdownStopButton"); countdownTimePicker = (TimePicker) scene.lookup("#countdownTimePicker"); } @Test public final void testInitializedFields() throws IllegalAccessException { super.testFxmlInitializedFields(); } /** * Testet den Zustand der Schaltflächen je nach Zustand des Countdowns. */ @Test public final void testStartStopButtonStates() { final ITimey facade = getController().getGuiHelper().getFacade(); // Zustand der Schaltflächen testen assertTrue(countdownStartButton.isVisible()); assertTrue(countdownStartButton.isDisabled()); assertFalse(countdownStopButton.isVisible()); assertFalse(countdownStopButton.isDisabled()); // Zeit setzen Platform.runLater(new Runnable() { public void run() { countdownTimePicker.setValue(DateTimeUtil.getLocalTimeForString("00:00:10")); } }); FXTestUtils.awaitEvents(); // Zustand der Schaltflächen testen assertTrue(countdownStartButton.isVisible()); assertFalse(countdownStartButton.isDisabled()); // Countdown starten click(countdownStartButton); verify(facade, timeout(WAIT_FOR_EVENT)).startCountdown(); // Zustand der Schaltflächen testen assertFalse(countdownStartButton.isVisible()); assertFalse(countdownStartButton.isDisabled()); assertTrue(countdownStopButton.isVisible()); assertFalse(countdownStopButton.isDisabled()); assertTrue(countdownStopButton.isFocused()); // Countdown stoppen click(countdownStopButton); verify(facade, timeout(WAIT_FOR_EVENT)).stopCountdown(); // Zustand der Schaltflächen testen assertTrue(countdownStartButton.isVisible()); assertFalse(countdownStartButton.isDisabled()); assertTrue(countdownStartButton.isFocused()); assertFalse(countdownStopButton.isVisible()); assertFalse(countdownStopButton.isDisabled()); // Zeit wieder auf 0 setzen Platform.runLater(new Runnable() { public void run() { countdownTimePicker.setValue(DateTimeUtil.getLocalTimeForString("00:00:00")); } }); FXTestUtils.awaitEvents(); // Zustand der Schaltflächen testen assertTrue(countdownStartButton.isVisible()); assertTrue(countdownStartButton.isDisabled()); } /** * Testet die Übertragung der Zeit zwischen TimePicker und Label. */ @Test public final void testTimeConversionBetweenPickerAndLabel() { // Zeit setzen Platform.runLater(new Runnable() { public void run() { countdownTimePicker.setValue(DateTimeUtil.getLocalTimeForString("00:00:10")); } }); FXTestUtils.awaitEvents(); // Countdown starten click(countdownStartButton); // verbleibende Zeit muss angezeigt sein assertEquals("00:00:10", countdownTimeLabel.getText()); assertFalse(countdownTimePicker.isVisible()); assertTrue(countdownTimeLabel.isVisible()); // Countdown stoppen click(countdownStopButton); // verbleibende Zeit muss stimmen assertEquals(10000L * DateTimeUtil.MILLI_TO_NANO, countdownTimePicker.getValue().toNanoOfDay()); assertTrue(countdownTimePicker.isVisible()); assertFalse(countdownTimeLabel.isVisible()); } /** * Testet Starten und Stoppen per Tastatur unter Berücksichtigung der korrekten Fokussierung. */ @Test @Ignore("Betätigen einer fokussierten Schaltfläche per Enter-Taste mit JavaFX 8 nicht mehr möglich") public final void testStartStopPerKeyboard() { final ITimey facade = getController().getGuiHelper().getFacade(); // Sekunden-Feld fokussieren click(scene.lookup("#secondsTextField")); // Zeit auf 0 setzen Platform.runLater(new Runnable() { public void run() { countdownTimePicker.setValue(DateTimeUtil.getLocalTimeForString("00:00:00")); } }); FXTestUtils.awaitEvents(); // bei Zeit = 0 darf sich Countdown nicht starten lassen type(KeyCode.ENTER); verify(facade, never()).startCountdown(); // Zeit setzen Platform.runLater(new Runnable() { public void run() { countdownTimePicker.setValue(DateTimeUtil.getLocalTimeForString("00:00:10")); } }); FXTestUtils.awaitEvents(); // Countdown starten type(KeyCode.ENTER); verify(facade).startCountdown(); // Countdown stoppen type(KeyCode.ENTER); verify(facade).stopCountdown(); } /** * Testet die Verarbeitung eines Ereignisses. */ @Test public final void testHandleEvent() { final CountdownController controller = (CountdownController) getController(); final MessageHelper messageHelper = mock(MessageHelper.class); controller.getGuiHelper().setMessageHelper(messageHelper); // Ereignis auslösen controller.handleEvent(new CountdownExpiredEvent()); waitForThreads(); // sicherstellen, dass Ereignis verarbeitet wird verify(messageHelper).showTrayMessageWithFallbackToDialog(anyString(), anyString(), isNull(TrayIcon.class), isA(ResourceBundle.class)); } /** * Testet die Verarbeitung eines unwichtigen Ereignisses. */ @Test public final void testIgnoreEvent() { final CountdownController controller = (CountdownController) getController(); final MessageHelper messageHelper = mock(MessageHelper.class); controller.getGuiHelper().setMessageHelper(messageHelper); // unwichtiges Ereignis auslösen controller.handleEvent(mock(TimeyEvent.class)); waitForThreads(); // sicherstellen, dass Ereignis ignoriert wird verify(messageHelper, never()).showTrayMessageWithFallbackToDialog(anyString(), anyString(), isNull(TrayIcon.class), isA(ResourceBundle.class)); } }