Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions src/main/java/com/example/usecase23/UseCase23View.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ private Component createViewEvents() {
bindData(chart, newYorkSeries, newYorkTimelineSignal);
bindData(chart, tokyoSeries, tokyoTimelineSignal);

Signal.effect(chart, () -> xAxis.setCategories(timelineCategoriesSignal
.get().stream().map(Signal::get).toArray(String[]::new)));
Signal.effect(chart, () -> xAxis.setCategories(
timelineCategoriesSignal.getValues().toArray(String[]::new)));

conf.addSeries(berlinSeries);
conf.addSeries(londonSeries);
Expand All @@ -165,12 +165,8 @@ private Component createViewEvents() {

private static void bindData(Chart chart, ListSeries series,
ListSignal<Number> signal) {
Signal.effect(chart, () -> {
series.setData(signal.get().stream().map(Signal::get)
.toArray(Number[]::new));
// TODO issue of getting the values from ListSignal instead of
// Signal<Number>
});
Signal.effect(chart,
() -> series.setData(signal.getValues().toArray(Number[]::new)));
}

private Component createServiceHealth() {
Expand Down Expand Up @@ -309,7 +305,7 @@ private String getStatusDisplayName(ServiceHealth serviceHealth) {
* Callback invoked by the scheduler service with new dashboard data. This
* method only updates signals - no UI access or chart drawing.
*/
private void onDataUpdate(DashboardData data) {
void onDataUpdate(DashboardData data) {
// Update highlight card signals
currentUsersSignal.set(data.currentUsers());
viewEventsSignal.set(data.viewEvents());
Expand Down Expand Up @@ -389,10 +385,13 @@ private HighlightCard(String title, ValueSignal<Number> signal,
signal.peek().doubleValue(), signal.peek().doubleValue()));

// update previous value when the main signal changes
// Uses runWithoutTransaction since we must track previous state
// No infinite loop risk: effect depends on signal, not changeSignal
Signal.effect(this, () -> {
double current = signal.get().doubleValue();
double previous = changeSignal.peek().current();
changeSignal.set(new Change(previous, current));
Signal.runWithoutTransaction(
() -> changeSignal.set(new Change(previous, current)));
});

// Computed signal for percentage change
Expand All @@ -415,8 +414,8 @@ private HighlightCard(String title, ValueSignal<Number> signal,
valueSpan.bindText(signal.map(format::apply));

Span percentageSpan = new Span();
percentageSpan.bindText(prefixSignal
.map(prefix -> prefix + percentageSignal.get()));
percentageSpan.bindText(Signal.computed(
() -> prefixSignal.get() + percentageSignal.get()));

Icon icon = new Icon(iconSignal);
icon.setSize("10px");
Expand Down
54 changes: 54 additions & 0 deletions src/test/java/com/example/usecase23/UseCase23ViewTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.usecase23;

import java.util.List;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;
Expand All @@ -9,6 +11,7 @@
import com.vaadin.flow.component.board.Board;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Span;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand Down Expand Up @@ -47,4 +50,55 @@ void serviceHealthGridRendered() {
// Grid for service health should be present
assertTrue($view(Grid.class).all().size() >= 1);
}

@Test
void highlightCardUpdatesValueOnDataUpdate() {
navigate(UseCase23View.class);
runPendingSignalsTasks();

UseCase23View view = $view(UseCase23View.class).first();

// Push data update with known values
view.onDataUpdate(createTestData(42, 1500, 3.5, 99));
runPendingSignalsTasks();

// "Current users" card should show "42"
assertTrue($view(Span.class).all().stream()
.anyMatch(s -> "42".equals(s.getText())),
"Expected a Span with text '42' for current users");
}

@Test
void highlightCardShowsPercentageChangeAfterTwoUpdates() {
navigate(UseCase23View.class);
runPendingSignalsTasks();

UseCase23View view = $view(UseCase23View.class).first();

// First update: baseline
view.onDataUpdate(createTestData(100, 1000, 2.0, 50));
runPendingSignalsTasks();

// Second update: double the users (100 → 200 = +100%)
view.onDataUpdate(createTestData(200, 1000, 2.0, 50));
runPendingSignalsTasks();

// Should show "+100.0" in the percentage badge
assertTrue($view(Span.class).all().stream().anyMatch(
s -> s.getText() != null && s.getText().contains("+100.0")),
"Expected percentage badge showing +100.0");
}

private DashboardData createTestData(int users, int views,
double conversion, double custom) {
return new DashboardData(users, views, conversion, custom,
new DashboardData.TimelineData("12:00", 10, 20, 30, 40),
List.of(new ServiceHealth(ServiceHealth.Status.OK,
"Münster", 100, 200),
new ServiceHealth(ServiceHealth.Status.EXCELLENT,
"Cluj-Napoca", 150, 250),
new ServiceHealth(ServiceHealth.Status.FAILING,
"Ciudad Victoria", 50, 75)),
List.of(10.0, 20.0, 30.0, 15.0, 25.0, 35.0));
}
}
Loading