diff --git a/CHANGELOG.md b/CHANGELOG.md index 32fc6b0a..1c7f8f6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ See [Release](https://github.com/itsallcode/white-rabbit/releases/tag/v1.2.0) / * [#52](https://github.com/itsallcode/white-rabbit/issues/52): Improve keyboard usage for autocomplete text fields, immediately show proposals. * [#54](https://github.com/itsallcode/white-rabbit/issues/54): First added activity has the remainder flag set. +### Fixed + +* [#50](https://github.com/itsallcode/white-rabbit/issues/50), [#51](https://github.com/itsallcode/white-rabbit/issues/51): Switch view when month changes. + ## [1.1.0] 2020-11-29 See [Release](https://github.com/itsallcode/white-rabbit/releases/tag/v1.1.0) / [Milestone](https://github.com/itsallcode/white-rabbit/milestone/2?closed=1) diff --git a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java index 44ce7c43..c0314312 100644 --- a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java +++ b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java @@ -2,6 +2,7 @@ import javafx.application.Platform; import javafx.beans.binding.Bindings; +import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; @@ -186,8 +187,7 @@ private BorderPane createMainPane() { final Insets insets = new Insets(GAP_PIXEL); final Node daysTable = dayRecordTable.initTable(); - state.currentDateProperty.property() - .addListener((observable, oldValue, newValue) -> dayRecordTable.selectRow(newValue)); + state.currentDateProperty.property().addListener(this::dateChanged); final Node activitiesTab = activitiesTable.initTable(); final Button addActivityButton = button("add-activity-button", "+", "Add activity", e -> app.addActivity()); final Button removeActivityButton = button("remove-activity-button", "-", "Remove activity", @@ -291,6 +291,7 @@ private Node monthDropDownBox() { state.availableMonths.addAll(appService.getAvailableDataYearMonth()); final ComboBox comboBox = new ComboBox<>(state.availableMonths); + comboBox.setId("selected-month-combobox"); state.currentMonth.addListener( (observable, oldValue, newValue) -> comboBox.getSelectionModel().select(newValue.getYearMonth())); @@ -316,5 +317,12 @@ private Button button(String id, String label, String tooltip, EventHandler observable, LocalDate oldDate, LocalDate newDate) { + dayRecordTable.selectRow(newDate); + if(oldDate.getMonth()!=newDate.getMonth()) { + app.loadMonth(YearMonth.from(newDate)); + } + } } } diff --git a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/JavaFxAppUiTest.java b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/JavaFxAppUiTest.java index e9a8bf7d..51dfcbaa 100644 --- a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/JavaFxAppUiTest.java +++ b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/JavaFxAppUiTest.java @@ -1,13 +1,8 @@ package org.itsallcode.whiterabbit.jfxui; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; - -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalTime; -import java.util.Locale; - +import javafx.scene.control.Labeled; +import javafx.stage.Stage; +import org.itsallcode.whiterabbit.jfxui.testutil.TestUtil; import org.itsallcode.whiterabbit.logic.model.json.JsonDay; import org.itsallcode.whiterabbit.logic.model.json.JsonMonth; import org.junit.jupiter.api.Test; @@ -18,8 +13,11 @@ import org.testfx.framework.junit5.Start; import org.testfx.framework.junit5.Stop; -import javafx.scene.control.Labeled; -import javafx.stage.Stage; +import java.time.*; +import java.util.Locale; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; @ExtendWith(ApplicationExtension.class) class JavaFxAppUiTest extends JavaFxAppUiTestBase @@ -101,6 +99,37 @@ void jsonFileWrittenAfterMinuteTick() () -> assertThat(month.getDays()).extracting(JsonDay::getEnd).containsExactly(end)); } + @Test + void newMonthSelectedWhenMonthChanges() + { + assertAll( + () -> assertThat(app().getSelectedMonth()).isEqualTo(YearMonth.of(2007, Month.DECEMBER)), + () -> app().dayTable().assertDate(0, LocalDate.of(2007, Month.DECEMBER, 1))); + + time().tickDay(LocalDateTime.of(2008, Month.JANUARY, 2, 8, 15, 0)); + + assertAll( + () -> assertThat(app().getSelectedMonth()).isEqualTo(YearMonth.of(2008, Month.JANUARY)), + () -> app().dayTable().assertDate(0, LocalDate.of(2008, Month.JANUARY, 1))); + } + + @Test + void newMonthSelectedUserChangesMonth() + { + time().tickDay(LocalDateTime.of(2008, Month.JANUARY, 2, 8, 15, 0)); + + assertAll( + () -> assertThat(app().getSelectedMonth()).isEqualTo(YearMonth.of(2008, Month.JANUARY)), + () -> app().dayTable().assertDate(0, LocalDate.of(2008, Month.JANUARY, 1))); + + app().setSelectedMonth(YearMonth.of(2007, Month.DECEMBER)); + TestUtil.sleepShort(); + + assertAll( + () -> assertThat(app().getSelectedMonth()).isEqualTo(YearMonth.of(2007, Month.DECEMBER)), + () -> app().dayTable().assertDate(0, LocalDate.of(2007, Month.DECEMBER, 1))); + } + @Override @Start void start(Stage stage) diff --git a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java index eb78a486..5af4755b 100644 --- a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java +++ b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java @@ -1,31 +1,20 @@ package org.itsallcode.whiterabbit.jfxui.testutil; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -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 java.time.Clock; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.ZoneId; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.mockito.ArgumentCaptor; + +import java.time.*; import java.time.temporal.ChronoUnit; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.mockito.ArgumentCaptor; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; public class TimeUtil { @@ -109,7 +98,13 @@ public void tickDay(LocalTime time) { final LocalDateTime now = LocalDateTime.now(clockMock); final LocalDateTime tomorrow = LocalDateTime.of(now.toLocalDate().plusDays(1), time); - final Duration duration = Duration.between(now, tomorrow); + tickDay(tomorrow); + } + + public void tickDay(LocalDateTime nextDay) + { + final LocalDateTime now = LocalDateTime.now(clockMock); + final Duration duration = Duration.between(now, nextDay); addTime(duration); LOG.info("Tick day by {} to {}", duration, clockMock.instant()); this.updateEverySecondRunnable.run(); @@ -145,10 +140,6 @@ public void captureScheduledRunnables() this.updateEverySecondRunnable = arg.getAllValues().get(1); this.updateEveryMinuteRunnable = arg.getAllValues().get(2); - LOG.trace("Found callback for seconds: {}", updateEverySecondRunnable); - LOG.trace("Found callback for days: {}", updateEveryDayRunnable); - LOG.trace("Found callback for minutes: {}", updateEveryMinuteRunnable); - assertAll( () -> assertThat(updateEverySecondRunnable.toString()) .contains("trigger=PeriodicTrigger [roundToUnit=Seconds]"), diff --git a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/ApplicationHelper.java b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/ApplicationHelper.java index fbf87592..bb4624be 100644 --- a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/ApplicationHelper.java +++ b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/ApplicationHelper.java @@ -1,16 +1,18 @@ package org.itsallcode.whiterabbit.jfxui.testutil.model; -import java.time.Duration; - +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.SplitMenuButton; +import javafx.scene.layout.StackPane; +import javafx.stage.Window; +import org.itsallcode.whiterabbit.jfxui.JavaFxUtil; import org.itsallcode.whiterabbit.jfxui.table.activities.ActivityPropertyAdapter; import org.itsallcode.whiterabbit.jfxui.table.days.DayRecordPropertyAdapter; import org.testfx.api.FxRobot; import org.testfx.assertions.api.Assertions; -import javafx.scene.control.Button; -import javafx.scene.control.SplitMenuButton; -import javafx.scene.layout.StackPane; -import javafx.stage.Window; +import java.time.Duration; +import java.time.YearMonth; public class ApplicationHelper { @@ -80,4 +82,19 @@ public AddInterruptionDialog addInterruption() Assertions.assertThat(dialogWindow).isShowing(); return new AddInterruptionDialog(robot, dialogWindow); } + + public YearMonth getSelectedMonth() + { + return getSelectedMonthComboBox().getValue(); + } + + public void setSelectedMonth(YearMonth month) + { + JavaFxUtil.runOnFxApplicationThread(() -> getSelectedMonthComboBox().setValue(month)); + } + + private ComboBox getSelectedMonthComboBox() + { + return robot.lookup("#selected-month-combobox").queryComboBox(); + } } diff --git a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/DayTable.java b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/DayTable.java index b8f75708..3e2c72fe 100644 --- a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/DayTable.java +++ b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/DayTable.java @@ -11,6 +11,7 @@ import org.testfx.api.FxRobot; import java.time.Duration; +import java.time.LocalDate; import java.time.LocalTime; import static org.assertj.core.api.Assertions.assertThat; @@ -46,6 +47,17 @@ public void assertBeginAndEnd(int row, LocalTime begin, LocalTime end) () -> assertThat(getEnd(row)).as("end").isEqualTo(end)); } + public void assertDate(int row, LocalDate expectedDate) + { + assertThat(getDate(row)).isEqualTo(expectedDate); + } + + public LocalDate getDate(int row) + { + final TableCell tableCell = table.getTableCell(row, "date"); + return (LocalDate) tableCell.getItem(); + } + public LocalTime getBegin(int row) { final TableCell tableCell = table.getTableCell(row, "begin"); @@ -94,7 +106,8 @@ public void typeComment(int row, String value) robot.doubleClickOn(getCommentCell(row)).write(value).type(KeyCode.TAB); } - public TableCell getCommentCell(int row) { + public TableCell getCommentCell(int row) + { return table.getTableCell(row, "comment"); }