package com.example.views; import com.example.Application; import com.example.components.BarChart; import com.example.components.GridStackItem; import com.example.components.GridStackLayout; import com.example.components.LineChart; import com.example.components.PieChart; import com.vaadin.browserless.SpringBrowserlessTest; import com.vaadin.browserless.ViewPackages; import com.vaadin.browserless.internal.ElementUtilsKt; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.html.Div; import com.vaadin.flow.dom.DomEvent; import com.vaadin.flow.internal.JacksonUtils; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @SpringBootTest(classes = Application.class) @ViewPackages(classes = DashboardView.class) class DashboardViewTest extends SpringBrowserlessTest { @Test void view_rendersGridWithDefaultWidgets() { navigate(DashboardView.class); GridStackLayout grid = $view(GridStackLayout.class).first(); assertNotNull(grid); List layout = grid.getLayout(); assertEquals(4, layout.size(), "expected the four default widgets"); assertTrue(layout.stream().allMatch(p -> p.w() > 0 && p.h() > 0)); } @Test void view_rendersTheThreeCharts() { navigate(DashboardView.class); assertNotNull($view(LineChart.class).first()); assertNotNull($view(BarChart.class).first()); assertNotNull($view(PieChart.class).first()); } @Test void addAndCloseWidget_changesItemCount() { navigate(DashboardView.class); GridStackLayout grid = $view(GridStackLayout.class).first(); int initial = grid.getLayout().size(); button("gridstack.addWidget").click(); assertEquals(initial + 1, grid.getLayout().size()); clickCloseButton($view(GridStackItem.class).last()); assertEquals(initial, grid.getLayout().size()); } @Test void closeButton_removesTheClickedWidgetOnly() { navigate(DashboardView.class); GridStackLayout grid = $view(GridStackLayout.class).first(); GridStackItem first = $view(GridStackItem.class).first(); String closedId = first.getItemId(); clickCloseButton(first); List layout = grid.getLayout(); assertEquals(3, layout.size()); assertFalse(layout.stream().anyMatch(p -> closedId.equals(p.id())), "the closed widget must be gone from the layout"); } @Test void closeListener_firesOnceItemIsDetached() { navigate(DashboardView.class); GridStackLayout grid = $view(GridStackLayout.class).first(); GridStackItem item = $view(GridStackItem.class).first(); int[] fired = {0}; item.addCloseListener(e -> fired[0]++); item.close(); assertEquals(1, fired[0]); assertEquals(3, grid.getLayout().size()); } @Test void nonClosableItem_hasNoCloseButton() { navigate(DashboardView.class); GridStackItem item = $view(GridStackItem.class).first(); assertTrue(item.isClosable(), "items are closable by default"); item.setClosable(false); assertFalse(item.isClosable()); assertFalse(item.getChildren().anyMatch(child -> child == item.getCloseButton())); } /** Fires the DOM click the close button listens for, rather than calling * {@code close()} directly, so the button's own wiring is covered too. */ private void clickCloseButton(GridStackItem item) { Div closeButton = item.getCloseButton(); ElementUtilsKt._fireDomEvent(closeButton.getElement(), new DomEvent(closeButton.getElement(), "click", JacksonUtils.createObjectNode())); } private Button button(String translationKey) { String caption = getCurrentView().getElement().getComponent() .orElseThrow().getTranslation(translationKey); return $view(Button.class).withText(caption).first(); } }