test: add MockDataServiceTest unit test

This commit is contained in:
5803024019 2026-05-15 22:32:43 +07:00
parent 1f64cee1e0
commit 8f265c8efa

View File

@ -0,0 +1,270 @@
package com.walkguide.service;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.Map;
import static org.assertj.core.api.Assertions.*;
@DisplayName("MockDataService Unit Tests")
class MockDataServiceTest {
private MockDataService mockDataService;
@BeforeEach
void setUp() {
mockDataService = new MockDataService();
}
// ===== getUserStatus TESTS =====
@Test
@DisplayName("getUserStatus - harus return data status user yang sudah diinisialisasi")
void getUserStatus_shouldReturnInitializedUserStatus() {
Map<String, Object> status = mockDataService.getUserStatus();
assertThat(status).isNotNull();
assertThat(status).containsKey("status");
assertThat(status).containsKey("location");
assertThat(status).containsKey("batteryLevel");
assertThat(status).containsKey("lastSeen");
}
@Test
@DisplayName("getUserStatus - nilai default status harus 'Sedang Berjalan'")
void getUserStatus_defaultStatus_shouldBeSedangBerjalan() {
Map<String, Object> status = mockDataService.getUserStatus();
assertThat(status.get("status")).isEqualTo("Sedang Berjalan");
}
@Test
@DisplayName("getUserStatus - nilai default location harus 'Jl. Kenangan, SBY'")
void getUserStatus_defaultLocation_shouldBeJlKenangan() {
Map<String, Object> status = mockDataService.getUserStatus();
assertThat(status.get("location")).isEqualTo("Jl. Kenangan, SBY");
}
@Test
@DisplayName("getUserStatus - nilai default batteryLevel harus 85")
void getUserStatus_defaultBatteryLevel_shouldBe85() {
Map<String, Object> status = mockDataService.getUserStatus();
assertThat(status.get("batteryLevel")).isEqualTo(85);
}
@Test
@DisplayName("getUserStatus - nilai default lastSeen harus berupa timestamp ISO 8601")
void getUserStatus_defaultLastSeen_shouldBeIsoTimestamp() {
Map<String, Object> status = mockDataService.getUserStatus();
assertThat(status.get("lastSeen")).isEqualTo("2026-04-23T08:40:00Z");
}
@Test
@DisplayName("getUserStatus - harus return referensi map yang sama (stateful)")
void getUserStatus_shouldReturnSameMapReference() {
Map<String, Object> first = mockDataService.getUserStatus();
Map<String, Object> second = mockDataService.getUserStatus();
assertThat(first).isSameAs(second);
}
// ===== updateShortcuts TESTS =====
@Test
@DisplayName("updateShortcuts - harus menambahkan entry baru ke hardwareShortcuts")
void updateShortcuts_newEntry_shouldBeAdded() {
Map<String, Object> newShortcuts = new HashMap<>();
newShortcuts.put("volumeUpAction", "start_navigation");
newShortcuts.put("powerAction", "send_sos");
Map<String, Object> result = mockDataService.updateShortcuts(newShortcuts);
assertThat(result.get("volumeUpAction")).isEqualTo("start_navigation");
assertThat(result.get("powerAction")).isEqualTo("send_sos");
}
@Test
@DisplayName("updateShortcuts - nilai lama harus ter-override dengan nilai baru")
void updateShortcuts_existingKey_shouldBeOverridden() {
Map<String, Object> update = new HashMap<>();
update.put("volumeUpAction", "call_guardian"); // override dari "accept_call"
Map<String, Object> result = mockDataService.updateShortcuts(update);
assertThat(result.get("volumeUpAction")).isEqualTo("call_guardian");
}
@Test
@DisplayName("updateShortcuts - key yang tidak diupdate harus tetap ada")
void updateShortcuts_unrelatedKeys_shouldBePreserved() {
Map<String, Object> update = new HashMap<>();
update.put("volumeUpAction", "call_guardian");
// volumeDownAction tidak diubah
Map<String, Object> result = mockDataService.updateShortcuts(update);
assertThat(result.get("volumeDownAction")).isEqualTo("emergency_ping");
}
@Test
@DisplayName("updateShortcuts - harus return map yang sama (bukan salinan baru)")
void updateShortcuts_shouldReturnSameMapInstance() {
Map<String, Object> before = mockDataService.updateShortcuts(new HashMap<>());
Map<String, Object> after = mockDataService.updateShortcuts(new HashMap<>());
assertThat(before).isSameAs(after);
}
@Test
@DisplayName("updateShortcuts - default awal volumeUpAction harus 'accept_call'")
void updateShortcuts_defaultVolumeUpAction_shouldBeAcceptCall() {
Map<String, Object> result = mockDataService.updateShortcuts(new HashMap<>());
assertThat(result.get("volumeUpAction")).isEqualTo("accept_call");
}
@Test
@DisplayName("updateShortcuts - default awal volumeDownAction harus 'emergency_ping'")
void updateShortcuts_defaultVolumeDownAction_shouldBeEmergencyPing() {
Map<String, Object> result = mockDataService.updateShortcuts(new HashMap<>());
assertThat(result.get("volumeDownAction")).isEqualTo("emergency_ping");
}
@Test
@DisplayName("updateShortcuts - update dengan map kosong tidak boleh mengubah nilai yang ada")
void updateShortcuts_emptyMap_shouldNotModifyExistingValues() {
Map<String, Object> result = mockDataService.updateShortcuts(new HashMap<>());
assertThat(result.get("volumeUpAction")).isEqualTo("accept_call");
assertThat(result.get("volumeDownAction")).isEqualTo("emergency_ping");
}
@Test
@DisplayName("updateShortcuts - update berulang harus accumulate semua perubahan")
void updateShortcuts_multipleUpdates_shouldAccumulateChanges() {
mockDataService.updateShortcuts(Map.of("cameraAction", "take_photo"));
mockDataService.updateShortcuts(Map.of("homeAction", "open_walkguide"));
Map<String, Object> result = mockDataService.updateShortcuts(new HashMap<>());
assertThat(result.get("cameraAction")).isEqualTo("take_photo");
assertThat(result.get("homeAction")).isEqualTo("open_walkguide");
}
// ===== updateAiSettings TESTS =====
@Test
@DisplayName("updateAiSettings - harus menambahkan entry baru ke aiSettings")
void updateAiSettings_newEntry_shouldBeAdded() {
Map<String, Object> newSettings = new HashMap<>();
newSettings.put("speechRate", 1.5);
newSettings.put("language", "id-ID");
Map<String, Object> result = mockDataService.updateAiSettings(newSettings);
assertThat(result.get("speechRate")).isEqualTo(1.5);
assertThat(result.get("language")).isEqualTo("id-ID");
}
@Test
@DisplayName("updateAiSettings - nilai lama harus ter-override dengan nilai baru")
void updateAiSettings_existingKey_shouldBeOverridden() {
Map<String, Object> update = new HashMap<>();
update.put("alertDistanceMeters", 5.0); // override dari 2.5
Map<String, Object> result = mockDataService.updateAiSettings(update);
assertThat(result.get("alertDistanceMeters")).isEqualTo(5.0);
}
@Test
@DisplayName("updateAiSettings - key yang tidak diupdate harus tetap ada")
void updateAiSettings_unrelatedKeys_shouldBePreserved() {
Map<String, Object> update = new HashMap<>();
update.put("alertDistanceMeters", 3.0);
// hapticFeedback tidak diubah
Map<String, Object> result = mockDataService.updateAiSettings(update);
assertThat(result.get("hapticFeedback")).isEqualTo(true);
}
@Test
@DisplayName("updateAiSettings - default alertDistanceMeters harus 2.5")
void updateAiSettings_defaultAlertDistance_shouldBe2point5() {
Map<String, Object> result = mockDataService.updateAiSettings(new HashMap<>());
assertThat(result.get("alertDistanceMeters")).isEqualTo(2.5);
}
@Test
@DisplayName("updateAiSettings - default hapticFeedback harus true")
void updateAiSettings_defaultHapticFeedback_shouldBeTrue() {
Map<String, Object> result = mockDataService.updateAiSettings(new HashMap<>());
assertThat(result.get("hapticFeedback")).isEqualTo(true);
}
@Test
@DisplayName("updateAiSettings - harus return map yang sama (bukan salinan baru)")
void updateAiSettings_shouldReturnSameMapInstance() {
Map<String, Object> before = mockDataService.updateAiSettings(new HashMap<>());
Map<String, Object> after = mockDataService.updateAiSettings(new HashMap<>());
assertThat(before).isSameAs(after);
}
@Test
@DisplayName("updateAiSettings - update dengan map kosong tidak boleh mengubah nilai yang ada")
void updateAiSettings_emptyMap_shouldNotModifyExistingValues() {
Map<String, Object> result = mockDataService.updateAiSettings(new HashMap<>());
assertThat(result.get("alertDistanceMeters")).isEqualTo(2.5);
assertThat(result.get("hapticFeedback")).isEqualTo(true);
}
@Test
@DisplayName("updateAiSettings - update boolean ke false harus tersimpan dengan benar")
void updateAiSettings_disableHapticFeedback_shouldBeFalse() {
Map<String, Object> update = new HashMap<>();
update.put("hapticFeedback", false);
Map<String, Object> result = mockDataService.updateAiSettings(update);
assertThat(result.get("hapticFeedback")).isEqualTo(false);
}
@Test
@DisplayName("updateAiSettings - update berulang harus accumulate semua perubahan")
void updateAiSettings_multipleUpdates_shouldAccumulateChanges() {
mockDataService.updateAiSettings(Map.of("confidenceThreshold", 0.85));
mockDataService.updateAiSettings(Map.of("maxObstacleRange", 10));
Map<String, Object> result = mockDataService.updateAiSettings(new HashMap<>());
assertThat(result.get("confidenceThreshold")).isEqualTo(0.85);
assertThat(result.get("maxObstacleRange")).isEqualTo(10);
}
// ===== Isolation Tests =====
@Test
@DisplayName("instance baru harus selalu punya data default yang segar")
void newInstance_shouldAlwaysHaveFreshDefaultData() {
MockDataService instance1 = new MockDataService();
MockDataService instance2 = new MockDataService();
instance1.updateShortcuts(Map.of("volumeUpAction", "changed_action"));
// instance2 tidak terpengaruh perubahan instance1
assertThat(instance2.updateShortcuts(new HashMap<>()).get("volumeUpAction"))
.isEqualTo("accept_call");
}
}