diff --git a/eeg_backend/src/test/java/at/mueller/eeg/backend/dashboard/service/DashboardServiceTest.java b/eeg_backend/src/test/java/at/mueller/eeg/backend/dashboard/service/DashboardServiceTest.java index e9514f6..d1ef0f1 100644 --- a/eeg_backend/src/test/java/at/mueller/eeg/backend/dashboard/service/DashboardServiceTest.java +++ b/eeg_backend/src/test/java/at/mueller/eeg/backend/dashboard/service/DashboardServiceTest.java @@ -1,21 +1,29 @@ package at.mueller.eeg.backend.dashboard.service; -import at.mueller.eeg.backend.community.domain.MembershipStatus; +import at.mueller.eeg.backend.community.domain.*; +import at.mueller.eeg.backend.community.domain.state.MakoState; import at.mueller.eeg.backend.community.repository.EnergyCommunityRepository; -import at.mueller.eeg.backend.community.repository.MembershipRepository; +import at.mueller.eeg.backend.community.repository.MeteringDataRepository; import at.mueller.eeg.backend.community.repository.MeteringPointRepository; +import at.mueller.eeg.backend.community.repository.MembershipRepository; import at.mueller.eeg.backend.dashboard.api.dto.DashboardStatsDto; import at.mueller.eeg.backend.iam.domain.RegistrationStatus; import at.mueller.eeg.backend.iam.repository.UserRepository; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.util.UUID; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.*; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) @@ -23,45 +31,131 @@ class DashboardServiceTest { @Mock private EnergyCommunityRepository energyCommunityRepository; - @Mock private UserRepository userRepository; - @Mock private MembershipRepository membershipRepository; - @Mock private MeteringPointRepository meteringPointRepository; + @Mock + private MeteringDataRepository meteringDataRepository; @InjectMocks private DashboardService dashboardService; - @Test - void getAdminStats_returnsCorrectCounts() { - when(energyCommunityRepository.count()).thenReturn(5L); - when(userRepository.countByStatusAndEmailVerified(RegistrationStatus.PENDING, true)).thenReturn(3L); - when(membershipRepository.countByStatus(MembershipStatus.PENDING)).thenReturn(2L); - when(membershipRepository.countByStatus(MembershipStatus.ACTIVE)).thenReturn(10L); + private UUID userId; + private UUID meteringPointId; + private MeteringPoint meteringPoint; - DashboardStatsDto.AdminStats stats = dashboardService.getAdminStats(); + @BeforeEach + void setUp() { + userId = UUID.randomUUID(); + meteringPointId = UUID.randomUUID(); - assertEquals(5, stats.totalCommunities()); - assertEquals(3, stats.pendingUsers()); - assertEquals(2, stats.pendingMemberships()); - assertEquals(10, stats.totalActiveMemberships()); + meteringPoint = new MeteringPoint(); + meteringPoint.setId(meteringPointId); + meteringPoint.setUserId(userId); + meteringPoint.setAtNumber("AT0010000000000000000000001234567"); + meteringPoint.setType(PointType.CONSUMER); + meteringPoint.setMakoState(MakoState.ACTIVE); } @Test - void getUserStats_returnsCorrectCounts() { - UUID userId = UUID.randomUUID(); - when(meteringPointRepository.countByUserId(userId)).thenReturn(2L); - when(membershipRepository.countByUserIdAndStatus(userId, MembershipStatus.ACTIVE)).thenReturn(1L); - when(membershipRepository.countByUserIdAndStatus(userId, MembershipStatus.PENDING)).thenReturn(1L); + void getMeteringDataOverview_withData_returnsTimeSeries() { + Instant from = Instant.parse("2026-01-01T00:00:00Z"); + Instant to = Instant.parse("2026-01-03T00:00:00Z"); - DashboardStatsDto.UserStats stats = dashboardService.getUserStats(userId); + when(meteringPointRepository.findAllByUserId(userId)).thenReturn(List.of(meteringPoint)); - assertEquals(2, stats.totalMeteringPoints()); - assertEquals(1, stats.activeMemberships()); - assertEquals(1, stats.pendingMemberships()); + ZoneId systemZone = ZoneId.systemDefault(); + List meteringData = List.of( + createMeteringData(meteringPointId, Instant.parse("2026-01-01T10:00:00Z"), 5.0), + createMeteringData(meteringPointId, Instant.parse("2026-01-02T10:00:00Z"), 3.0) + ); + when(meteringDataRepository.findByMeteringPointIdAndIntervalStartBetween(meteringPointId, from, to)) + .thenReturn(meteringData); + + DashboardStatsDto.MeteringDataOverview overview = dashboardService.getMeteringDataOverview(userId, from, to); + + assertEquals(1, overview.meteringPoints().size()); + assertEquals("AT0010000000000000000000001234567", overview.meteringPoints().get(0).atNumber()); + assertEquals(8.0, overview.meteringPoints().get(0).totalKwh(), 0.01); + assertEquals(2, overview.timeSeries().size()); + } + + @Test + void getMeteringDataOverview_noMeteringPoints_returnsEmptyOverview() { + Instant from = Instant.parse("2026-01-01T00:00:00Z"); + Instant to = Instant.parse("2026-01-03T00:00:00Z"); + + when(meteringPointRepository.findAllByUserId(userId)).thenReturn(Collections.emptyList()); + + DashboardStatsDto.MeteringDataOverview overview = dashboardService.getMeteringDataOverview(userId, from, to); + + assertTrue(overview.meteringPoints().isEmpty()); + assertTrue(overview.timeSeries().isEmpty()); + } + + @Test + void getMeteringDataOverview_noDataInTimeRange_returnsEmptyTimeSeries() { + Instant from = Instant.parse("2026-01-01T00:00:00Z"); + Instant to = Instant.parse("2026-01-03T00:00:00Z"); + + when(meteringPointRepository.findAllByUserId(userId)).thenReturn(List.of(meteringPoint)); + when(meteringDataRepository.findByMeteringPointIdAndIntervalStartBetween(meteringPointId, from, to)) + .thenReturn(Collections.emptyList()); + + DashboardStatsDto.MeteringDataOverview overview = dashboardService.getMeteringDataOverview(userId, from, to); + + assertEquals(1, overview.meteringPoints().size()); + assertEquals(0.0, overview.meteringPoints().get(0).totalKwh(), 0.01); + assertTrue(overview.timeSeries().isEmpty()); + } + + @Test + void getMeteringDataOverview_multipleMeteringPoints_aggregatesCorrectly() { + Instant from = Instant.parse("2026-06-01T00:00:00Z"); + Instant to = Instant.parse("2026-06-02T00:00:00Z"); + + MeteringPoint mp2 = new MeteringPoint(); + mp2.setId(UUID.randomUUID()); + mp2.setUserId(userId); + mp2.setAtNumber("AT0010000000000000000000001234568"); + mp2.setType(PointType.PRODUCER); + mp2.setMakoState(MakoState.ACTIVE); + + when(meteringPointRepository.findAllByUserId(userId)).thenReturn(List.of(meteringPoint, mp2)); + + List data1 = List.of(createMeteringData(meteringPointId, Instant.parse("2026-06-01T10:00:00Z"), 5.0)); + List data2 = List.of(createMeteringData(mp2.getId(), Instant.parse("2026-06-01T10:00:00Z"), 3.0)); + + when(meteringDataRepository.findByMeteringPointIdAndIntervalStartBetween(meteringPointId, from, to)) + .thenReturn(data1); + when(meteringDataRepository.findByMeteringPointIdAndIntervalStartBetween(mp2.getId(), from, to)) + .thenReturn(data2); + + DashboardStatsDto.MeteringDataOverview overview = dashboardService.getMeteringDataOverview(userId, from, to); + + assertEquals(2, overview.meteringPoints().size()); + assertEquals(1, overview.timeSeries().size()); + + DashboardStatsDto.TimeSeriesEntry entry = overview.timeSeries().get(0); + assertEquals(5.0, entry.values().get("AT0010000000000000000000001234567"), 0.01); + assertEquals(3.0, entry.values().get("AT0010000000000000000000001234568"), 0.01); + } + + private MeteringData createMeteringData(UUID meteringPointId, Instant intervalStart, double kwh) { + MeteringPoint mp = new MeteringPoint(); + mp.setId(meteringPointId); + + MeteringData data = new MeteringData(); + data.setMeteringPoint(mp); + data.setDataType(MeteringDataType.CONSUMPTION); + data.setIntervalStart(intervalStart); + data.setIntervalEnd(intervalStart.plusSeconds(3600)); + data.setKwh(kwh); + data.setSource(DataSource.EMAIL_XLSX); + data.setUploadId(UUID.randomUUID()); + return data; } } diff --git a/eeg_frontend/src/app/pages/dashboard-overview/dashboard-overview.ts b/eeg_frontend/src/app/pages/dashboard-overview/dashboard-overview.ts index f1958cb..ac4d063 100644 --- a/eeg_frontend/src/app/pages/dashboard-overview/dashboard-overview.ts +++ b/eeg_frontend/src/app/pages/dashboard-overview/dashboard-overview.ts @@ -65,7 +65,11 @@ export class DashboardOverview implements OnInit { this.meteringData.set(data); this.buildChartOptions(data); }, - error: () => {} + error: (err) => { + console.error('Fehler beim Laden der Messdaten:', err); + this.error.set('Fehler beim Laden der Messdaten.'); + this.isLoading.set(false); + } }); }